Skip to content

Commit

Permalink
add log retention to 1 month
Browse files Browse the repository at this point in the history
  • Loading branch information
docwho2 committed Nov 18, 2023
1 parent 2179b2b commit b9191eb
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 73 deletions.
8 changes: 4 additions & 4 deletions src/main/java/cloud/cleo/chimesma/cdk/InfrastructureApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

public final class InfrastructureApp {

private final static String STACK_DESC = "Provision Chime Voice SDK resources (VoiceConnector, SIP Rule, SIP Media App)";
private static final String STACK_DESC = "Provision Chime Voice SDK resources (VoiceConnector, SIP Rule, SIP Media App)";

public static void main(final String[] args) {
final var app = new App();
Expand All @@ -21,13 +21,13 @@ public static void main(final String[] args) {
String regionWest = getParamOrDefault(app, "regionWest", "us-west-2");


final var stack_east = new InfrastructureStack(app, "east", StackProps.builder()
new InfrastructureStack(app, "east", StackProps.builder()
.description(STACK_DESC)
.stackName(stackName)
.env(makeEnv(accountId, regionEast))
.build());

final var stack_west = new InfrastructureStack(app, "west", StackProps.builder()
new InfrastructureStack(app, "west", StackProps.builder()
.description(STACK_DESC)
.stackName(stackName)
.env(makeEnv(accountId, regionWest))
Expand All @@ -46,7 +46,7 @@ static Environment makeEnv(String accountId, String region) {

static String getParamOrDefault(App app, String param, String defaultValue) {
final var val = (String) app.getNode().tryGetContext(param);
return val == null || val.isBlank() ? defaultValue : val;
return val.isBlank() ? defaultValue : val;
}

static void requireNonEmpty(String string, String message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public InfrastructureStack(final Construct parent, final String id, final StackP
ChimeVoiceConnector vc = new ChimeVoiceConnector(this,cidrAllowList,PBX_HOSTNAME);

// SIP rule that associates the SMA with the Voice Connector
ChimeSipRule sr = new ChimeSipRuleVC(this, vc, List.of(sma));
new ChimeSipRuleVC(this, vc, List.of(sma));

new StringParameter(this, "SMA_ID_PARAM" , StringParameterProps.builder()
.parameterName("/" + getStackName() + "/SMA_ID")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,22 @@
import software.amazon.awscdk.services.iam.PolicyStatement;
import software.amazon.awscdk.services.lambda.CfnPermission;
import software.amazon.awscdk.services.lambda.CfnPermissionProps;
import software.amazon.awscdk.services.logs.RetentionDays;

/**
*
* @author sjensen
*/
public class ChimeSipMediaApp extends AwsCustomResource {

private final static String ID = "SMA-CR";
private final static String ID_PERM = ID + "-PERM";
private static final String ID = "SMA-CR";
private static final String ID_PERM = ID + "-PERM";

/**
* The SMA ID in the API response
*/
private final static String SMA_ID = "SipMediaApplication.SipMediaApplicationId";
private final static String SMA_ARN = "SipMediaApplication.SipMediaApplicationArn";
private static final String SMA_ID = "SipMediaApplication.SipMediaApplicationId";
private static final String SMA_ARN = "SipMediaApplication.SipMediaApplicationArn";

public ChimeSipMediaApp(Stack scope, Reference lambdaArn) {
super(scope, ID, AwsCustomResourceProps.builder()
Expand All @@ -53,10 +54,11 @@ public ChimeSipMediaApp(Stack scope, Reference lambdaArn) {
.action("DeleteSipMediaApplicationCommand")
.parameters(Map.of("SipMediaApplicationId", new PhysicalResourceIdReference()))
.build())
.logRetention(RetentionDays.ONE_MONTH)
.build());

// Add permission for Chime to Call the Lambda
final var perm = new CfnPermission(scope, ID_PERM, CfnPermissionProps.builder()
new CfnPermission(scope, ID_PERM, CfnPermissionProps.builder()
.functionName(lambdaArn.toString())
.action("lambda:InvokeFunction")
.principal("voiceconnector.chime.amazonaws.com")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,22 @@
import software.amazon.awscdk.customresources.PhysicalResourceId;
import software.amazon.awscdk.customresources.PhysicalResourceIdReference;
import software.amazon.awscdk.customresources.SdkCallsPolicyOptions;
import software.amazon.awscdk.services.logs.RetentionDays;

/**
* Base to support both URI and Phone number rules
*
* @author sjensen
*/
public abstract class ChimeSipRule extends AwsCustomResource {
private final static AtomicInteger ID_COUNTER = new AtomicInteger(0);
private final static String ID = "SR-CR";
private static final AtomicInteger ID_COUNTER = new AtomicInteger(0);
private static final String ID = "SR-CR";


/**
* The SIP Rule ID in the API response
*/
private final static String SR_ID = "SipRule.SipRuleId";
private static final String SR_ID = "SipRule.SipRuleId";

protected ChimeSipRule(Stack scope, String triggerValue, List<ChimeSipMediaApp> smas, SipRuleTriggerType type) {
super(scope, ID + ID_COUNTER.incrementAndGet(), AwsCustomResourceProps.builder()
Expand All @@ -56,12 +57,13 @@ protected ChimeSipRule(Stack scope, String triggerValue, List<ChimeSipMediaApp>
.action("DeleteSipRuleCommand")
.parameters(Map.of("SipRuleId", new PhysicalResourceIdReference()))
.build())
.logRetention(RetentionDays.ONE_MONTH)
.build());


}

public static enum SipRuleTriggerType {
public enum SipRuleTriggerType {
RequestUriHostname,
ToPhoneNumber
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
*/
package cloud.cleo.chimesma.cdk.customresources;

import cloud.cleo.chimesma.cdk.customresources.ChimeSipRule.SipRuleTriggerType;
import java.util.List;
import software.amazon.awscdk.Stack;

Expand All @@ -16,8 +15,8 @@
public abstract class ChimeSipRulePhone extends ChimeSipRule {


public ChimeSipRulePhone(Stack scope, String phone_e164, List<ChimeSipMediaApp> smas) {
super(scope,phone_e164, smas, SipRuleTriggerType.ToPhoneNumber);
protected ChimeSipRulePhone(Stack scope, String phoneE164, List<ChimeSipMediaApp> smas) {
super(scope,phoneE164, smas, SipRuleTriggerType.ToPhoneNumber);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
*/
package cloud.cleo.chimesma.cdk.customresources;

import cloud.cleo.chimesma.cdk.customresources.ChimeSipRule.SipRuleTriggerType;
import java.util.List;
import software.amazon.awscdk.Stack;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package cloud.cleo.chimesma.cdk.customresources;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
Expand All @@ -19,6 +18,7 @@
import software.amazon.awscdk.customresources.SdkCallsPolicyOptions;
import software.amazon.awscdk.services.ec2.AclCidr;
import software.amazon.awscdk.services.iam.PolicyStatement;
import software.amazon.awscdk.services.logs.RetentionDays;

/**
*
Expand Down Expand Up @@ -62,6 +62,7 @@ public ChimeVoiceConnector(Stack scope, List<AclCidr> termAllow, String pbx) {
.action("DeleteVoiceConnectorCommand")
.parameters(Map.of("VoiceConnectorId", new PhysicalResourceIdReference()))
.build())
.logRetention(RetentionDays.ONE_MONTH)
.build());


Expand All @@ -87,7 +88,7 @@ public ChimeVoiceConnector(Stack scope, List<AclCidr> termAllow, String pbx) {
termAllow = List.of(AclCidr.anyIpv4());
}

final var termination = new AwsCustomResource(scope, ID + "-TERM", AwsCustomResourceProps.builder()
new AwsCustomResource(scope, ID + "-TERM", AwsCustomResourceProps.builder()
.resourceType("Custom::VoiceConnectorTerm")
.installLatestAwsSdk(Boolean.FALSE)
.policy(AwsCustomResourcePolicy.fromSdkCalls(SdkCallsPolicyOptions.builder().resources(AwsCustomResourcePolicy.ANY_RESOURCE).build()))
Expand All @@ -98,13 +99,14 @@ public ChimeVoiceConnector(Stack scope, List<AclCidr> termAllow, String pbx) {
.parameters(Map.of("VoiceConnectorId", getResponseFieldReference(VC_ID),
"Termination", Map.of("CallingRegions", List.of("US"), "CidrAllowedList", termAllow.stream().map(ta -> ta.toCidrConfig().getCidrBlock()).toList(), "Disabled", false)))
.build())
.logRetention(RetentionDays.ONE_MONTH)
.build());

/**
* Only need to configure origination if outbound calls are needed for SIP
*/
if ( pbx != null ) {
final var origination = new AwsCustomResource(scope, ID + "-ORIG", AwsCustomResourceProps.builder()
new AwsCustomResource(scope, ID + "-ORIG", AwsCustomResourceProps.builder()
.resourceType("Custom::VoiceConnectorOrig")
.installLatestAwsSdk(Boolean.FALSE)
.policy(AwsCustomResourcePolicy.fromSdkCalls(SdkCallsPolicyOptions.builder().resources(AwsCustomResourcePolicy.ANY_RESOURCE).build()))
Expand All @@ -115,6 +117,7 @@ public ChimeVoiceConnector(Stack scope, List<AclCidr> termAllow, String pbx) {
.parameters(Map.of("VoiceConnectorId", getResponseFieldReference(VC_ID),
"Origination", Map.of("Routes", List.of(Map.of("Host", pbx, "Port", 5060, "Protocol", "UDP", "Priority", 1, "Weight", 1)), "Disabled", false)))
.build())
.logRetention(RetentionDays.ONE_MONTH)
.build());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public ChimeS3PromptBucket(Construct scope, String id, BucketProps props) {
.removalPolicy(RemovalPolicy.DESTROY)
.build());

CfnBucketPolicy bp = new CfnBucketPolicy(this, "PromptBucketPolicy", CfnBucketPolicyProps.builder()
new CfnBucketPolicy(this, "PromptBucketPolicy", CfnBucketPolicyProps.builder()
.bucket(getBucketName())
.policyDocument(PolicyDocument.Builder.create()
.statements(List.of(PolicyStatement.Builder.create()
Expand Down
120 changes: 69 additions & 51 deletions src/main/java/cloud/cleo/chimesma/cdk/resources/ChimeSMAFunction.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
*/
package cloud.cleo.chimesma.cdk.resources;

import software.amazon.awscdk.RemovalPolicy;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.services.logs.LogGroup;
import software.amazon.awscdk.services.logs.LogGroupProps;
import software.amazon.awscdk.services.logs.RetentionDays;
import software.amazon.awscdk.services.sam.CfnFunction;
import software.amazon.awscdk.services.sam.CfnFunctionProps;

Expand All @@ -15,61 +19,75 @@
*/
public class ChimeSMAFunction extends CfnFunction {

public ChimeSMAFunction(Stack scope, String id) {
super(scope, id, CfnFunctionProps.builder()
.handler("index.handler")
.runtime(software.amazon.awscdk.services.lambda.Runtime.NODEJS_LATEST.getName())
.build());
/**
* @param scope
* @param id
*/
public ChimeSMAFunction(Stack scope, String id) {
super(scope, id, CfnFunctionProps.builder()
.handler("index.handler")
.runtime(software.amazon.awscdk.services.lambda.Runtime.NODEJS_LATEST.getName())
.build());

setInlineCode("""
exports.handler = async (event, context, callback) => {
return {
SchemaVersion: '1.0',
Actions: await getActions(event),
};
};
setInlineCode("""
exports.handler = async (event, context, callback) => {
return {
SchemaVersion: '1.0',
Actions: await getActions(event),
};
};
const getActions = async (event) => {
const participantACallId = getParticipantACallId(event);
switch (event.InvocationEventType) {
case 'NEW_INBOUND_CALL':
return [createSpeakAction(participantACallId)];
case 'ACTION_SUCCESSFUL':
const actionData = event.ActionData;
if (actionData.Type === 'Speak') {
return [createHangupAction()];
}
return [];
default:
return [];
}
};
const getActions = async (event) => {
const participantACallId = getParticipantACallId(event);
switch (event.InvocationEventType) {
case 'NEW_INBOUND_CALL':
return [createSpeakAction(participantACallId)];
case 'ACTION_SUCCESSFUL':
const actionData = event.ActionData;
if (actionData.Type === 'Speak') {
return [createHangupAction()];
}
return [];
default:
return [];
}
};
const createSpeakAction = (callerId) => {
return {
Type: 'Speak',
Parameters: {
CallId: callerId,
Engine: 'neural',
Text: 'Thank you for calling the Chime Session Media Application. Goodbye.',
},
};
};
const createSpeakAction = (callerId) => {
return {
Type: 'Speak',
Parameters: {
CallId: callerId,
Engine: 'neural',
Text: 'Thank you for calling the Chime Session Media Application. Goodbye.',
},
};
};
const createHangupAction = () => ({
Type: 'Hangup',
Parameters: {
SipResponseCode: '480',
},
});
const createHangupAction = () => ({
Type: 'Hangup',
Parameters: {
SipResponseCode: '480',
},
});
const getParticipantACallId = (event) => {
const participantA = event.CallDetails.Participants.find(
(participant) => participant.ParticipantTag === 'LEG-A'
);
return participantA.CallId;
};
""");

const getParticipantACallId = (event) => {
const participantA = event.CallDetails.Participants.find(
(participant) => participant.ParticipantTag === 'LEG-A'
);
return participantA.CallId;
};
""");
}
// Assocaite log group so we can set a retention
new LogGroup(scope, id + "-LOG", LogGroupProps.builder()
.logGroupName("/aws/lambda/" + this.getFunctionName())
.retention(RetentionDays.ONE_MONTH)
.removalPolicy(RemovalPolicy.DESTROY)
.build()
);


}

}

0 comments on commit b9191eb

Please sign in to comment.