1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
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
76 private String volumeId;
77 private Attachment.Status attachmentStatus;
78 private Date attachTime;
79 private boolean deleteOnTermination;
80 private String deviceName;
81
82
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
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
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
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 }