You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by il...@apache.org on 2014/07/28 12:31:36 UTC

git commit: [OLINGO-381] provided samples for advanced HTTP client-side handling; the submodule is not included in olingo-parent, being not meant for any distribution nor artifact, but only as reference

Repository: olingo-odata4
Updated Branches:
  refs/heads/master 05e41557f -> 16f35e90b


[OLINGO-381] provided samples for advanced HTTP client-side handling; the submodule is not included in olingo-parent, being not meant for any distribution nor artifact, but only as reference


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/16f35e90
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/16f35e90
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/16f35e90

Branch: refs/heads/master
Commit: 16f35e90bd40f2115adb3eff0736b85cd56b5f05
Parents: 05e4155
Author: Francesco Chicchiriccò <--global>
Authored: Mon Jul 28 12:31:26 2014 +0200
Committer: Francesco Chicchiriccò <--global>
Committed: Mon Jul 28 12:31:26 2014 +0200

----------------------------------------------------------------------
 samples/client/pom.xml                          |  46 ++++
 .../http/AzureADOAuth2HttpClientFactory.java    | 217 +++++++++++++++++++
 .../core/http/CookieHttpClientFactory.java      |  54 +++++
 .../CustomConnectionsHttpClientFactory.java     | 123 +++++++++++
 .../core/http/ParametersHttpClientFactory.java  |  53 +++++
 .../http/ParametersHttpUriRequestFactory.java   |  53 +++++
 .../ProtocolInterceptorHttpClientFactory.java   |  75 +++++++
 .../http/RequestRetryHttpClientFactory.java     |  86 ++++++++
 .../http/SocketFactoryHttpClientFactory.java    |  77 +++++++
 .../core/http/StatefulHttpClientFactory.java    |  57 +++++
 10 files changed, 841 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/16f35e90/samples/client/pom.xml
