Jersey 2 fixes for ContentTypeFilter and associated test, down to 1 failing test now.
Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/c8b84305 Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/c8b84305 Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/c8b84305 Branch: refs/heads/two-dot-o-dev Commit: c8b84305910f8916991a9c3f50c4d9d97a3572ec Parents: dfa65d6 Author: Dave Johnson <[email protected]> Authored: Fri Sep 4 11:12:32 2015 -0400 Committer: Dave Johnson <[email protected]> Committed: Fri Sep 4 11:12:32 2015 -0400 ---------------------------------------------------------------------- .../exceptions/UnsupportedMediaTypeMapper.java | 43 ++++++++++++++++++ .../rest/filters/ContentTypeFilter.java | 48 ++++++++------------ stack/rest/src/main/webapp/WEB-INF/web.xml | 3 +- .../rest/filters/ContentTypeResourceIT.java | 35 ++++++++------ 4 files changed, 82 insertions(+), 47 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/usergrid/blob/c8b84305/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/UnsupportedMediaTypeMapper.java ---------------------------------------------------------------------- diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/UnsupportedMediaTypeMapper.java b/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/UnsupportedMediaTypeMapper.java new file mode 100644 index 0000000..99ae992 --- /dev/null +++ b/stack/rest/src/main/java/org/apache/usergrid/rest/exceptions/UnsupportedMediaTypeMapper.java @@ -0,0 +1,43 @@ +/* + * 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.usergrid.rest.exceptions; + + +import javax.ws.rs.NotSupportedException; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.Provider; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static javax.ws.rs.core.Response.Status.UNSUPPORTED_MEDIA_TYPE; + + +@Provider +public class UnsupportedMediaTypeMapper extends AbstractExceptionMapper<NotSupportedException> { + + private static final Logger logger = LoggerFactory.getLogger(UnsupportedMediaTypeMapper.class); + + @Override + public Response toResponse( NotSupportedException e ) { + + logger.error( "Unsupported media type", e ); + + return toResponse( UNSUPPORTED_MEDIA_TYPE, e ); + } +} + http://git-wip-us.apache.org/repos/asf/usergrid/blob/c8b84305/stack/rest/src/main/java/org/apache/usergrid/rest/filters/ContentTypeFilter.java ---------------------------------------------------------------------- diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/filters/ContentTypeFilter.java b/stack/rest/src/main/java/org/apache/usergrid/rest/filters/ContentTypeFilter.java index 93048db..d79451c 100644 --- a/stack/rest/src/main/java/org/apache/usergrid/rest/filters/ContentTypeFilter.java +++ b/stack/rest/src/main/java/org/apache/usergrid/rest/filters/ContentTypeFilter.java @@ -133,26 +133,24 @@ public class ContentTypeFilter implements Filter { */ private void adapt() throws IOException { - //check if the accept header was set - @SuppressWarnings( "rawtypes" ) Enumeration contentType = origRequest.getHeaders( HttpHeaders.ACCEPT ); - - if ( !contentType.hasMoreElements() ) { - setHeader( HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON ); - } - - String path = origRequest.getRequestURI(); - + String method = origRequest.getMethod(); logger.debug( "Content path is '{}'", path ); - int initial = inputStream.read(); - String method = origRequest.getMethod(); + // first ensure that an Accept header is set + + @SuppressWarnings( "rawtypes" ) Enumeration acceptHeaders = origRequest.getHeaders( HttpHeaders.ACCEPT ); + if ( !acceptHeaders.hasMoreElements() ) { + setHeader( HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON ); + } + // next, ensure that one and only one content-type is set - // nothing to read, check if it's a put or a post. If so set the - // content type to json to create an empty json request + int initial = inputStream.read(); if ( initial == -1 ) { + + // request has no body, set type to application/json if ( ( HttpMethod.POST.equals( method ) || HttpMethod.PUT.equals( method ) ) && !MediaType.APPLICATION_FORM_URLENCODED.equals( getContentType() ) ) { logger.debug("Setting content type to application/json " + @@ -166,14 +164,12 @@ public class ContentTypeFilter implements Filter { } char firstChar = ( char ) initial; + if ( ( firstChar == '{' || firstChar == '[' ) + && !MediaType.APPLICATION_JSON.equals( getContentType() )) { - // its json, make it so - if ( firstChar == '{' || firstChar == '[' - && !MediaType.APPLICATION_JSON.equals( getContentType() )) { - + // request appears to be JSON so set type to application/json logger.debug( "Setting content type to application/json " + "for POST or PUT with json content at path '{}'", path ); - setHeader( HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON ); setHeader( HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON ); } @@ -182,12 +178,8 @@ public class ContentTypeFilter implements Filter { } - /** - * @throws IOException - * - */ public void setHeader( String name, String value ) { - newHeaders.put( name, value ); + newHeaders.put( name.toLowerCase(), value ); } @@ -219,20 +211,16 @@ public class ContentTypeFilter implements Filter { */ @Override public Enumeration getHeaders( String name ) { - Set<String> headers = new LinkedHashSet<String>(); + Set<String> headers = new LinkedHashSet<String>(); String overridden = newHeaders.get( name ); if ( overridden != null ) { headers.add( overridden ); - } - else { - for ( Enumeration e = super.getHeaders( name ); e.hasMoreElements(); ) { - headers.add( e.nextElement().toString() ); - } + return Collections.enumeration( headers ); } - return Collections.enumeration( headers ); + return super.getHeaders( name ); } http://git-wip-us.apache.org/repos/asf/usergrid/blob/c8b84305/stack/rest/src/main/webapp/WEB-INF/web.xml ---------------------------------------------------------------------- diff --git a/stack/rest/src/main/webapp/WEB-INF/web.xml b/stack/rest/src/main/webapp/WEB-INF/web.xml index 0c46fe4..a7ca5b8 100644 --- a/stack/rest/src/main/webapp/WEB-INF/web.xml +++ b/stack/rest/src/main/webapp/WEB-INF/web.xml @@ -53,7 +53,7 @@ <url-pattern>/management.json</url-pattern> </filter-mapping> - <!-- filter for setting default accept and Content-Type as application/json when undefined by client + <!-- filter for setting default accept and Content-Type as application/json when undefined by client --> <filter> <filter-name>contentTypeFilter</filter-name> <filter-class>org.apache.usergrid.rest.filters.ContentTypeFilter</filter-class> @@ -62,7 +62,6 @@ <filter-name>contentTypeFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> - --> <filter> <filter-name>shiroFilter</filter-name> http://git-wip-us.apache.org/repos/asf/usergrid/blob/c8b84305/stack/rest/src/test/java/org/apache/usergrid/rest/filters/ContentTypeResourceIT.java ---------------------------------------------------------------------- diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/filters/ContentTypeResourceIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/filters/ContentTypeResourceIT.java index 31ceb8c..47afb8c 100644 --- a/stack/rest/src/test/java/org/apache/usergrid/rest/filters/ContentTypeResourceIT.java +++ b/stack/rest/src/test/java/org/apache/usergrid/rest/filters/ContentTypeResourceIT.java @@ -20,6 +20,7 @@ import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; @@ -34,12 +35,10 @@ import org.glassfish.jersey.client.ClientResponse; import org.junit.Test; import javax.ws.rs.client.Invocation; -import javax.ws.rs.core.Form; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.*; import java.io.IOException; import java.text.ParseException; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -80,7 +79,7 @@ public class ContentTypeResourceIT extends AbstractRestIT { this.clientSetup.getOrganization().getName(), this.clientSetup.getAppName()) ); post.setEntity(new StringEntity(json)); post.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token.getAccessToken()); - post.setHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON); + post.setHeader( HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON ); post.setHeader(HttpHeaders.CONTENT_TYPE, "*/*"); HttpResponse rsp = client.execute( host, post ); @@ -105,7 +104,7 @@ public class ContentTypeResourceIT extends AbstractRestIT { @Test public void textPlainContentType() throws Exception { User user = new User("shawn","shawn","[email protected]","aliensquirrel"); - this.app().collection("users").post(user); + this.app().collection("users").post( user ); Token token = this.app().token().post(new Token("shawn","aliensquirrel")); Map<String, String> data = hashMap( "name", "Solitaire2" ); @@ -171,7 +170,8 @@ public class ContentTypeResourceIT extends AbstractRestIT { HttpHost host = new HttpHost( super.getBaseURI().getHost(), super.getBaseURI().getPort() ); - HttpPost post = new HttpPost( String.format("/%s/%s/games", this.clientSetup.getOrganization().getName(), this.clientSetup.getAppName()) ); + HttpPost post = new HttpPost( String.format("/%s/%s/games", + this.clientSetup.getOrganization().getName(), this.clientSetup.getAppName()) ); post.setEntity( new StringEntity( json ) ); post.setHeader( HttpHeaders.AUTHORIZATION, "Bearer " + token.getAccessToken() ); @@ -191,8 +191,8 @@ public class ContentTypeResourceIT extends AbstractRestIT { /** - * Creates a simple entity of type game. Does not set the Accepts header. The type should be set to json to match the - * body. Then does a get without Accept type, it should return application/json, not text/csv + * Creates a simple entity of type game. Does not set the Accepts header. The type should be set to json + * to match the body. Then does a get without Accept type, it should return application/json, not text/csv */ @Test public void noAcceptGet() throws Exception { @@ -222,23 +222,28 @@ public class ContentTypeResourceIT extends AbstractRestIT { .queryParam( "access_token", this.getAdminToken().getAccessToken() ) .request(); - ClientResponse clientResponse = builder.post( - javax.ws.rs.client.Entity.json( hashMap( "name", "bar2" ) ), ClientResponse.class ); + Response clientResponse = builder.post( + javax.ws.rs.client.Entity.json( new HashMap() {{ put( "name", "bar2" ); }} ), Response.class ); assertEquals(200, clientResponse.getStatus()); - MultivaluedMap<String, String> headers = clientResponse.getHeaders(); + MultivaluedMap<String, Object> headers = clientResponse.getHeaders(); - List<String> contentType = headers.get("Content-Type"); + List contentType = headers.get( "Content-Type" ); assertEquals(1, contentType.size()); assertEquals(MediaType.APPLICATION_JSON, contentType.get(0)); //do the get with no content type, it should get set to application/json - HttpPost get = new HttpPost( String.format("/%s/%s/games", + + builder = app().collection( "games" ).getTarget() + .queryParam( "access_token", this.getAdminToken().getAccessToken() ) + .request(); + + HttpGet get = new HttpGet( String.format("/%s/%s/games", this.clientSetup.getOrganization().getName(), this.clientSetup.getAppName()) ); get.setHeader( HttpHeaders.AUTHORIZATION, "Bearer " + token.getAccessToken() ); - clientResponse = builder.get(ClientResponse.class); + clientResponse = builder.get( Response.class ); assertEquals(200, clientResponse.getStatus());
