@Test public void handleRequestShouldThrowException() throws TemplateException, KeyOperationException, IOException { expectedException.expect(RuntimeException.class); expectedException.expectMessage("Email"); LinkGeneratorLambdaHandler handler = mock(LinkGeneratorLambdaHandler.class); doCallRealMethod().when(handler).handleRequest(any(), any()); Exception ex = new TemplateException("Message", null); doThrow(ex).when(handler).getUploadPageUrlFromRequest(any(), any()); Context context = mock(Context.class); LambdaLogger logger = mock(LambdaLogger.class); doNothing().when(logger).log(anyString()); doReturn(logger).when(context).getLogger(); handler.handleRequest(mock(LinkGeneratorRequest.class), context); }
boolean createItemIfNotExists(String key, long currentTimeMillis, Context context) { LambdaLogger logger = context.getLogger(); AmazonDynamoDB client = createDynamoDBClient(cc); String functionName = context.getFunctionName(); try { // Create a record if it does not exist PutItemRequest req = new PutItemRequest().withTableName(TABLE_NAME) .addItemEntry(COL_FUNCTION_NAME, new AttributeValue(functionName)) .addItemEntry(COL_KEY, new AttributeValue(key)) .addItemEntry(COL_CREATED_TIME, new AttributeValue().withN(Long.toString(currentTimeMillis))) .addExpectedEntry(COL_FUNCTION_NAME, new ExpectedAttributeValue().withExists(false)) .addExpectedEntry(COL_KEY, new ExpectedAttributeValue().withExists(false)); client.putItem(req); return true; } catch (ConditionalCheckFailedException e) { logger.log("Record exsited. functionName[" + functionName + "] key[" + key + "]"); return false; } finally { client.shutdown(); } }
public void createSnapshotFromTagName(TagNameRequest tagNameRequest, Context context) { LambdaLogger logger = context.getLogger(); logger.log("create ebs snapshot from tag name Start. backup target[" + tagNameRequest + "]"); String regionName = System.getenv("AWS_DEFAULT_REGION"); AmazonEC2Async client = RegionUtils.getRegion(regionName).createClient(AmazonEC2AsyncClient.class, new DefaultAWSCredentialsProviderChain(), cc); try { List<Volume> volumes = describeBackupVolumes(client, tagNameRequest); for (Volume volume : volumes) { createSnapshot(volume.getVolumeId(), tagNameRequest.getGenerationCount(), context); } } finally { client.shutdown(); } }
String createAMI(ImageCreateRequest request, Context context) { LambdaLogger logger = context.getLogger(); AmazonEC2Async client = createEC2Client(); String imageId = null; try { Future<CreateImageResult> result = client .createImageAsync(new CreateImageRequest(request.getInstanceId(), request.getAmiName()) .withNoReboot(request.isNoReboot())); while (!result.isDone()) { Thread.sleep(1000); } imageId = result.get().getImageId(); logger.log("AMI Create Request End. instanceId[" + request.getInstanceId() + "] noReboot[" + request.isNoReboot() + "] imageId[" + imageId + "]"); } catch (Exception e) { throw new RuntimeException("An unexpected error at the time of AMI creation has occurred", e); } finally { client.shutdown(); } return imageId; }
public boolean lock(String key, int expiredIntervalMillis, Context context) { LambdaLogger logger = context.getLogger(); long currentTimeMillis = System.currentTimeMillis(); String functionName = context.getFunctionName(); // Create a record if it does not exist if (createItemIfNotExists(key, currentTimeMillis, context)) { logger.log("[SUCCESS]It won the lock. functionName[" + functionName + "] key[" + key + "]"); return true; } // To update, if the lock out of period if (updateItem(key, currentTimeMillis, expiredIntervalMillis, context)) { logger.log("[SUCCESS]It won the lock. functionName[" + functionName + "] key[" + key + "]"); return true; } else { context.getLogger().log( "[ERROR]You can not acquire a lock because it does not have one second has elapsed from the last lock acquisition Time."); return false; } }
/** * Adds revving suffix to all filenames beneath a folder. * * <p>Adds revving suffix to all filenames beneath a folder, recursing into subfolders. * Only js and css files are revved. * * @param suffix the suffix to add to all filenames. * @param startFolder the folder at root of tree within which to suffix files * @param logger a CloudwatchLogs logger. * @throws IOException */ public static void appendRevvingSuffix(String suffix, Path startFolder, LambdaLogger logger) throws IOException { Files .walk(startFolder, FileVisitOption.FOLLOW_LINKS) .filter(Files::isRegularFile) .forEach(path -> { File file = path.toFile(); if (file.isDirectory()) { return; } String absolutePath = file.getAbsolutePath(); String fileExtension = FilenameUtils.getExtension(absolutePath); if (!fileExtension.equals("js") && !fileExtension.equals("css")) { // We rev only js and css return; } String suffixedName = FilenameUtils.getBaseName(absolutePath) + "_" + suffix + "." + fileExtension; File suffixedFile = new File(file.getParentFile(), suffixedName); file.renameTo(suffixedFile); logger.log("Appended suffix to file: " + absolutePath + ", giving: " + suffixedFile.getAbsolutePath()); }); }
String getBookingPostRequestTemplate(LambdaLogger logger) throws IOException { // This template transforms the url-encoded POST body to JSON for lambda logger.log("About to add request template to transform POST body to JSON"); // / Get the mapping template from our resources String mappingTemplate = null; try (InputStream stream = GetBookingsLambda.class .getResourceAsStream("/squash/booking/lambdas/BookingPostMappingTemplate.vm")) { logger.log("Reading BookingPostMappingTemplate.vm from resources"); mappingTemplate = CharStreams.toString(new InputStreamReader(stream, "UTF-8")); logger.log("Mapping template read from resources: " + mappingTemplate); } catch (IOException e) { logger.log("Exception caught reading mapping template from resources: " + e.getMessage()); throw e; } return mappingTemplate; }
void addRolesToIdentityPool(String unauthenticatedRoleName, String unauthenticatedRole, String authenticatedRoleName, String authenticatedRole, String identityPoolId, AmazonCognitoIdentity client, LambdaLogger logger) { // First update the roles to use the actual pool id in their conditions logger .log("Updating authenticated and unauthenticated roles to use the actual identity pool id: " + identityPoolId); AmazonIdentityManagement iamClient = AmazonIdentityManagementClientBuilder.standard().build(); UpdateAssumeRolePolicyRequest updateAssumeRolePolicyRequest = new UpdateAssumeRolePolicyRequest(); updateAssumeRolePolicyRequest.setRoleName(unauthenticatedRoleName); updateAssumeRolePolicyRequest.setPolicyDocument(getAssumeRolePolicyDocument(false, identityPoolId, logger)); iamClient.updateAssumeRolePolicy(updateAssumeRolePolicyRequest); updateAssumeRolePolicyRequest.setRoleName(authenticatedRoleName); updateAssumeRolePolicyRequest.setPolicyDocument(getAssumeRolePolicyDocument(true, identityPoolId, logger)); iamClient.updateAssumeRolePolicy(updateAssumeRolePolicyRequest); // And add the updated roles to the pool logger.log("Adding updated authenticated and unauthenticated roles to the identity pool"); SetIdentityPoolRolesRequest setIdentityPoolRolesRequest = new SetIdentityPoolRolesRequest(); setIdentityPoolRolesRequest.addRolesEntry("authenticated", authenticatedRole); setIdentityPoolRolesRequest.addRolesEntry("unauthenticated", unauthenticatedRole); setIdentityPoolRolesRequest.setIdentityPoolId(identityPoolId); client.setIdentityPoolRoles(setIdentityPoolRolesRequest); }
String getAssumeRolePolicyDocument(Boolean isAuthenticatedRole, String identityPoolId, LambdaLogger logger) { // N.B. We have to add this here rather than in the CloudFormation // template since we don't know the identity pool id until here. String amrLine = isAuthenticatedRole ? " \"cognito-identity.amazonaws.com:amr\": \"authenticated\"\n" : " \"cognito-identity.amazonaws.com:amr\": \"unauthenticated\"\n"; String assumeRolePolicyDocument = "{" + " \"Version\" : \"2012-10-17\",\n" + " \"Statement\": [ {\n" + " \"Effect\": \"Allow\",\n" + " \"Principal\": {\n" + " \"Federated\": \"cognito-identity.amazonaws.com\"\n" + " },\n" + " \"Action\": \"sts:AssumeRoleWithWebIdentity\",\n" + " \"Condition\": {\n" + " \"StringEquals\": {\n" + " \"cognito-identity.amazonaws.com:aud\":\n" + " \"" + identityPoolId + "\"\n" + " },\n" + " \"ForAnyValue:StringLike\": {\n" + amrLine + " }\n" + " }\n" + " }]\n" + " }"; logger.log("Assume role policy document: "); logger.log(assumeRolePolicyDocument); return assumeRolePolicyDocument; }
private PutDeleteBookingRuleOrExclusionLambdaResponse createBookingRuleExclusion( PutDeleteBookingRuleOrExclusionLambdaRequest request, Context context) throws Exception { LambdaLogger logger = context.getLogger(); logger.log("About to create booking rule exclusion for request: " + request.toString()); IRuleManager ruleManager = getRuleManager(logger); Optional<BookingRule> updatedRule = ruleManager.addRuleExclusion(request.getDateToExclude(), request.getBookingRule(), true); logger.log("Created booking rule exclusion"); // Backup this updated booking rule - if a change was necessary if (updatedRule.isPresent()) { getBackupManager(logger).backupSingleBookingRule(updatedRule.get(), true); } return new PutDeleteBookingRuleOrExclusionLambdaResponse(); }
private PutDeleteBookingRuleOrExclusionLambdaResponse deleteBookingRuleExclusion( PutDeleteBookingRuleOrExclusionLambdaRequest request, Context context) throws Exception { LambdaLogger logger = context.getLogger(); logger.log("About to delete booking rule exclusion for request: " + request.toString()); IRuleManager ruleManager = getRuleManager(logger); Optional<BookingRule> updatedRule = ruleManager.deleteRuleExclusion(request.getDateToExclude(), request.getBookingRule(), true); logger.log("Deleted booking rule exclusion"); // Backup this updated booking rule - if a change was necessary if (updatedRule.isPresent()) { getBackupManager(logger).backupSingleBookingRule(updatedRule.get(), true); } return new PutDeleteBookingRuleOrExclusionLambdaResponse(); }
/** * Returns the {@link squash.booking.lambdas.core.IRuleManager}. */ protected IRuleManager getRuleManager(LambdaLogger logger) throws Exception { // Use a getter here so unit tests can substitute a mock manager if (!ruleManager.isPresent()) { ruleManager = Optional.of(new RuleManager()); ruleManager.get().initialise(getBookingManager(logger), getLifecycleManager(logger), logger); } return ruleManager.get(); }
@Override public final void initialise(int maxNumberOfAttributes, LambdaLogger logger) throws Exception { if (initialised) { throw new IllegalStateException("The optimistic persister has already been initialised"); } this.logger = logger; simpleDbDomainName = getEnvironmentVariable("SimpleDBDomainName"); versionAttributeName = "VersionNumber"; this.maxNumberOfAttributes = maxNumberOfAttributes; region = Region.getRegion(Regions.fromName(getEnvironmentVariable("AWS_REGION"))); initialised = true; }
public void createSnapshotFromVolumeIds(VolumeIdRequests volumeIdRequests, Context context) { LambdaLogger logger = context.getLogger(); logger.log("create ebs snapshot from volumeids Start. backup target[" + volumeIdRequests + "]"); for (VolumeIdRequest volumeIdRequest : volumeIdRequests.getVolumeIdRequests()) { createSnapshotFromVolumeId(volumeIdRequest, context); } }
/** * Returns the {@link squash.booking.lambdas.core.ILifecycleManager}. */ protected ILifecycleManager getLifecycleManager(LambdaLogger logger) throws Exception { // Use a getter here so unit tests can substitute a mock manager if (!lifecycleManager.isPresent()) { lifecycleManager = Optional.of(new LifecycleManager()); lifecycleManager.get().initialise(logger); } return lifecycleManager.get(); }
SendMessageResult createQueueMessage(ImageCreateRequest request, Context context) { LambdaLogger logger = context.getLogger(); final String queueName = request.getQueueName(); final String sqsEndpoint = request.getSqsEndpoint(); if (queueName == null || sqsEndpoint == null) { logger.log("skip create queue. [" + request + "]"); return null; } AmazonSQSAsync client = createSQSClient(); client.setEndpoint(sqsEndpoint); request.setSendMessageTimeMillis(System.currentTimeMillis()); try { CreateQueueRequest req = new CreateQueueRequest(queueName); String queueUrl = client.createQueue(req).getQueueUrl(); SendMessageRequest sendMessage = new SendMessageRequest(); sendMessage.setQueueUrl(queueUrl); ObjectMapper om = new ObjectMapper(); sendMessage.setMessageBody(om.writeValueAsString(request)); Future<SendMessageResult> result = client.sendMessageAsync(sendMessage); while (!result.isDone()) { Thread.sleep(100); } return result.get(); } catch (Exception e) { throw new RuntimeException("unexpected error occured in the create queue request.", e); } finally { client.shutdown(); } }
SendMessageResult createQueueMessage(InstanceRequest instanceRequest, Context context) { LambdaLogger logger = context.getLogger(); final String queueName = instanceRequest.getQueueName(); final String sqsEndpoint = instanceRequest.getSqsEndpoint(); if (queueName == null || sqsEndpoint == null) { logger.log("skip create queue. instanceRequest[" + instanceRequest + "]"); return null; } AmazonSQSAsync client = createSQSClient(); client.setEndpoint(sqsEndpoint); try { CreateQueueRequest req = new CreateQueueRequest(queueName); String queueUrl = client.createQueue(req).getQueueUrl(); instanceRequest.setSendMessageTimeMillis(System.currentTimeMillis()); SendMessageRequest sendMessage = new SendMessageRequest(); sendMessage.setQueueUrl(queueUrl); ObjectMapper om = new ObjectMapper(); sendMessage.setMessageBody(om.writeValueAsString(instanceRequest)); Future<SendMessageResult> result = client.sendMessageAsync(sendMessage); while (!result.isDone()) { Thread.sleep(100); } return result.get(); } catch (Exception e) { throw new RuntimeException("unexpected error occured in the create queue request.", e); } finally { client.shutdown(); } }
public void request(InstanceRequest instanceRequest, Context context) { LambdaLogger logger = context.getLogger(); try { String instanceState = getInstanceStateName(instanceRequest, context); // instance can not be found. if (instanceState == null) { return; } if (!"running".equals(instanceState)) { logger.log("instance state is not running."); } else { // stop ec2 instance request. stopInstance(instanceRequest, context); } // create queue createQueueMessage(instanceRequest, context); logger.log("[SUCCESS][" + instanceRequest.getInstanceId() + "][StopInstanceRequest]" + "Stop request of the instance has completed successfully." + instanceRequest); } catch (Exception e) { logger.log("[ERROR][" + instanceRequest.getInstanceId() + "][StopInstanceRequest] message[" + e.getMessage() + "] stackTrace[" + getStackTrace(e) + "]" + instanceRequest); } }
/** * Returns the {@link squash.booking.lambdas.core.IBookingManager}. */ protected IBookingManager getBookingManager(LambdaLogger logger) throws Exception { // Use a getter here so unit tests can substitute a mock manager if (!bookingManager.isPresent()) { bookingManager = Optional.of(new BookingManager()); bookingManager.get().initialise(logger); } return bookingManager.get(); }
public void checkInstanceState(InstanceCheckStateRequest checkInstanceStateRequest, Context context) { LambdaLogger logger = context.getLogger(); final String queueName = checkInstanceStateRequest.getQueueName(); final String sqsEndpoint = checkInstanceStateRequest.getSqsEndpoint(); // illegal parameter if (queueName == null || sqsEndpoint == null) { logger.log("[ERROR][checkInstanceStatus][running]QueueName or SQSEndpoint is not found Parameter. "); throw new IllegalArgumentException("QueueName or SQSEndpoint is not found Parameter. " + "CheckInstanceStateRequest[" + checkInstanceStateRequest + "]"); } // Only the specified number, reliably acquired int numberOfMessages = checkInstanceStateRequest.getNumberOfMessages(); for (int i = 0; i < numberOfMessages; i++) { AmazonSQSAsync client = createSQSClient(); client.setEndpoint(sqsEndpoint); try { String queueUrl = client.createQueue(queueName).getQueueUrl(); ReceiveMessageRequest req = new ReceiveMessageRequest(queueUrl).withVisibilityTimeout(5) .withMaxNumberOfMessages(checkInstanceStateRequest.getNumberOfMessages()); Future<ReceiveMessageResult> result = client.receiveMessageAsync(req); while (!result.isDone()) { Thread.sleep(100); } result.get().getMessages().stream() .forEach(s -> checkInstanceState(s, "running", checkInstanceStateRequest, context)); } catch (Exception e) { logger.log("[ERROR][checkInstanceStatus][running]message[" + e.getMessage() + "] stackTrace[" + getStackTrace(e) + "] CheckInstanceStateRequest[" + checkInstanceStateRequest + "]"); } finally { client.shutdown(); } } }
@Override public final void initialise(LambdaLogger logger) throws Exception { this.logger = logger; adminSnsTopicArn = getEnvironmentVariable("AdminSNSTopicArn"); region = Region.getRegion(Regions.fromName(getEnvironmentVariable("AWS_REGION"))); initialised = true; }
public void copySnapshotFromSnapshotId(SnapshotIdRequest snapshotIdRequest, Context context) { LambdaLogger logger = context.getLogger(); logger.log("copy ebs snapshot from snapshot id Start. backup target[" + snapshotIdRequest + "]"); copySnapshot(snapshotIdRequest.getSourceSnapshotId(), snapshotIdRequest.getDestinationRegion(), snapshotIdRequest.getGenerationCount(), context); }
void pargeEbsSnapshot(AmazonEC2Async client, String sourceSnapshotId, String snapshotId, int generationCount, Context context) { LambdaLogger logger = context.getLogger(); logger.log( "Parge snapshot start. SnapshotId[" + sourceSnapshotId + "] generationCount[" + generationCount + "]"); // get volumeId from tags String volumeId = getVolumeIdFromTag(client, snapshotId); // describe filter tag VolumeId List<Filter> filters = new ArrayList<>(); filters.add(new Filter().withName("tag:VolumeId").withValues(volumeId)); filters.add(new Filter().withName("tag:BackupType").withValues("copy-snapshot")); DescribeSnapshotsRequest snapshotRequest = new DescribeSnapshotsRequest().withFilters(filters); DescribeSnapshotsResult snapshotResult = client.describeSnapshots(snapshotRequest); // snapshot作成開始日でソートします。(古い→新しい) List<Snapshot> snapshots = snapshotResult.getSnapshots(); Collections.sort(snapshots, new SnapshotComparator()); // 世代管理保持数 < snapshotの数の場合、対象をpargeします。 int snapshotSize = snapshots.size(); if (generationCount < snapshotSize) { for (int i = 0; i < snapshotSize - generationCount; i++) { Snapshot snapshot = snapshots.get(i); // (念のため)snapshotのステータスが完了しているものだけをparge対象とする。 if (SnapshotState.Completed.toString().equals(snapshot.getState())) { String pargeSnapshotId = snapshot.getSnapshotId(); pargeSnapshot(client, pargeSnapshotId); logger.log("Parge EBS snapshot. snapshotId[" + pargeSnapshotId + "]"); } } } }
@Override public String getEnvironmentVariable(String variableName, LambdaLogger logger) { if (variableName.equals("RevvingSuffix")) { return revvingSuffix; } else if (variableName.equals("ApiGatewayBaseUrl")) { return apiGatewayBaseUrl; } return null; }
ImmutablePair<String, String> setUpPostMidnightRuleAndTargets(String ruleName, String websiteRefreshTargetId, String updateBookingsLambdaArn, String apiGatewayBaseUrl, AmazonCloudWatchEvents amazonCloudWatchEventsClient, LambdaLogger logger) { // Create post-midnight rule with Cron expression logger.log("Creating post-midnight rule"); PutRuleRequest putRuleRequest = new PutRuleRequest(); // Put just after midnight to avoid any timing glitch i.e. somehow still // thinking it's the previous day when it runs. This is 10 minutes after // midnight UTC - i.e. 1.10AM BST. putRuleRequest.setScheduleExpression("cron(10 0 * * ? *)"); putRuleRequest.setName(ruleName); putRuleRequest.setState(RuleState.ENABLED); putRuleRequest .setDescription("This runs just after midnight every day to refresh all the squash booking pages in S3"); ImmutablePair<String, String> ruleArn = new ImmutablePair<>( "UpdateFrontendServiceEventRuleArn", amazonCloudWatchEventsClient.putRule(putRuleRequest) .getRuleArn()); // Create target with updateBookings lambda, and attach rule to it. logger.log("Attaching updataBookings lambda to the post-midnight rule"); Target updateBookingsTarget = new Target(); updateBookingsTarget.setArn(updateBookingsLambdaArn); updateBookingsTarget.setInput("{\"apiGatewayBaseUrl\" : \"" + apiGatewayBaseUrl + "\"}"); updateBookingsTarget.setId(websiteRefreshTargetId); Collection<Target> midnightTargets = new ArrayList<>(); midnightTargets.add(updateBookingsTarget); PutTargetsRequest putMidnightTargetsRequest = new PutTargetsRequest(); putMidnightTargetsRequest.setRule(ruleName); putMidnightTargetsRequest.setTargets(midnightTargets); amazonCloudWatchEventsClient.putTargets(putMidnightTargetsRequest); return ruleArn; }
ImmutablePair<String, String> setUpPrewarmerRuleAndTargets(String ruleName, String prewarmerTargetId, String createOrDeleteBookingsLambdaArn, AmazonCloudWatchEvents amazonCloudWatchEventsClient, LambdaLogger logger) { // Create prewarmer rule with Rate expression logger.log("Creating prewarmer rule"); PutRuleRequest putRuleRequest = new PutRuleRequest(); putRuleRequest.setScheduleExpression("rate(5 minutes)"); putRuleRequest.setName(ruleName); putRuleRequest.setState(RuleState.ENABLED); putRuleRequest .setDescription("This runs every 5 minutes to prewarm the squash bookings lambdas"); ImmutablePair<String, String> ruleArn = new ImmutablePair<>("PrewarmerEventRuleArn", amazonCloudWatchEventsClient.putRule(putRuleRequest).getRuleArn()); // Create target with bookings lambda, and attach rule to it logger.log("Attaching bookings lambda to the prewarmer rule"); Target prewarmerTarget = new Target(); prewarmerTarget.setArn(createOrDeleteBookingsLambdaArn); prewarmerTarget.setInput("{\"slot\" : \"-1\"}"); prewarmerTarget.setId(prewarmerTargetId); Collection<Target> prewarmerTargets = new ArrayList<>(); prewarmerTargets.add(prewarmerTarget); PutTargetsRequest putPrewarmerTargetsRequest = new PutTargetsRequest(); putPrewarmerTargetsRequest.setRule(ruleName); putPrewarmerTargetsRequest.setTargets(prewarmerTargets); amazonCloudWatchEventsClient.putTargets(putPrewarmerTargetsRequest); return ruleArn; }
void deleteAngularjsApp(String websiteBucket, LambdaLogger logger) { logger.log("Removing AngularjsApp content from website versioned S3 bucket"); // We need to delete every version of every key ListVersionsRequest listVersionsRequest = new ListVersionsRequest() .withBucketName(websiteBucket); VersionListing versionListing; AmazonS3 client = TransferManagerBuilder.defaultTransferManager().getAmazonS3Client(); do { versionListing = client.listVersions(listVersionsRequest); versionListing .getVersionSummaries() .stream() .filter(k -> (k.getKey().startsWith("app"))) .forEach( k -> { logger.log("About to delete version: " + k.getVersionId() + " of AngularjsApp page: " + k.getKey()); DeleteVersionRequest deleteVersionRequest = new DeleteVersionRequest(websiteBucket, k.getKey(), k.getVersionId()); client.deleteVersion(deleteVersionRequest); logger.log("Successfully deleted version: " + k.getVersionId() + " of AngularjsApp page: " + k.getKey()); }); listVersionsRequest.setKeyMarker(versionListing.getNextKeyMarker()); } while (versionListing.isTruncated()); logger.log("Finished removing AngularjsApp content from website S3 bucket"); }
/** * Logs an AmazonClientException to a lambda logger. */ public static void logAmazonClientException(AmazonClientException ace, LambdaLogger logger) { logger.log("Caught an AmazonClientException, which means " + "the client encountered " + "an internal error while trying to " + "communicate with AWS, " + "such as not being able to access the network."); logger.log("Error Message: " + ace.getMessage()); }
/** * Sets public read permissions on content within an S3 bucket. * * <p>Web content served from an S3 bucket must have public read permissions. * * @param bucketName the bucket to apply the permissions to. * @param prefix prefix within the bucket, beneath which to apply the permissions. * @param logger a CloudwatchLogs logger. */ public static void setPublicReadPermissionsOnBucket(String bucketName, Optional<String> prefix, LambdaLogger logger) { // Ensure newly uploaded content has public read permission ListObjectsRequest listObjectsRequest; if (prefix.isPresent()) { logger.log("Setting public read permission on bucket: " + bucketName + " and prefix: " + prefix.get()); listObjectsRequest = new ListObjectsRequest().withBucketName(bucketName).withPrefix( prefix.get()); } else { logger.log("Setting public read permission on bucket: " + bucketName); listObjectsRequest = new ListObjectsRequest().withBucketName(bucketName); } ObjectListing objectListing; AmazonS3 client = TransferManagerBuilder.defaultTransferManager().getAmazonS3Client(); do { objectListing = client.listObjects(listObjectsRequest); for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) { logger.log("Setting permissions for S3 object: " + objectSummary.getKey()); client.setObjectAcl(bucketName, objectSummary.getKey(), CannedAccessControlList.PublicRead); } listObjectsRequest.setMarker(objectListing.getNextMarker()); } while (objectListing.isTruncated()); logger.log("Finished setting public read permissions"); }
/** * Adds cache-control header to S3 objects. * * <p>Adds cache-control header to S3 objects. All objects * beneath the specified prefix (i.e. folder), and with the * specified extension will have the header added. When the * bucket serves objects it will then add a suitable * Cache-Control header. * * @param headerValue value of the cache-control header * @param bucketName the bucket to apply the header to. * @param prefix prefix within the bucket, beneath which to apply the header. * @param extension file extension to apply header to * @param logger a CloudwatchLogs logger. */ public static void addCacheControlHeader(String headerValue, String bucketName, Optional<String> prefix, String extension, LambdaLogger logger) { // To add new metadata, we must copy each object to itself. ListObjectsRequest listObjectsRequest; if (prefix.isPresent()) { logger.log("Setting cache-control metadata: " + headerValue + ", on bucket: " + bucketName + " and prefix: " + prefix.get() + " and extension: " + extension); listObjectsRequest = new ListObjectsRequest().withBucketName(bucketName).withPrefix( prefix.get()); } else { logger.log("Setting cache-control metadata: " + headerValue + ", on bucket: " + bucketName + " and extension: " + extension); listObjectsRequest = new ListObjectsRequest().withBucketName(bucketName); } ObjectListing objectListing; AmazonS3 client = TransferManagerBuilder.defaultTransferManager().getAmazonS3Client(); do { objectListing = client.listObjects(listObjectsRequest); for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) { String key = objectSummary.getKey(); if (!key.endsWith(extension)) { continue; } logger.log("Setting metadata for S3 object: " + key); // We must specify ALL metadata - not just the one we're adding. ObjectMetadata objectMetadata = client.getObjectMetadata(bucketName, key); objectMetadata.setCacheControl(headerValue); CopyObjectRequest copyObjectRequest = new CopyObjectRequest(bucketName, key, bucketName, key).withNewObjectMetadata(objectMetadata).withCannedAccessControlList( CannedAccessControlList.PublicRead); client.copyObject(copyObjectRequest); logger.log("Set metadata for S3 object: " + key); } listObjectsRequest.setMarker(objectListing.getNextMarker()); } while (objectListing.isTruncated()); logger.log("Set cache-control metadata on bucket"); }
/** * Retrieves and logs Cloudformation custom resource request parameters. * * <p>Cloudformation custom resource requests provide their parameters * via a map. Most of these are standard (and present in all requests), * but some are specific to each custom resource. This method retrieves * and logs only the standard parameters. * * @param request the Cloudformation custom resource request. * @param logger a CloudwatchLogs logger. * @return the retrieved Cloudformation standard request parameters. */ public static Map<String, String> logStandardRequestParameters(Map<String, Object> request, LambdaLogger logger) { logger.log("Logging standard input parameters to custom resource request"); // Create map of params lambda actually uses Map<String, String> standardRequestParameters = new HashMap<>(); String requestType = (String) request.get("RequestType"); standardRequestParameters.put("RequestType", requestType); String requestId = (String) request.get("RequestId"); standardRequestParameters.put("RequestId", requestId); String stackId = (String) request.get("StackId"); standardRequestParameters.put("StackId", stackId); String logicalResourceId = (String) request.get("LogicalResourceId"); standardRequestParameters.put("LogicalResourceId", logicalResourceId); String physicalResourceId = (String) request.get("PhysicalResourceId"); if (physicalResourceId != null) { // Create RequestTypes do not have the physical id standardRequestParameters.put("PhysicalResourceId", physicalResourceId); } String responseURL = (String) request.get("ResponseURL"); standardRequestParameters.put("ResponseURL", responseURL); // Log out our request parameters logger.log("RequestType: " + requestType); logger.log("RequestId: " + requestId); logger.log("StackId: " + stackId); logger.log("LogicalResourceId: " + logicalResourceId); if (physicalResourceId != null) { logger.log("PhysicalResourceId: " + physicalResourceId); } logger.log("ResponseURL: " + responseURL); return standardRequestParameters; }
void removeSdkFromS3(LambdaLogger logger) { logger.log("About to remove apigateway sdk from website versioned S3 bucket"); // We need to delete every version of every key ListVersionsRequest listVersionsRequest = new ListVersionsRequest() .withBucketName(squashWebsiteBucket); VersionListing versionListing; IS3TransferManager transferManager = getS3TransferManager(); AmazonS3 client = transferManager.getAmazonS3Client(); do { versionListing = client.listVersions(listVersionsRequest); versionListing .getVersionSummaries() .stream() .filter( k -> !(k.getKey().startsWith("20") || k.getKey().equals("today.html") || k.getKey() .equals("bookings.html"))) .forEach( k -> { logger.log("About to delete version: " + k.getVersionId() + " of API SDK: " + k.getKey()); DeleteVersionRequest deleteVersionRequest = new DeleteVersionRequest( squashWebsiteBucket, k.getKey(), k.getVersionId()); client.deleteVersion(deleteVersionRequest); logger.log("Successfully deleted version: " + k.getVersionId() + " of API SDK key: " + k.getKey()); }); listVersionsRequest.setKeyMarker(versionListing.getNextKeyMarker()); } while (versionListing.isTruncated()); logger.log("Finished remove apigateway sdk from website S3 bucket"); }
void pause(LambdaLogger logger) { // Short sleep - this avoids the Too Many Requests error in this // custom resource when creating the cloudformation stack. try { Thread.sleep(1000); // ms } catch (InterruptedException e) { logger.log("Sleep interrupted in createMethodOnResource"); } }