Skip to content

Commit

Permalink
active mq
Browse files Browse the repository at this point in the history
  • Loading branch information
prenagha committed Aug 22, 2024
1 parent 896dd19 commit 4062297
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,23 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
private final Endpoint messageBrokerEndpoint;
private final String messageBrokerUser;
private final String messageBrokerPassword;
private final boolean messageBrokerUseSssl;
private final boolean messageBrokerUseSSL;

public WebSocketConfig(
@Value("${spring.activemq.broker-url}") String websocketRelayEndpoint,
@Value("${spring.activemq.user}") String messageBrokerUser,
@Value("${spring.activemq.password}") String messageBrokerPassword,
@Value("${custom.web-socket-relay-use-ssl:#{false}}") boolean messageBrokerUseSssl) {
@Value("${custom.web-socket-relay-use-ssl:#{false}}") boolean messageBrokerUseSSL) {
this.messageBrokerEndpoint = Endpoint.fromEndpointString(websocketRelayEndpoint);
this.messageBrokerUser = messageBrokerUser;
this.messageBrokerPassword = messageBrokerPassword;
this.messageBrokerUseSssl = messageBrokerUseSssl;
this.messageBrokerUseSSL = messageBrokerUseSSL;
}

@Override
public void configureMessageBroker(@NonNull MessageBrokerRegistry registry) {
ReactorNettyTcpClient<byte[]> customTcpClient =
this.messageBrokerUseSssl
this.messageBrokerUseSSL
? getCustomTcpClientWithSSLSupport()
: getCustomTcpClientWithoutSSLSupport();

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/resources/templates/layout/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ <h1 th:text="${headline}" class="title text-center"></h1>
<div th:replace="~{fragments/footer :: footer}"></div>

<script sec:authorize="isAuthenticated()">
// connectToWebSocketEndpoint('[[${#authentication.principal.attributes.email}]]');
connectToWebSocketEndpoint('[[${#authentication.principal.attributes.email}]]');
</script>
</div>
</body>
Expand Down
1 change: 1 addition & 0 deletions cdk/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dependencies {
implementation("software.amazon.awscdk:aws-cdk-lib:2.151.1")
implementation("software.constructs:constructs:10.3.0")
implementation("dev.stratospheric:cdk-constructs:0.1.15")
implementation("org.passay:passay:1.6.4")
}

tasks.register<JavaExec>("infra") {
Expand Down
218 changes: 218 additions & 0 deletions cdk/src/main/java/com/renaghan/todo/cdk/ActiveMQ.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
package com.renaghan.todo.cdk;

import dev.stratospheric.cdk.ApplicationEnvironment;
import dev.stratospheric.cdk.Network;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.passay.CharacterData;
import org.passay.CharacterRule;
import org.passay.EnglishCharacterData;
import org.passay.PasswordGenerator;
import software.amazon.awscdk.Fn;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.services.amazonmq.CfnBroker;
import software.amazon.awscdk.services.ec2.CfnSecurityGroup;
import software.amazon.awscdk.services.ssm.StringParameter;
import software.constructs.Construct;

class ActiveMQ {

private static final String PARAMETER_USERNAME = "activeMqUsername";
private static final String PARAMETER_PASSWORD = "activeMqPassword";
private static final String PARAMETER_AMQP_ENDPOINT = "amqpEndpoint";
private static final String PARAMETER_STOMP_ENDPOINT = "stompEndpoint";
private static final String PARAMETER_SECURITY_GROUP_ID = "activeMqSecurityGroupId";

private final CDKApp app;
private final Stack stack;
private final CfnBroker broker;
private final String username;
private final String password;
private final String securityGroupId;

ActiveMQ(CDKApp app, Stack stack, Network network) {
this.app = app;
this.stack = stack;

this.username = app.getContext("activeMqUsername");
this.password = generatePassword();

List<User> userList = new ArrayList<>();
userList.add(new User(username, password));

CfnSecurityGroup amqSecurityGroup =
CfnSecurityGroup.Builder.create(stack, "amqSecurityGroup")
.vpcId(network.getVpc().getVpcId())
.groupDescription("Security Group for the Amazon MQ instance")
.groupName(app.appEnv().prefix("amqSecurityGroup"))
.build();

this.securityGroupId = amqSecurityGroup.getAttrGroupId();

this.broker =
CfnBroker.Builder.create(stack, "amqBroker")
.brokerName(app.appEnv().prefix("stratospheric-amq-message-broker"))
.securityGroups(Collections.singletonList(this.securityGroupId))
.subnetIds(
Collections.singletonList(
network.getVpc().getIsolatedSubnets().get(0).getSubnetId()))
.hostInstanceType("mq.t3.micro")
.engineType("ACTIVEMQ")
.engineVersion("5.18")
.authenticationStrategy("SIMPLE")
.encryptionOptions(
CfnBroker.EncryptionOptionsProperty.builder().useAwsOwnedKey(true).build())
.users(userList)
.publiclyAccessible(false)
.autoMinorVersionUpgrade(true)
.deploymentMode("SINGLE_INSTANCE")
.logs(CfnBroker.LogListProperty.builder().general(true).build())
.build();

createOutputParameters();
}

public static ActiveMqOutputParameters getOutputParametersFromParameterStore(
Construct scope, ApplicationEnvironment applicationEnvironment) {
return new ActiveMqOutputParameters(
getParameterUsername(scope, applicationEnvironment),
getParameterPassword(scope, applicationEnvironment),
getParameterAmqpEndpoint(scope, applicationEnvironment),
getParameterStompEndpoint(scope, applicationEnvironment),
getParameterSecurityGroupId(scope, applicationEnvironment));
}

private static String getParameterUsername(
Construct scope, ApplicationEnvironment applicationEnvironment) {
return StringParameter.fromStringParameterName(
scope,
PARAMETER_USERNAME,
createParameterName(applicationEnvironment, PARAMETER_USERNAME))
.getStringValue();
}

private static String getParameterPassword(
Construct scope, ApplicationEnvironment applicationEnvironment) {
return StringParameter.fromStringParameterName(
scope,
PARAMETER_PASSWORD,
createParameterName(applicationEnvironment, PARAMETER_PASSWORD))
.getStringValue();
}

private static String getParameterAmqpEndpoint(
Construct scope, ApplicationEnvironment applicationEnvironment) {
return StringParameter.fromStringParameterName(
scope,
PARAMETER_AMQP_ENDPOINT,
createParameterName(applicationEnvironment, PARAMETER_AMQP_ENDPOINT))
.getStringValue();
}

private static String getParameterStompEndpoint(
Construct scope, ApplicationEnvironment applicationEnvironment) {
return StringParameter.fromStringParameterName(
scope,
PARAMETER_STOMP_ENDPOINT,
createParameterName(applicationEnvironment, PARAMETER_STOMP_ENDPOINT))
.getStringValue();
}

private static String getParameterSecurityGroupId(
Construct scope, ApplicationEnvironment applicationEnvironment) {
return StringParameter.fromStringParameterName(
scope,
PARAMETER_SECURITY_GROUP_ID,
createParameterName(applicationEnvironment, PARAMETER_SECURITY_GROUP_ID))
.getStringValue();
}

private String generatePassword() {
PasswordGenerator passwordGenerator = new PasswordGenerator();
CharacterData lowerCaseChars = EnglishCharacterData.LowerCase;
CharacterRule lowerCaseRule = new CharacterRule(lowerCaseChars);
lowerCaseRule.setNumberOfCharacters(5);
CharacterData upperCaseChars = EnglishCharacterData.UpperCase;
CharacterRule upperCaseRule = new CharacterRule(upperCaseChars);
upperCaseRule.setNumberOfCharacters(5);
CharacterData digitChars = EnglishCharacterData.Digit;
CharacterRule digitRule = new CharacterRule(digitChars);
digitRule.setNumberOfCharacters(5);
return passwordGenerator.generatePassword(32, lowerCaseRule, upperCaseRule, digitRule);
}

private void createOutputParameters() {
StringParameter.Builder.create(stack, PARAMETER_USERNAME)
.parameterName(createParameterName(app.appEnv(), PARAMETER_USERNAME))
.stringValue(username)
.build();

StringParameter.Builder.create(stack, PARAMETER_PASSWORD)
.parameterName(createParameterName(app.appEnv(), PARAMETER_PASSWORD))
.stringValue(password)
.build();

StringParameter.Builder.create(stack, PARAMETER_AMQP_ENDPOINT)
.parameterName(createParameterName(app.appEnv(), PARAMETER_AMQP_ENDPOINT))
.stringValue(Fn.select(0, this.broker.getAttrAmqpEndpoints()))
.build();

StringParameter.Builder.create(stack, PARAMETER_STOMP_ENDPOINT)
.parameterName(createParameterName(app.appEnv(), PARAMETER_STOMP_ENDPOINT))
.stringValue(Fn.select(0, this.broker.getAttrStompEndpoints()))
.build();

StringParameter.Builder.create(stack, PARAMETER_SECURITY_GROUP_ID)
.parameterName(createParameterName(app.appEnv(), PARAMETER_SECURITY_GROUP_ID))
.stringValue(this.securityGroupId)
.build();
}

private static String createParameterName(
ApplicationEnvironment applicationEnvironment, String parameterName) {
return applicationEnvironment.getEnvironmentName()
+ "-"
+ applicationEnvironment.getApplicationName()
+ "-ActiveMq-"
+ parameterName;
}

public record ActiveMqOutputParameters(
String activeMqUsername,
String activeMqPassword,
String amqpEndpoint,
String stompEndpoint,
String activeMqSecurityGroupId) {}

@SuppressWarnings("unused")
static class User {

String username;

String password;

public User() {}

public User(String username, String password) {
this.username = username;
this.password = password;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}
}
60 changes: 7 additions & 53 deletions cdk/src/main/java/com/renaghan/todo/cdk/Database.java
Original file line number Diff line number Diff line change
Expand Up @@ -313,57 +313,11 @@ public DatabaseInputParameters withPostgresVersion(String postgresVersion) {
}
}

public static class DatabaseOutputParameters {
private final String endpointAddress;
private final String endpointPort;
private final String dbName;
private final String databaseSecretArn;
private final String databaseSecurityGroupId;
private final String instanceId;

public DatabaseOutputParameters(
String endpointAddress,
String endpointPort,
String dbName,
String databaseSecretArn,
String databaseSecurityGroupId,
String instanceId) {
this.endpointAddress = endpointAddress;
this.endpointPort = endpointPort;
this.dbName = dbName;
this.databaseSecretArn = databaseSecretArn;
this.databaseSecurityGroupId = databaseSecurityGroupId;
this.instanceId = instanceId;
}

/** The URL of the Postgres instance. */
public String getEndpointAddress() {
return endpointAddress;
}

/** The port of the Postgres instance. */
public String getEndpointPort() {
return endpointPort;
}

/** The database name of the Postgres instance. */
public String getDbName() {
return dbName;
}

/** The secret containing username and password. */
public String getDatabaseSecretArn() {
return databaseSecretArn;
}

/** The database's security group. */
public String getDatabaseSecurityGroupId() {
return databaseSecurityGroupId;
}

/** The database's identifier. */
public String getInstanceId() {
return instanceId;
}
}
public record DatabaseOutputParameters(
String endpointAddress,
String endpointPort,
String dbName,
String databaseSecretArn,
String databaseSecurityGroupId,
String instanceId) {}
}
5 changes: 5 additions & 0 deletions cdk/src/main/java/com/renaghan/todo/cdk/Infrastructure.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ private void messaging() {
.build();
}

private void activeMQ() {
new ActiveMQ(app, stack, network);
}

private void generate() {
dockerRepo();
cert();
Expand All @@ -123,6 +127,7 @@ private void generate() {
cognito();
messaging();
database();
activeMQ();
app.appEnv().tag(stack);
app.synth();
}
Expand Down
26 changes: 12 additions & 14 deletions cdk/src/main/java/com/renaghan/todo/cdk/ServiceApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,33 +52,31 @@ public static void main(String[] args) {
Database.getOutputParametersFromParameterStore(serviceStack, app.appEnv());
ISecret databaseSecret =
Secret.fromSecretCompleteArn(
serviceStack, "databaseSecret", databaseOutputParameters.getDatabaseSecretArn());
serviceStack, "databaseSecret", databaseOutputParameters.databaseSecretArn());
vars.put(
"SPRING_DATASOURCE_URL",
String.format(
"jdbc:postgresql://%s:%s/%s",
databaseOutputParameters.getEndpointAddress(),
databaseOutputParameters.getEndpointPort(),
databaseOutputParameters.getDbName()));
databaseOutputParameters.endpointAddress(),
databaseOutputParameters.endpointPort(),
databaseOutputParameters.dbName()));
vars.put(
"SPRING_DATASOURCE_USERNAME", databaseSecret.secretValueFromJson("username").toString());

