PageRenderTime 29ms CodeModel.GetById 13ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main/java/nl/bitbrains/nebu/rest/client/RequestSender.java

https://github.com/deltaforge/nebu-core
Java | 265 lines | 140 code | 22 blank | 103 comment | 8 complexity | e45b9010131ce7e832d241c6b62ee8ac MD5 | raw file
  1package nl.bitbrains.nebu.rest.client;
  2
  3import java.util.List;
  4
  5import javax.ws.rs.ProcessingException;
  6import javax.ws.rs.WebApplicationException;
  7import javax.ws.rs.client.Entity;
  8import javax.ws.rs.client.Invocation;
  9import javax.ws.rs.client.Invocation.Builder;
 10import javax.ws.rs.core.MediaType;
 11import javax.ws.rs.core.Response;
 12
 13import nl.bitbrains.nebu.common.VirtualMachine;
 14import nl.bitbrains.nebu.common.cache.CacheException;
 15import nl.bitbrains.nebu.common.cache.CacheManager;
 16import nl.bitbrains.nebu.common.topology.PhysicalTopology;
 17import nl.bitbrains.nebu.common.util.xml.XMLConverter;
 18import nl.bitbrains.nebu.rest.RESTRequestException;
 19
 20import org.apache.logging.log4j.LogManager;
 21import org.apache.logging.log4j.Logger;
 22import org.jdom2.Element;
 23import org.jdom2.JDOMException;
 24import org.w3c.dom.Document;
 25
 26/**
 27 * @author Jesse Donkervliet, Tim Hegeman, and Stefan Hugtenburg
 28 * 
 29 *         Use this class for sending requests to the webserver as configured in
 30 *         the configuration.
 31 */
 32public final class RequestSender {
 33
 34    public static final String INVALID_RESPONSE = "Invalid response gotten :";
 35    public static final String CONNECTION_REFUSED = "Connection refused :";
 36    private static final String INVALID_BODY = "Invalid xml specified";
 37    private static Logger logger = LogManager.getLogger();
 38    private static RequestSender instance;
 39
 40    /**
 41     * Private constructor to prevent instantiation outside of this class.
 42     */
 43    private RequestSender() {
 44    }
 45
 46    /**
 47     * @return the RequestSender singleton.
 48     */
 49    public static RequestSender get() {
 50        if (RequestSender.instance == null) {
 51            RequestSender.instance = new RequestSender();
 52        }
 53        return RequestSender.instance;
 54    }
 55
 56    /**
 57     * @param <T>
 58     *            Type that you want returned out.
 59     * @param builder
 60     *            invocation to perform.
 61     * @param classType
 62     *            type of result you expect.
 63     * @return the expected result of the request.
 64     * @throws RESTRequestException
 65     *             if an HTTP error code is returned.
 66     */
 67    protected static <T> T performGETRequestAndCheckResponse(final Invocation.Builder builder,
 68            final Class<T> classType) throws RESTRequestException {
 69        try {
 70            final Response rep = builder.get();
 71
 72            if (rep.getStatus() != Response.Status.OK.getStatusCode()) {
 73                RequestSender.logger.error("Got StatusCode: " + rep.getStatus());
 74                throw new RESTRequestException(rep.getStatusInfo().toString(), rep.getStatus());
 75            }
 76            return rep.readEntity(classType);
 77        } catch (final WebApplicationException e) {
 78            throw RequestSender.logger.throwing(new RESTRequestException(
 79                    RequestSender.INVALID_RESPONSE + e.getMessage(),
 80                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e));
 81        } catch (final ProcessingException e) {
 82            throw RequestSender.logger.throwing(new RESTRequestException(
 83                    RequestSender.CONNECTION_REFUSED + e.getMessage(),
 84                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e));
 85        }
 86    }
 87
 88    /**
 89     * @return the Physical topology obtained from the server.
 90     * @throws CacheException
 91     *             if an HTTP error code is returned.
 92     */
 93    public PhysicalTopology getTopology() throws CacheException {
 94        return (PhysicalTopology) CacheManager.get(RequestBuilder.URI_TOPOLOGY,
 95                                                   new TopologyCacheLoader());
 96    }
 97
 98    /**
 99     * @return the List of VirtualMachine instances obtained from the server.
100     * @throws CacheException
101     *             if an HTTP error code is returned.
102     */
103    @SuppressWarnings("unchecked")
104    public List<String> getVirtualMachines() throws CacheException {
105        return (List<String>) CacheManager.get(RequestBuilder.URI_VIRTUAL_MACHINES,
106                                               new VirtListCacheLoader());
107    }
108
109    /**
110     * @param uuid
111     *            identifier of the VM you want information on.
112     * @return the Virtualmachine instance obtained from the server.
113     * @throws CacheException
114     *             if an HTTP error code is returned.
115     */
116    public VirtualMachine getVirtualMachine(final String uuid) throws CacheException {
117        return (VirtualMachine) CacheManager.get(RequestBuilder.URI_VIRTUAL_MACHINES + "/" + uuid,
118                                                 new VirtItemCacheLoader(uuid));
119    }
120
121    /**
122     * @param uuid
123     *            identifier of the VM you want the status of.
124     * @return the Virtualmachine instance obtained from the server.
125     * @throws CacheException
126     *             if an HTTP error code is returned.
127     */
128    public VirtualMachine getVirtualMachineStatus(final String uuid) throws CacheException {
129        return (VirtualMachine) CacheManager.get(RequestBuilder.URI_VIRTUAL_MACHINES + "/" + uuid,
130                                                 new VirtStatusCacheLoader(uuid),
131                                                 VirtStatusCacheLoader.EXPIRATION_TIME);
132    }
133
134    /**
135     * @param uuid
136     *            of the vmTemplate to get the topology tree for.
137     * @return the Physical topology obtained from the server.
138     * @throws CacheException
139     *             if an HTTP error code is returned.
140     */
141    public PhysicalTopology getVMTemplateTopologyOptions(final String uuid) throws CacheException {
142        return (PhysicalTopology) CacheManager.get(RequestBuilder.URI_VMTEMPLATES + "/" + uuid
143                + "/phys", new VMTemplateTopologyCacheLoader(uuid));
144    }
145
146    /**
147     * @param uuid
148     *            identifier of the VM you want information on.
149     * @param xml
150     *            PUT body.
151     * @throws RESTRequestException
152     *             if an HTTP error code is returned.
153     */
154    public void putTemplate(final String uuid, final Element xml) throws RESTRequestException {
155        final Invocation.Builder builder = RequestBuilder.get().newPutTemplateClient(uuid);
156        RequestSender.performPUTRequestAndCheckResponseCreated(builder, xml);
157    }
158
159    /**
160     * @param uuid
161     *            identifier of the template you are putting.
162     * @param hostName
163     *            prefix of the hostname of the new vm.
164     * @param template
165     *            VMTemplate uuid to use.
166     * @return the response
167     * @throws RESTRequestException
168     *             if an HTTP error code is returned.
169     */
170    public Response postCreateVM(final String uuid, final String hostName, final String template)
171            throws RESTRequestException {
172        final Invocation.Builder builder = RequestBuilder.get().newPostCreateVMClient(uuid,
173                                                                                      hostName,
174                                                                                      template);
175        return RequestSender.performPOSTRequestAndCheckResponseCreated(builder);
176    }
177
178    /**
179     * @param uuid
180     *            identifier of the template you are putting.
181     * @param hostName
182     *            prefix of the hostname of the new vm.
183     * @param template
184     *            VMTemplate uuid to use.
185     * @param store
186     *            store to use for this vm.
187     * @return the response
188     * @throws RESTRequestException
189     *             if an HTTP error code is returned.
190     */
191    public Response postCreateVM(final String uuid, final String hostName, final String template,
192            final String store) throws RESTRequestException {
193        final Invocation.Builder builder = RequestBuilder.get().newPostCreateVMClient(uuid,
194                                                                                      hostName,
195                                                                                      template,
196                                                                                      store);
197        return RequestSender.performPOSTRequestAndCheckResponseCreated(builder);
198    }
199
200    /**
201     * @param builder
202     *            invocation to perform.
203     * 
204     * @return Response gotten.
205     * @throws RESTRequestException
206     *             iff http fails.
207     */
208    private static Response performPOSTRequestAndCheckResponseCreated(final Builder builder)
209            throws RESTRequestException {
210        try {
211            final Response rep = builder.post(null);
212
213            if (rep.getStatus() != Response.Status.CREATED.getStatusCode()) {
214                RequestSender.logger.error(rep.getStatus());
215                throw RequestSender.logger.throwing(new RESTRequestException(rep.getStatusInfo()
216                        .toString(), rep.getStatus()));
217            }
218            return rep;
219        } catch (final WebApplicationException e) {
220            throw RequestSender.logger.throwing(new RESTRequestException(
221                    RequestSender.INVALID_RESPONSE + e.getMessage(),
222                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e));
223        } catch (final ProcessingException e) {
224            throw RequestSender.logger.throwing(new RESTRequestException(
225                    RequestSender.CONNECTION_REFUSED + e.getMessage(),
226                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e));
227        }
228    }
229
230    /**
231     * @param builder
232     *            invocation to perform.
233     * @param xml
234     *            body for the put request.
235     * @return the Response object
236     * @throws RESTRequestException
237     *             if an HTTP error code is returned.
238     */
239    private static Response performPUTRequestAndCheckResponseCreated(final Builder builder,
240            final Element xml) throws RESTRequestException {
241        try {
242            final Entity<Document> entity = Entity.entity(XMLConverter
243                    .convertJDOMElementW3CDocument(xml), MediaType.APPLICATION_XML_TYPE);
244            final Response rep = builder.put(entity);
245
246            if (rep.getStatus() != Response.Status.CREATED.getStatusCode()) {
247                RequestSender.logger.error(rep.getStatus());
248                throw RequestSender.logger.throwing(new RESTRequestException(rep.getStatusInfo()
249                        .toString(), rep.getStatus()));
250            }
251            return RequestSender.logger.exit(rep);
252        } catch (final WebApplicationException e) {
253            throw RequestSender.logger.throwing(new RESTRequestException(
254                    RequestSender.INVALID_RESPONSE + e.getMessage(),
255                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e));
256        } catch (final ProcessingException e) {
257            throw RequestSender.logger.throwing(new RESTRequestException(
258                    RequestSender.CONNECTION_REFUSED + e.getMessage(),
259                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e));
260        } catch (final JDOMException e) {
261            throw RequestSender.logger.throwing(new RESTRequestException(RequestSender.INVALID_BODY
262                    + e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e));
263        }
264    }
265}