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.aws.ec2.xml;
20  
21  import static org.jclouds.util.SaxUtils.currentOrNull;
22  import static org.jclouds.util.SaxUtils.equalsOrSuffix;
23  
24  import java.util.Date;
25  import java.util.Map;
26  import java.util.Set;
27  
28  import javax.annotation.Resource;
29  import javax.inject.Inject;
30  
31  import org.jclouds.aws.ec2.domain.AWSRunningInstance;
32  import org.jclouds.aws.ec2.domain.MonitoringState;
33  import org.jclouds.aws.util.AWSUtils;
34  import org.jclouds.date.DateService;
35  import org.jclouds.ec2.domain.Attachment;
36  import org.jclouds.ec2.domain.BlockDevice;
37  import org.jclouds.ec2.domain.InstanceState;
38  import org.jclouds.ec2.domain.Reservation;
39  import org.jclouds.ec2.domain.RootDeviceType;
40  import org.jclouds.ec2.domain.RunningInstance;
41  import org.jclouds.http.functions.ParseSax.HandlerForGeneratedRequestWithResult;
42  import org.jclouds.location.Region;
43  import org.jclouds.logging.Logger;
44  import org.xml.sax.Attributes;
45  import org.xml.sax.SAXException;
46  
47  import com.google.common.collect.Maps;
48  import com.google.common.collect.Sets;
49  import com.google.inject.Provider;
50  
51  /**
52   * 
53   * @author Adrian Cole
54   */
55  public abstract class BaseAWSReservationHandler<T> extends HandlerForGeneratedRequestWithResult<T> {
56  
57     @Resource
58     protected Logger logger = Logger.NULL;
59  
60     protected final DateService dateService;
61     protected final String defaultRegion;
62     protected final Provider<AWSRunningInstance.Builder> builderProvider;
63  
64     @Inject
65     public BaseAWSReservationHandler(DateService dateService, @Region String defaultRegion,
66           Provider<AWSRunningInstance.Builder> builderProvider) {
67        this.dateService = dateService;
68        this.defaultRegion = defaultRegion;
69        this.builderProvider = builderProvider;
70        this.builder = builderProvider.get();
71     }
72  
73     protected StringBuilder currentText = new StringBuilder();
74  
75     protected AWSRunningInstance.Builder builder;
76  
77     protected int itemDepth;
78     boolean inInstancesSet;
79     // attachments
80     private String volumeId;
81     private Attachment.Status attachmentStatus;
82     private Date attachTime;
83     private boolean deleteOnTermination;
84     private String deviceName;
85  
86     // reservation stuff
87     private String groupId;
88     private Map<String, String> reservationGroupIdToNames = Maps.newLinkedHashMap();
89     private String ownerId;
90     private String requesterId;
91     private String reservationId;
92  
93     private Set<RunningInstance> instances = Sets.newLinkedHashSet();
94  
95     protected int depth = 0;
96  
97     private boolean inPlacement;
98  
99     @Override
100    public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
101       if (equalsOrSuffix(qName, "item")) {
102          itemDepth++;
103       } else if (equalsOrSuffix(qName, "instancesSet")) {
104          inInstancesSet = true;
105       } else if (equalsOrSuffix(qName, "placement")) {
106          inPlacement = true;
107       }
108    }
109 
110    public void endElement(String uri, String name, String qName) {
111       if (equalsOrSuffix(qName, "item")) {
112          inItem();
113          itemDepth--;
114       } else if (equalsOrSuffix(qName, "state")) {
115          builder.monitoringState(MonitoringState.fromValue(currentOrNull(currentText)));
116       } else if (equalsOrSuffix(qName, "groupId")) {
117          groupId = currentOrNull(currentText);
118       } else if (equalsOrSuffix(qName, "groupName") && inPlacement) {
119          builder.placementGroup(currentOrNull(currentText));
120       } else if (equalsOrSuffix(qName, "groupName")) {
121          switch (itemDepth) {
122          case 2:
123             reservationGroupIdToNames.put(groupId, currentOrNull(currentText));
124             break;
125          case 3:
126             builder.securityGroupIdToName(groupId, currentOrNull(currentText));
127             break;
128          }
129          groupId = null;
130       } else if (equalsOrSuffix(qName, "subnetId")) {
131          builder.subnetId(currentOrNull(currentText));
132       } else if (equalsOrSuffix(qName, "spotInstanceRequestId")) {
133          builder.spotInstanceRequestId(currentOrNull(currentText));
134       } else if (equalsOrSuffix(qName, "vpcId")) {
135          builder.vpcId(currentOrNull(currentText));
136       } else if (equalsOrSuffix(qName, "productCode")) {
137          builder.productCode(currentOrNull(currentText));
138       } else if (equalsOrSuffix(qName, "instancesSet")) {
139          inInstancesSet = false;
140       } else if (equalsOrSuffix(qName, "placement")) {
141          inPlacement = false;
142       } else if (equalsOrSuffix(qName, "ownerId")) {
143          ownerId = currentOrNull(currentText);
144       } else if (equalsOrSuffix(qName, "requesterId")) {
145          requesterId = currentOrNull(currentText);
146       } else if (equalsOrSuffix(qName, "reservationId")) {
147          reservationId = currentOrNull(currentText);
148       } else if (equalsOrSuffix(qName, "amiLaunchIndex")) {
149          builder.amiLaunchIndex(currentOrNull(currentText));
150       } else if (equalsOrSuffix(qName, "dnsName")) {
151          builder.dnsName(currentOrNull(currentText));
152       } else if (equalsOrSuffix(qName, "imageId")) {
153          builder.imageId(currentOrNull(currentText));
154       } else if (equalsOrSuffix(qName, "instanceId")) {
155          builder.instanceId(currentOrNull(currentText));
156       } else if (equalsOrSuffix(qName, "name")) {
157          builder.instanceState(InstanceState.fromValue(currentOrNull(currentText)));
158       } else if (equalsOrSuffix(qName, "instanceType")) {
159          builder.instanceType(currentOrNull(currentText));
160       } else if (equalsOrSuffix(qName, "ipAddress")) {
161          builder.ipAddress(currentOrNull(currentText));
162       } else if (equalsOrSuffix(qName, "kernelId")) {
163          builder.kernelId(currentOrNull(currentText));
164       } else if (equalsOrSuffix(qName, "keyName")) {
165          builder.keyName(currentOrNull(currentText));
166       } else if (equalsOrSuffix(qName, "launchTime")) {
167          builder.launchTime(parseDate());
168       } else if (equalsOrSuffix(qName, "availabilityZone")) {
169          builder.availabilityZone(currentOrNull(currentText));
170       } else if (equalsOrSuffix(qName, "virtualizationType")) {
171          builder.virtualizationType(currentOrNull(currentText));
172       } else if (equalsOrSuffix(qName, "platform")) {
173          builder.platform(currentOrNull(currentText));
174       } else if (equalsOrSuffix(qName, "privateDnsName")) {
175          builder.privateDnsName(currentOrNull(currentText));
176       } else if (equalsOrSuffix(qName, "privateIpAddress")) {
177          builder.privateIpAddress(currentOrNull(currentText));
178       } else if (equalsOrSuffix(qName, "ramdiskId")) {
179          builder.ramdiskId(currentOrNull(currentText));
180       } else if (equalsOrSuffix(qName, "reason")) {
181          builder.reason(currentOrNull(currentText));
182       } else if (equalsOrSuffix(qName, "rootDeviceType")) {
183          builder.rootDeviceType(RootDeviceType.fromValue(currentOrNull(currentText)));
184       } else if (equalsOrSuffix(qName, "rootDeviceName")) {
185          builder.rootDeviceName(currentOrNull(currentText));
186       } else if (equalsOrSuffix(qName, "deviceName")) {
187          deviceName = currentOrNull(currentText);
188       } else if (equalsOrSuffix(qName, "volumeId")) {
189          volumeId = currentOrNull(currentText);
190       } else if (equalsOrSuffix(qName, "status")) {
191          attachmentStatus = Attachment.Status.fromValue(currentText.toString().trim());
192       } else if (equalsOrSuffix(qName, "attachTime")) {
193          attachTime = dateService.iso8601DateParse(currentText.toString().trim());
194       } else if (equalsOrSuffix(qName, "deleteOnTermination")) {
195          deleteOnTermination = Boolean.parseBoolean(currentText.toString().trim());
196       } else if (equalsOrSuffix(qName, "ebs")) {
197          builder.device(deviceName, new BlockDevice(volumeId, attachmentStatus, attachTime, deleteOnTermination));
198          this.deviceName = null;
199          this.volumeId = null;
200          this.attachmentStatus = null;
201          this.attachTime = null;
202          this.deleteOnTermination = true;
203       }
204       currentText = new StringBuilder();
205    }
206 
207    protected Date parseDate() {
208       return dateService.iso8601DateParse(currentOrNull(currentText));
209    }
210 
211    protected void inItem() {
212       if (endOfInstanceItem()) {
213          refineBuilderBeforeAddingInstance();
214          instances.add(builder.build());
215          builder = builderProvider.get();
216       }
217    }
218 
219    protected void refineBuilderBeforeAddingInstance() {
220       String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null;
221       builder.region((region == null) ? defaultRegion : region);
222    }
223 
224    protected abstract boolean endOfInstanceItem();
225 
226    public void characters(char ch[], int start, int length) {
227       currentText.append(ch, start, length);
228    }
229 
230    protected Reservation<? extends RunningInstance> newReservation() {
231       String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null;
232       if (region == null)
233          region = defaultRegion;
234       Reservation<? extends RunningInstance> info = new Reservation<RunningInstance>(region,
235             reservationGroupIdToNames.values(), instances, ownerId, requesterId, reservationId);
236       this.reservationGroupIdToNames = Maps.newLinkedHashMap();
237       this.instances = Sets.newLinkedHashSet();
238       this.ownerId = null;
239       this.requesterId = null;
240       this.reservationId = null;
241       return info;
242    }
243 
244 }