In this exercise, you will manually create and configure a serverless microservice. As you progress through this lab, you will use other techniques for build and deployment, so that you can compare and contrast the efficiencies of each approach and how automation makes the development experience more agile and increases developer efficiency.
You will create the TripSearch microservice manually. The TripSearch microservice exposes the following functions:
This is the same microservice we looked at in a previous lab. But this time, we will expose this functionality in our TravelBuddy website, and so need to deploy the service to be available to the website. Previously, the API Gateway configuration was taken care of for you by the deployment pipeline - in this exercise, you will manually configure the setup of both the Lambda function and the API Gateway.
set AWS_PROFILE=devaxacademy
set DDB_TABLENAME_TRIPSECTOR=TravelBuddyTripSectors
mvn test
3. You will see the following result:
Note that the from and to city examples shown here, and the dates and times, will be different for your environment because they have been randomly generated.
You should see no errors emitted by the unit test, which confirms the source code is building and running as expected. If you see an error, investigate.
When you run the tests on your local development environment, the AWS X-ray agent is not available, and so the calls through the AWS SDK cannot be recorded with AWS X-ray. However, since the pom.xml file defines a dependency to the AWS X-ray recorder, all calls through the SDK (for example, to DynamoDB) are attempted to be recorded. This would normally cause an error, and the tests would fail.
Notice that each of the Lambda handler classes extend a base class called LambdaHandlerWithXRayBase? In this class, there is a static initializer, and it builds ContextMissingStrategy object, overrides the behaviour for when there is no AWS X-ray context, and sets this as the default behaviour. In the implementation of the contextMissing handler, we simply print a message to the console, rather than the default action, which is to throw an exception. The implementation of the LambdaHandlerWithXRayBase class looks like this:
public class LambdaHandlerWithXRayBase
{
static
{
AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard();
builder.withContextMissingStrategy(new ContextMissingStrategy()
{
@Override
public void contextMissing(String arg0, Class<? extends RuntimeException> arg1)
{
System.out.println("AWS X-ray unavailable - ignoring");
}
});
AWSXRay.setGlobalRecorder(builder.build());
}
}
As an optional experiment, you could try removing the static initializer from the LambdaHandlerWithXRayBase base class, and re-running the Maven build. You will see errors such as:
com.amazonaws.xray.exceptions.SegmentNotFoundException: Thread failed to begin a subsegment: segment not found. Verify that a segment is in progress, and that the SegmentContextResolverChain is configured correctly in order to discover the segment.
Without the agent being present, and the call to the Lambda function having the correct correlation Id context passed to it, the SegmentContextResolverChain cannot determine the AWS X-ray segment to attach the recorded metadata to, and throws an exception. The implementation we provide in the base class overrides this behaviour, to safely ignore this condition while testing on your development environment.
mvn package shade:shade
to build
DevAx-06
in the search bar and press Enteraws s3 cp target/tripsearch-1.0.0.jar s3://<S3BucketLambdaCodeBucketName> --region <YOUR_REGION>
Replace <S3BucketLambdaCodeBucketName> by the value S3BucketLambdaCodeBucketName we saved in step 7
Replace <YOUR_REGION> by your Region
aws lambda create-function --function-name idevelopTripSearchFull --runtime java8 --role <LambdaRoleARN> --handler devlounge.lambda.FindAllTripsHandler --code S3Bucket=<S3BucketLambdaCodeBucketName>,S3Key=tripsearch-1.0.0.jar --timeout 15 --description "TravelBuddy TripSearch microservice - FindAllTrips" --memory-size 1024 --region <YOUR_REGION>
Replace <LambdaRoleARN> by the value LambdaRoleARN we saved in step 7
Replace <S3BucketLambdaCodeBucketName> by the value S3BucketLambdaCodeBucketName we saved in step 7
Replace <YOUR_REGION> by your Region
The code that implements our TripSearch function has three handlers exposed - one for finding all trips; one for finding trips that originate from a given city; and one for finding trips that have a given city as the destination. We have exposed only one handler so far - the search for all trips. In this section, we will create two new Lambda functions, each exposing one of the two remaining handlers.
aws lambda create-function --function-name idevelopTripSearchFromCity --runtime java8 --role <LambdaRoleARN> --handler devlounge.lambda.FindTripsFromCityHandler --code S3Bucket=<S3BucketLambdaCodeBucketName>,S3Key=tripsearch-1.0.0.jar --timeout 15 --description "TravelBuddy TripSearch microservice - FindTripsFromCity" --memory-size 1024 --region <YOUR_REGION>
Replace <LambdaRoleARN> by the value LambdaRoleARN we saved in step 7
Replace <S3BucketLambdaCodeBucketName> by the value S3BucketLambdaCodeBucketName we saved in step 7
Replace <YOUR_REGION> by your Region
aws lambda create-function --function-name idevelopFindTripsToCity --runtime java8 --role <LambdaRoleARN> --handler devlounge.lambda.FindTripsToCityHandler --code S3Bucket=<S3BucketLambdaCodeBucketName>,S3Key=tripsearch-1.0.0.jar --timeout 15 --description "TravelBuddy TripSearch microservice - FindTripsToCity" --memory-size 1024 --region <YOUR_REGION>
Replace <LambdaRoleARN> by the value LambdaRoleARN we saved in step 7
Replace <S3BucketLambdaCodeBucketName> by the value S3BucketLambdaCodeBucketName we saved in step 7
Replace <YOUR_REGION> by your Region
Confirm that you receive a success response similar to the response when you successfully created the first Lambda function.