Statistics
| Branch: | Revision:

root / main / java / net / elasticgrid / rackspace / cloudservers / XMLCloudServers.java @ af63e739

History | View | Annotate | Download (28.2 kB)

1
/**
2
 * Licensed to the Apache Software Foundation (ASF) under one
3
 * or more contributor license agreements.  See the NOTICE file
4
 * distributed with this work for additional information
5
 * regarding copyright ownership.  The ASF 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 net.elasticgrid.rackspace.cloudservers;
20

    
21
import net.elasticgrid.rackspace.cloudservers.Server.Status;
22
import net.elasticgrid.rackspace.cloudservers.internal.ConfirmResize;
23
import net.elasticgrid.rackspace.cloudservers.internal.Flavors;
24
import net.elasticgrid.rackspace.cloudservers.internal.Images;
25
import net.elasticgrid.rackspace.cloudservers.internal.Metadata;
26
import net.elasticgrid.rackspace.cloudservers.internal.MetadataItem;
27
import net.elasticgrid.rackspace.cloudservers.internal.Private;
28
import net.elasticgrid.rackspace.cloudservers.internal.Public;
29
import net.elasticgrid.rackspace.cloudservers.internal.Reboot;
30
import net.elasticgrid.rackspace.cloudservers.internal.Rebuild;
31
import net.elasticgrid.rackspace.cloudservers.internal.Resize;
32
import net.elasticgrid.rackspace.cloudservers.internal.RevertResize;
33
import net.elasticgrid.rackspace.cloudservers.internal.ServerID;
34
import net.elasticgrid.rackspace.cloudservers.internal.Servers;
35
import net.elasticgrid.rackspace.cloudservers.internal.SharedIpGroup;
36
import net.elasticgrid.rackspace.cloudservers.internal.SharedIpGroups;
37
import net.elasticgrid.rackspace.cloudservers.internal.ShareIp;
38
import net.elasticgrid.rackspace.common.RackspaceConnection;
39
import net.elasticgrid.rackspace.common.RackspaceException;
40
import org.apache.http.HttpException;
41
import org.apache.http.client.methods.HttpDelete;
42
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
43
import org.apache.http.client.methods.HttpGet;
44
import org.apache.http.client.methods.HttpPost;
45
import org.apache.http.client.methods.HttpPut;
46
import org.apache.http.client.methods.HttpRequestBase;
47
import org.apache.http.entity.ContentProducer;
48
import org.apache.http.entity.EntityTemplate;
49
import org.jibx.runtime.BindingDirectory;
50
import org.jibx.runtime.IBindingFactory;
51
import org.jibx.runtime.IMarshallingContext;
52
import org.jibx.runtime.JiBXException;
53
import java.io.IOException;
54
import java.io.OutputStream;
55
import java.net.InetAddress;
56
import java.net.MalformedURLException;
57
import java.net.UnknownHostException;
58
import java.util.ArrayList;
59
import java.util.HashMap;
60
import java.util.List;
61
import java.util.Map;
62
import java.util.Collections;
63
import java.util.logging.Level;
64
import java.util.logging.Logger;
65

    
66
/**
67
 * Implementation based on the XML documents.
68
 *
69
 * @author Jerome Bernard
70
 */
