/*
 * 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.CreateVirtualHostClient;
import eu.fp7.scase.eticsbte.operationcommit.service.impl.DeleteVirtualHostClient;
import eu.fp7.scase.eticsbte.operationcommit.service.impl.RemoveSoftwareClient;
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<String, String> 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<String> 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.getoResponse().getStatus() != 200)
                {
                	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 if (this.oJavaAlgooptimizeModel.getVirtualMachineId() < 0)
        {
            JavaOptimizeOutputModel firstSearchResults = searchVirtualMachines (oJAXRSRESTClient);
            
            if (firstSearchResults.getlinklist().size() == 0) directCreation(oJAXRSRESTClient);
            else
            {
            	List<String> 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());
            	}
            	
            	
            }
        }
        else // this.oJavaAlgooptimizeModel.getVirtualMachineId() == 0
        {
        	// Direct creation forced
        	directCreation(oJAXRSRESTClient);
        }
    }
    
    private void deleteVMProcess (Client oJAXRSRESTClient)
    {
    	// Delete
    	int virtualMachineID = this.oJavaAlgooptimizeModel.getVirtualMachineId();
    	VirtualMachineDetails vmDetails = getVirtualMachineDetails(oJAXRSRESTClient, virtualMachineID);
    	List<Integer> virtualEnvironments = vmDetails.getVirtualEnvironmentIds();
    	
    	if (virtualEnvironments.size()>1 && virtualEnvironments.contains(this.oJavaAlgooptimizeModel.getVirtualEnvironmentId()))
    	{
    		// Remve VM from Virtual Environment
    		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 DeleteVirtualHostClient();
            serviceClient.setParameters(requestBean);
            ResponseBean response =  serviceClient.execute(oJAXRSRESTClient);
            
            if (response.getoResponse().getStatus()!= 200)
            {
            	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<HypermediaLink> 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 CreateVirtualHostClient();
        serviceClient.setParameters(request);
        ResponseBean response =  serviceClient.execute(oJAXRSRESTClient);
        
        if (response.getoResponse().getStatus() == 200 || response.getoResponse().getStatus() == 201)
        {
        	this.oOutputDataModel.getlinklist().add(virtualMachine);
            this.oOutputDataModel.setCompleted(true);
        }
        else throw new WebApplicationException();
    }
    
    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<String> keys = this.searchKeywords.keySet().iterator();
        JavaOptimizeOutputModel response = new JavaOptimizeOutputModel();
        Map<String, HypermediaLink> 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<String> searchVirtualMachinesUnderEnvironments (Client oJAXRSRESTClient)
    {

    	List<String> 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";
        	
     		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();
        		String idString = virtualEnvironmentUrl.substring(virtualEnvironmentUrl.lastIndexOf('/')+1);
        		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";
    	System.out.println(url);
     	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)
    {
     	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;
	}
	
}
