Skip to content

Commit

Permalink
Merge pull request #83 from awslabs/package-refactor
Browse files Browse the repository at this point in the history
Refactor preparing for 1.0 release.

**This is a breaking change since some classes have moved to new/different packages**
  • Loading branch information
sapessi authored Jan 11, 2018
2 parents ba8ea46 + bb07467 commit e8e41cc
Show file tree
Hide file tree
Showing 60 changed files with 241 additions and 171 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ handler.onStartup(c -> {
# Using the Lambda Stream handler
By default, Lambda does not use Jackson annotations when marshalling and unmarhsalling JSON. This can cause issues when receiving requests that include the claims object from a Cognito User Pool authorizer. To support these type of requests, use Lambda's `RequestStreamHandler` interface instead of the POJO-based `RequestHandler`. This allows you to use a custom version of Jackson with support for annotations.

This library uses Jackson annotations in the `com.amazonaws.serverless.proxy.internal.model.CognitoAuthorizerClaims` object. The example below shows how to do this with a `SpringLambdaContainerHandler`, you can use the same methodology with all of the other implementations.
This library uses Jackson annotations in the `com.amazonaws.serverless.proxy.model.CognitoAuthorizerClaims` object. The example below shows how to do this with a `SpringLambdaContainerHandler`, you can use the same methodology with all of the other implementations.

```java
public class StreamLambdaHandler implements RequestStreamHandler {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@
*/
package com.amazonaws.serverless.exceptions;


import com.amazonaws.serverless.proxy.RequestReader;


/**
* This exception is thrown when the ContainerHandler fails to parse a request object or input stream into the
* object required by the Container. The exception is thrown by implementing sub-classes of <code>RequestReader</code>
*
* @see com.amazonaws.serverless.proxy.internal.RequestReader
* @see RequestReader
*/
public class ContainerInitializationException extends Exception {
public ContainerInitializationException(String message, Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@
*/
package com.amazonaws.serverless.exceptions;


import com.amazonaws.serverless.proxy.RequestReader;


/**
* This exception is thrown when the ContainerHandler fails to parse a request object or input stream into the
* object required by the Container. The exception is thrown by implementing sub-classes of <code>RequestReader</code>
*
* @see com.amazonaws.serverless.proxy.internal.RequestReader
* @see RequestReader
*/
public class InvalidRequestEventException extends Exception {
public InvalidRequestEventException(String message, Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@
*/
package com.amazonaws.serverless.exceptions;


import com.amazonaws.serverless.proxy.ResponseWriter;


/**
* This exception is thrown when the ContainerHandler cannot transform the Container response into a valid return value
* for the Lambda function. This exception is thrown by implementing sub-classes of <code>ResponseWriter</code>
*
* @see com.amazonaws.serverless.proxy.internal.ResponseWriter
* @see ResponseWriter
*/
public class InvalidResponseObjectException extends Exception {
public InvalidResponseObjectException(String message, Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
* OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
package com.amazonaws.serverless.proxy.internal;
package com.amazonaws.serverless.proxy;

import com.amazonaws.serverless.exceptions.InvalidRequestEventException;
import com.amazonaws.serverless.proxy.internal.model.AwsProxyResponse;
import com.amazonaws.serverless.proxy.internal.model.ErrorModel;
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import com.amazonaws.serverless.proxy.model.ErrorModel;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
Expand All @@ -34,7 +35,7 @@
* Returns application/json messages with a status code of 500 when the RequestReader failed to read the incoming event.
* For all other exceptions returns a 502. Responses are populated with a JSON object containing a message property.
*
* @see com.amazonaws.serverless.proxy.internal.ExceptionHandler
* @see ExceptionHandler
*/
public class AwsProxyExceptionHandler
implements ExceptionHandler<AwsProxyResponse> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
* OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
package com.amazonaws.serverless.proxy.internal;
package com.amazonaws.serverless.proxy;

import com.amazonaws.serverless.proxy.internal.jaxrs.AwsProxySecurityContext;
import com.amazonaws.serverless.proxy.internal.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
import com.amazonaws.services.lambda.runtime.Context;

import javax.ws.rs.core.SecurityContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
package com.amazonaws.serverless.proxy.internal;
package com.amazonaws.serverless.proxy;

import java.io.IOException;
import java.io.OutputStream;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,15 @@
* OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
package com.amazonaws.serverless.proxy.internal;
package com.amazonaws.serverless.proxy;


import com.amazonaws.serverless.exceptions.InvalidRequestEventException;
import com.amazonaws.serverless.proxy.internal.model.ContainerConfig;
import com.amazonaws.serverless.proxy.model.ContainerConfig;
import com.amazonaws.services.lambda.runtime.Context;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.ws.rs.core.SecurityContext;

import java.io.IOException;
import java.io.InputStream;


/**
* Implementations of the RequestReader object are used by container objects to transform the incoming Lambda event into
Expand Down Expand Up @@ -63,13 +58,13 @@ public abstract class RequestReader<RequestType, ContainerRequestType> {
/**
* Reads the incoming event object and produces a populated request for the underlying container
* @param request The incoming request object
* @param securityContext A jax-rs SecurityContext object (@see com.amazonaws.serverless.proxy.internal.SecurityContextWriter)
* @param securityContext A jax-rs SecurityContext object (@see com.amazonaws.serverless.proxy.SecurityContextWriter)
* @param lambdaContext The AWS Lambda context for the request
* @param config The container configuration object. This is passed in by the LambdaContainerHandler.
* @return A valid request object for the underlying container
* @throws InvalidRequestEventException This exception is thrown if anything goes wrong during the creation of the request object
*/
protected abstract ContainerRequestType readRequest(RequestType request, SecurityContext securityContext, Context lambdaContext, ContainerConfig config)
public abstract ContainerRequestType readRequest(RequestType request, SecurityContext securityContext, Context lambdaContext, ContainerConfig config)
throws InvalidRequestEventException;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
package com.amazonaws.serverless.proxy.internal;
package com.amazonaws.serverless.proxy;


import com.amazonaws.serverless.exceptions.InvalidResponseObjectException;
Expand Down Expand Up @@ -44,7 +44,7 @@ public abstract class ResponseWriter<ContainerResponseType, ResponseType> {
* @return A valid return value for the Lambda function
* @throws InvalidResponseObjectException When the implementation cannot read the container response object
*/
protected abstract ResponseType writeResponse(ContainerResponseType containerResponse, Context lambdaContext)
public abstract ResponseType writeResponse(ContainerResponseType containerResponse, Context lambdaContext)
throws InvalidResponseObjectException;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
* OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
package com.amazonaws.serverless.proxy.internal;
package com.amazonaws.serverless.proxy;

import com.amazonaws.serverless.proxy.internal.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
import com.amazonaws.services.lambda.runtime.Context;

import javax.ws.rs.core.SecurityContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
package com.amazonaws.serverless.proxy.internal;


import com.amazonaws.serverless.proxy.internal.model.ContainerConfig;
import com.amazonaws.serverless.proxy.model.ContainerConfig;
import com.amazonaws.serverless.proxy.ExceptionHandler;
import com.amazonaws.serverless.proxy.RequestReader;
import com.amazonaws.serverless.proxy.ResponseWriter;
import com.amazonaws.serverless.proxy.SecurityContextWriter;
import com.amazonaws.services.lambda.runtime.Context;

import org.slf4j.Logger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
*/
package com.amazonaws.serverless.proxy.internal.jaxrs;

import com.amazonaws.serverless.proxy.internal.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.internal.model.CognitoAuthorizerClaims;
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.model.CognitoAuthorizerClaims;
import com.amazonaws.services.lambda.runtime.Context;

import javax.ws.rs.core.SecurityContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
*/
package com.amazonaws.serverless.proxy.internal.servlet;

import com.amazonaws.serverless.proxy.internal.RequestReader;
import com.amazonaws.serverless.proxy.internal.model.ApiGatewayRequestContext;
import com.amazonaws.serverless.proxy.internal.model.ContainerConfig;
import com.amazonaws.serverless.proxy.RequestReader;
import com.amazonaws.serverless.proxy.model.ApiGatewayRequestContext;
import com.amazonaws.serverless.proxy.model.ContainerConfig;
import com.amazonaws.services.lambda.runtime.Context;

import org.slf4j.Logger;
Expand All @@ -26,7 +26,7 @@
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,50 @@
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;

import java.time.Instant;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;


/**
* This class emulates the behavior of an HTTP session. At the moment a new instance of this class
* is created for each request/event. In the future, we may define a session id resolver interface
* allowing clients to store a map of sessions within a Lambda container.
*/
public class AwsHttpSession implements HttpSession {

public static final int SESSION_DURATION_SEC = 60 * 30;

private static final Logger log = LoggerFactory.getLogger(AwsHttpSession.class);
private Map<String, Object> attributes;
private String id;
private long creationTime;
private int maxInactiveInterval;
private long lastAccessedTime;
private boolean valid;

/**
* @param id API gateway request ID.
* @param id A unique session identifier
*/
public AwsHttpSession(String id) {
if (null == id) {
throw new RuntimeException("HTTP session id (from request ID) cannot be null");
}
log.debug("Creating session " + id);
this.id = id;
attributes = new HashMap<>();
creationTime = Instant.now().getEpochSecond();
maxInactiveInterval = SESSION_DURATION_SEC;
lastAccessedTime = creationTime;
valid = true;
}

@Override
public long getCreationTime() {
return 0;
return creationTime;
}

@Override
Expand All @@ -46,66 +69,88 @@ public ServletContext getServletContext() {

@Override
public void setMaxInactiveInterval(int interval) {

maxInactiveInterval = interval;
}

@Override
public int getMaxInactiveInterval() {
return 0;
return maxInactiveInterval;
}

@Override
@Deprecated
public HttpSessionContext getSessionContext() {
return null;
throw new UnsupportedOperationException("Session context is deprecated and no longer supported");
}

@Override
public Object getAttribute(String name) {
return null;
touch();
return attributes.get(name);
}

@Override
@Deprecated
public Object getValue(String name) {
return null;
throw new UnsupportedOperationException("Session values are deprecated and not suported");
}

@Override
public Enumeration<String> getAttributeNames() {
return null;
touch();
return Collections.enumeration(attributes.keySet());
}

@Override
@Deprecated
public String[] getValueNames() {
return new String[0];
throw new UnsupportedOperationException("Session values are deprecated and not suported");
}

@Override
public void setAttribute(String name, Object value) {

touch();
attributes.put(name, value);
}

@Override
@Deprecated
public void putValue(String name, Object value) {

throw new UnsupportedOperationException("Session values are deprecated and not suported");
}

@Override
public void removeAttribute(String name) {

touch();
attributes.remove(name);
}

@Override
@Deprecated
public void removeValue(String name) {

throw new UnsupportedOperationException("Session values are deprecated and not suported");
}

@Override
public void invalidate() {

valid = false;
attributes.clear();
}

@Override
public boolean isNew() {
return false;
return lastAccessedTime == creationTime;
}

private void touch() {
lastAccessedTime = Instant.now().getEpochSecond();
}

boolean isValid() {
if (lastAccessedTime - creationTime < maxInactiveInterval) {
return valid;
} else {
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
*/
package com.amazonaws.serverless.proxy.internal.servlet;

import com.amazonaws.serverless.proxy.internal.ExceptionHandler;
import com.amazonaws.serverless.proxy.ExceptionHandler;
import com.amazonaws.serverless.proxy.internal.LambdaContainerHandler;
import com.amazonaws.serverless.proxy.internal.RequestReader;
import com.amazonaws.serverless.proxy.internal.ResponseWriter;
import com.amazonaws.serverless.proxy.internal.SecurityContextWriter;
import com.amazonaws.serverless.proxy.RequestReader;
import com.amazonaws.serverless.proxy.ResponseWriter;
import com.amazonaws.serverless.proxy.SecurityContextWriter;
import com.amazonaws.services.lambda.runtime.Context;

import org.slf4j.Logger;
Expand Down
Loading

0 comments on commit e8e41cc

Please sign in to comment.