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.annotation.Resource;
28 import javax.inject.Inject;
29
30 import org.jclouds.aws.util.AWSUtils;
31 import org.jclouds.date.DateService;
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.jclouds.logging.Logger;
42 import org.xml.sax.Attributes;
43
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 @Resource
54 protected Logger logger = Logger.NULL;
55
56 protected final DateService dateService;
57 protected final String defaultRegion;
58 protected final Provider<Builder> builderProvider;
59
60 @Inject
61 public BaseReservationHandler(DateService dateService, @Region String defaultRegion,
62 Provider<RunningInstance.Builder> builderProvider) {
63 this.dateService = dateService;
64 this.defaultRegion = defaultRegion;
65 this.builderProvider = builderProvider;
66 this.builder = builderProvider.get();
67 }
68
69 protected StringBuilder currentText = new StringBuilder();
70
71 protected Builder builder;
72
73 protected int itemDepth;
74 boolean inInstancesSet;
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> groupIds = Sets.newLinkedHashSet();
84 private String ownerId;
85 private String requesterId;
86 private String reservationId;
87
88 private Set<RunningInstance> instances = Sets.newLinkedHashSet();
89
90 public void startElement(String uri, String name, String qName, Attributes attrs) {
91 if (equalsOrSuffix(qName, "item")) {
92 itemDepth++;
93 } else if (equalsOrSuffix(qName, "instancesSet")) {
94 inInstancesSet = true;
95 }
96 }
97
98 public void endElement(String uri, String name, String qName) {
99 if (equalsOrSuffix(qName, "item")) {
100 inItem();
101 itemDepth--;
102 } else if (equalsOrSuffix(qName, "instancesSet")) {
103 inInstancesSet = false;
104 } else if (equalsOrSuffix(qName, "groupId")) {
105 groupIds.add(currentOrNull(currentText));
106 } else if (equalsOrSuffix(qName, "ownerId")) {
107 ownerId = currentOrNull(currentText);
108 } else if (equalsOrSuffix(qName, "requesterId")) {
109 requesterId = currentOrNull(currentText);
110 } else if (equalsOrSuffix(qName, "reservationId")) {
111 reservationId = currentOrNull(currentText);
112 } else if (equalsOrSuffix(qName, "amiLaunchIndex")) {
113 builder.amiLaunchIndex(currentOrNull(currentText));
114 } else if (equalsOrSuffix(qName, "dnsName")) {
115 String dnsName = currentOrNull(currentText);
116
117 if (!"0.0.0.0".equals(dnsName))
118 builder.dnsName(dnsName);
119 } else if (equalsOrSuffix(qName, "imageId")) {
120 builder.imageId(currentOrNull(currentText));
121 } else if (equalsOrSuffix(qName, "instanceId")) {
122 builder.instanceId(currentOrNull(currentText));
123 } else if (equalsOrSuffix(qName, "name")) {
124 builder.instanceState(InstanceState.fromValue(currentOrNull(currentText)));
125 } else if (equalsOrSuffix(qName, "instanceType")) {
126 builder.instanceType(currentOrNull(currentText));
127 } else if (equalsOrSuffix(qName, "ipAddress")) {
128 builder.ipAddress(currentOrNull(currentText));
129 } else if (equalsOrSuffix(qName, "kernelId")) {
130 builder.kernelId(currentOrNull(currentText));
131 } else if (equalsOrSuffix(qName, "keyName")) {
132 builder.keyName(currentOrNull(currentText));
133 } else if (equalsOrSuffix(qName, "launchTime")) {
134 builder.launchTime(parseDate());
135 } else if (equalsOrSuffix(qName, "availabilityZone")) {
136 builder.availabilityZone(currentOrNull(currentText));
137 } else if (equalsOrSuffix(qName, "virtualizationType")) {
138 builder.virtualizationType(currentOrNull(currentText));
139 } else if (equalsOrSuffix(qName, "platform")) {
140 builder.platform(currentOrNull(currentText));
141 } else if (equalsOrSuffix(qName, "privateDnsName")) {
142 String privateDnsName = currentOrNull(currentText);
143
144 if (!"0.0.0.0".equals(privateDnsName))
145 builder.privateDnsName(privateDnsName);
146 } else if (equalsOrSuffix(qName, "privateIpAddress")) {
147 builder.privateIpAddress(currentOrNull(currentText));
148 } else if (equalsOrSuffix(qName, "ramdiskId")) {
149 builder.ramdiskId(currentOrNull(currentText));
150 } else if (equalsOrSuffix(qName, "reason")) {
151 builder.reason(currentOrNull(currentText));
152 } else if (equalsOrSuffix(qName, "rootDeviceType")) {
153 builder.rootDeviceType(RootDeviceType.fromValue(currentOrNull(currentText)));
154 } else if (equalsOrSuffix(qName, "rootDeviceName")) {
155 builder.rootDeviceName(currentOrNull(currentText));
156 } else if (equalsOrSuffix(qName, "deviceName")) {
157 deviceName = currentOrNull(currentText);
158 } else if (equalsOrSuffix(qName, "volumeId")) {
159 volumeId = currentOrNull(currentText);
160 } else if (equalsOrSuffix(qName, "status")) {
161 attachmentStatus = Attachment.Status.fromValue(currentText.toString().trim());
162 } else if (equalsOrSuffix(qName, "attachTime")) {
163 attachTime = dateService.iso8601DateParse(currentText.toString().trim());
164 } else if (equalsOrSuffix(qName, "deleteOnTermination")) {
165 deleteOnTermination = Boolean.parseBoolean(currentText.toString().trim());
166 } else if (equalsOrSuffix(qName, "ebs")) {
167 builder.device(deviceName, new BlockDevice(volumeId, attachmentStatus, attachTime, deleteOnTermination));
168 this.deviceName = null;
169 this.volumeId = null;
170 this.attachmentStatus = null;
171 this.attachTime = null;
172 this.deleteOnTermination = true;
173 }
174 currentText = new StringBuilder();
175 }
176
177 protected Date parseDate() {
178 try {
179 return dateService.iso8601DateParse(currentOrNull(currentText));
180 } catch (RuntimeException e) {
181
182 return dateService.iso8601SecondsDateParse(currentOrNull(currentText));
183 }
184 }
185
186 protected void inItem() {
187 if (endOfInstanceItem()) {
188 refineBuilderBeforeAddingInstance();
189 instances.add(builder.build());
190 builder = builderProvider.get();
191 }
192 }
193
194 protected void refineBuilderBeforeAddingInstance() {
195 String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null;
196
197
198 if (builder.getIpAddress() == null && builder.getDnsName() != null && builder.getDnsName().matches(".*[0-9]$")) {
199 builder.ipAddress(builder.getDnsName());
200 builder.dnsName(null);
201 }
202 if (builder.getPrivateIpAddress() == null && builder.getPrivateDnsName() != null
203 && builder.getPrivateDnsName().matches(".*[0-9]$")) {
204 builder.privateIpAddress(builder.getPrivateDnsName());
205 builder.privateDnsName(null);
206 }
207
208 builder.region((region == null) ? defaultRegion : region);
209 builder.groupIds(groupIds);
210 }
211
212 protected Builder builder() {
213 return builder;
214 }
215
216 protected boolean endOfInstanceItem() {
217 return itemDepth <= 2 && inInstancesSet;
218 }
219
220 public void characters(char ch[], int start, int length) {
221 currentText.append(ch, start, length);
222 }
223
224 protected Reservation<? extends RunningInstance> newReservation() {
225 String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null;
226 if (region == null)
227 region = defaultRegion;
228 Reservation<? extends RunningInstance> info = new Reservation<RunningInstance>(region, groupIds, instances,
229 ownerId, requesterId, reservationId);
230 this.groupIds = Sets.newLinkedHashSet();
231 this.instances = Sets.newLinkedHashSet();
232 this.ownerId = null;
233 this.requesterId = null;
234 this.reservationId = null;
235 return info;
236 }
237
238 }