/* * AbstractCall.java * * Copyright (C) 2010-2016, Microsoft Corporation * * This program is licensed to you under the terms of Version 2.0 of the * Apache License. This program is distributed WITHOUT * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the * Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) for more details. * */ package com.revo.deployr.client.call; import com.revo.deployr.client.core.RCoreResponse; import com.revo.deployr.client.core.RCoreResult; import com.revo.deployr.client.core.RExecutionException; import com.revo.deployr.client.core.RInterruptedException; import com.revo.deployr.client.core.impl.RCoreResultImpl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; /** * Provides abstract base class for PCall implementations. */ public abstract class AbstractCall implements RCall, RCoreResponse { private Log log = LogFactory.getLog(AbstractCall.class); protected HttpClient httpClient; protected String serverUrl; protected Future future; protected HttpUriRequest httpUriRequest; protected Map<String, String> httpParams = new HashMap(); protected Map<String, String> httpHeaders = new HashMap(); /** * Method, internal use only. */ public void setClient(HttpClient httpClient, String serverUrl) { this.httpClient = httpClient; this.serverUrl = serverUrl; } /** * Method, internal use only. */ public void setFuture(Future future) { this.future = future; } /* * RCall Implementation - Interface Marker Only, No Implementation. */ /* * RCoreResponse Implementation */ public RCoreResult get() throws RInterruptedException, RExecutionException { RCoreResult pResult = null; try { pResult = (RCoreResult) future.get(); } catch (InterruptedException iex) { log.warn("Interrupted exception on call, httpUriRequest=" + httpUriRequest); try { httpUriRequest.abort(); log.warn("Interrupted exception, call aborted."); } catch (UnsupportedOperationException uoe) { log.warn("Interrupted, unsupported operation exception.", uoe); } if (httpUriRequest.isAborted()) throw new RInterruptedException("InterruptedException, call aborted."); else throw new RInterruptedException("InterruptedException, call not aborted."); } catch (ExecutionException eex) { throw new RExecutionException("ExecutionException, call aborted.", eex); } return pResult; } public boolean cancel() { return future.cancel(true); } public boolean isCancelled() { return future.isCancelled(); } public boolean isCompleted() { return future.isDone(); } public void addHeader(String name, String value) { if (value != null) { httpHeaders.put(name, value); } } /* * Protected implementation making HTTP Request. */ protected RCoreResult makePostRequest(String API) { try { HttpPost httpPost = new HttpPost(serverUrl + API); List<NameValuePair> postParams = new ArrayList<NameValuePair>(); for (Map.Entry<String, String> entry : httpParams.entrySet()) { postParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } UrlEncodedFormEntity entity = new UrlEncodedFormEntity(postParams, "UTF-8"); httpPost.setEntity(entity); return makeRequest(httpPost, API); } catch (UnsupportedEncodingException uex) { log.warn("AbstractCall: makePostRequest unsupported encoding exception.", uex); return null; } } protected RCoreResult makeGetRequest(String API) { List<NameValuePair> getParams = new ArrayList<NameValuePair>(); for (Map.Entry<String, String> entry : httpParams.entrySet()) { getParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } String encodedParams = URLEncodedUtils.format(getParams, "UTF-8"); HttpGet httpGet = new HttpGet(serverUrl + API + "?" + encodedParams); return makeRequest(httpGet, API); } protected RCoreResult makeRequest(HttpUriRequest httpUriRequest, String API) { this.httpUriRequest = httpUriRequest; RCoreResultImpl pResult = null; try { // set any custom headers on the request for (Map.Entry<String, String> entry : httpHeaders.entrySet()) { httpUriRequest.addHeader(entry.getKey(), entry.getValue()); } HttpResponse response = httpClient.execute(this.httpUriRequest); StatusLine statusLine = response.getStatusLine(); HttpEntity responseEntity = response.getEntity(); String markup = EntityUtils.toString(responseEntity); pResult = new RCoreResultImpl(response.getAllHeaders()); pResult.parseMarkup(markup, API, statusLine.getStatusCode(), statusLine.getReasonPhrase()); } catch (UnsupportedEncodingException ueex) { log.warn("AbstractCall: makeRequest unsupported encoding exception=" + ueex); } catch (IOException ioex) { log.warn("AbstractCall: makeRequest io exception=" + ioex); } catch (Exception ex) { log.warn("AbstractCall: makeRequest exception=" + ex); } finally { log.debug("AbstractCall: makeRequest pResult=" + pResult); } return pResult; } }