public Object handleRequest()

in resources/custom-resources/clear-s3-bucket/src/main/java/com/amazon/aws/partners/saasfactory/saasboost/ClearS3Bucket.java [50:179]


    public Object handleRequest(Map<String, Object> event, Context context) {
        Utils.logRequestEvent(event);

        final String requestType = (String) event.get("RequestType");
        Map<String, Object> resourceProperties = (Map<String, Object>) event.get("ResourceProperties");
        final String bucket = (String) resourceProperties.get("Bucket");

        ExecutorService service = Executors.newSingleThreadExecutor();
        ObjectNode responseData = JsonNodeFactory.instance.objectNode();
        try {
            Runnable r = () -> {
                if ("Create".equalsIgnoreCase(requestType) || "Update".equalsIgnoreCase(requestType)) {
                    LOGGER.info("CREATE or UPDATE");
                    sendResponse(event, context, "SUCCESS", responseData);
                } else if ("Delete".equalsIgnoreCase(requestType)) {
                    LOGGER.info("DELETE");

                    // The list of objects in the bucket to delete
                    List<ObjectIdentifier> toDelete = new ArrayList<>();

                    // Is the bucket versioned?
                    GetBucketVersioningResponse versioningResponse = s3.getBucketVersioning(request -> request.bucket(bucket));
                    if (BucketVersioningStatus.ENABLED == versioningResponse.status() || BucketVersioningStatus.SUSPENDED == versioningResponse.status()) {
                        LOGGER.info("Bucket " + bucket + " is versioned (" + versioningResponse.status() + ")");
                        ListObjectVersionsResponse response;
                        String keyMarker = null;
                        String versionIdMarker = null;
                        do {
                            ListObjectVersionsRequest request;
                            if (Utils.isNotBlank(keyMarker) && Utils.isNotBlank(versionIdMarker)) {
                                request = ListObjectVersionsRequest.builder()
                                        .bucket(bucket)
                                        .keyMarker(keyMarker)
                                        .versionIdMarker(versionIdMarker)
                                        .build();
                            } else if (Utils.isNotBlank(keyMarker)) {
                                request = ListObjectVersionsRequest.builder()
                                        .bucket(bucket)
                                        .keyMarker(keyMarker)
                                        .build();
                            } else {
                                request = ListObjectVersionsRequest.builder()
                                        .bucket(bucket)
                                        .build();
                            }
                            response = s3.listObjectVersions(request);
                            keyMarker = response.nextKeyMarker();
                            versionIdMarker = response.nextVersionIdMarker();
                            response.versions()
                                    .stream()
                                    .map(version ->
                                        ObjectIdentifier.builder()
                                                .key(version.key())
                                                .versionId(version.versionId())
                                                .build()
                                    )
                                    .forEachOrdered(toDelete::add);
                        } while (response.isTruncated());
                    } else {
                        LOGGER.info("Bucket " + bucket + " is not versioned (" + versioningResponse.status() + ")");
                        ListObjectsV2Response response;
                        String token = null;
                        do {
                            ListObjectsV2Request request;
                            if (Utils.isNotBlank(token)) {
                                request = ListObjectsV2Request.builder()
                                        .bucket(bucket)
                                        .continuationToken(token)
                                        .build();
                            } else {
                                request = ListObjectsV2Request.builder()
                                        .bucket(bucket)
                                        .build();
                            }
                            response = s3.listObjectsV2(request);
                            token = response.nextContinuationToken();
                            response.contents()
                                    .stream()
                                    .map(obj ->
                                            ObjectIdentifier.builder()
                                                    .key(obj.key())
                                                    .build()
                                    )
                                    .forEachOrdered(toDelete::add);
                        } while (response.isTruncated());
                    }
                    if (!toDelete.isEmpty()) {
                        LOGGER.info("Deleting " + toDelete.size() + " objects");
                        final int maxBatchSize = 1000;
                        int batchStart = 0;
                        int batchEnd = 0;
                        while (batchEnd < toDelete.size()) {
                            batchStart = batchEnd;
                            batchEnd += maxBatchSize;
                            if (batchEnd > toDelete.size()) {
                                batchEnd = toDelete.size();
                            }
                            Delete delete = Delete.builder()
                                    .objects(toDelete.subList(batchStart, batchEnd))
                                    .build();
                            DeleteObjectsResponse deleteResponse = s3.deleteObjects(builder -> builder
                                    .bucket(bucket)
                                    .delete(delete)
                            );
                            LOGGER.info("Cleaned up " + deleteResponse.deleted().size() + " objects in bucket " + bucket);
                        }
                    } else {
                        LOGGER.info("Bucket " + bucket + " is empty. No objects to clean up.");
                    }
                    sendResponse(event, context, "SUCCESS", responseData);
                } else {
                    LOGGER.error("FAILED unknown requestType " + requestType);
                    responseData.put("Reason", "Unknown RequestType " + requestType);
                    sendResponse(event, context, "FAILED", responseData);
                }
            };
            Future<?> f = service.submit(r);
            f.get(context.getRemainingTimeInMillis() - 1000, TimeUnit.MILLISECONDS);
        } catch (final TimeoutException | InterruptedException | ExecutionException e) {
            // Timed out
            LOGGER.error("FAILED unexpected error or request timed out " + e.getMessage());
            String stackTrace = Utils.getFullStackTrace(e);
            LOGGER.error(stackTrace);
            responseData.put("Reason", stackTrace);
            sendResponse(event, context, "FAILED", responseData);
        } finally {
            service.shutdown();
        }
        return null;
    }