vars.put(
"SPRING_DATASOURCE_PASSWORD", databaseSecret.secretValueFromJson("password").toString());
/*
ActiveMqStack.ActiveMqOutputParameters activeMqOutputParameters =
ActiveMqStack.getOutputParametersFromParameterStore(parametersStack, applicationEnvironment);

vars.put("WEB_SOCKET_RELAY_ENDPOINT", activeMqOutputParameters.getStompEndpoint());
vars.put("WEB_SOCKET_RELAY_USERNAME", activeMqOutputParameters.getActiveMqUsername());
vars.put("WEB_SOCKET_RELAY_PASSWORD", activeMqOutputParameters.getActiveMqPassword());
*/
ActiveMQ.ActiveMqOutputParameters activeMqOutputParameters =
ActiveMQ.getOutputParametersFromParameterStore(serviceStack, app.appEnv());

vars.put("WEB_SOCKET_RELAY_ENDPOINT", activeMqOutputParameters.stompEndpoint());
vars.put("WEB_SOCKET_RELAY_USERNAME", activeMqOutputParameters.activeMqUsername());
vars.put("WEB_SOCKET_RELAY_PASSWORD", activeMqOutputParameters.activeMqPassword());

List<String> securityGroupIdsToGrantIngressFromEcs =
Arrays.asList(
databaseOutputParameters.getDatabaseSecurityGroupId()
// ,activeMqOutputParameters.getActiveMqSecurityGroupId()
);
databaseOutputParameters.databaseSecurityGroupId(),
activeMqOutputParameters.activeMqSecurityGroupId());

Service.ServiceInputParameters inputParameters =
new Service.ServiceInputParameters(
Expand Down

0 comments on commit 4062297

Please sign in to comment.