71
public class XMLCloudServers extends RackspaceConnection implements CloudServers {
72
    private static final Logger logger = Logger.getLogger(XMLCloudServers.class.getName());
73

    
74
    /**
75
     * Initializes the Rackspace Cloud Servers connection with the Rackspace login information.
76
     *
77
     * @param username the Rackspace username
78
     * @param apiKey   the Rackspace API key
79
     * @throws RackspaceException if the credentials are invalid
80
     * @throws IOException        if there is a network issue
81
     * @see #authenticate()
82
     */
83
    public XMLCloudServers(String username, String apiKey) throws RackspaceException, IOException {
84
        super(username, apiKey);
85
    }
86

    
87
    public List<Server> getServers() throws CloudServersException {
88
        logger.info("Retrieving servers information...");
89
        HttpGet request = new HttpGet(getServerManagementURL() + "/servers");
90
        return buildListOfServers(request);
91
    }
92

    
93
    public List<Server> getServersWithDetails() throws CloudServersException {
94
        logger.info("Retrieving detailed servers information...");
95
        HttpGet request = new HttpGet(getServerManagementURL() + "/servers/detail");
96
        return buildListOfServers(request);
97
    }
98

    
99
    private List<Server> buildListOfServers(HttpGet request) throws CloudServersException {
100
        Servers response = makeRequestInt(request, Servers.class);
101
        List<Server> servers = new ArrayList<Server>(response.getServers().size());
102
        for (net.elasticgrid.rackspace.cloudservers.internal.Server server : response.getServers())
103
            servers.add(buildServer(server));
104
        return servers;
105
    }
106

    
107
    public Server getServerDetails(int serverID) throws CloudServersException {
108
        logger.log(Level.INFO, "Retrieving detailed information for server {0}...", serverID);
109
        validateServerID(serverID);
110
        HttpGet request = new HttpGet(getServerManagementURL() + "/servers/" + serverID);
111
        return buildServer(makeRequestInt(request, net.elasticgrid.rackspace.cloudservers.internal.Server.class));
112
    }
113

    
114
    private Server buildServer(net.elasticgrid.rackspace.cloudservers.internal.Server response) throws CloudServersException {
115
        try {
116
            return new Server(
117
                    response.getId(), response.getName(), response.getAdminPass(),
118
                    response.getImageId(), response.getFlavorId(),
119
                    response.getStatus() == null ? null : Status.valueOf(response.getStatus().name()),
120
                    metadataAsMap(response.getMetadata()),
121
                    new Addresses(response.getAddresses()),
122
                    new Personality(response.getPersonality())
123
            );
124
        } catch (UnknownHostException e) {
125
            throw new CloudServersException("Can't build server", e);
126
        }
127
    }
128

    
129
    private static Map<String, String> metadataAsMap(Metadata metadata) {
130
        if (metadata == null)
131
            return Collections.emptyMap();
132
        Map<String, String> meta = new HashMap<String, String>();
133
        for (MetadataItem item : metadata.getMetadatas()) {
134
            meta.put(item.getKey(), item.getString());
135
        }
136
        return meta;
137
    }
138

    
139
    public Addresses getServerAddresses(int serverID) throws CloudServersException {
140
        logger.log(Level.INFO, "Retrieving all IP addresses of server {0}...", serverID);
141
        validateServerID(serverID);
142
        HttpGet request = new HttpGet(getServerManagementURL() + "/servers/" + serverID + "/ips");
143
        net.elasticgrid.rackspace.cloudservers.internal.Addresses response = makeRequestInt(request, net.elasticgrid.rackspace.cloudservers.internal.Addresses.class);
144
        try {
145
            return new Addresses(response);
146
        } catch (UnknownHostException e) {
147
            throw new CloudServersException("Can't validate server addresses", e);
148
        }
149
    }
150

    
151
    public List<InetAddress> getServerPublicAddresses(int serverID) throws CloudServersException {
152
        logger.log(Level.INFO, "Retrieving all public IP addresses of server {0}...", serverID);
153
        validateServerID(serverID);
154
        HttpGet request = new HttpGet(getServerManagementURL() + "/servers/" + serverID + "/ips/public");
155
        Public response = makeRequestInt(request, Public.class);
156
        try {
157
            List<InetAddress> addresses = new ArrayList<InetAddress>(response.getAddressLists().size());
158
            for (net.elasticgrid.rackspace.cloudservers.internal.Address address : response.getAddressLists()) {
159
                addresses.add(InetAddress.getByName(address.getAddr()));
160
            }
161
            return addresses;
162
        } catch (UnknownHostException e) {
163
            throw new CloudServersException("Can't validate server addresses", e);
164
        }
165
    }
166

    
167
    public List<InetAddress> getServerPrivateAddresses(int serverID) throws CloudServersException {
168
        logger.log(Level.INFO, "Retrieving all private IP addresses of server {0}...", serverID);
169
        validateServerID(serverID);
170
        HttpGet request = new HttpGet(getServerManagementURL() + "/servers/" + serverID + "/ips/private");
171
        Private response = makeRequestInt(request, Private.class);
172
        try {
173
            List<InetAddress> addresses = new ArrayList<InetAddress>(response.getAddressLists().size());
174
            for (net.elasticgrid.rackspace.cloudservers.internal.Address address : response.getAddressLists()) {
175
                addresses.add(InetAddress.getByName(address.getAddr()));
176
            }
177
            return addresses;
178
        } catch (UnknownHostException e) {
179
            throw new CloudServersException("Can't validate server addresses", e);
180
        }
181
    }
182

    
183
    public void shareAddress(int groupID, int serverID, InetAddress address) throws CloudServersException {
184
        shareAddress(groupID, serverID, address, false);
185
    }
186

    
187
    public void shareAddress(int groupID, int serverID, InetAddress address, boolean configureServer) throws CloudServersException {
188
        logger.log(Level.INFO, "Sharing IP in group {0} for address {1} with server {2}...", new Object[]{groupID, address, serverID});
189
        validateServerID(serverID);
190
        if (address == null)
191
            throw new IllegalArgumentException("Invalid IP address");
192
        ShareIp shareIp = new ShareIp();
193
        shareIp.setSharedIpGroupId(groupID);
194
        shareIp.setConfigureServer(configureServer);
195
        HttpPut request = new HttpPut(getServerManagementURL() + "/servers/" + serverID
196
                + "/ips/public/" + address.getHostAddress());
197
        makeRequestInt(request);
198
    }
199

    
200
    public void unshareAddress(int serverID, InetAddress address) throws CloudServersException {
201
        logger.log(Level.INFO, "Unsharing IP address {0} with server {1}...", new Object[]{address, serverID});
202
        validateServerID(serverID);
203
        if (address == null)
204
            throw new IllegalArgumentException("Invalid IP address");
205
        HttpDelete request = new HttpDelete(getServerManagementURL() + "/servers/" + serverID
206
                + "/ips/public/" + address.getHostAddress());
207
        makeRequestInt(request);
208
    }
209

    
210
    public Server createServer(String name, int imageID, int flavorID) throws CloudServersException {
211
        return createServer(name, imageID, flavorID, null);
212
    }
213

    
214
    public Server createServer(String name, int imageID, int flavorID, Map<String, String> metadata) throws CloudServersException {
215
        logger.log(Level.INFO, "Creating server {0} from image {1} running on flavor {2}...",
216
                new Object[]{name, imageID, flavorID});
217
        if (name == null)
218
            throw new IllegalArgumentException("Server name has to be specified!");
219
        if (imageID == 0)
220
            throw new IllegalArgumentException("Image ID has to be specified!");
221
        if (flavorID == 0)
222
            throw new IllegalArgumentException("Flavor ID has to be specified!");
223
        HttpPost request = new HttpPost(getServerManagementURL() + "/servers");
224
        net.elasticgrid.rackspace.cloudservers.internal.Server server = new net.elasticgrid.rackspace.cloudservers.internal.Server();
225
        server.setName(name);
226
        server.setImageId(imageID);
227
        server.setFlavorId(flavorID);
228
        if (metadata != null && !metadata.isEmpty()) {
229
            Metadata rawMetadata = new Metadata();
230
            List<MetadataItem> metadataItems = rawMetadata.getMetadatas();
231
            for (Map.Entry<String, String> entry : metadata.entrySet()) {
232
                MetadataItem item = new MetadataItem();
233
                item.setKey(entry.getKey());
234
                item.setString(entry.getValue());
235
                metadataItems.add(item);
236
            }
237
            server.setMetadata(rawMetadata);
238
        }
239
        return buildServer(makeEntityRequestInt(request, server, net.elasticgrid.rackspace.cloudservers.internal.Server.class));
240
    }
241

    
242
    public void rebootServer(int serverID) throws CloudServersException {
243
        rebootServer(serverID, RebootType.SOFT);
244
    }
245

    
246
    public void rebootServer(int serverID, RebootType type) throws CloudServersException {
247
        logger.log(Level.INFO, "Rebooting server {0} via {1} reboot...", new Object[]{serverID, type.name()});
248
        validateServerID(serverID);
249
        HttpPost request = new HttpPost(getServerManagementURL() + "/servers/" + serverID + "/action");
250
        Reboot reboot = new Reboot();
251
        reboot.setType(net.elasticgrid.rackspace.cloudservers.internal.RebootType.valueOf(type.name()));
252
        makeEntityRequestInt(request, reboot);
253
    }
254

    
255
    public void rebuildServer(int serverID) throws CloudServersException {
256
        logger.log(Level.INFO, "Rebuilding server {0}...", serverID);
257
        validateServerID(serverID);
258
        HttpPost request = new HttpPost(getServerManagementURL() + "/servers/" + serverID + "/action");
259
        makeEntityRequestInt(request, new Rebuild());
260
    }
261

    
262
    public void rebuildServer(int serverID, int imageID) throws CloudServersException {
263
        logger.log(Level.INFO, "Rebuilding server {0} from image {1}...", new Object[]{serverID, imageID});
264
        validateServerID(serverID);
265
        HttpPost request = new HttpPost(getServerManagementURL() + "/servers/" + serverID + "/action");
266
        Rebuild rebuild = new Rebuild();
267
        rebuild.setImageId(imageID);
268
        makeEntityRequestInt(request, rebuild);
269
    }
270

    
271
    public void resizeServer(int serverID, int flavorID) throws CloudServersException {
272
        logger.log(Level.INFO, "Resizing server {0} to run on flavor {1}...", new Object[]{serverID, flavorID});
273
        validateServerID(serverID);
274
        HttpPost request = new HttpPost(getServerManagementURL() + "/servers/" + serverID + "/action");
275
        Resize resize = new Resize();
276
        resize.setFlavorId(flavorID);
277
        makeEntityRequestInt(request, resize);
278
    }
279

    
280
    public void confirmResize(int serverID) throws CloudServersException {
281
        logger.log(Level.INFO, "Confirming resize of server {0}...", serverID);
282
        validateServerID(serverID);
283
        HttpPost request = new HttpPost(getServerManagementURL() + "/servers/" + serverID + "/action");
284
        makeEntityRequestInt(request, new ConfirmResize());
285
    }
286

    
287
    public void revertResize(int serverID) throws CloudServersException {
288
        logger.log(Level.INFO, "Cancelling resize of server {0}...", serverID);
289
        validateServerID(serverID);
290
        HttpPost request = new HttpPost(getServerManagementURL() + "/servers/" + serverID + "/action");
291
        makeEntityRequestInt(request, new RevertResize());
292
    }
293

    
294
    public void updateServerName(int serverID, String name) throws CloudServersException {
295
        updateServerNameAndPassword(serverID, name, null);
296
    }
297

    
298
    public void updateServerPassword(int serverID, String password) throws CloudServersException {
299
        updateServerNameAndPassword(serverID, null, password);
300
    }
301

    
302
    public void updateServerNameAndPassword(final int serverID, final String name, final String password) throws CloudServersException {
303
        validateServerID(serverID);
304
        HttpPut request = new HttpPut(getServerManagementURL() + "/servers/" + serverID);
305
        net.elasticgrid.rackspace.cloudservers.internal.Server server = new net.elasticgrid.rackspace.cloudservers.internal.Server();
306
        server.setId(serverID);
307
        if (name != null)
308
            server.setName(name);
309
        if (password != null)
310
            server.setAdminPass(password);
311
        makeEntityRequestInt(request, server);
312
    }
313

    
314
    public void deleteServer(int serverID) throws CloudServersException {
315
        logger.log(Level.INFO, "Deleting server {0}...", serverID);
316
        validateServerID(serverID);
317
        HttpDelete request = new HttpDelete(getServerManagementURL() + "/servers/" + serverID);
318
        makeRequestInt(request);
319
    }
320

    
321
    public Limits getLimits() throws CloudServersException {
322
        HttpGet request = new HttpGet(getServerManagementURL() + "/limits");
323
        net.elasticgrid.rackspace.cloudservers.internal.Limits response = makeRequestInt(request, net.elasticgrid.rackspace.cloudservers.internal.Limits.class);
324
        List<RateLimit> rateLimits = new ArrayList<RateLimit>(response.getRate().getRateLimits().size());
325
        for (net.elasticgrid.rackspace.cloudservers.internal.RateLimit limit : response.getRate().getRateLimits())
326
            rateLimits.add(new RateLimit(
327
                    HTTPVerb.valueOf(limit.getVerb().name()),
328
                    limit.getURI(),
329
                    limit.getRegex(),
330
                    limit.getValue(),
331
                    limit.getRemaining(),
332
                    RateLimit.Unit.valueOf(limit.getUnit().name()),
333
                    limit.getResetTime()
334
            ));
335
        List<AbsoluteLimit> absoluteLimits = new ArrayList<AbsoluteLimit>(response.getAbsolute().getAbsoluteLimits().size());
336
        for (net.elasticgrid.rackspace.cloudservers.internal.AbsoluteLimit limit : response.getAbsolute().getAbsoluteLimits())
337
            absoluteLimits.add(new AbsoluteLimit(limit.getName(), limit.getValue()));
338
        return new Limits(rateLimits, absoluteLimits);
339
    }
340

    
341
    public List<Flavor> getFlavors() throws CloudServersException {
342
        logger.info("Retrieving flavors information...");
343
        HttpGet request = new HttpGet(getServerManagementURL() + "/flavors");
344
        return buildListOfFlavors(request);
345
    }
346

    
347
    public List<Flavor> getFlavorsWithDetails() throws CloudServersException {
348
        logger.info("Retrieving detailed flavors information...");
349
        HttpGet request = new HttpGet(getServerManagementURL() + "/flavors/detail");
350
        return buildListOfFlavors(request);
351
    }
352

    
353
    public Flavor getFlavorDetails(int flavorID) throws CloudServersException {
354
        logger.log(Level.INFO, "Retrieving detailed information for flavor {0}...", flavorID);
355
        validateFlavorID(flavorID);
356
        HttpGet request = new HttpGet(getServerManagementURL() + "/flavors/" + flavorID);
357
        return buildFlavor(makeRequestInt(request, net.elasticgrid.rackspace.cloudservers.internal.Flavor.class));
358
    }
359

    
360
    private List<Flavor> buildListOfFlavors(HttpGet request) throws CloudServersException {
361
        Flavors response = makeRequestInt(request, Flavors.class);
362
        List<Flavor> flavors = new ArrayList<Flavor>(response.getFlavors().size());
363
        for (net.elasticgrid.rackspace.cloudservers.internal.Flavor flavor : response.getFlavors())
364
            flavors.add(buildFlavor(flavor));
365
        return flavors;
366
    }
367

    
368
    private Flavor buildFlavor(net.elasticgrid.rackspace.cloudservers.internal.Flavor response) {
369
        return new Flavor(response.getId(), response.getName(), response.getRam(), response.getDisk());
370
    }
371

    
372
    public List<Image> getImages() throws CloudServersException {
373
        logger.info("Retrieving images information...");
374
        HttpGet request = new HttpGet(getServerManagementURL() + "/images");
375
        return buildListOfImages(makeRequestInt(request, Images.class));
376
    }
377

    
378
    public List<Image> getImagesWithDetails() throws CloudServersException {
379
        logger.info("Retrieving detailed images information...");
380
        HttpGet request = new HttpGet(getServerManagementURL() + "/images/detail");
381
        return buildListOfImages(makeRequestInt(request, Images.class));
382
    }
383

    
384
    public Image getImageDetails(int imageID) throws CloudServersException {
385
        logger.log(Level.INFO, "Retrieving detailed information for image {0}...", imageID);
386
        validateImageID(imageID);
387
        HttpGet request = new HttpGet(getServerManagementURL() + "/images/" + imageID);
388
        return buildImage(makeRequestInt(request, net.elasticgrid.rackspace.cloudservers.internal.Image.class));
389
    }
390

    
391
    public Image createImage(String name, int serverID) throws CloudServersException {
392
        logger.log(Level.INFO, "Creating image named ''{0}'' from server {1}...", new Object[]{name, serverID});
393
        validateServerID(serverID);
394
        HttpPost request = new HttpPost(getServerManagementURL() + "/images");
395
        net.elasticgrid.rackspace.cloudservers.internal.Image image = new net.elasticgrid.rackspace.cloudservers.internal.Image();
396
        image.setName(name);
397
        image.setServerId(serverID);
398
        return buildImage(makeEntityRequestInt(request, image, net.elasticgrid.rackspace.cloudservers.internal.Image.class));
399
    }
400

    
401
    private List<Image> buildListOfImages(Images response) {
402
        List<Image> images = new ArrayList<Image>(response.getImages().size());
403
        for (net.elasticgrid.rackspace.cloudservers.internal.Image image : response.getImages())
404
            images.add(buildImage(image));
405
        return images;
406
    }
407

    
408
    private Image buildImage(net.elasticgrid.rackspace.cloudservers.internal.Image created) {
409
        return new Image(
410
                created.getId(), created.getName(), created.getServerId(),
411
                created.getUpdated(), created.getCreated(), created.getProgress(),
412
                created.getStatus() == null ? null : Image.Status.valueOf(created.getStatus().name())
413
        );
414
    }
415

    
416
    public BackupSchedule getBackupSchedule(int serverID) throws CloudServersException {
417
        logger.log(Level.INFO, "Retrieving backup schedule for server {0}...", serverID);
418
        validateServerID(serverID);
419
        HttpGet request = new HttpGet(getServerManagementURL() + "/servers/" + serverID + "/backup_schedule");
420
        net.elasticgrid.rackspace.cloudservers.internal.BackupSchedule response = makeRequestInt(request, net.elasticgrid.rackspace.cloudservers.internal.BackupSchedule.class);
421
        return new BackupSchedule(
422
                response.getEnabled(),
423
                BackupSchedule.WeeklyBackup.valueOf(response.getWeekly().name()),
424
                BackupSchedule.DailyBackup.valueOf(response.getDaily().name())
425
        );
426
    }
427

    
428
    public void scheduleBackup(int serverID, BackupSchedule schedule) throws CloudServersException {
429
        logger.log(Level.INFO, "Updating backup schedule for server {0} to {1}...",
430
                new Object[]{serverID, schedule});
431
        validateServerID(serverID);
432
        HttpPost request = new HttpPost(getServerManagementURL() + "/servers/" + serverID + "/backup_schedule");
433
        net.elasticgrid.rackspace.cloudservers.internal.BackupSchedule s = new net.elasticgrid.rackspace.cloudservers.internal.BackupSchedule();
434
        s.setEnabled(schedule.isEnabled());
435
        s.setWeekly(net.elasticgrid.rackspace.cloudservers.internal.WeeklyBackup.valueOf(schedule.getWeekly().name()));
436
        s.setDaily(net.elasticgrid.rackspace.cloudservers.internal.DailyBackup.valueOf(schedule.getDaily().name()));
437
        makeEntityRequestInt(request, s);
438
    }
439

    
440
    public void deleteBackupSchedule(int serverID) throws CloudServersException {
441
        logger.log(Level.INFO, "Deleting backup schedule for server {0}...", serverID);
442
        validateServerID(serverID);
443
        HttpDelete request = new HttpDelete(getServerManagementURL() + "/servers/" + serverID + "/backup_schedule");
444
        makeRequestInt(request);
445
    }
446

    
447
    public List<SharedIPGroup> getSharedIPGroups() throws CloudServersException {
448
        logger.info("Retrieving shared IP groups information...");
449
        HttpGet request = new HttpGet(getServerManagementURL() + "/shared_ip_groups");
450
        return buildListOfSharedIPGroups(request);
451
    }
452

    
453
    public List<SharedIPGroup> getSharedIPGroupsWithDetails() throws CloudServersException {
454
        logger.info("Retrieving detailed shared IP groups information...");
455
        HttpGet request = new HttpGet(getServerManagementURL() + "/shared_ip_groups/detail");
456
        return buildListOfSharedIPGroups(request);
457
    }
458

    
459
    public SharedIPGroup getSharedIPGroup(int groupID) throws CloudServersException {
460
        logger.log(Level.INFO, "Retrieving detailed shared IP group information for {0}...", groupID);
461
        HttpGet request = new HttpGet(getServerManagementURL() + "/shared_ip_groups/" + groupID);
462
        return buildSharedIPGroup(makeRequestInt(request, SharedIpGroup.class));
463
    }
464

    
465
    public SharedIPGroup createSharedIPGroup(String name) throws CloudServersException {
466
        return createSharedIPGroup(name, 0);
467
    }
468

    
469
    public SharedIPGroup createSharedIPGroup(String name, int serverID) throws CloudServersException {
470
        logger.log(Level.INFO, "Creating shared IP group named {0} for server {1}...", new Object[]{name, serverID});
471
        HttpPost request = new HttpPost(getServerManagementURL() + "/shared_ip_groups");
472
        SharedIpGroup group = new SharedIpGroup();
473
        group.setName(name);
474
        if (serverID != 0) {
475
            ServerID server = new ServerID();
476
            server.setId(serverID);
477
            group.setServer(server);
478
        }
479
        return buildSharedIPGroup(makeEntityRequestInt(request, group, SharedIpGroup.class));
480
    }
481

    
482
    public void deleteSharedIPGroup(int groupID) throws CloudServersException {
483
        logger.log(Level.INFO, "Deleting shared IP group {0}...", groupID);
484
        validateSharedIPGroupID(groupID);
485
        HttpDelete request = new HttpDelete(getServerManagementURL() + "/shared_ip_groups/" + groupID);
486
        makeRequestInt(request);
487
    }
488

    
489
    private List<SharedIPGroup> buildListOfSharedIPGroups(HttpGet request) throws CloudServersException {
490
        SharedIpGroups response = makeRequestInt(request, SharedIpGroups.class);
491
        List<SharedIPGroup> groups = new ArrayList<SharedIPGroup>(response.getSharedIpGroups().size());
492
        for (SharedIpGroup group : response.getSharedIpGroups())
493
            groups.add(buildSharedIPGroup(group));
494
        return groups;
495
    }
496

    
497
    private SharedIPGroup buildSharedIPGroup(SharedIpGroup group) {
498
        List<Integer> serverIDs = new ArrayList<Integer>(group.getServers().getServerIDLists().size());
499
        for (ServerID id : group.getServers().getServerIDLists())
500
            serverIDs.add(id.getId());
501
        return new SharedIPGroup(group.getId(), group.getName(), serverIDs);
502
    }
503

    
504
    protected void makeEntityRequestInt(HttpEntityEnclosingRequestBase request, final Object entity) throws CloudServersException {
505
        makeEntityRequestInt(request, entity, Void.class);
506
    }
507

    
508
    protected <T> T makeEntityRequestInt(HttpEntityEnclosingRequestBase request, final Object entity, Class<T> respType) throws CloudServersException {
509
        request.setEntity(new EntityTemplate(new ContentProducer() {
510
            public void writeTo(OutputStream output) throws IOException {
511
                try {
512
                    IBindingFactory bindingFactory = BindingDirectory.getFactory(entity.getClass());
513
                    final IMarshallingContext marshallingCxt = bindingFactory.createMarshallingContext();
514
                    marshallingCxt.marshalDocument(entity, "UTF-8", true, output);
515
                } catch (JiBXException e) {
516
                    IOException ioe = new IOException("Can't marshal server details");
517
                    ioe.initCause(e);
518
                    e.printStackTrace();
519
                    throw ioe;
520
                }
521
            }
522
        }));
523
        return makeRequestInt(request, respType);
524
    }
525

    
526
    protected void makeRequestInt(HttpRequestBase request) throws CloudServersException {
527
        makeRequestInt(request, Void.class);
528
    }
529

    
530
    protected <T> T makeRequestInt(HttpRequestBase request, Class<T> respType) throws CloudServersException {
531
        try {
532
            return makeRequest(request, respType);
533
        } catch (RackspaceException e) {
534
            throw new CloudServersException(e);
535
        } catch (JiBXException e) {
536
            throw new CloudServersException("Problem parsing returned message.", e);
537
        } catch (MalformedURLException e) {
538
            throw new CloudServersException(e.getMessage(), e);
539
        } catch (IOException e) {
540
            throw new CloudServersException(e.getMessage(), e);
541
        } catch (HttpException e) {
542
            throw new CloudServersException(e.getMessage(), e);
543
        }
544
    }
545

    
546
    private void validateServerID(int serverID) throws IllegalArgumentException {
547
        if (serverID == 0)
548
            throw new IllegalArgumentException("Invalid serverID " + serverID);
549
    }
550

    
551
    private void validateFlavorID(int flavorID) throws IllegalArgumentException {
552
        if (flavorID == 0)
553
            throw new IllegalArgumentException("Invalid flavorID " + flavorID);
554
    }
555

    
556
    private void validateImageID(int imageID) throws IllegalArgumentException {
557
        if (imageID == 0)
558
            throw new IllegalArgumentException("Invalid imageID " + imageID);
559
    }
560

    
561
    private void validateSharedIPGroupID(int groupID) throws IllegalArgumentException {
562
        if (groupID == 0)
563
            throw new IllegalArgumentException("Invalid shared IP group ID " + groupID);
564
    }
565
}