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 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
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
73 private String volumeId;
74 private Attachment.Status attachmentStatus;
75 private Date attachTime;
76 private boolean deleteOnTermination;
77 private String deviceName;
78
79
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
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
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
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
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 }