Return-Path: X-Original-To: apmail-olingo-commits-archive@minotaur.apache.org Delivered-To: apmail-olingo-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 69AC311037 for ; Mon, 28 Jul 2014 10:31:36 +0000 (UTC) Received: (qmail 50287 invoked by uid 500); 28 Jul 2014 10:31:36 -0000 Delivered-To: apmail-olingo-commits-archive@olingo.apache.org Received: (qmail 50261 invoked by uid 500); 28 Jul 2014 10:31:36 -0000 Mailing-List: contact commits-help@olingo.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@olingo.apache.org Delivered-To: mailing list commits@olingo.apache.org Received: (qmail 50252 invoked by uid 99); 28 Jul 2014 10:31:36 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 28 Jul 2014 10:31:36 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 0771E9B7757; Mon, 28 Jul 2014 10:31:36 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: ilgrosso@apache.org To: commits@olingo.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: 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 Date: Mon, 28 Jul 2014 10:31:36 +0000 (UTC) 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 @@ + + + + + 4.0.0 + + olingo-client-samples + jar + ${project.artifactId} + Olingo client customization samples. + + + org.apache.olingo + olingo-parent + 0.1.0-SNAPSHOT + ../.. + + + + + org.apache.olingo + olingo-client-proxy + ${project.version} + + + + 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. + * More information. + */ +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 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, "
"); + final String ppsx = StringUtils.substringBefore( + StringUtils.substringAfter(loginPage, ""); + final String ppft = StringUtils.substringBefore( + StringUtils.substringAfter(loginPage, ""); + + List data = new ArrayList(); + 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, ""); + final String wctx = StringUtils.substringBefore( + StringUtils.substringAfter(samlPage, ""); + final String wresult = StringUtils.substringBefore(StringUtils.substringAfter(samlPage, + ""); + final String wa = StringUtils.substringBefore( + StringUtils.substringAfter(samlPage, ""); + + data = new ArrayList(); + data.add(new BasicNameValuePair("wctx", wctx)); + data.add(new BasicNameValuePair("wresult", wresult.replace(""", "\""))); + 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 data = new ArrayList(); + 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 data = new ArrayList(); + 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. + * More + * information. + */ +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. + *
+ * 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. + * More + * information. + */ +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 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. + * More + * information. + * + * @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. + * More + * information. + * + * @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. + *
+ * 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. + * More + * information. + */ +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. + * More + * information. + */ +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. + *
+ * 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. + * More + * information. + */ +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. + *
+ * HttpClient relies on UserTokenHandler 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. + * More + * information. + */ +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; + } + +}