----------------------------------------------------------------------
diff --git a/samples/client/pom.xml b/samples/client/pom.xml
new file mode 100644
index 0000000..87d64fe
--- /dev/null
+++ b/samples/client/pom.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>olingo-client-samples</artifactId>
+  <packaging>jar</packaging>
+  <name>${project.artifactId}</name>
+  <description>Olingo client customization samples.</description>
+  
+  <parent>
+    <groupId>org.apache.olingo</groupId>
+    <artifactId>olingo-parent</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <relativePath>../..</relativePath>
+  </parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-client-proxy</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/16f35e90/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/AzureADOAuth2HttpClientFactory.java
----------------------------------------------------------------------
diff --git a/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/AzureADOAuth2HttpClientFactory.java b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/AzureADOAuth2HttpClientFactory.java
new file mode 100644
index 0000000..e281bd9
--- /dev/null
+++ b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/AzureADOAuth2HttpClientFactory.java
@@ -0,0 +1,217 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.samples.client.core.http;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.Header;
+import org.apache.http.HttpException;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.UsernamePasswordCredentials;
+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.utils.URIBuilder;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.EntityUtils;
+import org.apache.olingo.client.core.http.AbstractOAuth2HttpClientFactory;
+import org.apache.olingo.client.core.http.OAuth2Exception;
+
+/**
+ * Shows how to work with OAuth 2.0 native applications protected by Azure Active Directory.
+ * <a href="http://msdn.microsoft.com/en-us/library/azure/dn645542.aspx">More information</a>.
+ */
+public class AzureADOAuth2HttpClientFactory extends AbstractOAuth2HttpClientFactory {
+
+  private final String clientId;
+
+  private final String redirectURI;
+
+  private final String resourceURI;
+
+  private final UsernamePasswordCredentials creds;
+
+  private ObjectNode token;
+
+  public AzureADOAuth2HttpClientFactory(final String authority, final String clientId,
+          final String redirectURI, final String resourceURI, final UsernamePasswordCredentials creds) {
+
+    super(URI.create(authority + "/oauth2/authorize"), URI.create(authority + "/oauth2/token"));
+    this.clientId = clientId;
+    this.redirectURI = redirectURI;
+    this.resourceURI = resourceURI;
+    this.creds = creds;
+  }
+
+  @Override
+  protected boolean isInited() throws OAuth2Exception {
+    return token != null;
+  }
+
+  private void fetchAccessToken(final DefaultHttpClient httpClient, final List<BasicNameValuePair> data) {
+    token = null;
+
+    InputStream tokenResponse = null;
+    try {
+      final HttpPost post = new HttpPost(oauth2TokenServiceURI);
+      post.setEntity(new UrlEncodedFormEntity(data, "UTF-8"));
+
+      final HttpResponse response = httpClient.execute(post);
+
+      tokenResponse = response.getEntity().getContent();
+      token = (ObjectNode) new ObjectMapper().readTree(tokenResponse);
+    } catch (Exception e) {
+      throw new OAuth2Exception(e);
+    } finally {
+      IOUtils.closeQuietly(tokenResponse);
+    }
+  }
+
+  @Override
+  protected void init() throws OAuth2Exception {
+    final DefaultHttpClient httpClient = wrapped.create(null, null);
+
+    // 1. access the OAuth2 grant service (with authentication)
+    String code = null;
+    try {
+      final URIBuilder builder = new URIBuilder(oauth2GrantServiceURI).
+              addParameter("response_type", "code").
+              addParameter("client_id", clientId).
+              addParameter("redirect_uri", redirectURI);
+
+      HttpResponse response = httpClient.execute(new HttpGet(builder.build()));
+
+      final String loginPage = EntityUtils.toString(response.getEntity());
+
+      String postURL = StringUtils.substringBefore(
+              StringUtils.substringAfter(loginPage, "<form id=\"credentials\" method=\"post\" action=\""),
+              "\">");
+      final String ppsx = StringUtils.substringBefore(
+              StringUtils.substringAfter(loginPage, "<input type=\"hidden\" id=\"PPSX\" name=\"PPSX\" value=\""),
+              "\"/>");
+      final String ppft = StringUtils.substringBefore(
+              StringUtils.substringAfter(loginPage, "<input type=\"hidden\" name=\"PPFT\" id=\"i0327\" value=\""),
+              "\"/>");
+
+      List<BasicNameValuePair> data = new ArrayList<BasicNameValuePair>();
+      data.add(new BasicNameValuePair("login", creds.getUserName()));
+      data.add(new BasicNameValuePair("passwd", creds.getPassword()));
+      data.add(new BasicNameValuePair("PPSX", ppsx));
+      data.add(new BasicNameValuePair("PPFT", ppft));
+
+      HttpPost post = new HttpPost(postURL);
+      post.setEntity(new UrlEncodedFormEntity(data, "UTF-8"));
+
+      response = httpClient.execute(post);
+
+      final String samlPage = EntityUtils.toString(response.getEntity());
+
+      postURL = StringUtils.substringBefore(
+              StringUtils.substringAfter(samlPage, "<form name=\"fmHF\" id=\"fmHF\" action=\""),
+              "\" method=\"post\" target=\"_top\">");
+      final String wctx = StringUtils.substringBefore(
+              StringUtils.substringAfter(samlPage, "<input type=\"hidden\" name=\"wctx\" id=\"wctx\" value=\""),
+              "\">");
+      final String wresult = StringUtils.substringBefore(StringUtils.substringAfter(samlPage,
+              "<input type=\"hidden\" name=\"wresult\" id=\"wresult\" value=\""), "\">");
+      final String wa = StringUtils.substringBefore(
+              StringUtils.substringAfter(samlPage, "<input type=\"hidden\" name=\"wa\" id=\"wa\" value=\""),
+              "\">");
+
+      data = new ArrayList<BasicNameValuePair>();
+      data.add(new BasicNameValuePair("wctx", wctx));
+      data.add(new BasicNameValuePair("wresult", wresult.replace("&quot;", "\"")));
+      data.add(new BasicNameValuePair("wa", wa));
+
+      post = new HttpPost(postURL);
+      post.setEntity(new UrlEncodedFormEntity(data, "UTF-8"));
+
+      response = httpClient.execute(post);
+
+      final Header locationHeader = response.getFirstHeader("Location");
+      if (response.getStatusLine().getStatusCode() != 302 || locationHeader == null) {
+        throw new OAuth2Exception("Unexpected response from server");
+      }
+
+      final String[] oauth2Info = StringUtils.split(
+              StringUtils.substringAfter(locationHeader.getValue(), "?"), '&');
+      code = StringUtils.substringAfter(oauth2Info[0], "=");
+
+      EntityUtils.consume(response.getEntity());
+    } catch (Exception e) {
+      throw new OAuth2Exception(e);
+    }
+
+    if (code == null) {
+      throw new OAuth2Exception("No OAuth2 grant");
+    }
+
+    // 2. ask the OAuth2 token service
+    final List<BasicNameValuePair> data = new ArrayList<BasicNameValuePair>();
+    data.add(new BasicNameValuePair("grant_type", "authorization_code"));
+    data.add(new BasicNameValuePair("code", code));
+    data.add(new BasicNameValuePair("client_id", clientId));
+    data.add(new BasicNameValuePair("redirect_uri", redirectURI));
+    data.add(new BasicNameValuePair("resource", resourceURI));
+
+    fetchAccessToken(httpClient, data);
+
+    if (token == null) {
+      throw new OAuth2Exception("No OAuth2 access token");
+    }
+  }
+
+  @Override
+  protected void accessToken(final DefaultHttpClient client) throws OAuth2Exception {
+    client.addRequestInterceptor(new HttpRequestInterceptor() {
+
+      @Override
+      public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
+        request.removeHeaders(HttpHeaders.AUTHORIZATION);
+        request.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token.get("access_token").asText());
+      }
+    });
+  }
+
+  @Override
+  protected void refreshToken(final DefaultHttpClient client) throws OAuth2Exception {
+    final List<BasicNameValuePair> data = new ArrayList<BasicNameValuePair>();
+    data.add(new BasicNameValuePair("grant_type", "refresh_token"));
+    data.add(new BasicNameValuePair("refresh_token", token.get("refresh_token").asText()));
+
+    fetchAccessToken(wrapped.create(null, null), data);
+
+    if (token == null) {
+      throw new OAuth2Exception("No OAuth2 refresh token");
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/16f35e90/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/CookieHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/CookieHttpClientFactory.java b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/CookieHttpClientFactory.java
new file mode 100644
index 0000000..4857b11
--- /dev/null
+++ b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/CookieHttpClientFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.samples.client.core.http;
+
+import java.net.URI;
+import org.apache.http.client.CookieStore;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.cookie.BasicClientCookie;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.http.DefaultHttpClientFactory;
+
+/**
+ * Shows how to work with HTTP cookies.
+ * <a
+ * href="http://svn.apache.org/repos/asf/httpcomponents/site/httpcomponents-client-4.2.x/tutorial/html/statemgmt.html#d5e669">More
+ * information</a>.
+ */
+public class CookieHttpClientFactory extends DefaultHttpClientFactory {
+
+  @Override
+  public DefaultHttpClient create(final HttpMethod method, final URI uri) {
+    final CookieStore cookieStore = new BasicCookieStore();
+
+    // Populate cookies if needed
+    final BasicClientCookie cookie = new BasicClientCookie("name", "value");
+    cookie.setVersion(0);
+    cookie.setDomain(".mycompany.com");
+    cookie.setPath("/");
+    cookieStore.addCookie(cookie);
+
+    final DefaultHttpClient httpClient = super.create(method, uri);
+    httpClient.setCookieStore(cookieStore);
+
+    return httpClient;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/16f35e90/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/CustomConnectionsHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/CustomConnectionsHttpClientFactory.java b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/CustomConnectionsHttpClientFactory.java
new file mode 100644
index 0000000..8975678
--- /dev/null
+++ b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/CustomConnectionsHttpClientFactory.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.samples.client.core.http;
+
+import java.net.URI;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpResponseFactory;
+import org.apache.http.ParseException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.conn.ClientConnectionOperator;
+import org.apache.http.conn.OperatedClientConnection;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.BasicClientConnectionManager;
+import org.apache.http.impl.conn.DefaultClientConnection;
+import org.apache.http.impl.conn.DefaultClientConnectionOperator;
+import org.apache.http.impl.conn.DefaultHttpResponseParser;
+import org.apache.http.io.HttpMessageParser;
+import org.apache.http.io.SessionInputBuffer;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.message.BasicLineParser;
+import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpParams;
+import org.apache.http.util.CharArrayBuffer;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.http.AbstractHttpClientFactory;
+
+/**
+ * Shows how to use custom client connections.
+ * <br/>
+ * In certain situations it may be necessary to customize the way HTTP messages get transmitted across the wire beyond
+ * what is possible using HTTP parameters in order to be able to deal non-standard, non-compliant behaviours. For
+ * instance, for web crawlers it may be necessary to force HttpClient into accepting malformed response heads in order
+ * to salvage the content of the messages.
+ * <a
+ * href="http://svn.apache.org/repos/asf/httpcomponents/site/httpcomponents-client-4.2.x/tutorial/html/advanced.html#d5e1339">More
+ * information</a>.
+ */
+public class CustomConnectionsHttpClientFactory extends AbstractHttpClientFactory {
+
+  private static class MyLineParser extends BasicLineParser {
+
+    @Override
+    public Header parseHeader(final CharArrayBuffer buffer) throws ParseException {
+      try {
+        return super.parseHeader(buffer);
+      } catch (ParseException ex) {
+        // Suppress ParseException exception
+        return new BasicHeader("invalid", buffer.toString());
+      }
+    }
+
+  }
+
+  private static class MyClientConnection extends DefaultClientConnection {
+
+    @Override
+    protected HttpMessageParser<HttpResponse> createResponseParser(
+            final SessionInputBuffer buffer,
+            final HttpResponseFactory responseFactory,
+            final HttpParams params) {
+
+      return new DefaultHttpResponseParser(
+              buffer,
+              new MyLineParser(),
+              responseFactory,
+              params);
+    }
+
+  }
+
+  private static class MyClientConnectionOperator extends DefaultClientConnectionOperator {
+
+    public MyClientConnectionOperator(final SchemeRegistry registry) {
+      super(registry);
+    }
+
+    @Override
+    public OperatedClientConnection createConnection() {
+      return new MyClientConnection();
+    }
+
+  }
+
+  private static class MyClientConnManager extends BasicClientConnectionManager {
+
+    @Override
+    protected ClientConnectionOperator createConnectionOperator(final SchemeRegistry registry) {
+      return new MyClientConnectionOperator(registry);
+    }
+
+  }
+
+  @Override
+  public DefaultHttpClient create(final HttpMethod method, final URI uri) {
+    final DefaultHttpClient httpClient = new DefaultHttpClient(new MyClientConnManager());
+    httpClient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, USER_AGENT);
+
+    return httpClient;
+  }
+
+  @Override
+  public void close(final HttpClient httpClient) {
+    httpClient.getConnectionManager().shutdown();
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/16f35e90/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/ParametersHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/ParametersHttpClientFactory.java b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/ParametersHttpClientFactory.java
new file mode 100644
index 0000000..bdee1d0
--- /dev/null
+++ b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/ParametersHttpClientFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.samples.client.core.http;
+
+import java.net.URI;
+import org.apache.http.HttpVersion;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.http.DefaultHttpClientFactory;
+
+/**
+ * Shows how to customize the runtime behavior of HTTP client component.
+ * <a
+ * href="http://svn.apache.org/repos/asf/httpcomponents/site/httpcomponents-client-4.2.x/tutorial/html/fundamentals.html#d5e299">More
+ * information</a>.
+ *
+ * @see ParametersHttpUriRequestFactory for how to customize at request level
+ */
+public class ParametersHttpClientFactory extends DefaultHttpClientFactory {
+
+  @Override
+  public DefaultHttpClient create(final HttpMethod method, final URI uri) {
+    final DefaultHttpClient httpClient = super.create(method, uri);
+
+    httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_0);
+    httpClient.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8");
+
+    final int timeout = 1000;
+    HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), timeout);
+    HttpConnectionParams.setSoTimeout(httpClient.getParams(), timeout);
+
+    return httpClient;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/16f35e90/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/ParametersHttpUriRequestFactory.java
----------------------------------------------------------------------
diff --git a/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/ParametersHttpUriRequestFactory.java b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/ParametersHttpUriRequestFactory.java
new file mode 100644
index 0000000..9ba0746
--- /dev/null
+++ b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/ParametersHttpUriRequestFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.samples.client.core.http;
+
+import java.net.URI;
+import org.apache.http.HttpVersion;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.http.DefaultHttpUriRequestFactory;
+
+/**
+ * Shows how to customize the runtime behavior of an HTTP request.
+ * <a
+ * href="http://svn.apache.org/repos/asf/httpcomponents/site/httpcomponents-client-4.2.x/tutorial/html/fundamentals.html#d5e299">More
+ * information</a>.
+ *
+ * @see ParametersHttpClientFactory for how to customize at whole client level
+ */
+public class ParametersHttpUriRequestFactory extends DefaultHttpUriRequestFactory {
+
+  @Override
+  public HttpUriRequest create(final HttpMethod method, final URI uri) {
+    final HttpUriRequest request = super.create(method, uri);
+
+    request.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_0);
+    request.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8");
+
+    final int timeout = 1000;
+    HttpConnectionParams.setConnectionTimeout(request.getParams(), timeout);
+    HttpConnectionParams.setSoTimeout(request.getParams(), timeout);
+
+    return request;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/16f35e90/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/ProtocolInterceptorHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/ProtocolInterceptorHttpClientFactory.java b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/ProtocolInterceptorHttpClientFactory.java
new file mode 100644
index 0000000..72beab9
--- /dev/null
+++ b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/ProtocolInterceptorHttpClientFactory.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.samples.client.core.http;
+
+import java.io.IOException;
+import java.net.URI;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpResponseInterceptor;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.protocol.HttpContext;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.http.DefaultHttpClientFactory;
+
+/**
+ * Shows how to install HTTP protocol interceptors, an easy handle to hook into HTTP request / response processing.
+ * <br/>
+ * Usually protocol interceptors are expected to act upon one specific header or a group of related headers of the
+ * incoming message, or populate the outgoing message with one specific header or a group of related headers. Protocol
+ * interceptors can also manipulate content entities enclosed with messages - transparent content compression /
+ * decompression being a good example. Usually this is accomplished by using the 'Decorator' pattern where a wrapper
+ * entity class is used to decorate the original entity. Several protocol interceptors can be combined to form one
+ * logical unit.
+ * <a
+ * href="http://svn.apache.org/repos/asf/httpcomponents/site/httpcomponents-client-4.2.x/tutorial/html/fundamentals.html#protocol_interceptors">More
+ * information</a>.
+ */
+public class ProtocolInterceptorHttpClientFactory extends DefaultHttpClientFactory {
+
+  @Override
+  public DefaultHttpClient create(final HttpMethod method, final URI uri) {
+
+    final DefaultHttpClient httpClient = super.create(method, uri);
+
+    httpClient.addRequestInterceptor(new HttpRequestInterceptor() {
+
+      @Override
+      public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
+        request.addHeader("CUSTOM_HEADER", "CUSTOM VALUE");
+      }
+
+    });
+
+    httpClient.addResponseInterceptor(new HttpResponseInterceptor() {
+
+      @Override
+      public void process(final HttpResponse response, final HttpContext context) throws HttpException, IOException {
+        if ("ANOTHER CUSTOM VALUE".equals(response.getFirstHeader("ANOTHER_CUSTOM_HEADER"))) {
+          // do something
+        }
+      }
+    });
+
+    return httpClient;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/16f35e90/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/RequestRetryHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/RequestRetryHttpClientFactory.java b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/RequestRetryHttpClientFactory.java
new file mode 100644
index 0000000..e39e07b
--- /dev/null
+++ b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/RequestRetryHttpClientFactory.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.samples.client.core.http;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.ConnectException;
+import java.net.URI;
+import java.net.UnknownHostException;
+import javax.net.ssl.SSLException;
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpRequest;
+import org.apache.http.client.HttpRequestRetryHandler;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.http.DefaultHttpClientFactory;
+
+/**
+ * Shows how to install a custom exception recovery mechanism.
+ * <a
+ * href="http://svn.apache.org/repos/asf/httpcomponents/site/httpcomponents-client-4.2.x/tutorial/html/fundamentals.html#d5e281">More
+ * information</a>.
+ */
+public class RequestRetryHttpClientFactory extends DefaultHttpClientFactory {
+
+  @Override
+  public DefaultHttpClient create(final HttpMethod method, final URI uri) {
+    final HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
+
+      @Override
+      public boolean retryRequest(final IOException exception, final int executionCount, final HttpContext context) {
+        if (executionCount >= 5) {
+          // Do not retry if over max retry count
+          return false;
+        }
+        if (exception instanceof InterruptedIOException) {
+          // Timeout
+          return false;
+        }
+        if (exception instanceof UnknownHostException) {
+          // Unknown host
+          return false;
+        }
+        if (exception instanceof ConnectException) {
+          // Connection refused
+          return false;
+        }
+        if (exception instanceof SSLException) {
+          // SSL handshake exception
+          return false;
+        }
+        final HttpRequest request = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
+        boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
+        if (idempotent) {
+          // Retry if the request is considered idempotent 
+          return true;
+        }
+        return false;
+      }
+
+    };
+
+    final DefaultHttpClient httpClient = super.create(method, uri);
+    httpClient.setHttpRequestRetryHandler(myRetryHandler);
+    return httpClient;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/16f35e90/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/SocketFactoryHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/SocketFactoryHttpClientFactory.java b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/SocketFactoryHttpClientFactory.java
new file mode 100644
index 0000000..1d41005
--- /dev/null
+++ b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/SocketFactoryHttpClientFactory.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.samples.client.core.http;
+
+import java.net.URI;
+import java.security.cert.X509Certificate;
+import org.apache.http.client.HttpClient;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.BasicClientConnectionManager;
+import org.apache.http.params.CoreProtocolPNames;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.http.AbstractHttpClientFactory;
+import org.apache.olingo.commons.api.ODataRuntimeException;
+
+/**
+ * Shows how to customize the way how the underlying network socket are managed by the HTTP component; the specific
+ * sample is about how to trust self-signed SSL certificates and also empowers connection management.
+ * <br/>
+ * HTTP connections make use of a java.net.Socket object internally to handle transmission of data across the wire.
+ * However they rely on the SchemeSocketFactory interface to create, initialize and connect sockets. This enables the
+ * users of HttpClient to provide application specific socket initialization code at runtime. PlainSocketFactory is the
+ * default factory for creating and initializing plain (unencrypted) sockets.
+ * <a
+ * href="http://svn.apache.org/repos/asf/httpcomponents/site/httpcomponents-client-4.2.x/tutorial/html/connmgmt.html#d5e512">More
+ * information</a>.
+ */
+public class SocketFactoryHttpClientFactory extends AbstractHttpClientFactory {
+
+  @Override
+  public DefaultHttpClient create(final HttpMethod method, final URI uri) {
+    final TrustStrategy acceptTrustStrategy = new TrustStrategy() {
+      @Override
+      public boolean isTrusted(final X509Certificate[] certificate, final String authType) {
+        return true;
+      }
+    };
+
+    final SchemeRegistry registry = new SchemeRegistry();
+    try {
+      final SSLSocketFactory ssf =
+              new SSLSocketFactory(acceptTrustStrategy, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+      registry.register(new Scheme(uri.getScheme(), uri.getPort(), ssf));
+    } catch (Exception e) {
+      throw new ODataRuntimeException(e);
+    }
+
+    final DefaultHttpClient httpClient = new DefaultHttpClient(new BasicClientConnectionManager(registry));
+    httpClient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, USER_AGENT);
+
+    return httpClient;
+  }
+
+  @Override
+  public void close(final HttpClient httpClient) {
+    httpClient.getConnectionManager().shutdown();
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/16f35e90/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/StatefulHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/StatefulHttpClientFactory.java b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/StatefulHttpClientFactory.java
new file mode 100644
index 0000000..4d69abd
--- /dev/null
+++ b/samples/client/src/main/java/org/apache/olingo/samples/client/core/http/StatefulHttpClientFactory.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.samples.client.core.http;
+
+import java.net.URI;
+import org.apache.http.client.UserTokenHandler;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.protocol.HttpContext;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.http.DefaultHttpClientFactory;
+
+/**
+ * Shows how to work with stateful HTTP connections.
+ * <br/>
+ * HttpClient relies on <tt>UserTokenHandler</tt> interface to determine if the given execution context is user specific
+ * or not. The token object returned by this handler is expected to uniquely identify the current user if the context is
+ * user specific or to be null if the context does not contain any resources or details specific to the current user.
+ * The user token will be used to ensure that user specific resources will not be shared with or reused by other users.
+ * <a
+ * href="http://svn.apache.org/repos/asf/httpcomponents/site/httpcomponents-client-4.2.x/tutorial/html/advanced.html#stateful_conn">More
+ * information</a>.
+ */
+public class StatefulHttpClientFactory extends DefaultHttpClientFactory {
+
+  @Override
+  public DefaultHttpClient create(final HttpMethod method, final URI uri) {
+    final DefaultHttpClient httpClient = super.create(method, uri);
+
+    httpClient.setUserTokenHandler(new UserTokenHandler() {
+
+      @Override
+      public Object getUserToken(final HttpContext context) {
+        return context.getAttribute("my-token");
+      }
+
+    });
+
+    return httpClient;
+  }
+
+}