Example usage for com.amazonaws.services.apigateway.model CreateRestApiResult getId

List of usage examples for com.amazonaws.services.apigateway.model CreateRestApiResult getId

Introduction

In this page you can find the example usage for com.amazonaws.services.apigateway.model CreateRestApiResult getId.

Prototype


public String getId() 

Source Link

Document

The API's identifier.

Usage

From source file:squash.deployment.lambdas.ApiGatewayCustomResourceLambda.java

License:Apache License

/**
 * Implementation for the AWS Lambda function backing the ApiGateway resource.
 * /*  www .  jav a  2  s  .co  m*/
 * <p>This lambda requires the following environment variables:
 * 
 * <p>Keys suppling arn of other AWS lambda functions that the Api invokes:
 * <ul>
 *    <li>ValidDatesGETLambdaURI</li>
 *    <li>BookingsGETLambdaURI</li>
 *    <li>BookingRulesGETLambdaURI</li>
 *    <li>BookingsPUTDELETELambdaURI</li>
 *    <li>BookingRuleOrExclusionPUTDELETELambdaURI</li>
 * </ul>
 * 
 * <p>Other keys:
 * <ul>
 *    <li>BookingsApiGatewayInvocationRole - role allowing Api to invoke these three lambda functions.</li>
 *    <li>WebsiteBucket - name of S3 bucket serving the booking website.</li>
 *    <li>StageName - the name to give to the Api's stage.</li>
 *    <li>Region - the AWS region in which the Cloudformation stack is created.</li>
 *    <li>Revision - integer incremented to force stack updates to update this resource.</li>
 * </ul>
 * 
 * <p>On success, it returns the following output to Cloudformation:
 * <ul>
 *    <li>ApiGatewayBaseUrl - base Url of the created ApiGateway Api.</li>
 * </ul>
 *
 * @param request request parameters as provided by the CloudFormation service
 * @param context context as provided by the CloudFormation service
 */
