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