View Javadoc

1   /**
2    *
3    * Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
4    *
5    * ====================================================================
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   * ====================================================================
18   */
19  package org.jclouds.ec2.xml;
20  
21  import java.util.Date;
22  import java.util.Set;
23  
24  import javax.annotation.Resource;
25  import javax.inject.Inject;
26  
27  import org.jclouds.aws.util.AWSUtils;
28  import org.jclouds.date.DateService;
29  import org.jclouds.ec2.domain.Attachment;
30  import org.jclouds.ec2.domain.BlockDevice;
31  import org.jclouds.ec2.domain.InstanceState;
32  import org.jclouds.ec2.domain.Reservation;
33  import org.jclouds.ec2.domain.RootDeviceType;
34  import org.jclouds.ec2.domain.RunningInstance;
35  import org.jclouds.ec2.domain.RunningInstance.Builder;
36  import org.jclouds.http.functions.ParseSax.HandlerForGeneratedRequestWithResult;
37  import org.jclouds.location.Region;
38  import org.jclouds.logging.Logger;
39  import org.xml.sax.Attributes;
40  
41  import com.google.common.collect.Sets;
42  import com.google.inject.Provider;
43  
44  /**
45   * 
46   * @author Adrian Cole
47   */
48  public abstract class BaseReservationHandler<T> extends HandlerForGeneratedRequestWithResult<T> {
49  
50     @Resource
51     protected Logger logger = Logger.NULL;
52  
53     protected final DateService dateService;
54     protected final String defaultRegion;
55     protected final Provider<Builder> builderProvider;
56  
57     @Inject
58     public BaseReservationHandler(DateService dateService, @Region String defaultRegion,
59              Provider<RunningInstance.Builder> builderProvider) {
60        this.dateService = dateService;
61        this.defaultRegion = defaultRegion;
62        this.builderProvider = builderProvider;
63        this.builder = builderProvider.get();
64     }
65  
66     protected StringBuilder currentText = new StringBuilder();
67  
68     protected Builder builder;
69  
70     protected int itemDepth;
71     boolean inInstancesSet;
72     // attachments
73     private String volumeId;
74     private Attachment.Status attachmentStatus;
75     private Date attachTime;
76     private boolean deleteOnTermination;
77     private String deviceName;
78  
79     // reservation stuff
80     private Set<String> groupIds = Sets.newLinkedHashSet();
81     private String ownerId;
82     private String requesterId;
83     private String reservationId;
84  
85     private Set<RunningInstance> instances = Sets.newLinkedHashSet();
86  
87     public void startElement(String uri, String name, String qName, Attributes attrs) {
88        if (qName.equals("item")) {
89           itemDepth++;
90        } else if (qName.equals("instancesSet")) {
91           inInstancesSet = true;
92        }
93     }
94  
95     protected String currentOrNull() {
96        String returnVal = currentText.toString().trim();
97        return returnVal.equals("") ? null : returnVal;
98     }
99  
100    public void endElement(String uri, String name, String qName) {
101       if (qName.equals("item")) {
102          inItem();
103          itemDepth--;
104       } else if (qName.equals("instancesSet")) {
105          inInstancesSet = false;
106       } else if (qName.equals("groupId")) {
107          groupIds.add(currentOrNull());
108       } else if (qName.equals("ownerId")) {
109          ownerId = currentOrNull();
110       } else if (qName.equals("requesterId")) {
111          requesterId = currentOrNull();
112       } else if (qName.equals("reservationId")) {
113          reservationId = currentOrNull();
114       } else if (qName.equals("amiLaunchIndex")) {
115          builder.amiLaunchIndex(currentOrNull());
116       } else if (qName.equals("dnsName")) {
117          String dnsName = currentOrNull();
118          // Eucalyptus
119          if (!"0.0.0.0".equals(dnsName))
120             builder.dnsName(dnsName);
121       } else if (qName.equals("imageId")) {
122          builder.imageId(currentOrNull());
123       } else if (qName.equals("instanceId")) {
124          builder.instanceId(currentOrNull());
125       } else if (qName.equals("name")) {
126          builder.instanceState(InstanceState.fromValue(currentOrNull()));
127       } else if (qName.equals("instanceType")) {
128          builder.instanceType(currentOrNull());
129       } else if (qName.equals("ipAddress")) {
130          builder.ipAddress(currentOrNull());
131       } else if (qName.equals("kernelId")) {
132          builder.kernelId(currentOrNull());
133       } else if (qName.equals("keyName")) {
134          builder.keyName(currentOrNull());
135       } else if (qName.equals("launchTime")) {
136          builder.launchTime(parseDate());
137       } else if (qName.equals("availabilityZone")) {
138          builder.availabilityZone(currentOrNull());
139       } else if (qName.equals("virtualizationType")) {
140          builder.virtualizationType(currentOrNull());
141       } else if (qName.equals("platform")) {
142          builder.platform(currentOrNull());
143       } else if (qName.equals("privateDnsName")) {
144          String privateDnsName = currentOrNull();
145          // Eucalyptus
146          if (!"0.0.0.0".equals(privateDnsName))
147             builder.privateDnsName(privateDnsName);
148       } else if (qName.equals("privateIpAddress")) {
149          builder.privateIpAddress(currentOrNull());
150       } else if (qName.equals("ramdiskId")) {
151          builder.ramdiskId(currentOrNull());
152       } else if (qName.equals("reason")) {
153          builder.reason(currentOrNull());
154       } else if (qName.equals("rootDeviceType")) {
155          builder.rootDeviceType(RootDeviceType.fromValue(currentOrNull()));
156       } else if (qName.equals("rootDeviceName")) {
157          builder.rootDeviceName(currentOrNull());
158       } else if (qName.equals("deviceName")) {
159          deviceName = currentOrNull();
160       } else if (qName.equals("volumeId")) {
161          volumeId = currentOrNull();
162       } else if (qName.equals("status")) {
163          attachmentStatus = Attachment.Status.fromValue(currentText.toString().trim());
164       } else if (qName.equals("attachTime")) {
165          attachTime = dateService.iso8601DateParse(currentText.toString().trim());
166       } else if (qName.equals("deleteOnTermination")) {
167          deleteOnTermination = Boolean.parseBoolean(currentText.toString().trim());
168       } else if (qName.equals("ebs")) {
169          builder.device(deviceName, new BlockDevice(volumeId, attachmentStatus, attachTime, deleteOnTermination));
170          this.deviceName = null;
171          this.volumeId = null;
172          this.attachmentStatus = null;
173          this.attachTime = null;
174          this.deleteOnTermination = true;
175       } 
176       currentText = new StringBuilder();
177    }
178 
179    protected Date parseDate() {
180       try {
181          return dateService.iso8601DateParse(currentOrNull());
182       } catch (RuntimeException e) {
183          // Eucalyptus
184          return dateService.iso8601SecondsDateParse(currentOrNull());
185       }
186    }
187 
188    protected void inItem() {
189       if (endOfInstanceItem()) {
190          refineBuilderBeforeAddingInstance();
191          instances.add(builder.build());
192          builder = builderProvider.get();
193       }
194    }
195 
196    protected void refineBuilderBeforeAddingInstance() {
197       String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null;
198 
199       // Eucalyptus
200       if (builder.getIpAddress() == null && builder.getDnsName() != null && builder.getDnsName().matches(".*[0-9]$")) {
201          builder.ipAddress(builder.getDnsName());
202          builder.dnsName(null);
203       }
204       if (builder.getPrivateIpAddress() == null && builder.getPrivateDnsName() != null
205                && builder.getPrivateDnsName().matches(".*[0-9]$")) {
206          builder.privateIpAddress(builder.getPrivateDnsName());
207          builder.privateDnsName(null);
208       }
209 
210       builder.region((region == null) ? defaultRegion : region);
211       builder.groupIds(groupIds);
212    }
213 
214    protected Builder builder() {
215       return builder;
216    }
217 
218    protected boolean endOfInstanceItem() {
219       return itemDepth <= 2 && inInstancesSet;
220    }
221 
222    public void characters(char ch[], int start, int length) {
223       currentText.append(ch, start, length);
224    }
225 
226    protected Reservation<? extends RunningInstance> newReservation() {
227       String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null;
228       if (region == null)
229          region = defaultRegion;
230       Reservation<? extends RunningInstance> info = new Reservation<RunningInstance>(region, groupIds, instances,
231                ownerId, requesterId, reservationId);
232       this.groupIds = Sets.newLinkedHashSet();
233       this.instances = Sets.newLinkedHashSet();
234       this.ownerId = null;
235       this.requesterId = null;
236       this.reservationId = null;
237       return info;
238    }
239 
240 }