View Javadoc

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