protected HttpResponse sendHttpRequest(
      String method, String url, HttpEntity entity, List<NameValuePair> qparams, CallingContext cc)
      throws IOException {

    HttpParams httpParams = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(
        httpParams, SOCKET_ESTABLISHMENT_TIMEOUT_MILLISECONDS);
    HttpConnectionParams.setSoTimeout(httpParams, SERVICE_TIMEOUT_MILLISECONDS);

    // setup client
    HttpClientFactory factory = (HttpClientFactory) cc.getBean(BeanDefs.HTTP_CLIENT_FACTORY);
    HttpClient client = factory.createHttpClient(httpParams);

    // support redirecting to handle http: => https: transition
    HttpClientParams.setRedirecting(httpParams, true);
    // support authenticating
    HttpClientParams.setAuthenticating(httpParams, true);

    // redirect limit is set to some unreasonably high number
    // resets of the socket cause a retry up to MAX_REDIRECTS times,
    // so we should be careful not to set this too high...
    httpParams.setParameter(ClientPNames.MAX_REDIRECTS, 32);
    httpParams.setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);

    // context holds authentication state machine, so it cannot be
    // shared across independent activities.
    HttpContext localContext = new BasicHttpContext();

    localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
    localContext.setAttribute(ClientContext.CREDS_PROVIDER, credsProvider);

    HttpUriRequest request = null;
    if (entity == null && (POST.equals(method) || PATCH.equals(method) || PUT.equals(method))) {
      throw new IllegalStateException("No body supplied for POST, PATCH or PUT request");
    } else if (entity != null
        && !(POST.equals(method) || PATCH.equals(method) || PUT.equals(method))) {
      throw new IllegalStateException("Body was supplied for GET or DELETE request");
    }

    URI nakedUri;
    try {
      nakedUri = new URI(url);
    } catch (Exception e) {
      e.printStackTrace();
      throw new IllegalStateException(e);
    }

    if (qparams == null) {
      qparams = new ArrayList<NameValuePair>();
    }
    URI uri;
    try {
      uri =
          new URI(
              nakedUri.getScheme(),
              nakedUri.getUserInfo(),
              nakedUri.getHost(),
              nakedUri.getPort(),
              nakedUri.getPath(),
              URLEncodedUtils.format(qparams, HtmlConsts.UTF8_ENCODE),
              null);
    } catch (URISyntaxException e1) {
      e1.printStackTrace();
      throw new IllegalStateException(e1);
    }
    System.out.println(uri.toString());

    if (GET.equals(method)) {
      HttpGet get = new HttpGet(uri);
      request = get;
    } else if (DELETE.equals(method)) {
      HttpDelete delete = new HttpDelete(uri);
      request = delete;
    } else if (PATCH.equals(method)) {
      HttpPatch patch = new HttpPatch(uri);
      patch.setEntity(entity);
      request = patch;
    } else if (POST.equals(method)) {
      HttpPost post = new HttpPost(uri);
      post.setEntity(entity);
      request = post;
    } else if (PUT.equals(method)) {
      HttpPut put = new HttpPut(uri);
      put.setEntity(entity);
      request = put;
    } else {
      throw new IllegalStateException("Unexpected request method");
    }

    HttpResponse resp = client.execute(request);
    return resp;
  }
 private HttpResponse forward(
     HttpClient httpclient,
     String verb,
     String uri,
     HttpServletRequest request,
     MultiValueMap<String, String> headers,
     MultiValueMap<String, String> params,
     InputStream requestEntity)
     throws Exception {
   Map<String, Object> info = this.helper.debug(verb, uri, headers, params, requestEntity);
   URL host = RequestContext.getCurrentContext().getRouteHost();
   HttpHost httpHost = getHttpHost(host);
   uri = StringUtils.cleanPath(host.getPath() + uri);
   HttpRequest httpRequest;
   switch (verb.toUpperCase()) {
     case "POST":
       HttpPost httpPost = new HttpPost(uri + getQueryString());
       httpRequest = httpPost;
       httpPost.setEntity(new InputStreamEntity(requestEntity, request.getContentLength()));
       break;
     case "PUT":
       HttpPut httpPut = new HttpPut(uri + getQueryString());
       httpRequest = httpPut;
       httpPut.setEntity(new InputStreamEntity(requestEntity, request.getContentLength()));
       break;
     case "PATCH":
       HttpPatch httpPatch = new HttpPatch(uri + getQueryString());
       httpRequest = httpPatch;
       httpPatch.setEntity(new InputStreamEntity(requestEntity, request.getContentLength()));
       break;
     default:
       httpRequest = new BasicHttpRequest(verb, uri + getQueryString());
       log.debug(uri + getQueryString());
   }
   try {
     httpRequest.setHeaders(convertHeaders(headers));
     log.debug(httpHost.getHostName() + " " + httpHost.getPort() + " " + httpHost.getSchemeName());
     HttpResponse zuulResponse = forwardRequest(httpclient, httpHost, httpRequest);
     this.helper.appendDebug(
         info,
         zuulResponse.getStatusLine().getStatusCode(),
         revertHeaders(zuulResponse.getAllHeaders()));
     return zuulResponse;
   } finally {
     // When HttpClient instance is no longer needed,
     // shut down the connection manager to ensure
     // immediate deallocation of all system resources
     // httpclient.getConnectionManager().shutdown();
   }
 }
  /**
   * Tests whether a Sparql update is visible within a transaction and if the update is made
   * persistent along with the commit.
   *
   * @throws IOException exception thrown during this function
   */
  @Test
  public void testIngestNewWithSparqlPatchWithinTransaction() throws IOException {
    final String objectInTxCommit = getRandomUniqueId();

    /* create new tx */
    final String txLocation = createTransaction();

    final HttpPost postNew = new HttpPost(txLocation);
    postNew.addHeader("Slug", objectInTxCommit);
    final String newObjectLocation;
    try (CloseableHttpResponse resp = execute(postNew)) {
      assertEquals(CREATED.getStatusCode(), getStatus(resp));
      newObjectLocation = getLocation(resp);
    }

    /* update sparql */
    final HttpPatch method = new HttpPatch(newObjectLocation);
    method.addHeader(CONTENT_TYPE, "application/sparql-update");
    final String newTitle = "this is a new title";
    method.setEntity(
        new StringEntity(
            "INSERT { <> <http://purl.org/dc/elements/1.1/title> \"" + newTitle + "\" } WHERE {}"));
    assertEquals("Didn't get a NO CONTENT status!", NO_CONTENT.getStatusCode(), getStatus(method));
    /* make sure the change was made within the tx */
    try (final CloseableDataset dataset = getDataset(new HttpGet(newObjectLocation))) {
      assertTrue(
          "The sparql update did not succeed within a transaction",
          dataset
              .asDatasetGraph()
              .contains(
                  ANY, createURI(newObjectLocation), title.asNode(), createLiteral(newTitle)));
    }
    /* commit */
    assertEquals(
        NO_CONTENT.getStatusCode(), getStatus(new HttpPost(txLocation + "/fcr:tx/fcr:commit")));

    /* it must exist after commit */
    try (final CloseableDataset dataset =
        getDataset(new HttpGet(serverAddress + objectInTxCommit))) {
      assertTrue(
          "The inserted triple does not exist after the transaction has committed",
          dataset.asDatasetGraph().contains(ANY, ANY, title.asNode(), createLiteral(newTitle)));
    }
  }
  public boolean patchObject(String path, JSONObject body) {
    log.info("patchRequest(" + path + ")");

    // http://msdn.microsoft.com/en-us/library/windowsazure/dn151671.aspx
    HttpPatch httpPatch = new HttpPatch(getAPIEndPoint(path));
    httpPatch.addHeader("Authorization", this.getToken());
    // patch.addHeader("Content-Type", "application/json;odata=verbose");
    httpPatch.addHeader("Content-Type", "application/json;charset=utf-8;odata=verbose");
    httpPatch.addHeader("DataServiceVersion", "3.0;NetFx");
    httpPatch.addHeader("MaxDataServiceVersion", "3.0;NetFx");
    httpPatch.addHeader("Accept", "application/atom+xml");

    StringEntity postEntity = null;
    try {
      postEntity = new StringEntity(body.toString(), "UTF-8");
    } catch (UnsupportedEncodingException ex) {
      log.error(
          "Unsupported Encoding when updating object in Office 365, path was {0}. Error: {1}",
          path, ex);
    }

    httpPatch.setEntity(postEntity);
    HttpClient httpClient = HttpClientBuilder.create().build();

    try {
      HttpResponse response = httpClient.execute(httpPatch);
      HttpEntity entity = response.getEntity();

      if (response.getStatusLine().getStatusCode() != 204) {
        log.error("An error occured when modify an object in Office 365");
        this.invalidateToken();
        StringBuffer sb = new StringBuffer();
        if (entity != null && entity.getContent() != null) {
          BufferedReader in = new BufferedReader(new InputStreamReader(entity.getContent()));
          String s = null;

          log.info("Response :{0}", response.getStatusLine().toString());

          while ((s = in.readLine()) != null) {
            sb.append(s);
            log.info(s);
          }
        }
        throw new ConnectorException(
            "Modify Object failed to "
                + path
                + " and body of "
                + body.toString()
                + ". Error code was "
                + response.getStatusLine().getStatusCode()
                + ". Received the following response "
                + sb.toString());
      } else {
        return true;
      }
    } catch (ClientProtocolException cpe) {
      log.error(cpe, "Error doing patchRequest to path {0}", path);
      throw new ConnectorException("Exception whilst doing PATCH to " + path);
    } catch (IOException ioe) {
      log.error(ioe, "IOE Error doing patchRequest to path {0}", path);
      throw new ConnectorException("Exception whilst doing PATCH to " + path);
    }
  }