/* * ARISTOTLE UNIVERSITY OF THESSALONIKI * Copyright (C) 2015 * Aristotle University of Thessaloniki * Department of Electrical & Computer Engineering * Division of Electronics & Computer Engineering * Intelligent Systems & Software Engineering Lab * * Project : eticsbte * WorkFile : * Compiler : * File Description : * Document Description: * Related Documents : * Note : * Programmer : RESTful MDE Engine created by Christoforos Zolotas * Contact : christopherzolotas@issel.ee.auth.gr */ package eu.fp7.scase.eticsbte.optimize; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.UriInfo; import org.codehaus.jackson.map.ObjectMapper; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.jersey.api.json.JSONConfiguration; import eu.fp7.scase.eticsbte.operationcommit.service.RequestBean; import eu.fp7.scase.eticsbte.operationcommit.service.ResponseBean; import eu.fp7.scase.eticsbte.operationcommit.service.ServiceClient; import eu.fp7.scase.eticsbte.operationcommit.service.impl.AddSoftwareClient; import eu.fp7.scase.eticsbte.operationcommit.service.impl.CreateHostClient; import eu.fp7.scase.eticsbte.operationcommit.service.impl.DeleteHostClient; import eu.fp7.scase.eticsbte.searchvirtualmachine.JavaAlgosearchVirtualMachineModel; import eu.fp7.scase.eticsbte.software.JavasoftwareModel; import eu.fp7.scase.eticsbte.software.JavasoftwareModelManager; import eu.fp7.scase.eticsbte.utilities.HibernateController; import eu.fp7.scase.eticsbte.utilities.HypermediaLink; import eu.fp7.scase.eticsbte.virtualmachine.JavavirtualMachineModel; import eu.fp7.scase.eticsbte.virtualmachine.JavavirtualMachineModelManager; /* *This class processes client requests for optimize resource that are to be delegated to an existing 3rd party service. *Uppon its output receival, this class repackages the output and creates the hypermedia links with the search results to be returned to the client */ public class PostoptimizeHandler{ private HibernateController oHibernateController; private UriInfo oApplicationUri; //Standard datatype that holds information on the URI info of this request private JavaAlgooptimizeModel oJavaAlgooptimizeModel; private JavaOptimizeOutputModel oOutputDataModel; private Map searchKeywords; private ClientConfig oClientConfiguration; private final String ENV_TYPE = "testing"; public PostoptimizeHandler(JavaAlgooptimizeModel oTempJavaAlgooptimizeModel, UriInfo oApplicationUri){ oJavaAlgooptimizeModel = new JavaAlgooptimizeModel(); this.oHibernateController = HibernateController.getHibernateControllerHandle(); this.oApplicationUri = oApplicationUri; this.oJavaAlgooptimizeModel = oTempJavaAlgooptimizeModel; this.searchKeywords = new HashMap<>() ; searchKeywords.put("searchVirtualMachineCpuPower", oTempJavaAlgooptimizeModel.getCpuPower()); searchKeywords.put("searchVirtualMachineHdDimension", oTempJavaAlgooptimizeModel.getHdDimension()); //initialize JAX-RS Client configuration this.oClientConfiguration = new DefaultClientConfig(); this.oClientConfiguration.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); } public JavaOptimizeOutputModel postoptimize(){ //Return any results in the hypermedia links form. return interoperateWithExternalService(); } /* * This function handles the interoperation with the existing 3rd party service. It calls the according functions to create the input * to be sent to it, to receive its output and if necessary to persist the outcome in the database. * Finally, the result is returned to the client. */ public JavaOptimizeOutputModel interoperateWithExternalService(){ //create a new JAX-RS client Client oJAXRSRESTClient = Client.create(this.oClientConfiguration); this.oOutputDataModel = new JavaOptimizeOutputModel(); String delete = this.oJavaAlgooptimizeModel.getDelete(); if (delete != null && delete.equalsIgnoreCase("true")) deleteVMProcess(oJAXRSRESTClient); else createVMProcess(oJAXRSRESTClient); return this.oOutputDataModel; } private void createVMProcess (Client oJAXRSRESTClient) { if (this.oJavaAlgooptimizeModel.getVirtualMachineId() > 0) { int virtualMachineID = this.oJavaAlgooptimizeModel.getVirtualMachineId(); // Virtual Machine selected, getting software VirtualMachineDetails vmDetails = getVirtualMachineDetails(oJAXRSRESTClient, virtualMachineID); List software = vmDetails.getSoftwareElements(); if (!software.contains(this.oJavaAlgooptimizeModel.getSoftwareName()+"_"+this.oJavaAlgooptimizeModel.getSoftwareVersion())) { // Install software on the VM createSoftware(oJAXRSRESTClient, "http://localhost:8080/eticsbte/api/virtualMachine/"+virtualMachineID+"/software"); RequestBean requestBean = createForemanRequestBean(); ServiceClient serviceClient = new AddSoftwareClient(); serviceClient.setParameters(requestBean); ResponseBean response = serviceClient.execute(oJAXRSRESTClient); if (response.getResponseObject() == null) { throw new WebApplicationException(); } } if (!vmDetails.getVirtualEnvironmentIds().contains(this.oJavaAlgooptimizeModel.getVirtualEnvironmentId())) { //Generating new link to the new VirtualEnvironment updateVirtualMachine (oJAXRSRESTClient,vmDetails.getUpdateUrl(),this.oJavaAlgooptimizeModel.getVirtualEnvironmentId(),true); } HypermediaLink virtualMachine = new HypermediaLink(); virtualMachine.setIdType(0); virtualMachine.setLinkRel("Modified Virtual machine"); virtualMachine.setLinkURI("http://localhost:8080/eticsbte/api/virtualEnvironment/"+this.oJavaAlgooptimizeModel.getVirtualEnvironmentId()+"virtualMachine/"+virtualMachineID); virtualMachine.setLinkVerb("GET"); this.oOutputDataModel.getlinklist().add(virtualMachine); this.oOutputDataModel.setCompleted(true); } else { JavaOptimizeOutputModel firstSearchResults = searchVirtualMachines (oJAXRSRESTClient); if (firstSearchResults.getlinklist().size() == 0) directCreation(oJAXRSRESTClient); else { List testvirtualMachinessID = searchVirtualMachinesUnderEnvironments(oJAXRSRESTClient); if (!testvirtualMachinessID.isEmpty()) { for (HypermediaLink hl : firstSearchResults.getlinklist()) { if (!testvirtualMachinessID.contains(hl.getLinkURI())) { this.oOutputDataModel.getlinklist().add(hl); } } if (this.oOutputDataModel.getlinklist().size() == 0) directCreation(oJAXRSRESTClient); else this.oOutputDataModel.setCompleted(false); } else { this.oOutputDataModel.setCompleted(false); this.oOutputDataModel.getlinklist().addAll( firstSearchResults.getlinklist()); } } } } private void deleteVMProcess (Client oJAXRSRESTClient) { // Delete int virtualMachineID = this.oJavaAlgooptimizeModel.getVirtualMachineId(); VirtualMachineDetails vmDetails = getVirtualMachineDetails(oJAXRSRESTClient, virtualMachineID); List virtualEnvironments = vmDetails.getVirtualEnvironmentIds(); if (virtualEnvironments.size()>1 && virtualEnvironments.contains(this.oJavaAlgooptimizeModel.getVirtualEnvironmentId())) { // Remve VM from Virtual Environment System.out.println("Removing relationship"); updateVirtualMachine (oJAXRSRESTClient,vmDetails.getUpdateUrl(),this.oJavaAlgooptimizeModel.getVirtualEnvironmentId(),false); } else if (virtualEnvironments.contains(this.oJavaAlgooptimizeModel.getVirtualEnvironmentId())) { // Completely remove the Virtual Machine RequestBean requestBean = createForemanRequestBean(); ServiceClient serviceClient = new DeleteHostClient(); serviceClient.setParameters(requestBean); ResponseBean response = serviceClient.execute(oJAXRSRESTClient); if (response.getResponseObject() == null) { throw new WebApplicationException(); } // Delete the Host from the DB WebResource deleteVirtualMachineResource = oJAXRSRESTClient.resource(vmDetails.getDeleteUrl()); deleteVirtualMachineResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON).accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).delete(ClientResponse.class); } this.oOutputDataModel.setCompleted(true); } private void directCreation (Client oJAXRSRESTClient) { JavavirtualMachineModel newVirtualMachine = createVirtualMachine(oJAXRSRESTClient); HypermediaLink createSoftware = null; HypermediaLink virtualMachine = null; boolean exit = false; Iterator hls = newVirtualMachine.getlinklist().iterator(); while (hls.hasNext() && !exit) { HypermediaLink hl = hls.next(); if (hl.getLinkType().equals("Child") && hl.getLinkVerb().equals("POST")) { createSoftware = hl; exit = createSoftware != null && virtualMachine != null; } else if (hl.getLinkType().equals("Sibling") && hl.getLinkVerb().equals("GET")) { virtualMachine = hl; exit = createSoftware != null && virtualMachine != null; } } if (createSoftware == null) { throw new WebApplicationException(); } String createSoftwareUrl = createSoftware.getLinkURI(); JavasoftwareModel softwareModel = createSoftware(oJAXRSRESTClient, createSoftwareUrl); // Create VM and software on Foreman RequestBean request = createForemanRequestBean(); //construct the query ServiceClient serviceClient = new CreateHostClient(); serviceClient.setParameters(request); ResponseBean response = serviceClient.execute(oJAXRSRESTClient); if (response.getResponseObject() != null) { this.oOutputDataModel.getlinklist().add(virtualMachine); this.oOutputDataModel.setCompleted(true); } } private RequestBean createForemanRequestBean () { RequestBean request = new RequestBean(); request.setHostId(this.oJavaAlgooptimizeModel.getVirtualMachineName()); request.setForemanUserName(this.oJavaAlgooptimizeModel.getForemanUsername()); request.setForemanPassword(this.oJavaAlgooptimizeModel.getForemanPassword()); request.setBaseUrl("http://localhost:8080"); String softwareName = this.oJavaAlgooptimizeModel.getSoftwareName(); if (softwareName != null) request.addParameter(softwareName); return request; } private JavaOptimizeOutputModel searchVirtualMachines (Client oJAXRSRESTClient) { Iterator keys = this.searchKeywords.keySet().iterator(); JavaOptimizeOutputModel response = new JavaOptimizeOutputModel(); Map hyperMediaMap = new HashMap<>(); while (keys.hasNext()) { String key = keys.next(); String searchKeyword = this.searchKeywords.get(key); WebResource oTargetResource = oJAXRSRESTClient.resource("http://localhost:8080/eticsbte/api/AlgosearchVirtualMachine").queryParam(key, "true").queryParam("searchKeyword", searchKeyword); ClientResponse oResponse = oTargetResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON).accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).post(ClientResponse.class, this.oJavaAlgooptimizeModel); if (isSuccessfullResponseCode(oResponse) == false) { throw new WebApplicationException(); } String tempotputDataModelString = oResponse.getEntity(String.class); JavaAlgosearchVirtualMachineModel tempotputDataModel = new JavaAlgosearchVirtualMachineModel(); if (tempotputDataModelString.indexOf('[')==-1) { try { JavaSinglesearchVirtualMachineModel tempModel = new ObjectMapper().readValue(tempotputDataModelString, JavaSinglesearchVirtualMachineModel.class); tempotputDataModel.setlinklist(tempModel.getlinklist()); } catch (Exception e) { throw new WebApplicationException(); } } else { try { tempotputDataModel = new ObjectMapper().readValue(tempotputDataModelString, JavaAlgosearchVirtualMachineModel.class); } catch (Exception e) { throw new WebApplicationException(); } } for (HypermediaLink hl : tempotputDataModel.getlinklist()) { hyperMediaMap.put(hl.getLinkURI(), hl); } } response.getlinklist().addAll(hyperMediaMap.values()); return response; } private List searchVirtualMachinesUnderEnvironments (Client oJAXRSRESTClient) { List response = new ArrayList<>(); WebResource oTargetResource = oJAXRSRESTClient.resource("http://localhost:8080/eticsbte/api/AlgosearchVirtualMachine").queryParam("searchVirtualEnvironmentType", "true").queryParam("searchKeyword", ENV_TYPE); ClientResponse oResponse = oTargetResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON).accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).post(ClientResponse.class, this.oJavaAlgooptimizeModel); if (isSuccessfullResponseCode(oResponse) == false) { throw new WebApplicationException(); } JavaAlgosearchVirtualMachineModel tempotputDataModel = oResponse.getEntity(JavaAlgosearchVirtualMachineModel.class); for (HypermediaLink searchResult : tempotputDataModel.getlinklist()) { String url = searchResult.getLinkURI(); url = "http://localhost:8080/eticsbte/api/virtualEnvironment/"+url.substring(url.lastIndexOf('/')+1)+"/virtualMachine"; System.out.println("URL "+url); WebResource getVirtualMachinesResource = oJAXRSRESTClient.resource(url); ClientResponse getVirtualMachinesResponse = getVirtualMachinesResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON).accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(ClientResponse.class); if (isSuccessfullResponseCode(oResponse) == false) { throw new WebApplicationException(); } JavavirtualMachineModelManager getVirtualMachineOutputDataModel = getVirtualMachinesResponse.getEntity(JavavirtualMachineModelManager.class); for (HypermediaLink hl : getVirtualMachineOutputDataModel.getlinklist()) { if (hl.getLinkType().equals("Child") && hl.getLinkVerb().equals("GET")) { System.out.println("Child VM URI "+hl.getLinkURI()); response.add(hl.getLinkURI()); } } } return response; } private VirtualMachineDetails getUrlsVirtualMachine (Client oJAXRSRESTClient,VirtualMachineDetails details) { //String url = "http://localhost:8080/eticsbte/api/virtualEnvironment/"+virtualEnvironmentID+"/virtualMachine/"+virtualMachineID; WebResource oTargetResource = oJAXRSRESTClient.resource(details.getMainUrl()); ClientResponse oResponse = oTargetResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON).accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(ClientResponse.class); if (isSuccessfullResponseCode(oResponse) == false) { throw new WebApplicationException(); } JavavirtualMachineModel tempotputDataModel = oResponse.getEntity(JavavirtualMachineModel.class); for (HypermediaLink searchResult : tempotputDataModel.getlinklist()) { if (searchResult.getLinkType().equals("Parent") && searchResult.getLinkVerb().equals("GET")&&searchResult.getLinkRel().equals("virtualEnvironment")) { String virtualEnvironmentUrl = searchResult.getLinkURI(); System.out.println("Parent URI "+virtualEnvironmentUrl); String idString = virtualEnvironmentUrl.substring(virtualEnvironmentUrl.lastIndexOf('/')+1); System.out.println("Adding parent id "+idString); details.getVirtualEnvironmentIds().add(Integer.parseInt(idString)); } else if (searchResult.getLinkType().equals("Sibling") && searchResult.getLinkVerb().equals("PUT")) { details.setUpdateUrl(searchResult.getLinkURI()); } else if (searchResult.getLinkType().equals("Sibling") && searchResult.getLinkVerb().equals("DELETE")) { details.setDeleteUrl(searchResult.getLinkURI()); } } return details; } private VirtualMachineDetails getVirtualMachineDetails (Client oJAXRSRESTClient, int virtualMachineID) { VirtualMachineDetails details = new VirtualMachineDetails(); String url = "http://localhost:8080/eticsbte/api/virtualMachine/"+virtualMachineID+"/software"; WebResource oTargetResource = oJAXRSRESTClient.resource(url); ClientResponse oResponse = oTargetResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON).accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(ClientResponse.class); if (isSuccessfullResponseCode(oResponse) == false) { throw new WebApplicationException(); } JavasoftwareModelManager tempotputDataModel = oResponse.getEntity(JavasoftwareModelManager.class); for (HypermediaLink searchResult : tempotputDataModel.getlinklist()) { if (searchResult.getLinkType().equals("Child") && searchResult.getLinkVerb().equals("GET")) { String softwareUrl = searchResult.getLinkURI(); WebResource getSoftwareDetailsResource = oJAXRSRESTClient.resource(softwareUrl); ClientResponse getSoftwareDetailsResponse = getSoftwareDetailsResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON).accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(ClientResponse.class); JavasoftwareModel getSoftwareDetailsOutputDataModel = getSoftwareDetailsResponse.getEntity(JavasoftwareModel.class); details.getSoftwareElements().add(getSoftwareDetailsOutputDataModel.getname()+"_"+getSoftwareDetailsOutputDataModel.getversion()); } else if (searchResult.getLinkType().equals("Parent") && searchResult.getLinkVerb().equals("GET")) { details.setMainUrl(searchResult.getLinkURI()); } } return getUrlsVirtualMachine(oJAXRSRESTClient, details); } private JavavirtualMachineModel updateVirtualMachine (Client oJAXRSRESTClient,String updateUrl,int virtualEnvironmentID,boolean addRelationship) { System.out.println("Virtual Environment id "+virtualEnvironmentID); JavavirtualMachineModel updateVirtualMachine = prepareVMModel (); WebResource updateVirtualMachineResource = oJAXRSRESTClient.resource(updateUrl).queryParam("strOptionalUpdateRelations", "true").queryParam("strOptionalUpdateParent", "true") .queryParam("strOptionalRelationName", "virtualEnvironment").queryParam("strOptionalAddRelation", Boolean.toString(addRelationship)).queryParam("iOptionalResourceId", ""+virtualEnvironmentID); ClientResponse updateVirtualMachineResponse = updateVirtualMachineResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON).accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).put(ClientResponse.class,updateVirtualMachine); return parseVMResponse(updateVirtualMachineResponse); } private JavavirtualMachineModel createVirtualMachine (Client oJAXRSRESTClient) { JavavirtualMachineModel createVirtualMachine = prepareVMModel (); String url = "http://localhost:8080/eticsbte/api/virtualEnvironment/"+this.oJavaAlgooptimizeModel.getVirtualEnvironmentId()+"/virtualMachine"; ClientResponse oResponse = postRequest(oJAXRSRESTClient, url, createVirtualMachine); JavavirtualMachineModel tempotputDataModel = oResponse.getEntity(JavavirtualMachineModel.class); url = url+"/"+ tempotputDataModel.getvirtualMachineId(); WebResource getVirtualMachineResource = oJAXRSRESTClient.resource(url); ClientResponse getVirtualMachineResponse = getVirtualMachineResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON).accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(ClientResponse.class); return parseVMResponse(getVirtualMachineResponse); } private JavavirtualMachineModel prepareVMModel () { JavavirtualMachineModel virtualMachineModel = new JavavirtualMachineModel(); virtualMachineModel.setid(this.oJavaAlgooptimizeModel.getVirtualMachineName()); virtualMachineModel.setcpuPower(this.oJavaAlgooptimizeModel.getCpuPower()); virtualMachineModel.sethdDimension(this.oJavaAlgooptimizeModel.getHdDimension()); return virtualMachineModel; } private JavavirtualMachineModel parseVMResponse (ClientResponse getVirtualMachineResponse) { if (isSuccessfullResponseCode(getVirtualMachineResponse) == false) { throw new WebApplicationException(); } JavavirtualMachineModel getVirtualMachineOutputDataModel = getVirtualMachineResponse.getEntity(JavavirtualMachineModel.class); return getVirtualMachineOutputDataModel; } private JavasoftwareModel createSoftware (Client oJAXRSRESTClient,String createSoftwareUrl) { JavasoftwareModel software = new JavasoftwareModel(); software.setname(this.oJavaAlgooptimizeModel.getSoftwareName()); software.setversion(this.oJavaAlgooptimizeModel.getSoftwareVersion()); ClientResponse softwareCreateResponse = postRequest(oJAXRSRESTClient, createSoftwareUrl, software); JavasoftwareModel softwareotputDataModel = softwareCreateResponse.getEntity(JavasoftwareModel.class); return softwareotputDataModel; } private ClientResponse postRequest (Client oJAXRSRESTClient, String url, Object input) { WebResource postOperationResource = oJAXRSRESTClient.resource(url); ClientResponse postOperationResponse = postOperationResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON).accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).post(ClientResponse.class, input); if (isSuccessfullResponseCode(postOperationResponse) == false) { throw new WebApplicationException(); } return postOperationResponse; } /* * This function checks the response code of the server reply against the known success codes. If the server response HTTP * code is within the success code range, this functions returns true. Otherwise it returns false */ private boolean isSuccessfullResponseCode(ClientResponse oResponse){ if(oResponse.getStatus() == 200){ // Status OK return true; } else if(oResponse.getStatus() == 201){ // Status CREATED return true; } else if(oResponse.getStatus() == 202){ // Status Accepted return true; } else if(oResponse.getStatus() == 203){ // Status NON-AUTHORITATIVE INFORMATION return true; } else if(oResponse.getStatus() == 204){ // Status NO CONTENT return true; } else if(oResponse.getStatus() == 205){ // Status RESET CONTENT return true; } else if(oResponse.getStatus() == 206){ // Status PARTIAL CONTENT return true; } return false; } }