@Override
public Object handleRequest(Map<String, Object> request, Context context) {

    LambdaLogger logger = context.getLogger();
    logger.log("Starting ApiGateway custom resource handleRequest");

    // Handle standard request parameters
    Map<String, String> standardRequestParameters = LambdaInputLogger.logStandardRequestParameters(request,
            logger);
    String requestType = standardRequestParameters.get("RequestType");

    // Handle required environment variables
    logger.log("Logging required environment variables for custom resource request");
    String region = System.getenv("AWS_REGION");
    String revision = System.getenv("Revision");
    String validDatesGETLambdaURI = wrapURI((System.getenv("ValidDatesGETLambdaURI")), region);
    String bookingsGETLambdaURI = wrapURI((System.getenv("BookingsGETLambdaURI")), region);
    String bookingRulesGETLambdaURI = wrapURI((System.getenv("BookingRulesGETLambdaURI")), region);
    String bookingsPUTDELETELambdaURI = wrapURI((System.getenv("BookingsPUTDELETELambdaURI")), region);
    String bookingRuleOrExclusionPUTDELETELambdaURI = wrapURI(
            System.getenv("BookingRuleOrExclusionPUTDELETELambdaURI"), region);
    String bookingsApiGatewayInvocationRole = System.getenv("BookingsApiGatewayInvocationRole");
    squashWebsiteBucket = System.getenv("WebsiteBucket");
    String stageName = System.getenv("StageName");

    // Log out our required environment variables
    logger.log("Logging custom parameters to ApiGateway custom resource request:");
    logger.log("ValidDatesGETLambdaURI: " + validDatesGETLambdaURI);
    logger.log("BookingsGETLambdaURI: " + bookingsGETLambdaURI);
    logger.log("BookingRulesGETLambdaURI: " + bookingRulesGETLambdaURI);
    logger.log("BookingsPUTDELETELambdaURI: " + bookingsPUTDELETELambdaURI);
    logger.log("BookingRuleOrExclusionPUTDELETELambdaURI: " + bookingRuleOrExclusionPUTDELETELambdaURI);
    logger.log("BookingsApiGatewayInvocationRole: " + bookingsApiGatewayInvocationRole);
    logger.log("Squash website bucket: " + squashWebsiteBucket);
    logger.log("StageName: " + stageName);
    logger.log("Region: " + region);
    logger.log("Revision: " + revision);

    // API calls below can sometimes give access denied errors during stack
    // creation which I think is bc required new roles have not yet propagated
    // across AWS. We sleep here to allow time for this propagation.
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        logger.log("Sleep to allow new roles to propagate has been interrupted.");
    }

    // Prepare our response to be sent in the finally block
    CloudFormationResponder cloudFormationResponder = new CloudFormationResponder(standardRequestParameters,
            "DummyPhysicalResourceId");
    // Initialise failure response, which will be changed on success
    String responseStatus = "FAILED";
    String apiGatewayBaseUrl = null;

    try {
        cloudFormationResponder.initialise();

        // Create ApiGateway client
        AmazonApiGateway apiGatewayClient = AmazonApiGatewayClientBuilder.standard().withRegion(region).build();

        String apiName = "SquashApi" + standardRequestParameters.get("StackId");
        logger.log("Setting api name to: " + apiName);
        if (requestType.equals("Create")) {

            // Ensure an API of the same name does not already exist - can happen
            // e.g. if wrongly put two of these custom resources in the stack
            // template.
            logger.log("Verifying an api with name: " + apiName + " does not already exist.");
            GetRestApisRequest getRestApisRequest = new GetRestApisRequest();
            GetRestApisResult apis = apiGatewayClient.getRestApis(getRestApisRequest);
            List<RestApi> apiList = apis.getItems();
            Boolean apiExists = apiList.stream().filter(api -> api.getName().equals(apiName)).findFirst()
                    .isPresent();
            if (apiExists) {
                logger.log(apiName + " exists already - creating another api with this name is not allowed");
                // Change physical id in responder - this is bc CloudFormation will
                // follow up this failed creation with a Delete request to clean up
                // - and we want to ignore that delete call - but not delete calls
                // for our original resource - and we use the PhysicalId to tell these
                // two cases apart.
                cloudFormationResponder.setPhysicalResourceId("DuplicatePhysicalResourceId");

                return null;
            }

            // Api does not already exist - so create it
            logger.log("Creating API");
            CreateRestApiRequest createRestApiRequest = new CreateRestApiRequest();
            createRestApiRequest.setName(apiName);
            createRestApiRequest.setDescription("Api for managing squash court bookings");
            CreateRestApiResult createRestApiResult = apiGatewayClient.createRestApi(createRestApiRequest);
            String restApiId = createRestApiResult.getId();
            cloudFormationResponder.setPhysicalResourceId(restApiId);

            // Add all resources and methods to the Api, then upload its SDK to S3.
            constructApiAndUploadSdk(restApiId, apiGatewayClient, region, validDatesGETLambdaURI,
                    bookingsGETLambdaURI, bookingsPUTDELETELambdaURI, bookingRulesGETLambdaURI,
                    bookingRuleOrExclusionPUTDELETELambdaURI, bookingsApiGatewayInvocationRole, stageName,
                    logger);

            apiGatewayBaseUrl = getApiGatewayBaseUrl(restApiId, region, stageName);
            logger.log("Created API with base url: " + apiGatewayBaseUrl);

        } else if (requestType.equals("Update")) {
            // We update an Api by removing all existing resources from it and then
            // adding them back, whilst retaining the original ApiId. This ensures
            // that its deployment creates a new entry in the deployment history of
            // the Api - i.e. it mimics editing and re-deploying the api in the
            // console.

            String restApiId = standardRequestParameters.get("PhysicalResourceId");
            // Keep same physical id - otherwise CloudFormation thinks it needs to
            // follow up with a Delete request on the 'previous' physical resource.
            cloudFormationResponder.setPhysicalResourceId(restApiId);
            logger.log("Updating Api for apiId: " + restApiId);

            // Remove all existing resources (except the root) from this Api
            logger.log("Removing existing resources from Api with apiId: " + restApiId);
            GetResourcesRequest getResourcesRequest = new GetResourcesRequest();
            getResourcesRequest.setRestApiId(restApiId);
            GetResourcesResult getResourcesResult = apiGatewayClient.getResources(getResourcesRequest);
            getResourcesResult.getItems().stream().filter(r -> !r.getPath().equals("/")).forEach(resource -> {
                logger.log("About to delete resource: " + resource.getPath());
                DeleteResourceRequest deleteResourceRequest = new DeleteResourceRequest();
                deleteResourceRequest.setRestApiId(restApiId);
                deleteResourceRequest.setResourceId(resource.getId());
                apiGatewayClient.deleteResource(deleteResourceRequest);
                logger.log("Successfully deleted resource: " + resource.getPath());
            });

            // Remove the existing SDK from the S3 website bucket
            removeSdkFromS3(logger);

            // And add back the updated set of resources and SDK
            logger.log("Adding back updated resources to Api with apiId: " + restApiId);
            constructApiAndUploadSdk(restApiId, apiGatewayClient, region, validDatesGETLambdaURI,
                    bookingsGETLambdaURI, bookingsPUTDELETELambdaURI, bookingRulesGETLambdaURI,
                    bookingRuleOrExclusionPUTDELETELambdaURI, bookingsApiGatewayInvocationRole, stageName,
                    logger);

            apiGatewayBaseUrl = getApiGatewayBaseUrl(restApiId, region, stageName);
            logger.log("Updated API with base url: " + apiGatewayBaseUrl);

        } else if (requestType.equals("Delete")) {

            String restApiId = standardRequestParameters.get("PhysicalResourceId");
            logger.log("Deleting Api for apiId: " + restApiId);

            // Early-out if this is a Delete corresponding to a failed attempt to
            // create a duplicate API, otherwise we will end up wrongly deleting
            // our (valid) original API instead.
            if (restApiId.equals("DuplicatePhysicalResourceId")) {
                logger.log("Ignoring delete request as it's for a non-existent duplicate API");
            } else {
                // Delete the API
                GetRestApiRequest getRestApiRequest = new GetRestApiRequest();
                getRestApiRequest.setRestApiId(restApiId);
                // This will throw if the api does not exist
                GetRestApiResult api = apiGatewayClient.getRestApi(getRestApiRequest);
                DeleteRestApiRequest deleteRestApiRequest = new DeleteRestApiRequest();
                deleteRestApiRequest.setRestApiId(api.getId());
                apiGatewayClient.deleteRestApi(deleteRestApiRequest);

                // Remove the sdk from the website bucket
                removeSdkFromS3(logger);
            }
        }

        responseStatus = "SUCCESS";
        return null;
    } catch (AmazonServiceException ase) {
        ExceptionUtils.logAmazonServiceException(ase, logger);
        return null;
    } catch (AmazonClientException ace) {
        ExceptionUtils.logAmazonClientException(ace, logger);
        return null;
    } catch (Exception e) {
        logger.log("Exception caught in ApiGateway Lambda: " + e.getMessage());
        return null;
    } finally {
        cloudFormationResponder.addKeyValueOutputsPair("ApiGatewayBaseUrl", apiGatewayBaseUrl);
        cloudFormationResponder.sendResponse(responseStatus, logger);
    }
}