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/21 13:33:52 UTC
git commit: [OLINGO-362] Now supporting refresh token
Repository: olingo-odata4
Updated Branches:
refs/heads/master df7cba690 -> c155238d9
[OLINGO-362] Now supporting refresh token
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/c155238d
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/c155238d
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/c155238d
Branch: refs/heads/master
Commit: c155238d9cce9d1a2b170ac8a898b126b09c0f9a
Parents: df7cba6
Author: Francesco Chicchiriccò <--global>
Authored: Mon Jul 21 13:33:34 2014 +0200
Committer: Francesco Chicchiriccò <--global>
Committed: Mon Jul 21 13:33:34 2014 +0200
----------------------------------------------------------------------
.../java/org/apache/olingo/fit/V4OAuth2.java | 4 -
.../olingo/fit/rest/OAuth2InInterceptor.java | 98 ----------
.../apache/olingo/fit/rest/OAuth2Provider.java | 2 -
.../olingo/fit/rest/OAuth2RequestFilter.java | 38 ++++
.../main/webapp/WEB-INF/applicationContext.xml | 5 +-
.../olingo/fit/CXFOAuth2HttpClientFactory.java | 181 +++++++++++++++++++
.../fit/CXFOAuth2HttpUriRequestFactory.java | 131 --------------
.../apache/olingo/fit/v4/OAuth2TestITCase.java | 27 +--
.../api/http/WrappingHttpClientFactory.java | 24 +++
.../http/AbstractOAuth2HttpClientFactory.java | 116 ++++++++++++
.../AbstractOAuth2HttpUriRequestFactory.java | 53 ------
.../client/core/http/OAuth2Exception.java | 4 +
.../http/ProxyWrapperHttpClientFactory.java | 96 ----------
.../http/ProxyWrappingHttpClientFactory.java | 97 ++++++++++
.../AbstractODataDeserializer.java | 15 +-
.../apache/olingo/client/core/uri/URIUtils.java | 6 +-
.../core/serialization/JsonDeserializer.java | 148 ++++++++-------
17 files changed, 572 insertions(+), 473 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/fit/src/main/java/org/apache/olingo/fit/V4OAuth2.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/V4OAuth2.java b/fit/src/main/java/org/apache/olingo/fit/V4OAuth2.java
index 02dc887..dd5e89e 100644
--- a/fit/src/main/java/org/apache/olingo/fit/V4OAuth2.java
+++ b/fit/src/main/java/org/apache/olingo/fit/V4OAuth2.java
@@ -18,16 +18,12 @@
*/
package org.apache.olingo.fit;
-import org.apache.cxf.interceptor.InInterceptors;
-import org.apache.olingo.fit.rest.OAuth2InInterceptor;
import org.springframework.stereotype.Service;
-
import javax.ws.rs.Path;
import java.io.IOException;
@Service
@Path("/V40/OAuth2.svc")
-@InInterceptors(classes = {OAuth2InInterceptor.class})
public class V4OAuth2 extends V4Services {
public V4OAuth2() throws IOException {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2InInterceptor.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2InInterceptor.java b/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2InInterceptor.java
deleted file mode 100644
index d61d3f0..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2InInterceptor.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.fit.rest;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.cxf.interceptor.Fault;
-import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
-import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.cxf.message.Message;
-import org.apache.cxf.phase.AbstractPhaseInterceptor;
-import org.apache.cxf.phase.Phase;
-import org.apache.cxf.rs.security.oauth2.client.OAuthClientUtils;
-import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
-import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrant;
-import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
-import org.apache.cxf.transport.http.AbstractHTTPDestination;
-
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-
-public class OAuth2InInterceptor extends AbstractPhaseInterceptor<Message> {
-
- private static final OAuthClientUtils.Consumer OAUTH2_CONSUMER =
- new OAuthClientUtils.Consumer(OAuth2Provider.CLIENT_ID, OAuth2Provider.CLIENT_SECRET);
-
- public OAuth2InInterceptor() {
- super(Phase.PRE_INVOKE);
- }
-
- @Override
- public void handleMessage(final Message message) throws Fault {
- final String requestURL = (String) message.get(Message.REQUEST_URL);
- if (requestURL.contains("V40/OAuth2.svc")) {
- @SuppressWarnings("unchecked")
- final Map<String, List<String>> headers = (Map<String, List<String>>) message.get(Message.PROTOCOL_HEADERS);
- final List<String> oauth2CodeHeader = headers.get(OAuth2Provider.OAUTH2_CODE_HEADER);
- if (oauth2CodeHeader == null || oauth2CodeHeader.isEmpty()) {
- message.put(AbstractHTTPDestination.REQUEST_REDIRECTED, Boolean.TRUE);
-
- final HttpServletResponse response = (HttpServletResponse) message.get(AbstractHTTPDestination.HTTP_RESPONSE);
- try {
- final String authorizationServiceURI =
- StringUtils.substringBefore(requestURL, "V40/OAuth2.svc") + "oauth/authorize";
-
- final URI authorizationURI = OAuthClientUtils.getAuthorizationURI(
- authorizationServiceURI,
- OAuth2Provider.CLIENT_ID,
- OAuth2Provider.REDIRECT_URI,
- null,
- null);
- response.addHeader("Location", authorizationURI.toASCIIString());
- response.sendError(303);
- } catch (Exception e) {
- throw new Fault(e);
- }
- } else {
- try {
- final JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
- bean.setAddress(StringUtils.substringBefore(requestURL, "V40/OAuth2.svc") + "oauth/token");
- bean.setUsername("odatajclient");
- bean.setPassword("odatajclient");
- final WebClient accessTokenService = bean.createWebClient().
- type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).
- accept(MediaType.APPLICATION_JSON_TYPE);
-
- final AuthorizationCodeGrant codeGrant = new AuthorizationCodeGrant(oauth2CodeHeader.get(0));
- final ClientAccessToken accessToken =
- OAuthClientUtils.getAccessToken(accessTokenService, OAUTH2_CONSUMER, codeGrant);
- if (accessToken == null) {
- throw new WebApplicationException("No OAuth2 access token");
- }
- } catch (OAuthServiceException e) {
- throw new Fault(e);
- }
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2Provider.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2Provider.java b/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2Provider.java
index cfe25b9..7000650 100644
--- a/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2Provider.java
+++ b/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2Provider.java
@@ -40,8 +40,6 @@ public class OAuth2Provider implements AuthorizationCodeDataProvider {
public static final String REDIRECT_URI = "/stub/StaticService/V40/OAuth2.svc/";
- public static final String OAUTH2_CODE_HEADER = "oauth2.token";
-
private Client client;
private ServerAuthorizationCodeGrant grant;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java b/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java
new file mode 100644
index 0000000..9022374
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java
@@ -0,0 +1,38 @@
+/*
+ * 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.fit.rest;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.ext.Provider;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter;
+
+@Provider
+public class OAuth2RequestFilter extends OAuthRequestFilter implements ContainerRequestFilter {
+
+ @Override
+ public void filter(final ContainerRequestContext context) {
+ final String svcName =
+ StringUtils.substringBefore(StringUtils.substringAfter(context.getUriInfo().getPath(), "/"), "/");
+ if ("OAuth2.svc".equals(svcName)) {
+ super.filter(context);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/fit/src/main/webapp/WEB-INF/applicationContext.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/webapp/WEB-INF/applicationContext.xml b/fit/src/main/webapp/WEB-INF/applicationContext.xml
index 2cadd61..f1320b9 100644
--- a/fit/src/main/webapp/WEB-INF/applicationContext.xml
+++ b/fit/src/main/webapp/WEB-INF/applicationContext.xml
@@ -40,6 +40,9 @@
<jaxrs:server id="services" address="/" basePackages="org.apache.olingo.fit">
<jaxrs:providers>
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider"/>
+ <bean class="org.apache.olingo.fit.rest.OAuth2RequestFilter">
+ <property name="dataProvider" ref="oauthProvider"/>
+ </bean>
<bean class="org.apache.olingo.fit.rest.ServiceNameResponseFilter"/>
</jaxrs:providers>
</jaxrs:server>
@@ -52,7 +55,7 @@
<property name="dataProvider" ref="oauthProvider"/>
</bean>
<bean id="oauthSecurityInterceptor" class="org.apache.olingo.fit.rest.StaticSecurityInterceptor"/>
- <jaxrs:server id="oauthServer" address="/oauth">
+ <jaxrs:server id="oauthServer" address="/oauth2">
<jaxrs:serviceBeans>
<ref bean="authorizationService"/>
<ref bean="accessTokenService"/>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/fit/src/test/java/org/apache/olingo/fit/CXFOAuth2HttpClientFactory.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/CXFOAuth2HttpClientFactory.java b/fit/src/test/java/org/apache/olingo/fit/CXFOAuth2HttpClientFactory.java
new file mode 100644
index 0000000..28ff3d8
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/CXFOAuth2HttpClientFactory.java
@@ -0,0 +1,181 @@
+/*
+ * 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.fit;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import java.io.IOException;
+import java.net.URI;
+import javax.ws.rs.core.MediaType;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.rs.security.oauth2.client.OAuthClientUtils;
+import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
+import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrant;
+import org.apache.cxf.rs.security.oauth2.grants.refresh.RefreshTokenGrant;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+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.client.methods.HttpGet;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+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;
+import org.apache.olingo.fit.rest.OAuth2Provider;
+
+public class CXFOAuth2HttpClientFactory extends AbstractOAuth2HttpClientFactory {
+
+ private static final OAuthClientUtils.Consumer OAUTH2_CONSUMER =
+ new OAuthClientUtils.Consumer(OAuth2Provider.CLIENT_ID, OAuth2Provider.CLIENT_SECRET);
+
+ private ClientAccessToken accessToken;
+
+ public CXFOAuth2HttpClientFactory(final URI oauth2GrantServiceURI, final URI oauth2TokenServiceURI) {
+ super(oauth2GrantServiceURI, oauth2TokenServiceURI);
+ }
+
+ private WebClient getAccessTokenService() {
+ final JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+ bean.setAddress(oauth2TokenServiceURI.toASCIIString());
+ bean.setUsername("odatajclient");
+ bean.setPassword("odatajclient");
+ return bean.createWebClient().
+ type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).accept(MediaType.APPLICATION_JSON_TYPE);
+ }
+
+ @Override
+ protected boolean isInited() throws OAuth2Exception {
+ return accessToken != null;
+ }
+
+ @Override
+ protected void init() throws OAuth2Exception {
+ final URI authURI = OAuthClientUtils.getAuthorizationURI(
+ oauth2GrantServiceURI.toASCIIString(),
+ OAuth2Provider.CLIENT_ID,
+ OAuth2Provider.REDIRECT_URI,
+ null,
+ null);
+
+ // Disable automatic redirects handling
+ final HttpParams params = new BasicHttpParams();
+ params.setParameter(ClientPNames.HANDLE_REDIRECTS, false);
+ final DefaultHttpClient httpClient = new DefaultHttpClient(params);
+
+ JsonNode oAuthAuthorizationData = null;
+ String authenticityCookie = null;
+ try {
+ // 1. Need to (basic) authenticate against the OAuth2 service
+ final HttpGet method = new HttpGet(authURI);
+ method.addHeader("Authorization", "Basic " + Base64.encodeBase64String("odatajclient:odatajclient".getBytes()));
+ final HttpResponse response = httpClient.execute(method);
+
+ // 2. Pull out OAuth2 authorization data and "authenticity" cookie (CXF specific)
+ oAuthAuthorizationData = new XmlMapper().readTree(EntityUtils.toString(response.getEntity()));
+
+ final Header setCookieHeader = response.getFirstHeader("Set-Cookie");
+ if (setCookieHeader == null) {
+ throw new IllegalStateException("OAuth flow is broken");
+ }
+ authenticityCookie = setCookieHeader.getValue();
+ } catch (Exception e) {
+ throw new OAuth2Exception(e);
+ }
+
+ String code = null;
+ try {
+ // 3. Submit the HTTP form for allowing access to the application
+ final URI location = new URIBuilder(oAuthAuthorizationData.get("replyTo").asText()).
+ addParameter("session_authenticity_token", oAuthAuthorizationData.get("authenticityToken").asText()).
+ addParameter("client_id", oAuthAuthorizationData.get("clientId").asText()).
+ addParameter("redirect_uri", oAuthAuthorizationData.get("redirectUri").asText()).
+ addParameter("oauthDecision", "allow").
+ build();
+ final HttpGet method = new HttpGet(location);
+ method.addHeader("Authorization", "Basic " + Base64.encodeBase64String("odatajclient:odatajclient".getBytes()));
+ method.addHeader("Cookie", authenticityCookie);
+
+ final HttpResponse response = httpClient.execute(method);
+
+ final Header locationHeader = response.getFirstHeader("Location");
+ if (response.getStatusLine().getStatusCode() != 303 || locationHeader == null) {
+ throw new IllegalStateException("OAuth flow is broken");
+ }
+
+ // 4. Get the authorization code value out of this last redirect
+ code = StringUtils.substringAfterLast(locationHeader.getValue(), "=");
+
+ EntityUtils.consumeQuietly(response.getEntity());
+ } catch (Exception e) {
+ throw new OAuth2Exception(e);
+ }
+
+ // 5. Obtain the access token
+ try {
+ accessToken = OAuthClientUtils.getAccessToken(
+ getAccessTokenService(), OAUTH2_CONSUMER, new AuthorizationCodeGrant(code));
+ } catch (OAuthServiceException e) {
+ throw new OAuth2Exception(e);
+ }
+
+ if (accessToken == 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, OAuthClientUtils.createAuthorizationHeader(accessToken));
+ }
+ });
+ }
+
+ @Override
+ protected void refreshToken(final DefaultHttpClient client) throws OAuth2Exception {
+ final String refreshToken = accessToken.getRefreshToken();
+ if (refreshToken == null) {
+ throw new OAuth2Exception("No OAuth2 refresh token");
+ }
+
+ // refresh the token
+ try {
+ accessToken = OAuthClientUtils.getAccessToken(
+ getAccessTokenService(), OAUTH2_CONSUMER, new RefreshTokenGrant(refreshToken));
+ } catch (OAuthServiceException e) {
+ throw new OAuth2Exception(e);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/fit/src/test/java/org/apache/olingo/fit/CXFOAuth2HttpUriRequestFactory.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/CXFOAuth2HttpUriRequestFactory.java b/fit/src/test/java/org/apache/olingo/fit/CXFOAuth2HttpUriRequestFactory.java
deleted file mode 100644
index a682a52..0000000
--- a/fit/src/test/java/org/apache/olingo/fit/CXFOAuth2HttpUriRequestFactory.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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.fit;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.dataformat.xml.XmlMapper;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.http.Header;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.params.ClientPNames;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.util.EntityUtils;
-import org.apache.olingo.client.core.http.AbstractOAuth2HttpUriRequestFactory;
-import org.apache.olingo.client.core.http.OAuth2Exception;
-import org.apache.olingo.fit.rest.OAuth2Provider;
-
-import java.net.URI;
-
-public class CXFOAuth2HttpUriRequestFactory extends AbstractOAuth2HttpUriRequestFactory {
-
- private String code;
-
- public CXFOAuth2HttpUriRequestFactory(final URI redirectURI) {
- super(redirectURI);
- }
-
- @Override
- protected boolean isInited() {
- return code != null;
- }
-
- @Override
- protected void init() throws OAuth2Exception {
- // 1. Disable automatic redirects handling
- final HttpParams params = new BasicHttpParams();
- params.setParameter(ClientPNames.HANDLE_REDIRECTS, false);
- final DefaultHttpClient httpClient = new DefaultHttpClient(params);
-
- // 2. Try to access the redirect URI without any special header: get redirected to the OAuth2 service
- URI location = null;
- try {
- final HttpResponse response = httpClient.execute(new HttpGet(redirectURI));
-
- final Header locationHeader = response.getFirstHeader("Location");
- if (response.getStatusLine().getStatusCode() != 303 || locationHeader == null) {
- throw new IllegalStateException("OAuth flow is broken");
- }
-
- location = new URI(locationHeader.getValue());
-
- EntityUtils.consumeQuietly(response.getEntity());
- } catch (Exception e) {
- throw new OAuth2Exception(e);
- }
-
- JsonNode oAuthAuthorizationData = null;
- String authenticityCookie = null;
- try {
- // 3. Need to (basic) authenticate against the OAuth2 service
- final HttpGet method = new HttpGet(location);
- method.addHeader("Authorization", "Basic " + Base64.encodeBase64String("odatajclient:odatajclient".getBytes()));
- final HttpResponse response = httpClient.execute(method);
-
- // 4. Pull out OAuth2 authorization data and "authenticity" cookie (CXF specific)
- oAuthAuthorizationData = new XmlMapper().readTree(EntityUtils.toString(response.getEntity()));
-
- final Header setCookieHeader = response.getFirstHeader("Set-Cookie");
- if (setCookieHeader == null) {
- throw new IllegalStateException("OAuth flow is broken");
- }
- authenticityCookie = setCookieHeader.getValue();
- } catch (Exception e) {
- throw new OAuth2Exception(e);
- }
-
- try {
- // 5. Submit the HTTP form for allowing access to the application
- location = new URIBuilder(oAuthAuthorizationData.get("replyTo").asText()).
- addParameter("session_authenticity_token", oAuthAuthorizationData.get("authenticityToken").asText()).
- addParameter("client_id", oAuthAuthorizationData.get("clientId").asText()).
- addParameter("redirect_uri", oAuthAuthorizationData.get("redirectUri").asText()).
- addParameter("oauthDecision", "allow").
- build();
- final HttpGet method = new HttpGet(location);
- method.addHeader("Authorization", "Basic " + Base64.encodeBase64String("odatajclient:odatajclient".getBytes()));
- method.addHeader("Cookie", authenticityCookie);
-
- final HttpResponse response = httpClient.execute(method);
-
- final Header locationHeader = response.getFirstHeader("Location");
- if (response.getStatusLine().getStatusCode() != 303 || locationHeader == null) {
- throw new IllegalStateException("OAuth flow is broken");
- }
-
- // 6. Finally get the code value out of this last redirect
- code = StringUtils.substringAfterLast(locationHeader.getValue(), "=");
-
- EntityUtils.consumeQuietly(response.getEntity());
- } catch (Exception e) {
- throw new OAuth2Exception(e);
- }
- }
-
- @Override
- protected void sign(final HttpUriRequest request) {
- request.addHeader(OAuth2Provider.OAUTH2_CODE_HEADER, code);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/fit/src/test/java/org/apache/olingo/fit/v4/OAuth2TestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/v4/OAuth2TestITCase.java b/fit/src/test/java/org/apache/olingo/fit/v4/OAuth2TestITCase.java
index 8595c3f..be8eabb 100644
--- a/fit/src/test/java/org/apache/olingo/fit/v4/OAuth2TestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/v4/OAuth2TestITCase.java
@@ -18,6 +18,9 @@
*/
package org.apache.olingo.fit.v4;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
@@ -25,39 +28,41 @@ import org.apache.olingo.client.api.uri.v4.URIBuilder;
import org.apache.olingo.client.api.v4.EdmEnabledODataClient;
import org.apache.olingo.client.api.v4.ODataClient;
import org.apache.olingo.client.core.ODataClientFactory;
-import org.apache.olingo.client.core.http.DefaultHttpUriRequestFactory;
import org.apache.olingo.commons.api.domain.v4.ODataEntity;
import org.apache.olingo.commons.api.format.ODataFormat;
-import org.apache.olingo.fit.CXFOAuth2HttpUriRequestFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
-
import java.net.URI;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import org.apache.olingo.client.core.http.DefaultHttpClientFactory;
+import org.apache.olingo.fit.CXFOAuth2HttpClientFactory;
public class OAuth2TestITCase extends AbstractTestITCase {
+ private static final URI OAUTH2_GRANT_SERVICE_URI =
+ URI.create("http://localhost:9080/stub/StaticService/oauth2/authorize");
+
+ private static final URI OAUTH2_TOKEN_SERVICE_URI =
+ URI.create("http://localhost:9080/stub/StaticService/oauth2/token");
+
private EdmEnabledODataClient _edmClient;
@BeforeClass
public static void enableOAuth2() {
- client.getConfiguration().setHttpUriRequestFactory(
- new CXFOAuth2HttpUriRequestFactory(URI.create(testOAuth2ServiceRootURL)));
+ client.getConfiguration().setHttpClientFactory(
+ new CXFOAuth2HttpClientFactory(OAUTH2_GRANT_SERVICE_URI, OAUTH2_TOKEN_SERVICE_URI));
}
@AfterClass
public static void disableOAuth2() {
- client.getConfiguration().setHttpUriRequestFactory(new DefaultHttpUriRequestFactory());
+ client.getConfiguration().setHttpClientFactory(new DefaultHttpClientFactory());
}
protected EdmEnabledODataClient getEdmClient() {
if (_edmClient == null) {
_edmClient = ODataClientFactory.getEdmEnabledV4(testOAuth2ServiceRootURL);
- _edmClient.getConfiguration().setHttpUriRequestFactory(
- new CXFOAuth2HttpUriRequestFactory(URI.create(testOAuth2ServiceRootURL)));
+ _edmClient.getConfiguration().setHttpClientFactory(
+ new CXFOAuth2HttpClientFactory(OAUTH2_GRANT_SERVICE_URI, OAUTH2_TOKEN_SERVICE_URI));
}
return _edmClient;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/lib/client-api/src/main/java/org/apache/olingo/client/api/http/WrappingHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/http/WrappingHttpClientFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/http/WrappingHttpClientFactory.java
new file mode 100644
index 0000000..244cc5f
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/http/WrappingHttpClientFactory.java
@@ -0,0 +1,24 @@
+/*
+ * 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.client.api.http;
+
+public interface WrappingHttpClientFactory extends HttpClientFactory {
+
+ HttpClientFactory getWrappedHttpClientFactory();
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/lib/client-core/src/main/java/org/apache/olingo/client/core/http/AbstractOAuth2HttpClientFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/http/AbstractOAuth2HttpClientFactory.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/http/AbstractOAuth2HttpClientFactory.java
new file mode 100644
index 0000000..dd8b485
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/http/AbstractOAuth2HttpClientFactory.java
@@ -0,0 +1,116 @@
+/*
+ * 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.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.HttpStatus;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.protocol.HttpContext;
+import org.apache.olingo.client.api.http.HttpClientFactory;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.api.http.WrappingHttpClientFactory;
+
+public abstract class AbstractOAuth2HttpClientFactory
+ extends AbstractHttpClientFactory implements WrappingHttpClientFactory {
+
+ protected final DefaultHttpClientFactory wrapped;
+
+ protected final URI oauth2GrantServiceURI;
+
+ protected final URI oauth2TokenServiceURI;
+
+ protected HttpUriRequest currentRequest;
+
+ public AbstractOAuth2HttpClientFactory(final URI oauth2GrantServiceURI, final URI oauth2TokenServiceURI) {
+ this(new DefaultHttpClientFactory(), oauth2GrantServiceURI, oauth2TokenServiceURI);
+ }
+
+ public AbstractOAuth2HttpClientFactory(final DefaultHttpClientFactory wrapped,
+ final URI oauth2GrantServiceURI, final URI oauth2TokenServiceURI) {
+
+ super();
+ this.wrapped = wrapped;
+ this.oauth2GrantServiceURI = oauth2GrantServiceURI;
+ this.oauth2TokenServiceURI = oauth2TokenServiceURI;
+ }
+
+ @Override
+ public HttpClientFactory getWrappedHttpClientFactory() {
+ return wrapped;
+ }
+
+ protected abstract boolean isInited() throws OAuth2Exception;
+
+ protected abstract void init() throws OAuth2Exception;
+
+ protected abstract void accessToken(DefaultHttpClient client) throws OAuth2Exception;
+
+ protected abstract void refreshToken(DefaultHttpClient client) throws OAuth2Exception;
+
+ @Override
+ public HttpClient create(final HttpMethod method, final URI uri) {
+ if (!isInited()) {
+ init();
+ }
+
+ final DefaultHttpClient httpClient = wrapped.create(method, uri);
+ accessToken(httpClient);
+
+ httpClient.addRequestInterceptor(new HttpRequestInterceptor() {
+
+ @Override
+ public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
+ if (request instanceof HttpUriRequest) {
+ currentRequest = (HttpUriRequest) request;
+ } else {
+ currentRequest = null;
+ }
+ }
+ });
+ httpClient.addResponseInterceptor(new HttpResponseInterceptor() {
+
+ @Override
+ public void process(final HttpResponse response, final HttpContext context) throws HttpException, IOException {
+ if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
+ refreshToken(httpClient);
+
+ if (currentRequest != null) {
+ httpClient.execute(currentRequest);
+ }
+ }
+ }
+ });
+
+ return httpClient;
+ }
+
+ @Override
+ public void close(final HttpClient httpClient) {
+ wrapped.close(httpClient);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/lib/client-core/src/main/java/org/apache/olingo/client/core/http/AbstractOAuth2HttpUriRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/http/AbstractOAuth2HttpUriRequestFactory.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/http/AbstractOAuth2HttpUriRequestFactory.java
deleted file mode 100644
index e756dcb..0000000
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/http/AbstractOAuth2HttpUriRequestFactory.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.client.core.http;
-
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.olingo.client.api.http.HttpMethod;
-
-import java.net.URI;
-
-public abstract class AbstractOAuth2HttpUriRequestFactory extends DefaultHttpUriRequestFactory {
-
- protected final URI redirectURI;
-
- public AbstractOAuth2HttpUriRequestFactory(final URI redirectURI) {
- this.redirectURI = redirectURI;
- }
-
- protected abstract boolean isInited();
-
- protected abstract void init() throws OAuth2Exception;
-
- protected abstract void sign(HttpUriRequest request);
-
- @Override
- public HttpUriRequest create(final HttpMethod method, final URI uri) {
- if (!isInited()) {
- init();
- }
-
- final HttpUriRequest request = super.create(method, uri);
-
- sign(request);
-
- return request;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/lib/client-core/src/main/java/org/apache/olingo/client/core/http/OAuth2Exception.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/http/OAuth2Exception.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/http/OAuth2Exception.java
index 8158a51..9462ebc 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/http/OAuth2Exception.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/http/OAuth2Exception.java
@@ -22,6 +22,10 @@ public class OAuth2Exception extends RuntimeException {
private static final long serialVersionUID = 5695438980473040134L;
+ public OAuth2Exception(final String message) {
+ super(message);
+ }
+
public OAuth2Exception(final Throwable cause) {
super(cause);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/lib/client-core/src/main/java/org/apache/olingo/client/core/http/ProxyWrapperHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/http/ProxyWrapperHttpClientFactory.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/http/ProxyWrapperHttpClientFactory.java
deleted file mode 100644
index 365df37..0000000
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/http/ProxyWrapperHttpClientFactory.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.client.core.http;
-
-import org.apache.http.HttpHost;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.HttpClient;
-import org.apache.http.conn.params.ConnRoutePNames;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.olingo.client.api.http.HttpClientFactory;
-import org.apache.olingo.client.api.http.HttpMethod;
-
-import java.net.URI;
-
-/**
- * Implementation for working behind an HTTP proxy (possibly requiring authentication); requires another concrete
- * {@link HttpClientFactory} implementation acting as real HTTP client factory.
- */
-public class ProxyWrapperHttpClientFactory implements HttpClientFactory {
-
- private final URI proxy;
-
- private String proxyUsername;
-
- private String proxyPassword;
-
- private final DefaultHttpClientFactory wrapped;
-
- public ProxyWrapperHttpClientFactory(final URI proxy) {
- this(proxy, null, null, new DefaultHttpClientFactory());
- }
-
- public ProxyWrapperHttpClientFactory(final URI proxy, final String proxyUsername, final String proxyPassword) {
- this(proxy, proxyUsername, proxyPassword, new DefaultHttpClientFactory());
- }
-
- public ProxyWrapperHttpClientFactory(final URI proxy, final DefaultHttpClientFactory wrapped) {
- this(proxy, null, null, wrapped);
- }
-
- public ProxyWrapperHttpClientFactory(final URI proxy,
- final String proxyUsername, final String proxyPassword, final DefaultHttpClientFactory wrapped) {
-
- this.proxy = proxy;
- this.proxyUsername = proxyUsername;
- this.proxyPassword = proxyPassword;
- this.wrapped = wrapped;
- }
-
- public DefaultHttpClientFactory getWrappedHttpClientFactory() {
- return this.wrapped;
- }
-
- @Override
- public HttpClient create(final HttpMethod method, final URI uri) {
- // Use wrapped factory to obtain an httpclient instance for given method and uri
- final DefaultHttpClient httpclient = wrapped.create(method, uri);
-
- final HttpHost proxyHost = new HttpHost(proxy.getHost(), proxy.getPort());
-
- // Sets usage of HTTP proxy
- httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxyHost);
-
- // Sets proxy authentication, if credentials were provided
- if (proxyUsername != null && proxyPassword != null) {
- httpclient.getCredentialsProvider().setCredentials(
- new AuthScope(proxyHost),
- new UsernamePasswordCredentials(proxyUsername, proxyPassword));
- }
-
- return httpclient;
- }
-
- @Override
- public void close(final HttpClient httpClient) {
- wrapped.close(httpClient);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/lib/client-core/src/main/java/org/apache/olingo/client/core/http/ProxyWrappingHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/http/ProxyWrappingHttpClientFactory.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/http/ProxyWrappingHttpClientFactory.java
new file mode 100644
index 0000000..e371c5e
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/http/ProxyWrappingHttpClientFactory.java
@@ -0,0 +1,97 @@
+/*
+ * 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.client.core.http;
+
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.HttpClient;
+import org.apache.http.conn.params.ConnRoutePNames;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.olingo.client.api.http.HttpClientFactory;
+import org.apache.olingo.client.api.http.HttpMethod;
+
+import java.net.URI;
+import org.apache.olingo.client.api.http.WrappingHttpClientFactory;
+
+/**
+ * Implementation for working behind an HTTP proxy (possibly requiring authentication); requires another concrete
+ * {@link HttpClientFactory} implementation acting as real HTTP client factory.
+ */
+public class ProxyWrappingHttpClientFactory implements WrappingHttpClientFactory {
+
+ private final URI proxy;
+
+ private String proxyUsername;
+
+ private String proxyPassword;
+
+ private final DefaultHttpClientFactory wrapped;
+
+ public ProxyWrappingHttpClientFactory(final URI proxy) {
+ this(proxy, null, null, new DefaultHttpClientFactory());
+ }
+
+ public ProxyWrappingHttpClientFactory(final URI proxy, final String proxyUsername, final String proxyPassword) {
+ this(proxy, proxyUsername, proxyPassword, new DefaultHttpClientFactory());
+ }
+
+ public ProxyWrappingHttpClientFactory(final URI proxy, final DefaultHttpClientFactory wrapped) {
+ this(proxy, null, null, wrapped);
+ }
+
+ public ProxyWrappingHttpClientFactory(final URI proxy,
+ final String proxyUsername, final String proxyPassword, final DefaultHttpClientFactory wrapped) {
+
+ this.proxy = proxy;
+ this.proxyUsername = proxyUsername;
+ this.proxyPassword = proxyPassword;
+ this.wrapped = wrapped;
+ }
+
+ public DefaultHttpClientFactory getWrappedHttpClientFactory() {
+ return this.wrapped;
+ }
+
+ @Override
+ public HttpClient create(final HttpMethod method, final URI uri) {
+ // Use wrapped factory to obtain an httpclient instance for given method and uri
+ final DefaultHttpClient httpclient = wrapped.create(method, uri);
+
+ final HttpHost proxyHost = new HttpHost(proxy.getHost(), proxy.getPort());
+
+ // Sets usage of HTTP proxy
+ httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxyHost);
+
+ // Sets proxy authentication, if credentials were provided
+ if (proxyUsername != null && proxyPassword != null) {
+ httpclient.getCredentialsProvider().setCredentials(
+ new AuthScope(proxyHost),
+ new UsernamePasswordCredentials(proxyUsername, proxyPassword));
+ }
+
+ return httpclient;
+ }
+
+ @Override
+ public void close(final HttpClient httpClient) {
+ wrapped.close(httpClient);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataDeserializer.java
index 0e11c58..e739ec8 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataDeserializer.java
@@ -46,10 +46,11 @@ import java.io.InputStream;
public abstract class AbstractODataDeserializer {
protected final ODataServiceVersion version;
+
protected final ODataDeserializer deserializer;
public AbstractODataDeserializer(final ODataServiceVersion version, final boolean serverMode,
- final ODataFormat format) {
+ final ODataFormat format) {
this.version = version;
if (format == ODataFormat.XML || format == ODataFormat.ATOM) {
deserializer = new AtomDeserializer(version);
@@ -76,18 +77,18 @@ public abstract class AbstractODataDeserializer {
protected XmlMapper getXmlMapper() {
final XmlMapper xmlMapper = new XmlMapper(
- new XmlFactory(new InputFactoryImpl(), new OutputFactoryImpl()), new JacksonXmlModule());
+ new XmlFactory(new InputFactoryImpl(), new OutputFactoryImpl()), new JacksonXmlModule());
xmlMapper.setInjectableValues(new InjectableValues.Std().
- addValue(ODataServiceVersion.class, version).
- addValue(Boolean.class, Boolean.FALSE));
+ addValue(ODataServiceVersion.class, version).
+ addValue(Boolean.class, Boolean.FALSE));
xmlMapper.addHandler(new DeserializationProblemHandler() {
@Override
public boolean handleUnknownProperty(final DeserializationContext ctxt, final JsonParser jp,
- final com.fasterxml.jackson.databind.JsonDeserializer<?> deserializer,
- final Object beanOrClass, final String propertyName)
- throws IOException, JsonProcessingException {
+ final com.fasterxml.jackson.databind.JsonDeserializer<?> deserializer,
+ final Object beanOrClass, final String propertyName)
+ throws IOException, JsonProcessingException {
// skip any unknown property
ctxt.getParser().skipChildren();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java
index 8ddc273..b81b977 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIUtils.java
@@ -31,7 +31,6 @@ import org.apache.olingo.client.api.CommonODataClient;
import org.apache.olingo.client.api.http.HttpClientFactory;
import org.apache.olingo.client.api.uri.SegmentType;
import org.apache.olingo.client.core.http.BasicAuthHttpClientFactory;
-import org.apache.olingo.client.core.http.ProxyWrapperHttpClientFactory;
import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
@@ -65,6 +64,7 @@ import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Pattern;
+import org.apache.olingo.client.api.http.WrappingHttpClientFactory;
/**
* URI utilities.
@@ -354,8 +354,8 @@ public final class URIUtils {
HttpClientFactory httpclientFactory = client.getConfiguration().getHttpClientFactory();
if (httpclientFactory instanceof BasicAuthHttpClientFactory) {
return true;
- } else if (httpclientFactory instanceof ProxyWrapperHttpClientFactory) {
- ProxyWrapperHttpClientFactory tmp = (ProxyWrapperHttpClientFactory) httpclientFactory;
+ } else if (httpclientFactory instanceof WrappingHttpClientFactory) {
+ WrappingHttpClientFactory tmp = (WrappingHttpClientFactory) httpclientFactory;
if (tmp.getWrappedHttpClientFactory() instanceof BasicAuthHttpClientFactory) {
return true;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c155238d/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeserializer.java
index 1563e17..e1b8b1f 100755
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeserializer.java
@@ -53,7 +53,6 @@ import org.apache.olingo.commons.core.data.LinkImpl;
import org.apache.olingo.commons.core.data.LinkedComplexValueImpl;
import org.apache.olingo.commons.core.data.PropertyImpl;
import org.apache.olingo.commons.core.edm.EdmTypeInfo;
-
import java.io.IOException;
import java.io.InputStream;
import java.util.AbstractMap.SimpleEntry;
@@ -69,23 +68,39 @@ import java.util.regex.Pattern;
public class JsonDeserializer implements ODataDeserializer {
protected final Pattern CUSTOM_ANNOTATION = Pattern.compile("(.+)@(.+)\\.(.+)");
+
protected final ODataServiceVersion version;
+
protected final boolean serverMode;
protected String jsonType;
+
protected String jsonId;
+
protected String jsonETag;
+
protected String jsonReadLink;
+
protected String jsonEditLink;
+
protected String jsonMediaEditLink;
+
protected String jsonMediaReadLink;
+
protected String jsonMediaContentType;
+
protected String jsonMediaETag;
+
protected String jsonAssociationLink;
+
protected String jsonNavigationLink;
+
protected String jsonCount;
+
protected String jsonNextLink;
+
protected String jsonDeltaLink;
+
protected String jsonError;
private JsonGeoValueDeserializer geoDeserializer;
@@ -129,7 +144,7 @@ public class JsonDeserializer implements ODataDeserializer {
}
protected String setInline(final String name, final String suffix, final JsonNode tree,
- final ObjectCodec codec, final LinkImpl link) throws IOException {
+ final ObjectCodec codec, final LinkImpl link) throws IOException {
final String entityNamePrefix = name.substring(0, name.indexOf(suffix));
if (tree.has(entityNamePrefix)) {
@@ -143,11 +158,9 @@ public class JsonDeserializer implements ODataDeserializer {
} else if (inline instanceof ArrayNode) {
link.setType(ODataLinkType.ENTITY_SET_NAVIGATION.toString());
- EntitySet entitySet = new EntitySetImpl();
- Iterator<JsonNode> entries = inline.elements();
- while (entries.hasNext()) {
- entitySet.getEntities().add(
- entityDeserializer.doDeserialize(entries.next().traverse(codec)).getPayload());
+ final EntitySet entitySet = new EntitySetImpl();
+ for (final Iterator<JsonNode> entries = inline.elements(); entries.hasNext();) {
+ entitySet.getEntities().add(entityDeserializer.doDeserialize(entries.next().traverse(codec)).getPayload());
}
link.setInlineEntitySet(entitySet);
@@ -157,7 +170,7 @@ public class JsonDeserializer implements ODataDeserializer {
}
protected void links(final Map.Entry<String, JsonNode> field, final Linked linked, final Set<String> toRemove,
- final JsonNode tree, final ObjectCodec codec) throws IOException {
+ final JsonNode tree, final ObjectCodec codec) throws IOException {
if (serverMode) {
serverLinks(field, linked, toRemove, tree, codec);
} else {
@@ -166,7 +179,7 @@ public class JsonDeserializer implements ODataDeserializer {
}
private void clientLinks(final Map.Entry<String, JsonNode> field, final Linked linked, final Set<String> toRemove,
- final JsonNode tree, final ObjectCodec codec) throws IOException {
+ final JsonNode tree, final ObjectCodec codec) throws IOException {
if (field.getKey().endsWith(jsonNavigationLink)) {
final LinkImpl link = new LinkImpl();
@@ -195,10 +208,10 @@ public class JsonDeserializer implements ODataDeserializer {
}
private void serverLinks(final Map.Entry<String, JsonNode> field, final Linked linked, final Set<String> toRemove,
- final JsonNode tree, final ObjectCodec codec) throws IOException {
+ final JsonNode tree, final ObjectCodec codec) throws IOException {
if (field.getKey().endsWith(Constants.JSON_BIND_LINK_SUFFIX)
- || field.getKey().endsWith(jsonNavigationLink)) {
+ || field.getKey().endsWith(jsonNavigationLink)) {
if (field.getValue().isValueNode()) {
final String suffix = field.getKey().replaceAll("^.*@", "@");
@@ -258,7 +271,7 @@ public class JsonDeserializer implements ODataDeserializer {
if (node.has(Constants.ATTR_TYPE)) {
type = ODataPropertyType.PRIMITIVE;
typeInfo = new EdmTypeInfo.Builder().
- setTypeExpression("Edm.Geography" + node.get(Constants.ATTR_TYPE).asText()).build();
+ setTypeExpression("Edm.Geography" + node.get(Constants.ATTR_TYPE).asText()).build();
} else {
type = ODataPropertyType.COMPLEX;
}
@@ -270,8 +283,8 @@ public class JsonDeserializer implements ODataDeserializer {
}
protected void populate(final Annotatable annotatable, final List<Property> properties,
- final ObjectNode tree, final ObjectCodec codec)
- throws IOException, EdmPrimitiveTypeException {
+ final ObjectNode tree, final ObjectCodec codec)
+ throws IOException, EdmPrimitiveTypeException {
String type = null;
Annotation annotation = null;
@@ -297,8 +310,8 @@ public class JsonDeserializer implements ODataDeserializer {
final PropertyImpl property = new PropertyImpl();
property.setName(field.getKey());
property.setType(type == null
- ? null
- : new EdmTypeInfo.Builder().setTypeExpression(type).build().internal());
+ ? null
+ : new EdmTypeInfo.Builder().setTypeExpression(type).build().internal());
type = null;
value(property, field.getValue(), codec);
@@ -313,25 +326,25 @@ public class JsonDeserializer implements ODataDeserializer {
}
private Object fromPrimitive(final JsonNode node, final EdmTypeInfo typeInfo) throws EdmPrimitiveTypeException {
- return node.isNull() ? null :
- typeInfo == null ? node.asText() :
- typeInfo.getPrimitiveTypeKind().isGeospatial() ?
- getGeoDeserializer().deserialize(node, typeInfo) :
- ((EdmPrimitiveType) typeInfo.getType())
- .valueOfString(node.asText(), true, null,
- Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, true,
- ((EdmPrimitiveType) typeInfo.getType()).getDefaultType());
+ return node.isNull() ? null
+ : typeInfo == null ? node.asText()
+ : typeInfo.getPrimitiveTypeKind().isGeospatial()
+ ? getGeoDeserializer().deserialize(node, typeInfo)
+ : ((EdmPrimitiveType) typeInfo.getType())
+ .valueOfString(node.asText(), true, null,
+ Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, true,
+ ((EdmPrimitiveType) typeInfo.getType()).getDefaultType());
}
private Object fromComplex(final ObjectNode node, final ObjectCodec codec)
- throws IOException, EdmPrimitiveTypeException {
+ throws IOException, EdmPrimitiveTypeException {
if (version.compareTo(ODataServiceVersion.V40) < 0) {
- List<Property> properties = new ArrayList<Property>();
+ final List<Property> properties = new ArrayList<Property>();
populate(null, properties, node, codec);
return properties;
} else {
- LinkedComplexValue linkComplexValue = new LinkedComplexValueImpl();
+ final LinkedComplexValue linkComplexValue = new LinkedComplexValueImpl();
final Set<String> toRemove = new HashSet<String>();
for (final Iterator<Map.Entry<String, JsonNode>> itor = node.fields(); itor.hasNext();) {
final Map.Entry<String, JsonNode> field = itor.next();
@@ -346,13 +359,13 @@ public class JsonDeserializer implements ODataDeserializer {
}
private void fromCollection(final Valuable valuable, final Iterator<JsonNode> nodeItor, final EdmTypeInfo typeInfo,
- final ObjectCodec codec) throws IOException, EdmPrimitiveTypeException {
+ final ObjectCodec codec) throws IOException, EdmPrimitiveTypeException {
- List<Object> values = new ArrayList<Object>();
+ final List<Object> values = new ArrayList<Object>();
ValueType valueType = ValueType.COLLECTION_PRIMITIVE;
- final EdmTypeInfo type = typeInfo == null ? null :
- new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
+ final EdmTypeInfo type = typeInfo == null ? null
+ : new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
while (nodeItor.hasNext()) {
final JsonNode child = nodeItor.next();
@@ -371,8 +384,8 @@ public class JsonDeserializer implements ODataDeserializer {
((ObjectNode) child).remove(jsonType);
}
final Object value = fromComplex((ObjectNode) child, codec);
- valueType = value instanceof LinkedComplexValue ? ValueType.COLLECTION_LINKED_COMPLEX :
- ValueType.COLLECTION_COMPLEX;
+ valueType = value instanceof LinkedComplexValue ? ValueType.COLLECTION_LINKED_COMPLEX
+ : ValueType.COLLECTION_COMPLEX;
values.add(value);
}
}
@@ -380,50 +393,51 @@ public class JsonDeserializer implements ODataDeserializer {
}
protected void value(final Valuable valuable, final JsonNode node, final ObjectCodec codec)
- throws IOException, EdmPrimitiveTypeException {
- EdmTypeInfo typeInfo = StringUtils.isBlank(valuable.getType()) ? null :
- new EdmTypeInfo.Builder().setTypeExpression(valuable.getType()).build();
+ throws IOException, EdmPrimitiveTypeException {
+
+ EdmTypeInfo typeInfo = StringUtils.isBlank(valuable.getType()) ? null
+ : new EdmTypeInfo.Builder().setTypeExpression(valuable.getType()).build();
final Map.Entry<ODataPropertyType, EdmTypeInfo> guessed = guessPropertyType(node);
if (typeInfo == null) {
typeInfo = guessed.getValue();
}
- final ODataPropertyType propType = typeInfo == null ? guessed.getKey() :
- typeInfo.isCollection() ? ODataPropertyType.COLLECTION :
- typeInfo.isPrimitiveType() ? ODataPropertyType.PRIMITIVE :
- node.isValueNode() ? ODataPropertyType.ENUM : ODataPropertyType.COMPLEX;
+ final ODataPropertyType propType = typeInfo == null ? guessed.getKey()
+ : typeInfo.isCollection() ? ODataPropertyType.COLLECTION
+ : typeInfo.isPrimitiveType() ? ODataPropertyType.PRIMITIVE
+ : node.isValueNode() ? ODataPropertyType.ENUM : ODataPropertyType.COMPLEX;
switch (propType) {
- case COLLECTION:
- fromCollection(valuable, node.elements(), typeInfo, codec);
- break;
-
- case COMPLEX:
- if (node.has(jsonType)) {
- valuable.setType(node.get(jsonType).asText());
- ((ObjectNode) node).remove(jsonType);
- }
- final Object value = fromComplex((ObjectNode) node, codec);
- valuable.setValue(value instanceof LinkedComplexValue ? ValueType.LINKED_COMPLEX : ValueType.COMPLEX, value);
- break;
+ case COLLECTION:
+ fromCollection(valuable, node.elements(), typeInfo, codec);
+ break;
+
+ case COMPLEX:
+ if (node.has(jsonType)) {
+ valuable.setType(node.get(jsonType).asText());
+ ((ObjectNode) node).remove(jsonType);
+ }
+ final Object value = fromComplex((ObjectNode) node, codec);
+ valuable.setValue(value instanceof LinkedComplexValue ? ValueType.LINKED_COMPLEX : ValueType.COMPLEX, value);
+ break;
- case ENUM:
- valuable.setValue(ValueType.ENUM, node.asText());
- break;
+ case ENUM:
+ valuable.setValue(ValueType.ENUM, node.asText());
+ break;
- case PRIMITIVE:
- if (valuable.getType() == null && typeInfo != null) {
- valuable.setType(typeInfo.getFullQualifiedName().toString());
- }
- final Object primitiveValue = fromPrimitive(node, typeInfo);
- valuable.setValue(primitiveValue instanceof Geospatial ? ValueType.GEOSPATIAL : ValueType.PRIMITIVE,
- primitiveValue);
- break;
-
- case EMPTY:
- default:
- valuable.setValue(ValueType.PRIMITIVE, StringUtils.EMPTY);
+ case PRIMITIVE:
+ if (valuable.getType() == null && typeInfo != null) {
+ valuable.setType(typeInfo.getFullQualifiedName().toString());
+ }
+ final Object primitiveValue = fromPrimitive(node, typeInfo);
+ valuable.setValue(primitiveValue instanceof Geospatial ? ValueType.GEOSPATIAL : ValueType.PRIMITIVE,
+ primitiveValue);
+ break;
+
+ case EMPTY:
+ default:
+ valuable.setValue(ValueType.PRIMITIVE, StringUtils.EMPTY);
}
}