-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #61 from shinesolutions/RS-161
Add orchestrator logic for Preview Architecture
- Loading branch information
Showing
26 changed files
with
2,584 additions
and
283 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ pom.xml.releaseBackup | |
release.properties | ||
.idea/ | ||
aem-orchestrator.iml | ||
core |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
src/main/java/com/shinesolutions/aemorchestrator/actions/ScaleDownPreviewPublishAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package com.shinesolutions.aemorchestrator.actions; | ||
|
||
import javax.annotation.Resource; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
|
||
import com.shinesolutions.aemorchestrator.aem.AgentRunMode; | ||
import com.shinesolutions.aemorchestrator.aem.ReplicationAgentManager; | ||
import com.shinesolutions.aemorchestrator.service.AemInstanceHelperService; | ||
import com.shinesolutions.aemorchestrator.service.AwsHelperService; | ||
import com.shinesolutions.swaggeraem4j.ApiException; | ||
|
||
@Component | ||
public class ScaleDownPreviewPublishAction implements Action { | ||
|
||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | ||
|
||
@Value("${aem.reverseReplication.enable}") | ||
private boolean reverseReplicationEnabled; | ||
|
||
@Resource | ||
private AemInstanceHelperService aemHelperService; | ||
|
||
@Resource | ||
private AwsHelperService awsHelperService; | ||
|
||
@Resource | ||
private ReplicationAgentManager replicationAgentManager; | ||
|
||
public boolean execute(String instanceId) { | ||
logger.info("ScaleDownPreviewPublishAction executing"); | ||
|
||
// Delete paired dispatcher | ||
String pairedDispatcherId = aemHelperService.getDispatcherIdForPairedPreviewPublish(instanceId); | ||
logger.debug("Paired previewPublish dispatcher instance ID=" + pairedDispatcherId); | ||
|
||
if(pairedDispatcherId != null) { | ||
logger.info("Terminating paired previewPublish dispatcher with ID: " + pairedDispatcherId); | ||
awsHelperService.terminateInstance(pairedDispatcherId); | ||
} else { | ||
logger.warn("Unable to terminate paired previewPublish dispatcher with ID: " + pairedDispatcherId + | ||
". It may already be terminated"); | ||
} | ||
|
||
// Delete replication agent on author | ||
String authorAemBaseUrl = aemHelperService.getAemUrlForAuthorElb(); | ||
|
||
try { | ||
replicationAgentManager.deletePreviewReplicationAgent(instanceId, authorAemBaseUrl, AgentRunMode.AUTHOR); | ||
} catch (ApiException e) { | ||
logger.warn("Failed to delete replication agent on author for previewPublish id: " + instanceId + | ||
". It may already be deleted."); | ||
} | ||
|
||
// Remove and reverse replication agents if they exist | ||
if (reverseReplicationEnabled) { | ||
logger.debug("Reverse replication is enabled"); | ||
try { | ||
replicationAgentManager.deletePreviewReverseReplicationAgent(instanceId, authorAemBaseUrl, | ||
AgentRunMode.AUTHOR); | ||
|
||
} catch (ApiException e) { | ||
logger.warn("Failed to delete reverse replication agent on author for previewPublish id " + instanceId | ||
+ ". It may already be deleted."); | ||
} | ||
} | ||
|
||
// Delete the attached content health check alarm | ||
try { | ||
aemHelperService.deleteContentHealthAlarmForPreviewPublisher(instanceId); | ||
} catch (Exception e) { | ||
logger.warn("Failed to remove content health check alarm for previewPublish instance " + instanceId, e); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
} |
56 changes: 56 additions & 0 deletions
56
...a/com/shinesolutions/aemorchestrator/actions/ScaleDownPreviewPublishDispatcherAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package com.shinesolutions.aemorchestrator.actions; | ||
|
||
import javax.annotation.Resource; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.stereotype.Component; | ||
|
||
import com.shinesolutions.aemorchestrator.service.AemInstanceHelperService; | ||
import com.shinesolutions.aemorchestrator.service.AwsHelperService; | ||
|
||
@Component | ||
public class ScaleDownPreviewPublishDispatcherAction implements Action { | ||
|
||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | ||
|
||
@Resource | ||
private AemInstanceHelperService aemHelperService; | ||
|
||
@Resource | ||
private AwsHelperService awsHelperService; | ||
|
||
public boolean execute(String instanceId) { | ||
logger.info("ScaleDownPreviewPublishDispatcherAction executing"); | ||
|
||
// Find and terminate paired previewPublish instance | ||
String pairedPreviewPublishId = aemHelperService.getPreviewPublishIdForPairedDispatcher(instanceId); | ||
logger.debug("Paired previewPublish instance ID=" + pairedPreviewPublishId); | ||
|
||
if (pairedPreviewPublishId != null) { | ||
// Terminate paired previewPublish instance | ||
logger.info("Terminating paired previewPublish instance with ID: " + pairedPreviewPublishId); | ||
awsHelperService.terminateInstance(pairedPreviewPublishId); | ||
} else { | ||
logger.warn("Unable to terminate paired previewPublish instance with ID: " + pairedPreviewPublishId + | ||
". It may already be terminated"); | ||
} | ||
|
||
// Change previewPublish auto scaling group desired capacity to match dispatcher | ||
int currentDispatcherDesiredCapacity = aemHelperService | ||
.getAutoScalingGroupDesiredCapacityForPreviewPublishDispatcher(); | ||
int currentPreviewPublishDesiredCapacity = aemHelperService.getAutoScalingGroupDesiredCapacityForPreviewPublish(); | ||
|
||
if (currentDispatcherDesiredCapacity == currentPreviewPublishDesiredCapacity) { | ||
// If desired capacity already the same, then don't do anything | ||
logger.info("Desired capacity already matching for previewPublish and dispatcher. No changes will be made"); | ||
} else { | ||
logger.info("Changing previewPublish auto scaling group capacity of " + currentPreviewPublishDesiredCapacity + | ||
" to match dispatcher's capacity of " + currentDispatcherDesiredCapacity); | ||
aemHelperService.setAutoScalingGroupDesiredCapacityForPreviewPublish(currentDispatcherDesiredCapacity); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
} |
189 changes: 189 additions & 0 deletions
189
src/main/java/com/shinesolutions/aemorchestrator/actions/ScaleUpPreviewPublishAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
package com.shinesolutions.aemorchestrator.actions; | ||
|
||
import java.util.NoSuchElementException; | ||
|
||
import javax.annotation.Resource; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
|
||
import com.shinesolutions.aemorchestrator.aem.AgentRunMode; | ||
import com.shinesolutions.aemorchestrator.aem.ReplicationAgentManager; | ||
import com.shinesolutions.aemorchestrator.exception.InstanceNotInHealthyStateException; | ||
import com.shinesolutions.aemorchestrator.service.AemInstanceHelperService; | ||
import com.shinesolutions.aemorchestrator.service.AwsHelperService; | ||
import com.shinesolutions.swaggeraem4j.ApiException; | ||
|
||
@Component | ||
public class ScaleUpPreviewPublishAction implements Action { | ||
|
||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | ||
|
||
@Value("${aem.reverseReplication.enable}") | ||
private boolean enableReverseReplication; | ||
|
||
@Value("${aws.device.name}") | ||
private String awsDeviceName; | ||
|
||
@Resource | ||
private AemInstanceHelperService aemHelperService; | ||
|
||
@Resource | ||
private AwsHelperService awsHelperService; | ||
|
||
@Resource | ||
private ReplicationAgentManager replicationAgentManager; | ||
|
||
|
||
public boolean execute(String instanceId) { | ||
logger.info("ScaleUpPreviewPublishAction executing"); | ||
|
||
// First create replication agent on previewPublish instance | ||
String authorAemBaseUrl = aemHelperService.getAemUrlForAuthorElb(); | ||
String previewPublishAemBaseUrl = aemHelperService.getAemUrlForPreviewPublish(instanceId); | ||
|
||
// Find unpaired previewPublish dispatcher and pair it with tags | ||
boolean success = pairAndTagWithDispatcher(instanceId, authorAemBaseUrl); | ||
|
||
if (success) { | ||
success = prepareReplicationAgent(instanceId, authorAemBaseUrl, previewPublishAemBaseUrl); | ||
} | ||
|
||
// Create a new previewPublish from a snapshot of an active previewPublish instance | ||
if (success) { | ||
success = loadSnapshotFromActivePreviewPublisher(instanceId, authorAemBaseUrl); | ||
} | ||
|
||
if (success) { | ||
attachContentHealthCheckAlarm(instanceId); | ||
} | ||
|
||
return success; | ||
} | ||
|
||
|
||
private boolean prepareReplicationAgent(String instanceId, String authorAemBaseUrl, String previewPublishAemBaseUrl) { | ||
boolean success = true; | ||
try { | ||
replicationAgentManager.createPreviewReplicationAgent(instanceId, previewPublishAemBaseUrl, authorAemBaseUrl, | ||
AgentRunMode.PREVIEWPUBLISH); | ||
|
||
if(enableReverseReplication) { | ||
logger.debug("Reverse replication is enabled"); | ||
replicationAgentManager.createPreviewReverseReplicationAgent(instanceId, previewPublishAemBaseUrl, | ||
authorAemBaseUrl, AgentRunMode.PREVIEWPUBLISH); | ||
} | ||
|
||
} catch (ApiException e) { | ||
logger.error("Error while attempting to create a new previewPublish replication agent for previewPublish instance " | ||
+ instanceId, e); | ||
success = false; | ||
} | ||
return success; | ||
} | ||
|
||
|
||
private boolean loadSnapshotFromActivePreviewPublisher(String instanceId, String authorAemBaseUrl) { | ||
boolean success = true; | ||
|
||
if(aemHelperService.isFirstPreviewPublishInstance()) { | ||
logger.info("First previewPublish instance, no snapshot needed"); | ||
aemHelperService.tagInstanceWithSnapshotId(instanceId, ""); //Tag with empty Snapshot ID | ||
} else { | ||
String activePreviewPublishId = aemHelperService.getPreviewPublishIdToSnapshotFrom(instanceId); | ||
logger.debug("Active previewPublish instance id to snapshot from: " + activePreviewPublishId); | ||
|
||
logger.info("Waiting for active previewPublish instance " + activePreviewPublishId + " to be in an healthy state"); | ||
try { | ||
aemHelperService.waitForPreviewPublishToBeHealthy(activePreviewPublishId); | ||
logger.info("Active previewPublish instance " + activePreviewPublishId + " is in a healthy state"); | ||
} catch (InstanceNotInHealthyStateException e) { | ||
logger.warn("Active previewPublish instance " + activePreviewPublishId + " is NOT in a healthy state. " | ||
+ "Unable to take snapshot"); | ||
success = false; | ||
} | ||
|
||
if(success) { | ||
success = performSnapshot(instanceId, activePreviewPublishId, authorAemBaseUrl); | ||
} | ||
} | ||
|
||
return success; | ||
} | ||
|
||
private boolean performSnapshot(String instanceId, String activePreviewPublishId, String authorAemBaseUrl) { | ||
boolean success = true; | ||
|
||
// Pause active previewPublish's replication agent before taking snapshot | ||
try { | ||
replicationAgentManager.pausePreviewReplicationAgent(activePreviewPublishId, authorAemBaseUrl, AgentRunMode.PREVIEWPUBLISH); | ||
// Take snapshot | ||
String volumeId = awsHelperService.getVolumeId(activePreviewPublishId, awsDeviceName); | ||
|
||
logger.debug("Volume ID for snapshot: " + volumeId); | ||
|
||
if (volumeId != null) { | ||
String snapshotId = aemHelperService.createPreviewPublishSnapshot(activePreviewPublishId, volumeId); | ||
logger.info("Created snapshot with ID: " + snapshotId); | ||
|
||
aemHelperService.tagInstanceWithSnapshotId(instanceId, snapshotId); | ||
} else { | ||
logger.error("Unable to find volume id for block device '" + awsDeviceName + "' and instance id " | ||
+ activePreviewPublishId); | ||
success = false; | ||
} | ||
|
||
} catch (Exception e) { | ||
logger.error("Error while pausing and attempting to snapshot an active preview Publish instance", e); | ||
success = false; | ||
} finally { | ||
// Always need to resume active previewPublish instance replication queue | ||
try { | ||
replicationAgentManager.resumePreviewReplicationAgent(activePreviewPublishId, authorAemBaseUrl, | ||
AgentRunMode.PREVIEWPUBLISH); | ||
} catch (ApiException e) { | ||
logger.error("Failed to restart replication queue for active previewPublish instance: " + activePreviewPublishId, e); | ||
} | ||
} | ||
|
||
return success; | ||
} | ||
|
||
|
||
private boolean pairAndTagWithDispatcher(String instanceId, String authorAemBaseUrl) { | ||
boolean success = true; | ||
|
||
try { | ||
// Find unpaired previewPublish dispatcher and pair it with tags | ||
logger.debug("Attempting to find unpaired Preview Publish dispatcher instance"); | ||
String unpairedDispatcherId = aemHelperService.findUnpairedPreviewPublishDispatcher(instanceId); | ||
|
||
logger.debug("Pairing previewPublish instance (" + instanceId + ") with preview publish dispatcher (" | ||
+ unpairedDispatcherId + ") via tags"); | ||
aemHelperService.pairPreviewPublishWithDispatcher(instanceId, unpairedDispatcherId); | ||
|
||
} catch (NoSuchElementException nse) { | ||
logger.warn("Failed to find unpaired previewPublish dispatcher", nse); | ||
success = false; | ||
} catch (Exception e) { | ||
logger.error("Error while attempting to pair previewPublish instance (" + | ||
instanceId + ") with dispatcher", e); | ||
success = false; | ||
} | ||
|
||
return success; | ||
} | ||
|
||
|
||
private void attachContentHealthCheckAlarm(String instanceId) { | ||
try { | ||
logger.info("Creating content health check alarm"); | ||
aemHelperService.createContentHealthAlarmForPreviewPublisher(instanceId); | ||
} catch (Exception e) { | ||
logger.warn("Failed to create content health check alarm for Preview Publish instance " + instanceId, e); | ||
} | ||
} | ||
|
||
} |
39 changes: 39 additions & 0 deletions
39
...ava/com/shinesolutions/aemorchestrator/actions/ScaleUpPreviewPublishDispatcherAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.shinesolutions.aemorchestrator.actions; | ||
|
||
import javax.annotation.Resource; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.stereotype.Component; | ||
|
||
import com.shinesolutions.aemorchestrator.service.AemInstanceHelperService; | ||
|
||
@Component | ||
public class ScaleUpPreviewPublishDispatcherAction implements Action { | ||
|
||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | ||
|
||
@Resource | ||
private AemInstanceHelperService aemHelperService; | ||
|
||
public boolean execute(String instanceId) { | ||
logger.info("ScaleUpPreviewPublishDispatcherAction executing"); | ||
|
||
// Change previewPublish auto scaling group desired capacity to match dispatcher | ||
int currentDispatcherDesiredCapacity = aemHelperService | ||
.getAutoScalingGroupDesiredCapacityForPreviewPublishDispatcher(); | ||
int currentPreviewPublishDesiredCapacity = aemHelperService.getAutoScalingGroupDesiredCapacityForPreviewPublish(); | ||
|
||
if (currentDispatcherDesiredCapacity == currentPreviewPublishDesiredCapacity) { | ||
// If desired capacity already the same, then don't do anything | ||
logger.info("Desired capacity already matching for previewPublish auto scaling group and it's dispatcher. No changes will be made"); | ||
} else { | ||
logger.info("Changing previewPublish auto scaling group capacity of " + currentPreviewPublishDesiredCapacity + | ||
" to match dispatcher's capacity of " + currentDispatcherDesiredCapacity); | ||
aemHelperService.setAutoScalingGroupDesiredCapacityForPreviewPublish(currentDispatcherDesiredCapacity); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.