in functions/ecs-deploy/src/main/java/com/amazon/aws/partners/saasfactory/saasboost/EcsDeploy.java [107:199]
public Object handleRequest(Map<String, Object> event, Context context) {
Utils.logRequestEvent(event);
// Is this event an ECR image action or a first-time deploy custom event?
String source = (String) event.get("source");
List<Deployment> deployments = new ArrayList<>();
if ("aws.ecr".equals(source)) {
String imageUri = parseEcrEvent(event);
// We will deploy the image tagged as latest to every provisioned tenant
if (imageUri != null && imageUri.endsWith("latest")) {
ApiRequest provisionedTenants = ApiRequest.builder()
.resource("tenants/provisioned")
.method("GET")
.build();
SdkHttpFullRequest getTenantsApiRequest = ApiGatewayHelper.getApiRequest(API_GATEWAY_HOST, API_GATEWAY_STAGE, provisionedTenants);
LOGGER.info("Fetching Provisioned tenants from tenants/provisioned");
try {
String functionName = "sb-" + SAAS_BOOST_ENV + "-workload-deploy-" + AWS_REGION;
String getTenantsResponseBody = ApiGatewayHelper.signAndExecuteApiRequest(getTenantsApiRequest, API_TRUST_ROLE, functionName);
ArrayList<Map<String, Object>> getTenantsResponse = Utils.fromJson(getTenantsResponseBody, ArrayList.class);
if (null == getTenantsResponse) {
throw new RuntimeException("responseBody is invalid");
}
for (Map<String, Object> tenant : getTenantsResponse) {
String tenantId = (String) tenant.get("id");
String tenantCodePipeline = "tenant-" + tenantId.substring(0, tenantId.indexOf("-"));
Deployment deployment = new Deployment(tenantId, imageUri, tenantCodePipeline);
deployments.add(deployment);
}
} catch (Exception e) {
LOGGER.error("Error invoking API /" + API_GATEWAY_STAGE + "/tenants/provisioned");
LOGGER.error(Utils.getFullStackTrace(e));
throw new RuntimeException(e);
}
} else {
LOGGER.info("Image URI {} does not end with latest, skipping deployment", imageUri);
return null;
}
} else if ("tenant-onboarding".equals(source)) {
// Check to see if there are any images in the ECR repo before triggering the pipeline
boolean hasImageToDeploy = false;
String repo = ((Map<String, String>) event.get("detail")).get("repository-name");
try {
ListImagesResponse dockerImages = ecr.listImages(request -> request.repositoryName(repo));
//ListImagesResponse::hasImageIds will return true if the imageIds object is not null
if (dockerImages.hasImageIds() && !dockerImages.imageIds().isEmpty()) {
hasImageToDeploy = true;
}
LOGGER.info("ecr:ListImages {}", repo);
for (Object imageId : dockerImages.imageIds()) {
LOGGER.info(imageId.toString());
}
} catch (SdkServiceException ecrError) {
LOGGER.error("ecr::ListImages error", ecrError.getMessage());
LOGGER.error(Utils.getFullStackTrace(ecrError));
throw ecrError;
}
if (hasImageToDeploy) {
String imageUri = parseTenantOnboardingEvent(event);
if (imageUri != null) {
Map<String, String> detail = (Map<String, String>) event.get("detail");
String tenantId = detail.get("tenantId");
//String tenantCodePipeline = detail.get("pipeline");
String tenantCodePipeline = "tenant-" + tenantId.substring(0, tenantId.indexOf("-"));
Deployment deployment = new Deployment(tenantId, imageUri, tenantCodePipeline);
deployments.add(deployment);
}
} else {
LOGGER.info("Skipping CodePipeline for tenant onboarding. No images in ECR.");
}
}
if (!deployments.isEmpty()) {
LOGGER.info("Deploying for " + deployments.size() + " tenants");
for (Deployment deployment : deployments) {
String tenantId = deployment.getTenantId();
// Create an imagedefinitions.json document for the newly pushed image
byte[] zip = codePipelineArtifact(tenantId, deployment.getImageUri());
// Write the imagedefinitions.json document to the artifact bucket
writeToArtifactBucket(tenantId, zip);
// Trigger CodePipeline for this tenant
triggerPipeline(tenantId, deployment.getPipeline());
}
} else {
LOGGER.info("No active, provisioned tenants to deploy to {}", deployments.size());
}
return null;
}