diff --git a/service/application/pom.xml b/service/application/pom.xml
index 911ee86af..def1b307e 100644
--- a/service/application/pom.xml
+++ b/service/application/pom.xml
@@ -305,6 +305,9 @@
${jacocoSurefire}
+
+ **/realTests/**
+
diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/command/CommandManager.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/command/CommandManager.java
index c7bee5129..54d239997 100644
--- a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/command/CommandManager.java
+++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/command/CommandManager.java
@@ -5,19 +5,28 @@
import com.solace.maas.ep.event.management.agent.config.eventPortal.EventPortalProperties;
import com.solace.maas.ep.event.management.agent.plugin.command.model.Command;
import com.solace.maas.ep.event.management.agent.plugin.command.model.CommandBundle;
+import com.solace.maas.ep.event.management.agent.plugin.command.model.CommandResult;
+import com.solace.maas.ep.event.management.agent.plugin.command.model.JobStatus;
import com.solace.maas.ep.event.management.agent.plugin.service.MessagingServiceDelegateService;
import com.solace.maas.ep.event.management.agent.plugin.solace.processor.semp.SempClient;
import com.solace.maas.ep.event.management.agent.plugin.solace.processor.semp.SolaceHttpSemp;
import com.solace.maas.ep.event.management.agent.plugin.terraform.manager.TerraformManager;
import com.solace.maas.ep.event.management.agent.publisher.CommandPublisher;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
+import java.time.OffsetDateTime;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import static com.solace.maas.ep.event.management.agent.plugin.terraform.manager.TerraformManager.LOG_LEVEL_ERROR;
+import static com.solace.maas.ep.event.management.agent.plugin.terraform.manager.TerraformManager.setCommandError;
+
@Slf4j
@Service
+@ConditionalOnProperty(name = "event-portal.gateway.messaging.standalone", havingValue = "false")
public class CommandManager {
private final TerraformManager terraformManager;
private final CommandMapper commandMapper;
@@ -36,20 +45,46 @@ public CommandManager(TerraformManager terraformManager, CommandMapper commandMa
}
public void execute(CommandMessage request) {
- Map envVars = setBrokerSpecificEnvVars(request.getServiceId());
+ Map envVars;
+ try {
+ envVars = setBrokerSpecificEnvVars(request.getServiceId());
+ } catch (Exception e) {
+ log.error("Error getting terraform variables", e);
+ Command firstCommand = request.getCommandBundles().get(0).getCommands().get(0);
+ setCommandError(firstCommand, e);
+ sendResponse(request);
+ return;
+ }
+
for (CommandBundle bundle : request.getCommandBundles()) {
// For now everything is run serially
for (Command command : bundle.getCommands()) {
- switch (command.getCommandType()) {
- case terraform:
- terraformManager.execute(commandMapper.map(request), command, envVars);
- break;
- default:
- throw new IllegalStateException("Unexpected value: " + command.getCommandType());
+ try {
+ switch (command.getCommandType()) {
+ case terraform:
+ terraformManager.execute(commandMapper.map(request), command, envVars);
+ break;
+ default:
+ command.setResult(CommandResult.builder()
+ .status(JobStatus.error)
+ .logs(List.of(
+ Map.of("message", "unknown command type " + command.getCommandType(),
+ "errorType", "UnknownCommandType",
+ "level", LOG_LEVEL_ERROR,
+ "timestamp", OffsetDateTime.now())))
+ .build());
+ break;
+ }
+ } catch (Exception e) {
+ log.error("Error executing command", e);
+ setCommandError(command, e);
}
}
}
+ sendResponse(request);
+ }
+ private void sendResponse(CommandMessage request) {
Map topicVars = Map.of(
"orgId", request.getOrgId(),
"runtimeAgentId", eventPortalProperties.getRuntimeAgentId(),
diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/TestConfig.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/TestConfig.java
index fc54bdf57..e8a77de74 100644
--- a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/TestConfig.java
+++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/TestConfig.java
@@ -1,5 +1,8 @@
package com.solace.maas.ep.event.management.agent;
+import com.solace.maas.ep.event.management.agent.command.CommandManager;
+import com.solace.maas.ep.event.management.agent.command.mapper.CommandMapper;
+import com.solace.maas.ep.event.management.agent.config.eventPortal.EventPortalProperties;
import com.solace.maas.ep.event.management.agent.messagingServices.RtoMessagingService;
import com.solace.maas.ep.event.management.agent.plugin.config.VMRProperties;
import com.solace.maas.ep.event.management.agent.plugin.config.eventPortal.EventPortalPluginProperties;
@@ -140,6 +143,15 @@ public CommandPublisher getCommandPublisher() {
return mock(CommandPublisher.class);
}
+ @Bean
+ @Primary
+ public CommandManager getCommandManager(TerraformManager terraformManager, CommandMapper commandMapper,
+ CommandPublisher commandPublisher, MessagingServiceDelegateService messagingServiceDelegateService,
+ EventPortalProperties eventPortalProperties) {
+ return new CommandManager(terraformManager, commandMapper, commandPublisher,
+ messagingServiceDelegateService, eventPortalProperties);
+ }
+
@Bean
@Primary
KafkaClientConnection kafkaClientConnection() {
diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/realTests/NegativeTerraformEVMRConnectedTests.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/realTests/NegativeTerraformEVMRConnectedTests.java
new file mode 100644
index 000000000..7fab323b0
--- /dev/null
+++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/realTests/NegativeTerraformEVMRConnectedTests.java
@@ -0,0 +1,553 @@
+package com.solace.maas.ep.event.management.agent.realTests;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.solace.maas.ep.common.messages.CommandMessage;
+import com.solace.maas.ep.event.management.agent.config.eventPortal.EventPortalProperties;
+import com.solace.maas.ep.event.management.agent.plugin.command.model.Command;
+import com.solace.maas.ep.event.management.agent.plugin.command.model.CommandBundle;
+import com.solace.maas.ep.event.management.agent.plugin.command.model.CommandType;
+import com.solace.maas.ep.event.management.agent.plugin.command.model.ExecutionType;
+import com.solace.maas.ep.event.management.agent.plugin.command.model.JobStatus;
+import com.solace.maas.ep.event.management.agent.plugin.mop.MOPUHFlag;
+import com.solace.maas.ep.event.management.agent.plugin.publisher.SolacePublisher;
+import com.solace.maas.ep.event.management.agent.plugin.terraform.configuration.TerraformProperties;
+import com.solace.maas.ep.event.management.agent.realTests.badClasses.BadCommand;
+import com.solace.maas.ep.event.management.agent.realTests.badClasses.CommandTypeBad;
+import com.solace.messaging.MessagingService;
+import com.solace.messaging.receiver.DirectMessageReceiver;
+import com.solace.messaging.receiver.InboundMessage;
+import com.solace.messaging.resources.TopicSubscription;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.util.FileCopyUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Base64;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static com.solace.maas.ep.event.management.agent.plugin.mop.MOPMessageType.generic;
+import static com.solace.maas.ep.event.management.agent.plugin.mop.MOPProtocol.epConfigPush;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+@SuppressWarnings({"PMD.GodClass", "PMD.UnusedPrivateMethod"})
+@Slf4j
+@ActiveProfiles("negativetests")
+@EnableAutoConfiguration
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class NegativeTerraformEVMRConnectedTests {
+
+ @Autowired
+ private ResourceLoader resourceLoader;
+ @Autowired
+ private EventPortalProperties eventPortalProperties;
+ @Autowired
+ private SolacePublisher solacePublisher;
+ @Autowired
+ private MessagingService messagingService;
+ @Autowired
+ private TerraformProperties terraformProperties;
+
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+ private static final String mainServiceId = "49a23700m80";
+ private static String context = "abc123";
+ private long startTime;
+
+ static {
+ objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+ }
+
+ @BeforeAll
+ private static void envVarPrecheck() throws IOException, InterruptedException {
+ // These tests require some setup.
+ //
+ // Make sure the required environment variables are set.
+ // "SOLACE_SEMP_PASSWORD", "SOLACE_SEMP_URL", "SOLACE_SEMP_USERNAME" are for a valid Solace broker (version 10.4+)
+ // "OLD_SOLACE_SEMP_PASSWORD", "OLD_SOLACE_SEMP_URL", "OLD_SOLACE_SEMP_USERNAME" are for an older Solace broker (version 10.3-)
+ // "EP_GATEWAY_MSGVPN", "EP_GATEWAY_PASSWORD", "EP_GATEWAY_URL", "EP_GATEWAY_USERNAME" are for a valid eVMR
+ //
+ // They can be set for all Junit tests by going to the "Run" menu in IntelliJ, then "Edit Configuration templates", then
+ // then "JUnit", and set them in "Environment variables"
+ //
+ List requiredEnvVars = List.of("EP_GATEWAY_MSGVPN", "EP_GATEWAY_PASSWORD", "EP_GATEWAY_URL", "EP_GATEWAY_USERNAME",
+ "EP_ORGANIZATION_ID", "EP_RUNTIME_AGENT_ID", "OLD_SOLACE_SEMP_PASSWORD", "OLD_SOLACE_SEMP_URL", "OLD_SOLACE_SEMP_USERNAME",
+ "SOLACE_SEMP_PASSWORD", "SOLACE_SEMP_URL", "SOLACE_SEMP_USERNAME");
+ List actualEnvVars = List.copyOf(System.getenv().keySet());
+ if (!actualEnvVars.containsAll(requiredEnvVars)) {
+ throw new RuntimeException("Missing required environment variables: " + requiredEnvVars);
+ }
+
+ // On the valid Solace broker, create a read-only user with username "admin2" and password the same as the "SOLACE_SEMP_PASSWORD" environment variable
+ // This is required for the "createQueueReadOnlyUserTest" test
+ log.info("Creating user admin2 with R/O privileges");
+ HttpClient httpClient = HttpClient.newBuilder()
+ .version(HttpClient.Version.HTTP_1_1)
+ .build();
+ HttpRequest request = HttpRequest.newBuilder()
+ .POST(HttpRequest.BodyPublishers.ofString("{\"globalAccessLevel\":\"read-only\",\"msgVpnDefaultAccessLevel\":\"none\",\"password\":\"" +
+ System.getenv("SOLACE_SEMP_PASSWORD") + "\",\"userName\":\"admin2\"}"))
+ .setHeader("Accept", "application/json")
+ .setHeader("Content-Type", "application/json")
+ .setHeader("Authorization", getBasicAuthenticationHeader(System.getenv("SOLACE_SEMP_USERNAME"),
+ System.getenv("SOLACE_SEMP_PASSWORD")))
+ .uri(java.net.URI.create(System.getenv("SOLACE_SEMP_URL") + "/SEMP/v2/__private_config__/usernames"))
+ .build();
+ httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+ }
+
+ private static String getBasicAuthenticationHeader(String username, String password) {
+ String valueToEncode = username + ":" + password;
+ return "Basic " + Base64.getEncoder().encodeToString(valueToEncode.getBytes());
+ }
+
+
+ @BeforeEach
+ private void beforeEach() {
+ startTime = System.currentTimeMillis();
+ }
+
+ @Test
+ public void createQueuePositiveTest() {
+ String correlationId = "myCorrelationId";
+ CommandMessage commandResponse = runTest("addQueue.tf", mainServiceId, correlationId, context);
+ validateSuccessCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void deleteQueuePositiveTest() {
+ String correlationId = "myCorrelationId2";
+ CommandMessage commandResponse = runTest("deleteQueue.tf", mainServiceId, correlationId, context);
+ validateSuccessCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void createQueueBadHostTest() {
+ testOutputMdTitle2(getTestMethodName());
+ String correlationId = "myCorrelationId2";
+ CommandMessage commandResponse = runTest("addQueueBadHost.tf", mainServiceId, correlationId, context);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void createQueueBadPortTest() {
+ testOutputMdTitle2(getTestMethodName());
+
+ String correlationId = "myCorrelationId2";
+ CommandMessage commandResponse = runTest("addQueueBadPort.tf", mainServiceId, correlationId, context);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void createQueueBadCredentialsTest() {
+ testOutputMdTitle2(getTestMethodName());
+
+ String correlationId = "myCorrelationId2";
+ CommandMessage commandResponse = runTest("addQueueBadCredentials.tf", mainServiceId, correlationId, context);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ // Required to add new user admin2 with R/O privileges
+ @Test
+ public void createQueueReadOnlyUserTest() {
+ testOutputMdTitle2(getTestMethodName());
+ String correlationId = "myCorrelationId1";
+ CommandMessage commandResponse = runTest("AddQueueReadOnlyUser.tf", mainServiceId, correlationId, context);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void createQueueSempFailureTest() {
+ testOutputMdTitle2(getTestMethodName());
+
+ // First create the queue
+ String correlationId = "myCorrelationId";
+ CommandMessage commandResponse = runTest("addQueue.tf", mainServiceId, correlationId, context);
+ validateSuccessCommandResponse(commandResponse);
+
+ // Delete the terraform state file
+ Path terraformStatePath = Paths.get(terraformProperties.getWorkingDirectoryRoot(),
+ context + "-" + mainServiceId, "terraform.tfstate");
+ try {
+ Files.delete(terraformStatePath);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ // Now try to create the queue again
+ correlationId = "myCorrelationId2";
+ commandResponse = runTest("addQueue.tf", mainServiceId, correlationId, context);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void badBlockHclFailureTest() {
+ testOutputMdTitle2(getTestMethodName());
+
+ String correlationId = "myCorrelationId3";
+ CommandMessage commandResponse = runTest("badBlockHcl.tf", mainServiceId, correlationId, context);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void badFormatHclFailureTest() {
+ testOutputMdTitle2(getTestMethodName());
+
+ String correlationId = "myCorrelationId3";
+ CommandMessage commandResponse = runTest("badFormatHcl.tf", mainServiceId, correlationId, context);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void unknownTerraformCommandError() {
+ testOutputMdTitle2(getTestMethodName());
+
+ String correlationId = "myCorrelationId3";
+ CommandMessage commandResponse = runTest("addQueue.tf", mainServiceId, correlationId, context, this::createCommandMessageBadTerraformCommand);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void sempVersionTooOldTest() {
+ testOutputMdTitle2(getTestMethodName());
+
+ String correlationId = "myCorrelationId3";
+ String oldServiceId = "v0r806w0bmj";
+ CommandMessage commandResponse = runTest("addQueue.tf", oldServiceId, correlationId, context);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void badProviderTest() {
+ testOutputMdTitle2(getTestMethodName());
+
+ String correlationId = "myCorrelationId3";
+ CommandMessage commandResponse = runTest("badProvider.tf", mainServiceId, correlationId, context);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void badMessagingServiceIdTest() {
+ testOutputMdTitle2(getTestMethodName());
+
+ String correlationId = "myCorrelationId1";
+ CommandMessage commandResponse = runTest("addQueue.tf", "imABadServiceId", correlationId, context);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void badCommandTypeInCommand() {
+ testOutputMdTitle2(getTestMethodName());
+
+ String correlationId = "myCorrelationId3";
+ CommandMessage commandResponse = runTest("addQueue.tf", mainServiceId, correlationId, context, this::createCommandMessageBadCommandType);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+
+ @Test
+ public void missingParametersInCommand() {
+ testOutputMdTitle2(getTestMethodName());
+
+ String correlationId = "myCorrelationId3";
+ CommandMessage commandResponse = runTest("addQueue.tf", mainServiceId, correlationId, context, this::createCommandMessageMissingParameters);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void hclCommandIsNotBase64Encoded() {
+ testOutputMdTitle2(getTestMethodName());
+
+ String correlationId = "myCorrelationId3";
+ CommandMessage commandResponse = runTest("addQueue.tf", mainServiceId, correlationId, context, this::createCommandMessageHclNotBase64Encoded);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void hclHasVariableThatIsNotSetInTerraformPlugin() {
+ testOutputMdTitle2(getTestMethodName());
+
+ String correlationId = "myCorrelationId1";
+ CommandMessage commandResponse = runTest("addQueueNewVariableNotInPlugin.tf", mainServiceId, correlationId, context);
+ validateErrorCommandResponse(commandResponse);
+ }
+
+ @Test
+ public void manyRequestsForTheSameContextAtTheSameTime() {
+
+ String newQueueTf = asString(resourceLoader.getResource("classpath:hcl" + File.separator + "addQueue.tf"));
+ String newQueueTfBase64 = Base64.getEncoder().encodeToString(newQueueTf.getBytes(UTF_8));
+
+ int numberOfMessagesToSend = 10;
+
+ AtomicBoolean keepRunning = new AtomicBoolean(true);
+ List commandResponseList = new CopyOnWriteArrayList<>();
+ setupMessageReceiver(commandResponseList, keepRunning, this::handleCommandResponseMessage, numberOfMessagesToSend);
+
+ for (int i = 0; i < numberOfMessagesToSend; i++) {
+ log.debug("Sending command " + i);
+ String correlationId = "myCorrelationId" + i;
+ CommandMessage message = createCommandMessageCommand(mainServiceId, correlationId, context, newQueueTfBase64);
+ solacePublisher.publish(message,
+ "sc/ep/runtime/" + eventPortalProperties.getOrganizationId() + "/" +
+ eventPortalProperties.getRuntimeAgentId() + "/command/v1/" +
+ correlationId);
+ }
+
+ waitForReceivedMessages(keepRunning);
+
+ commandResponseList.forEach(this::validateSuccessCommandResponse);
+ }
+
+ private CommandMessage runTest(String hclFileName, String serviceId, String correlationId, String context) {
+ return runTest(hclFileName, serviceId, correlationId, context, this::createCommandMessageCommand);
+ }
+
+ private CommandMessage runTest(String hclFileName, String serviceId, String correlationId, String context,
+ Function4ArityWithReturn createCommandMessage) {
+
+ String newQueueTf = asString(resourceLoader.getResource("classpath:hcl" + File.separator + hclFileName));
+ String newQueueTfBase64 = Base64.getEncoder().encodeToString(newQueueTf.getBytes(UTF_8));
+
+ CommandMessage message = createCommandMessage.apply(serviceId, correlationId, context, newQueueTfBase64);
+
+ AtomicBoolean keepRunning = new AtomicBoolean(true);
+ List commandResponseList = new CopyOnWriteArrayList<>();
+ setupMessageReceiver(commandResponseList, keepRunning, this::handleCommandResponseMessage, 1);
+
+ log.debug("Sending command");
+ solacePublisher.publish(message,
+ "sc/ep/runtime/" + eventPortalProperties.getOrganizationId() + "/" +
+ eventPortalProperties.getRuntimeAgentId() + "/command/v1/" +
+ correlationId);
+
+ waitForReceivedMessages(keepRunning);
+
+ return commandResponseList.get(0);
+ }
+
+ private static void waitForReceivedMessages(AtomicBoolean keepRunning) {
+ while (keepRunning.get()) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private void setupMessageReceiver(List commandMessageList, AtomicBoolean keepRunning,
+ Function5ArityVoidReturn, AtomicBoolean, InboundMessage, Integer, AtomicInteger> messageHandler,
+ int numberOfExpectedMessages) {
+ log.debug("TEST: Starting receiver");
+ AtomicInteger numberOfMessagesReceived = new AtomicInteger(0);
+ DirectMessageReceiver directMessageReceiver = messagingService
+ .createDirectMessageReceiverBuilder()
+ .withSubscriptions(TopicSubscription.of("sc/ep/runtime/" +
+ eventPortalProperties.getOrganizationId() + "/" +
+ eventPortalProperties.getRuntimeAgentId() +
+ "/commandResponse/v1/>"))
+ .build()
+ .start();
+
+ directMessageReceiver.receiveAsync(inboundMessage ->
+ messageHandler.apply(commandMessageList, keepRunning, inboundMessage, numberOfExpectedMessages, numberOfMessagesReceived));
+ }
+
+ private void handleCommandResponseMessage(List commandResponseList, AtomicBoolean keepRunning,
+ InboundMessage inboundMessage, int numberOfExpectedMessages, AtomicInteger numberOfMessagesReceived) {
+ String messageAsString = inboundMessage.getPayloadAsString();
+ try {
+ CommandMessage receivedCommandMessage = objectMapper.readValue(messageAsString, CommandMessage.class);
+ log.debug("TEST: Received command response");
+ commandResponseList.add(receivedCommandMessage);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ } finally {
+ numberOfMessagesReceived.getAndIncrement();
+ if (numberOfMessagesReceived.get() >= numberOfExpectedMessages) {
+ keepRunning.set(false);
+ }
+ }
+ }
+
+ private void validateSuccessCommandResponse(CommandMessage commandResponse) {
+ List results = commandResponse.getCommandBundles().stream()
+ .map(commandBundle ->
+ commandBundle.getCommands().stream()
+ .map(command -> command.getResult().getStatus())
+ .toList())
+ .flatMap(List::stream)
+ .toList();
+ results.forEach(result -> {
+ if (result != JobStatus.success) {
+ throw new RuntimeException("JobStatus was not success");
+ }
+ });
+ }
+
+ private void validateErrorCommandResponse(CommandMessage commandResponse) {
+ List results = commandResponse.getCommandBundles().stream()
+ .map(commandBundle ->
+ commandBundle.getCommands().stream()
+ .map(command -> command.getResult().getStatus())
+ .toList())
+ .flatMap(List::stream)
+ .toList();
+ results.forEach(result -> {
+ if (result != JobStatus.error) {
+ throw new RuntimeException("JobStatus was not success");
+ }
+ });
+ log.debug("Received expected error response");
+ testOutput("\nTEST OUTPUT:");
+ testOutputMDCodeBlock();
+ commandResponse.getCommandBundles().get(0).getCommands().get(0).getResult().getLogs()
+ .forEach(tflog -> {
+ testOutput(tflog.toString());
+ });
+ testOutputMDCodeBlock();
+ testOutput("Elapsed time (seconds): " + (System.currentTimeMillis() - startTime) / 1000);
+ }
+
+ private void setMessageParams(String serviceId, String correlationId, String context, CommandMessage message) {
+ message.withMessageType(generic);
+ message.setMopVer("1");
+ message.setMopProtocol(epConfigPush);
+ message.setMopMsgType(generic);
+ message.setMsgPriority(4);
+ message.setMsgUh(MOPUHFlag.ignore);
+ message.setContext(context);
+ message.setActorId("myActorId");
+ message.setOrgId(eventPortalProperties.getOrganizationId());
+ message.setTraceId("myTraceId");
+ message.setServiceId(serviceId);
+ message.setCorrelationId(correlationId);
+ }
+
+
+ public static String asString(Resource resource) {
+ try (Reader reader = new InputStreamReader(resource.getInputStream(), UTF_8)) {
+ return FileCopyUtils.copyToString(reader);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ private CommandMessage createCommandMessageMissingParameters(String serviceId, String correlationId, String context,
+ String newQueueTfBase64) {
+ CommandMessage commandMessage = createCommandMessageCommand(serviceId, correlationId, context, newQueueTfBase64);
+ Command command = commandMessage.getCommandBundles().get(0).getCommands().get(0);
+ command.setParameters(Map.of());
+ return commandMessage;
+ }
+
+ private CommandMessage createCommandMessageBadTerraformCommand(String serviceId, String correlationId, String context,
+ String newQueueTfBase64) {
+ CommandMessage commandMessage = createCommandMessageCommand(serviceId, correlationId, context, newQueueTfBase64);
+ Command command = commandMessage.getCommandBundles().get(0).getCommands().get(0);
+ command.setCommand("badCommand");
+ return commandMessage;
+ }
+
+ private CommandMessage createCommandMessageHclNotBase64Encoded(String serviceId, String correlationId, String context,
+ String newQueueTfBase64) {
+ CommandMessage commandMessage = createCommandMessageCommand(serviceId, correlationId, context, newQueueTfBase64);
+ Command command = commandMessage.getCommandBundles().get(0).getCommands().get(0);
+ command.setBody("IHaveABadBody");
+ return commandMessage;
+ }
+
+ private CommandMessage createCommandMessageBadCommandType(String serviceId, String correlationId, String context,
+ String newQueueTfBase64) {
+ CommandMessage message = new CommandMessage();
+ setMessageParams(serviceId, correlationId, context, message);
+
+ BadCommand badCommand = new BadCommand();
+ badCommand.setCommandType(CommandTypeBad.badEnum);
+ badCommand.setBody(newQueueTfBase64);
+ badCommand.setParameters(Map.of(
+ "Content-Type", "application/hcl",
+ "Content-Encoding", "base64"));
+ badCommand.setCommand("apply");
+
+ message.setCommandBundles(List.of(CommandBundle.builder()
+ .executionType(ExecutionType.serial)
+ .exitOnFailure(true)
+ .commands(
+ List.of(badCommand))
+ .build()));
+ return message;
+ }
+
+ private CommandMessage createCommandMessageCommand(String serviceId, String correlationId, String context,
+ String newQueueTfBase64) {
+ CommandMessage message = new CommandMessage();
+ setMessageParams(serviceId, correlationId, context, message);
+ message.setCommandBundles(List.of(CommandBundle.builder()
+ .executionType(ExecutionType.serial)
+ .exitOnFailure(true)
+ .commands(
+ List.of(Command.builder()
+ .commandType(CommandType.terraform)
+ .body(newQueueTfBase64)
+ .parameters(Map.of(
+ "Content-Type", "application/hcl",
+ "Content-Encoding", "base64"))
+ .command("apply")
+ .build()))
+ .build()));
+ return message;
+ }
+
+ @FunctionalInterface
+ public interface Function5ArityVoidReturn {
+ void apply(A a, B b, C c, D d, E e);
+ }
+
+ @FunctionalInterface
+ public interface Function4ArityWithReturn {
+ R apply(A a, B b, C c, D d);
+ }
+
+ private void testOutput(String logMessage) {
+ log.info(logMessage);
+ }
+
+ private void testOutputMdTitle2(String logMessage) {
+ log.info("\n## " + logMessage);
+ }
+
+ private void testOutputMDCodeBlock() {
+ log.info("```");
+ }
+
+ private String getTestMethodName() {
+ final StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
+ return stackTraceElements[2].getMethodName();
+ }
+}
diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/realTests/OfflineRealTest.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/realTests/OfflineRealTest.java
new file mode 100644
index 000000000..dbcb60cd1
--- /dev/null
+++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/realTests/OfflineRealTest.java
@@ -0,0 +1,27 @@
+package com.solace.maas.ep.event.management.agent.realTests;
+
+import com.solace.maas.ep.event.management.agent.config.eventPortal.EventPortalProperties;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+
+import static org.junit.Assert.assertTrue;
+
+@Slf4j
+@ActiveProfiles("offlinetests")
+@EnableAutoConfiguration
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class OfflineRealTest {
+
+ @Autowired
+ private EventPortalProperties eventPortalProperties;
+
+ @Test
+ public void applicationStartsInOfflineMode() {
+ assertTrue(eventPortalProperties.getGateway().getMessaging().isStandalone());
+ }
+
+}
\ No newline at end of file
diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/realTests/badClasses/BadCommand.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/realTests/badClasses/BadCommand.java
new file mode 100644
index 000000000..632d7880b
--- /dev/null
+++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/realTests/badClasses/BadCommand.java
@@ -0,0 +1,12 @@
+package com.solace.maas.ep.event.management.agent.realTests.badClasses;
+
+import com.solace.maas.ep.event.management.agent.plugin.command.model.Command;
+
+@SuppressWarnings("PMD")
+public class BadCommand extends Command {
+ private CommandTypeBad commandType;
+
+ public void setCommandType(CommandTypeBad commandType) {
+ this.commandType = commandType;
+ }
+}
diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/realTests/badClasses/CommandTypeBad.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/realTests/badClasses/CommandTypeBad.java
new file mode 100644
index 000000000..d6d816135
--- /dev/null
+++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/realTests/badClasses/CommandTypeBad.java
@@ -0,0 +1,7 @@
+package com.solace.maas.ep.event.management.agent.realTests.badClasses;
+
+public enum CommandTypeBad {
+ terraform,
+ badEnum
+}
+
diff --git a/service/application/src/test/resources/application-negativetests.yml b/service/application/src/test/resources/application-negativetests.yml
new file mode 100644
index 000000000..3985aa8f8
--- /dev/null
+++ b/service/application/src/test/resources/application-negativetests.yml
@@ -0,0 +1,130 @@
+springdoc:
+ packages-to-scan: com.solace.maas.ep.event.management.agent.scanManager.rest
+ api-docs:
+ path: /docs/event-management-agent
+ swagger-ui:
+ path: /event-management-agent/swagger-ui.html
+server:
+ port: 8180
+spring:
+ main:
+ allow-bean-definition-overriding: true
+ servlet:
+ multipart:
+ max-request-size: ${MAX_REQUEST_SIZE:5MB}
+ max-file-size: ${MAX_FILE_SIZE:5MB}
+ jpa:
+ database-platform: org.hibernate.dialect.H2Dialect
+ hibernate:
+ ddl-auto: create-drop
+ defer-datasource-initialization: true
+ datasource:
+ url: jdbc:h2:file:./data/cache;DB_CLOSE_ON_EXIT=FALSE
+ username: sa
+ driver-class-name: org.h2.Driver
+ password: password
+ h2:
+ console:
+ settings:
+ web-allow-others: true
+ enabled: true
+ path: /h2
+camel:
+ springboot:
+ use-mdc-logging: true
+kafka:
+ client:
+ config:
+ reconnections:
+ max-backoff:
+ unit: milliseconds
+ value: 1000
+ backoff:
+ unit: milliseconds
+ value: 50
+ connections:
+ max-idle:
+ unit: milliseconds
+ value: 10000
+ request-timeout:
+ unit: milliseconds
+ value: 5000
+ timeout:
+ unit: milliseconds
+ value: 60000
+eventPortal:
+ topicPrefix: ${EP_TOPIC_PREFIX:sc/ep/runtime}
+ runtimeAgentId: ${EP_RUNTIME_AGENT_ID}
+ organizationId: ${EP_ORGANIZATION_ID}
+ gateway:
+ id: 1n257sln2bl
+ name: the ep vmr
+ messaging:
+ standalone: false
+ rtoSession: false
+ enableHeartbeats: true
+ testHeartbeats: true
+ connections:
+ - name: eventPortalGateway
+ authenticationType: ${EP_GATEWAY_AUTH:basicAuthentication}
+ msgVpn: ${EP_GATEWAY_MSGVPN}
+ url: ${EP_GATEWAY_URL}
+ users:
+ - clientName: client_7zu3ng4ed37
+ username: ${EP_GATEWAY_USERNAME}
+ password: ${EP_GATEWAY_PASSWORD}
+ name: messaging1
+plugins:
+ resources:
+ - id: 49a23700m80
+ type: solace
+ name: demo2
+ connections:
+ - name: demo2
+ url: ${SOLACE_SEMP_URL}
+ properties:
+ - name: msgVpn
+ value: default
+ - name: sempPageSize
+ value: 100
+ authentication:
+ - properties:
+ - name: type
+ value: basicAuthentication
+ protocol: semp
+ credentials:
+ - properties:
+ - name: username
+ value: ${SOLACE_SEMP_USERNAME}
+ - name: password
+ value: ${SOLACE_SEMP_PASSWORD}
+ source: ENVIRONMENT_VARIABLE
+ operations:
+ - name: ALL
+ - id: v0r806w0bmj
+ type: solace
+ name: gregSolaceService
+ connections:
+ - name: gregSolaceService
+ url: ${OLD_SOLACE_SEMP_URL}
+ properties:
+ - name: msgVpn
+ value: default
+ - name: sempPageSize
+ value: 100
+ authentication:
+ - properties:
+ - name: type
+ value: basicAuthentication
+ protocol: semp
+ credentials:
+ - properties:
+ - name: username
+ value: ${OLD_SOLACE_SEMP_USERNAME}
+ - name: password
+ value: ${OLD_SOLACE_SEMP_PASSWORD}
+ source: ENVIRONMENT_VARIABLE
+ operations:
+ - name: ALL
+logging:
+ config: "classpath:logback-spring-negativetests.xml"
diff --git a/service/application/src/test/resources/application-offlinetests.yml b/service/application/src/test/resources/application-offlinetests.yml
new file mode 100644
index 000000000..a2f72a7d2
--- /dev/null
+++ b/service/application/src/test/resources/application-offlinetests.yml
@@ -0,0 +1,130 @@
+springdoc:
+ packages-to-scan: com.solace.maas.ep.event.management.agent.scanManager.rest
+ api-docs:
+ path: /docs/event-management-agent
+ swagger-ui:
+ path: /event-management-agent/swagger-ui.html
+server:
+ port: 8180
+spring:
+ main:
+ allow-bean-definition-overriding: true
+ servlet:
+ multipart:
+ max-request-size: ${MAX_REQUEST_SIZE:5MB}
+ max-file-size: ${MAX_FILE_SIZE:5MB}
+ jpa:
+ database-platform: org.hibernate.dialect.H2Dialect
+ hibernate:
+ ddl-auto: create-drop
+ defer-datasource-initialization: true
+ datasource:
+ url: jdbc:h2:file:./data/cache;DB_CLOSE_ON_EXIT=FALSE
+ username: sa
+ driver-class-name: org.h2.Driver
+ password: password
+ h2:
+ console:
+ settings:
+ web-allow-others: true
+ enabled: true
+ path: /h2
+camel:
+ springboot:
+ use-mdc-logging: true
+kafka:
+ client:
+ config:
+ reconnections:
+ max-backoff:
+ unit: milliseconds
+ value: 1000
+ backoff:
+ unit: milliseconds
+ value: 50
+ connections:
+ max-idle:
+ unit: milliseconds
+ value: 10000
+ request-timeout:
+ unit: milliseconds
+ value: 5000
+ timeout:
+ unit: milliseconds
+ value: 60000
+eventPortal:
+ topicPrefix: ${EP_TOPIC_PREFIX:sc/ep/runtime}
+ runtimeAgentId: ${EP_RUNTIME_AGENT_ID}
+ organizationId: ${EP_ORGANIZATION_ID}
+ gateway:
+ id: 1n257sln2bl
+ name: the ep vmr
+ messaging:
+ standalone: true
+ rtoSession: false
+ enableHeartbeats: true
+ testHeartbeats: true
+ connections:
+ - name: eventPortalGateway
+ authenticationType: ${EP_GATEWAY_AUTH:basicAuthentication}
+ msgVpn: ${EP_GATEWAY_MSGVPN}
+ url: ${EP_GATEWAY_URL}
+ users:
+ - clientName: client_7zu3ng4ed37
+ username: ${EP_GATEWAY_USERNAME}
+ password: ${EP_GATEWAY_PASSWORD}
+ name: messaging1
+plugins:
+ resources:
+ - id: 49a23700m80
+ type: solace
+ name: demo2
+ connections:
+ - name: demo2
+ url: ${SOLACE_SEMP_URL}
+ properties:
+ - name: msgVpn
+ value: default
+ - name: sempPageSize
+ value: 100
+ authentication:
+ - properties:
+ - name: type
+ value: basicAuthentication
+ protocol: semp
+ credentials:
+ - properties:
+ - name: username
+ value: ${SOLACE_SEMP_USERNAME}
+ - name: password
+ value: ${SOLACE_SEMP_PASSWORD}
+ source: ENVIRONMENT_VARIABLE
+ operations:
+ - name: ALL
+ - id: v0r806w0bmj
+ type: solace
+ name: gregSolaceService
+ connections:
+ - name: gregSolaceService
+ url: ${OLD_SOLACE_SEMP_URL}
+ properties:
+ - name: msgVpn
+ value: default
+ - name: sempPageSize
+ value: 100
+ authentication:
+ - properties:
+ - name: type
+ value: basicAuthentication
+ protocol: semp
+ credentials:
+ - properties:
+ - name: username
+ value: ${OLD_SOLACE_SEMP_USERNAME}
+ - name: password
+ value: ${OLD_SOLACE_SEMP_PASSWORD}
+ source: ENVIRONMENT_VARIABLE
+ operations:
+ - name: ALL
+logging:
+ config: "classpath:logback-spring-offlinetests.xml"
\ No newline at end of file
diff --git a/service/application/src/test/resources/hcl/AddQueueReadOnlyUser.tf b/service/application/src/test/resources/hcl/AddQueueReadOnlyUser.tf
new file mode 100644
index 000000000..086fefc62
--- /dev/null
+++ b/service/application/src/test/resources/hcl/AddQueueReadOnlyUser.tf
@@ -0,0 +1,102 @@
+terraform {
+ required_providers {
+ solacebroker = {
+ source = "registry.terraform.io/solaceproducts/solacebroker"
+ }
+ }
+}
+
+provider "solacebroker" {
+ alias = "fh71c08said"
+ username = "admin2"
+ password = "${var.password}"
+ url = "${var.url}"
+}
+
+data "solacebroker_msg_vpn" "fh71c08said" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = "default"
+}
+
+resource "solacebroker_msg_vpn_queue" "fh71c08said-Consumer2" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = data.solacebroker_msg_vpn.fh71c08said.msg_vpn_name
+ owner = "discovery"
+ max_ttl = 0
+ queue_name = "Consumer2"
+ access_type = "exclusive"
+ max_msg_size = 10000000
+ permission = "consume"
+ dead_msg_queue = "#DEAD_MSG_QUEUE"
+ max_bind_count = 1000
+ delivery_delay = 0
+ egress_enabled = true
+ ingress_enabled = true
+ max_msg_spool_usage = 5000
+ redelivery_enabled = true
+ respect_ttl_enabled = false
+ max_redelivery_count = 0
+ delivery_count_enabled = false
+ event_bind_count_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+ reject_low_priority_msg_limit = 0
+ respect_msg_priority_enabled = false
+ event_msg_spool_usage_threshold = { "setPercent" : 25, "clearPercent" : 18 }
+ reject_low_priority_msg_enabled = false
+ consumer_ack_propagation_enabled = true
+ max_delivered_unacked_msgs_per_flow = 10000
+ reject_msg_to_sender_on_discard_behavior = "when-queue-enabled"
+ event_reject_low_priority_msg_limit_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+}
+
+resource "solacebroker_msg_vpn_queue_subscription" "fh71c08said-Consumer2_a_b_c__" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer2.msg_vpn_name
+ queue_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer2.queue_name
+ subscription_topic = "a/b/c/>"
+}
+
+resource "solacebroker_msg_vpn_queue" "fh71c08said-Consumer1" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = data.solacebroker_msg_vpn.fh71c08said.msg_vpn_name
+ owner = "discovery"
+ max_ttl = 0
+ queue_name = "Consumer2"
+ access_type = "exclusive"
+ max_msg_size = 10000000
+ permission = "consume"
+ dead_msg_queue = "#DEAD_MSG_QUEUE"
+ max_bind_count = 1000
+ delivery_delay = 0
+ egress_enabled = true
+ ingress_enabled = true
+ max_msg_spool_usage = 5000
+ redelivery_enabled = true
+ respect_ttl_enabled = false
+ max_redelivery_count = 0
+ delivery_count_enabled = false
+ event_bind_count_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+ reject_low_priority_msg_limit = 0
+ respect_msg_priority_enabled = false
+ event_msg_spool_usage_threshold = { "setPercent" : 25, "clearPercent" : 18 }
+ reject_low_priority_msg_enabled = false
+ consumer_ack_propagation_enabled = true
+ max_delivered_unacked_msgs_per_flow = 10000
+ reject_msg_to_sender_on_discard_behavior = "when-queue-enabled"
+ event_reject_low_priority_msg_limit_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+}
+
+resource "solacebroker_msg_vpn_queue_subscription" "fh71c08said-Consumer1_a_b_c__" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.msg_vpn_name
+ queue_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.queue_name
+ subscription_topic = "a/b/c/>"
+}
+
+variable username {
+}
+
+variable password {
+}
+
+variable url {
+}
\ No newline at end of file
diff --git a/service/application/src/test/resources/hcl/addQueue.tf b/service/application/src/test/resources/hcl/addQueue.tf
new file mode 100644
index 000000000..641ae0266
--- /dev/null
+++ b/service/application/src/test/resources/hcl/addQueue.tf
@@ -0,0 +1,65 @@
+terraform {
+ required_providers {
+ solacebroker = {
+ source = "registry.terraform.io/solaceproducts/solacebroker"
+ }
+ }
+}
+
+provider "solacebroker" {
+ alias = "fh71c08said"
+ username = "${var.username}"
+ password = "${var.password}"
+ url = "${var.url}"
+}
+
+data "solacebroker_msg_vpn" "fh71c08said" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = "default"
+}
+
+resource "solacebroker_msg_vpn_queue" "fh71c08said-Consumer1" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = data.solacebroker_msg_vpn.fh71c08said.msg_vpn_name
+ owner = "discovery"
+ max_ttl = 0
+ queue_name = "Consumer1"
+ access_type = "exclusive"
+ max_msg_size = 10000000
+ permission = "consume"
+ dead_msg_queue = "#DEAD_MSG_QUEUE"
+ max_bind_count = 1000
+ delivery_delay = 0
+ egress_enabled = true
+ ingress_enabled = true
+ max_msg_spool_usage = 5000
+ redelivery_enabled = true
+ respect_ttl_enabled = false
+ max_redelivery_count = 0
+ delivery_count_enabled = false
+ event_bind_count_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+ reject_low_priority_msg_limit = 0
+ respect_msg_priority_enabled = false
+ event_msg_spool_usage_threshold = { "setPercent" : 25, "clearPercent" : 18 }
+ reject_low_priority_msg_enabled = false
+ consumer_ack_propagation_enabled = true
+ max_delivered_unacked_msgs_per_flow = 10000
+ reject_msg_to_sender_on_discard_behavior = "when-queue-enabled"
+ event_reject_low_priority_msg_limit_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+}
+
+resource "solacebroker_msg_vpn_queue_subscription" "fh71c08said-Consumer1_a_b_c__" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.msg_vpn_name
+ queue_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.queue_name
+ subscription_topic = "a/b/c/>"
+}
+
+variable username {
+}
+
+variable password {
+}
+
+variable url {
+}
\ No newline at end of file
diff --git a/service/application/src/test/resources/hcl/addQueue2.tf b/service/application/src/test/resources/hcl/addQueue2.tf
new file mode 100644
index 000000000..0371cd991
--- /dev/null
+++ b/service/application/src/test/resources/hcl/addQueue2.tf
@@ -0,0 +1,65 @@
+terraform {
+ required_providers {
+ solacebroker = {
+ source = "registry.terraform.io/solaceproducts/solacebroker"
+ }
+ }
+}
+
+provider "solacebroker" {
+ alias = "fh71c08saie"
+ username = "${var.username}"
+ password = "${var.password}"
+ url = "${var.url}"
+}
+
+data "solacebroker_msg_vpn" "fh71c08saie" {
+ provider = solacebroker.fh71c08saie
+ msg_vpn_name = "default"
+}
+
+resource "solacebroker_msg_vpn_queue" "fh71c08saie-Consumer2" {
+ provider = solacebroker.fh71c08saie
+ msg_vpn_name = data.solacebroker_msg_vpn.fh71c08saie.msg_vpn_name
+ owner = "discovery"
+ max_ttl = 0
+ queue_name = "Consumer2"
+ access_type = "exclusive"
+ max_msg_size = 10000000
+ permission = "consume"
+ dead_msg_queue = "#DEAD_MSG_QUEUE"
+ max_bind_count = 1000
+ delivery_delay = 0
+ egress_enabled = true
+ ingress_enabled = true
+ max_msg_spool_usage = 5000
+ redelivery_enabled = true
+ respect_ttl_enabled = false
+ max_redelivery_count = 0
+ delivery_count_enabled = false
+ event_bind_count_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+ reject_low_priority_msg_limit = 0
+ respect_msg_priority_enabled = false
+ event_msg_spool_usage_threshold = { "setPercent" : 25, "clearPercent" : 18 }
+ reject_low_priority_msg_enabled = false
+ consumer_ack_propagation_enabled = true
+ max_delivered_unacked_msgs_per_flow = 10000
+ reject_msg_to_sender_on_discard_behavior = "when-queue-enabled"
+ event_reject_low_priority_msg_limit_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+}
+
+resource "solacebroker_msg_vpn_queue_subscription" "fh71c08saie-Consumer2_a_b_c__" {
+ provider = solacebroker.fh71c08saie
+ msg_vpn_name = solacebroker_msg_vpn_queue.fh71c08saie-Consumer2.msg_vpn_name
+ queue_name = solacebroker_msg_vpn_queue.fh71c08saie-Consumer2.queue_name
+ subscription_topic = "a/b/c/>"
+}
+
+variable username {
+}
+
+variable password {
+}
+
+variable url {
+}
\ No newline at end of file
diff --git a/service/application/src/test/resources/hcl/addQueueBadCredentials.tf b/service/application/src/test/resources/hcl/addQueueBadCredentials.tf
new file mode 100644
index 000000000..b8a1f8dfa
--- /dev/null
+++ b/service/application/src/test/resources/hcl/addQueueBadCredentials.tf
@@ -0,0 +1,65 @@
+terraform {
+ required_providers {
+ solacebroker = {
+ source = "registry.terraform.io/solaceproducts/solacebroker"
+ }
+ }
+}
+
+provider "solacebroker" {
+ alias = "fh71c08said"
+ username = "${var.username}"
+ password = "badpassword"
+ url = "${var.url}"
+}
+
+data "solacebroker_msg_vpn" "fh71c08said" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = "default"
+}
+
+resource "solacebroker_msg_vpn_queue" "fh71c08said-Consumer1" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = data.solacebroker_msg_vpn.fh71c08said.msg_vpn_name
+ owner = "discovery"
+ max_ttl = 0
+ queue_name = "Consumer1"
+ access_type = "exclusive"
+ max_msg_size = 10000000
+ permission = "consume"
+ dead_msg_queue = "#DEAD_MSG_QUEUE"
+ max_bind_count = 1000
+ delivery_delay = 0
+ egress_enabled = true
+ ingress_enabled = true
+ max_msg_spool_usage = 5000
+ redelivery_enabled = true
+ respect_ttl_enabled = false
+ max_redelivery_count = 0
+ delivery_count_enabled = false
+ event_bind_count_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+ reject_low_priority_msg_limit = 0
+ respect_msg_priority_enabled = false
+ event_msg_spool_usage_threshold = { "setPercent" : 25, "clearPercent" : 18 }
+ reject_low_priority_msg_enabled = false
+ consumer_ack_propagation_enabled = true
+ max_delivered_unacked_msgs_per_flow = 10000
+ reject_msg_to_sender_on_discard_behavior = "when-queue-enabled"
+ event_reject_low_priority_msg_limit_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+}
+
+resource "solacebroker_msg_vpn_queue_subscription" "fh71c08said-Consumer1_a_b_c__" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.msg_vpn_name
+ queue_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.queue_name
+ subscription_topic = "a/b/c/>"
+}
+
+variable username {
+}
+
+variable password {
+}
+
+variable url {
+}
\ No newline at end of file
diff --git a/service/application/src/test/resources/hcl/addQueueBadHost.tf b/service/application/src/test/resources/hcl/addQueueBadHost.tf
new file mode 100644
index 000000000..a6f657a8b
--- /dev/null
+++ b/service/application/src/test/resources/hcl/addQueueBadHost.tf
@@ -0,0 +1,65 @@
+terraform {
+ required_providers {
+ solacebroker = {
+ source = "registry.terraform.io/solaceproducts/solacebroker"
+ }
+ }
+}
+
+provider "solacebroker" {
+ alias = "fh71c08said"
+ username = "${var.username}"
+ password = "${var.password}"
+ url = "http://badurl:43434"
+}
+
+data "solacebroker_msg_vpn" "fh71c08said" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = "default"
+}
+
+resource "solacebroker_msg_vpn_queue" "fh71c08said-Consumer1" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = data.solacebroker_msg_vpn.fh71c08said.msg_vpn_name
+ owner = "discovery"
+ max_ttl = 0
+ queue_name = "Consumer1"
+ access_type = "exclusive"
+ max_msg_size = 10000000
+ permission = "consume"
+ dead_msg_queue = "#DEAD_MSG_QUEUE"
+ max_bind_count = 1000
+ delivery_delay = 0
+ egress_enabled = true
+ ingress_enabled = true
+ max_msg_spool_usage = 5000
+ redelivery_enabled = true
+ respect_ttl_enabled = false
+ max_redelivery_count = 0
+ delivery_count_enabled = false
+ event_bind_count_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+ reject_low_priority_msg_limit = 0
+ respect_msg_priority_enabled = false
+ event_msg_spool_usage_threshold = { "setPercent" : 25, "clearPercent" : 18 }
+ reject_low_priority_msg_enabled = false
+ consumer_ack_propagation_enabled = true
+ max_delivered_unacked_msgs_per_flow = 10000
+ reject_msg_to_sender_on_discard_behavior = "when-queue-enabled"
+ event_reject_low_priority_msg_limit_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+}
+
+resource "solacebroker_msg_vpn_queue_subscription" "fh71c08said-Consumer1_a_b_c__" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.msg_vpn_name
+ queue_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.queue_name
+ subscription_topic = "a/b/c/>"
+}
+
+variable username {
+}
+
+variable password {
+}
+
+variable url {
+}
\ No newline at end of file
diff --git a/service/application/src/test/resources/hcl/addQueueBadPort.tf b/service/application/src/test/resources/hcl/addQueueBadPort.tf
new file mode 100644
index 000000000..aec54e905
--- /dev/null
+++ b/service/application/src/test/resources/hcl/addQueueBadPort.tf
@@ -0,0 +1,65 @@
+terraform {
+ required_providers {
+ solacebroker = {
+ source = "registry.terraform.io/solaceproducts/solacebroker"
+ }
+ }
+}
+
+provider "solacebroker" {
+ alias = "fh71c08said"
+ username = "${var.username}"
+ password = "${var.password}"
+ url = "${var.url}33"
+}
+
+data "solacebroker_msg_vpn" "fh71c08said" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = "default"
+}
+
+resource "solacebroker_msg_vpn_queue" "fh71c08said-Consumer1" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = data.solacebroker_msg_vpn.fh71c08said.msg_vpn_name
+ owner = "discovery"
+ max_ttl = 0
+ queue_name = "Consumer1"
+ access_type = "exclusive"
+ max_msg_size = 10000000
+ permission = "consume"
+ dead_msg_queue = "#DEAD_MSG_QUEUE"
+ max_bind_count = 1000
+ delivery_delay = 0
+ egress_enabled = true
+ ingress_enabled = true
+ max_msg_spool_usage = 5000
+ redelivery_enabled = true
+ respect_ttl_enabled = false
+ max_redelivery_count = 0
+ delivery_count_enabled = false
+ event_bind_count_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+ reject_low_priority_msg_limit = 0
+ respect_msg_priority_enabled = false
+ event_msg_spool_usage_threshold = { "setPercent" : 25, "clearPercent" : 18 }
+ reject_low_priority_msg_enabled = false
+ consumer_ack_propagation_enabled = true
+ max_delivered_unacked_msgs_per_flow = 10000
+ reject_msg_to_sender_on_discard_behavior = "when-queue-enabled"
+ event_reject_low_priority_msg_limit_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+}
+
+resource "solacebroker_msg_vpn_queue_subscription" "fh71c08said-Consumer1_a_b_c__" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.msg_vpn_name
+ queue_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.queue_name
+ subscription_topic = "a/b/c/>"
+}
+
+variable username {
+}
+
+variable password {
+}
+
+variable url {
+}
\ No newline at end of file
diff --git a/service/application/src/test/resources/hcl/addQueueNewVariableNotInPlugin.tf b/service/application/src/test/resources/hcl/addQueueNewVariableNotInPlugin.tf
new file mode 100644
index 000000000..45bcdea78
--- /dev/null
+++ b/service/application/src/test/resources/hcl/addQueueNewVariableNotInPlugin.tf
@@ -0,0 +1,65 @@
+terraform {
+ required_providers {
+ solacebroker = {
+ source = "registry.terraform.io/solaceproducts/solacebroker"
+ }
+ }
+}
+
+provider "solacebroker" {
+ alias = "fh71c08said"
+ username = "${var.username}"
+ password = "${var.passwordd}"
+ url = "${var.url}"
+}
+
+data "solacebroker_msg_vpn" "fh71c08said" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = "default"
+}
+
+resource "solacebroker_msg_vpn_queue" "fh71c08said-Consumer1" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = data.solacebroker_msg_vpn.fh71c08said.msg_vpn_name
+ owner = "discovery"
+ max_ttl = 0
+ queue_name = "Consumer1"
+ access_type = "exclusive"
+ max_msg_size = 10000000
+ permission = "consume"
+ dead_msg_queue = "#DEAD_MSG_QUEUE"
+ max_bind_count = 1000
+ delivery_delay = 0
+ egress_enabled = true
+ ingress_enabled = true
+ max_msg_spool_usage = 5000
+ redelivery_enabled = true
+ respect_ttl_enabled = false
+ max_redelivery_count = 0
+ delivery_count_enabled = false
+ event_bind_count_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+ reject_low_priority_msg_limit = 0
+ respect_msg_priority_enabled = false
+ event_msg_spool_usage_threshold = { "setPercent" : 25, "clearPercent" : 18 }
+ reject_low_priority_msg_enabled = false
+ consumer_ack_propagation_enabled = true
+ max_delivered_unacked_msgs_per_flow = 10000
+ reject_msg_to_sender_on_discard_behavior = "when-queue-enabled"
+ event_reject_low_priority_msg_limit_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+}
+
+resource "solacebroker_msg_vpn_queue_subscription" "fh71c08said-Consumer1_a_b_c__" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.msg_vpn_name
+ queue_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.queue_name
+ subscription_topic = "a/b/c/>"
+}
+
+variable username {
+}
+
+variable password {
+}
+
+variable url {
+}
\ No newline at end of file
diff --git a/service/application/src/test/resources/hcl/badBlockHcl.tf b/service/application/src/test/resources/hcl/badBlockHcl.tf
new file mode 100644
index 000000000..2b73c978d
--- /dev/null
+++ b/service/application/src/test/resources/hcl/badBlockHcl.tf
@@ -0,0 +1,65 @@
+terraform {
+ required_providers {
+ solacebroker = {
+ source = "registry.terraform.io/solaceproducts/solacebroker"
+ }
+ }
+}
+
+provider "solacebroker" {
+ alias = "fh71c08said"
+ username = "${var.username}"
+ password = "${var.password}"
+ url = "${var.url}"
+}
+
+datam "solacebroker_msg_vpn" "fh71c08said" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = "default"
+}
+
+resource "solacebroker_msg_vpn_queue" "fh71c08said-Consumer1" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = data.solacebroker_msg_vpn.fh71c08said.msg_vpn_name
+ owner = "discovery"
+ max_ttl = 0
+ queue_name = "Consumer1"
+ access_type = "exclusive"
+ max_msg_size = 10000000
+ permission = "consume"
+ dead_msg_queue = "#DEAD_MSG_QUEUE"
+ max_bind_count = 1000
+ delivery_delay = 0
+ egress_enabled = true
+ ingress_enabled = true
+ max_msg_spool_usage = 5000
+ redelivery_enabled = true
+ respect_ttl_enabled = false
+ max_redelivery_count = 0
+ delivery_count_enabled = false
+ event_bind_count_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+ reject_low_priority_msg_limit = 0
+ respect_msg_priority_enabled = false
+ event_msg_spool_usage_threshold = { "setPercent" : 25, "clearPercent" : 18 }
+ reject_low_priority_msg_enabled = false
+ consumer_ack_propagation_enabled = true
+ max_delivered_unacked_msgs_per_flow = 10000
+ reject_msg_to_sender_on_discard_behavior = "when-queue-enabled"
+ event_reject_low_priority_msg_limit_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+}
+
+resource "solacebroker_msg_vpn_queue_subscription" "fh71c08said-Consumer1_a_b_c__" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.msg_vpn_name
+ queue_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.queue_name
+ subscription_topic = "a/b/c/>"
+}
+
+variable username {
+}
+
+variable password {
+}
+
+variable url {
+}
\ No newline at end of file
diff --git a/service/application/src/test/resources/hcl/badFormatHcl.tf b/service/application/src/test/resources/hcl/badFormatHcl.tf
new file mode 100644
index 000000000..4120f326f
--- /dev/null
+++ b/service/application/src/test/resources/hcl/badFormatHcl.tf
@@ -0,0 +1,65 @@
+terraform {
+ required_providers {
+ solacebroker = {
+ source = "registry.terraform.io/solaceproducts/solacebroker"
+ }
+ }
+}
+
+provider "solacebroker {
+ alias = "fh71c08said"
+ username = "${var.username}"
+ password = "${var.password}"
+ url = "${var.url}"
+}
+
+datam "solacebroker_msg_vpn" "fh71c08said" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = "default"
+}
+
+resource "solacebroker_msg_vpn_queue" "fh71c08said-Consumer1" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = data.solacebroker_msg_vpn.fh71c08said.msg_vpn_name
+ owner = "discovery"
+ max_ttl = 0
+ queue_name = "Consumer1"
+ access_type = "exclusive"
+ max_msg_size = 10000000
+ permission = "consume"
+ dead_msg_queue = "#DEAD_MSG_QUEUE"
+ max_bind_count = 1000
+ delivery_delay = 0
+ egress_enabled = true
+ ingress_enabled = true
+ max_msg_spool_usage = 5000
+ redelivery_enabled = true
+ respect_ttl_enabled = false
+ max_redelivery_count = 0
+ delivery_count_enabled = false
+ event_bind_count_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+ reject_low_priority_msg_limit = 0
+ respect_msg_priority_enabled = false
+ event_msg_spool_usage_threshold = { "setPercent" : 25, "clearPercent" : 18 }
+ reject_low_priority_msg_enabled = false
+ consumer_ack_propagation_enabled = true
+ max_delivered_unacked_msgs_per_flow = 10000
+ reject_msg_to_sender_on_discard_behavior = "when-queue-enabled"
+ event_reject_low_priority_msg_limit_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+}
+
+resource "solacebroker_msg_vpn_queue_subscription" "fh71c08said-Consumer1_a_b_c__" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.msg_vpn_name
+ queue_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.queue_name
+ subscription_topic = "a/b/c/>"
+}
+
+variable username {
+}
+
+variable password {
+}
+
+variable url {
+}
\ No newline at end of file
diff --git a/service/application/src/test/resources/hcl/badProvider.tf b/service/application/src/test/resources/hcl/badProvider.tf
new file mode 100644
index 000000000..760657447
--- /dev/null
+++ b/service/application/src/test/resources/hcl/badProvider.tf
@@ -0,0 +1,65 @@
+terraform {
+ required_providers {
+ solacebroker = {
+ source = "registry.terraform.io/solaceproducts/solacebrokerz"
+ }
+ }
+}
+
+provider "solacebroker" {
+ alias = "fh71c08said"
+ username = "${var.username}"
+ password = "${var.password}"
+ url = "${var.url}"
+}
+
+data "solacebroker_msg_vpn" "fh71c08said" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = "default"
+}
+
+resource "solacebroker_msg_vpn_queue" "fh71c08said-Consumer1" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = data.solacebroker_msg_vpn.fh71c08said.msg_vpn_name
+ owner = "discovery"
+ max_ttl = 0
+ queue_name = "Consumer1"
+ access_type = "exclusive"
+ max_msg_size = 10000000
+ permission = "consume"
+ dead_msg_queue = "#DEAD_MSG_QUEUE"
+ max_bind_count = 1000
+ delivery_delay = 0
+ egress_enabled = true
+ ingress_enabled = true
+ max_msg_spool_usage = 5000
+ redelivery_enabled = true
+ respect_ttl_enabled = false
+ max_redelivery_count = 0
+ delivery_count_enabled = false
+ event_bind_count_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+ reject_low_priority_msg_limit = 0
+ respect_msg_priority_enabled = false
+ event_msg_spool_usage_threshold = { "setPercent" : 25, "clearPercent" : 18 }
+ reject_low_priority_msg_enabled = false
+ consumer_ack_propagation_enabled = true
+ max_delivered_unacked_msgs_per_flow = 10000
+ reject_msg_to_sender_on_discard_behavior = "when-queue-enabled"
+ event_reject_low_priority_msg_limit_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+}
+
+resource "solacebroker_msg_vpn_queue_subscription" "fh71c08said-Consumer1_a_b_c__" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.msg_vpn_name
+ queue_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.queue_name
+ subscription_topic = "a/b/c/>"
+}
+
+variable username {
+}
+
+variable password {
+}
+
+variable url {
+}
\ No newline at end of file
diff --git a/service/application/src/test/resources/hcl/deleteQueue.tf b/service/application/src/test/resources/hcl/deleteQueue.tf
new file mode 100644
index 000000000..f77bdee2a
--- /dev/null
+++ b/service/application/src/test/resources/hcl/deleteQueue.tf
@@ -0,0 +1,28 @@
+terraform {
+ required_providers {
+ solacebroker = {
+ source = "registry.terraform.io/solaceproducts/solacebroker"
+ }
+ }
+}
+
+provider "solacebroker" {
+ alias = "fh71c08said"
+ username = "${var.username}"
+ password = "${var.password}"
+ url = "${var.url}"
+}
+
+data "solacebroker_msg_vpn" "fh71c08said" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = "default"
+}
+
+variable username {
+}
+
+variable password {
+}
+
+variable url {
+}
\ No newline at end of file
diff --git a/service/application/src/test/resources/hcl/deleteQueue2.tf b/service/application/src/test/resources/hcl/deleteQueue2.tf
new file mode 100644
index 000000000..67b64e5bd
--- /dev/null
+++ b/service/application/src/test/resources/hcl/deleteQueue2.tf
@@ -0,0 +1,28 @@
+terraform {
+ required_providers {
+ solacebroker = {
+ source = "registry.terraform.io/solaceproducts/solacebroker"
+ }
+ }
+}
+
+provider "solacebroker" {
+ alias = "fh71c08saie"
+ username = "${var.username}"
+ password = "${var.password}"
+ url = "${var.url}"
+}
+
+data "solacebroker_msg_vpn" "fh71c08saie" {
+ provider = solacebroker.fh71c08saie
+ msg_vpn_name = "default"
+}
+
+variable username {
+}
+
+variable password {
+}
+
+variable url {
+}
\ No newline at end of file
diff --git a/service/application/src/test/resources/hcl/updateQueue.tf b/service/application/src/test/resources/hcl/updateQueue.tf
new file mode 100644
index 000000000..4b5f7c75b
--- /dev/null
+++ b/service/application/src/test/resources/hcl/updateQueue.tf
@@ -0,0 +1,65 @@
+terraform {
+ required_providers {
+ solacebroker = {
+ source = "registry.terraform.io/solaceproducts/solacebroker"
+ }
+ }
+}
+
+provider "solacebroker" {
+ alias = "fh71c08said"
+ username = "${var.username}"
+ password = "${var.password}"
+ url = "${var.url}"
+}
+
+data "solacebroker_msg_vpn" "fh71c08said" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = "default"
+}
+
+resource "solacebroker_msg_vpn_queue" "fh71c08said-Consumer1" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = data.solacebroker_msg_vpn.fh71c08said.msg_vpn_name
+ owner = "discovery"
+ max_ttl = 0
+ queue_name = "Consumer1"
+ access_type = "exclusive"
+ max_msg_size = 10000000
+ permission = "consume"
+ dead_msg_queue = "#DEAD_MSG_QUEUE"
+ max_bind_count = 500
+ delivery_delay = 0
+ egress_enabled = true
+ ingress_enabled = true
+ max_msg_spool_usage = 5000
+ redelivery_enabled = false
+ respect_ttl_enabled = false
+ max_redelivery_count = 0
+ delivery_count_enabled = false
+ event_bind_count_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+ reject_low_priority_msg_limit = 0
+ respect_msg_priority_enabled = false
+ event_msg_spool_usage_threshold = { "setPercent" : 25, "clearPercent" : 18 }
+ reject_low_priority_msg_enabled = false
+ consumer_ack_propagation_enabled = true
+ max_delivered_unacked_msgs_per_flow = 10000
+ reject_msg_to_sender_on_discard_behavior = "when-queue-enabled"
+ event_reject_low_priority_msg_limit_threshold = { "setPercent" : 80, "clearPercent" : 60 }
+}
+
+resource "solacebroker_msg_vpn_queue_subscription" "fh71c08said-Consumer1_a_b_c__" {
+ provider = solacebroker.fh71c08said
+ msg_vpn_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.msg_vpn_name
+ queue_name = solacebroker_msg_vpn_queue.fh71c08said-Consumer1.queue_name
+ subscription_topic = "a/b/c/>"
+}
+
+variable username {
+}
+
+variable password {
+}
+
+variable url {
+}
\ No newline at end of file
diff --git a/service/application/src/test/resources/logback-spring-negativetests.xml b/service/application/src/test/resources/logback-spring-negativetests.xml
new file mode 100644
index 000000000..6388cdf51
--- /dev/null
+++ b/service/application/src/test/resources/logback-spring-negativetests.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+ EMA.log
+
+ %d [%thread] %-5level %-50logger{40} : %msg%n
+
+
+
+ EMA-%d{yyyy-MM-dd}.%i.log
+ 1MB
+ 30
+ 10MB
+ false
+
+
+
+
+ TestOutput.log
+
+ %msg%n
+
+
+
+ TestOutput-%d{yyyy-MM-dd}.%i.log
+ 1MB
+ 30
+ 10MB
+ false
+
+
+
+
+
+ SCAN_ID
+ general-logs
+
+
+
+ data_collection/logs/${SCAN_ID}.log
+
+ [%X{SCAN_ID}] ------ %date [%level] [%thread] %logger{10} [%file:%line] %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/service/application/src/test/resources/logback-spring-offlinetests.xml b/service/application/src/test/resources/logback-spring-offlinetests.xml
new file mode 100644
index 000000000..bc30d5668
--- /dev/null
+++ b/service/application/src/test/resources/logback-spring-offlinetests.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+ EMA.log
+
+ %d [%thread] %-5level %-50logger{40} : %msg%n
+
+
+
+ EMA-%d{yyyy-MM-dd}.%i.log
+ 1MB
+ 30
+ 10MB
+ false
+
+
+
+
+ TestOutput.log
+
+ %msg%n
+
+
+
+ TestOutput-%d{yyyy-MM-dd}.%i.log
+ 1MB
+ 30
+ 10MB
+ false
+
+
+
+
+
+ SCAN_ID
+ general-logs
+
+
+
+ data_collection/logs/${SCAN_ID}.log
+
+ [%X{SCAN_ID}] ------ %date [%level] [%thread] %logger{10} [%file:%line] %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/publisher/SolacePublisher.java b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/publisher/SolacePublisher.java
index ae94c1292..28a121c4c 100644
--- a/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/publisher/SolacePublisher.java
+++ b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/publisher/SolacePublisher.java
@@ -2,6 +2,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.solace.maas.ep.event.management.agent.plugin.config.EnableRtoCondition;
import com.solace.maas.ep.event.management.agent.plugin.mop.MOPConstants;
import com.solace.maas.ep.event.management.agent.plugin.mop.MOPMessage;
@@ -27,6 +28,10 @@ public class SolacePublisher {
private final OutboundMessageBuilder outboundMessageBuilder;
private final DirectMessagePublisher directMessagePublisher;
+ static {
+ mapper.registerModule(new JavaTimeModule());
+ }
+
public SolacePublisher(OutboundMessageBuilder outboundMessageBuilder,
DirectMessagePublisher directMessagePublisher) {
this.outboundMessageBuilder = outboundMessageBuilder;
diff --git a/service/terraform-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/terraform/manager/TerraformLogProcessingService.java b/service/terraform-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/terraform/manager/TerraformLogProcessingService.java
index b73141f2c..2805fa177 100644
--- a/service/terraform-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/terraform/manager/TerraformLogProcessingService.java
+++ b/service/terraform-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/terraform/manager/TerraformLogProcessingService.java
@@ -121,16 +121,13 @@ private Map simplifyApplyErroredLog(Map expanded
String.format("This method only handles logs of type %s", VALUE_TYPE_APPLY_ERRORED)
);
}
- //return expandedLogMessage;
return Map.of(
"address", extractResourceAddressFromDiagnostic(expandedLogMessage.get(KEY_DIAGNOSTIC)),
KEY_DIAGNOSTIC_DETAIL, extractDiagnosticDetailMessage(expandedLogMessage.get(KEY_DIAGNOSTIC)),
"message", expandedLogMessage.get(KEY_MESSAGE),
"level", expandedLogMessage.get(KEY_LEVEL).toString().toUpperCase(),
"timestamp", expandedLogMessage.get(KEY_TIMESTAMP)
-
);
-
}
private String extractDiagnosticDetailMessage(Object diagnostic) {
diff --git a/service/terraform-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/terraform/manager/TerraformManager.java b/service/terraform-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/terraform/manager/TerraformManager.java
index 2729f5643..0a7deaf88 100644
--- a/service/terraform-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/terraform/manager/TerraformManager.java
+++ b/service/terraform-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/terraform/manager/TerraformManager.java
@@ -34,7 +34,6 @@ public class TerraformManager {
private final TerraformLogProcessingService terraformLogProcessingService;
private final TerraformProperties terraformProperties;
private final TerraformClientFactory terraformClientFactory;
-
private final static String TF_CONFIG_FILENAME = "config.tf";
public TerraformManager(TerraformLogProcessingService terraformLogProcessingService,
@@ -89,8 +88,10 @@ private static String executeTerraformCommand(Command command, Map {
writeHclToFile(command, configPath);
- terraformClient.plan(envVars).get();
- terraformClient.apply(envVars).get();
+ Boolean planSuccessful = terraformClient.plan(envVars).get();
+ if (Boolean.TRUE.equals(planSuccessful)) {
+ terraformClient.apply(envVars).get();
+ }
}
case "write_HCL" -> writeHclToFile(command, configPath);
default -> throw new IllegalArgumentException("Unsupported command " + commandVerb);
@@ -118,7 +119,7 @@ private void processTerraformResponse(CommandRequest request, Command command, S
}
}
- private void setCommandError(Command command, Exception e) {
+ public static void setCommandError(Command command, Exception e) {
command.setResult(CommandResult.builder()
.status(JobStatus.error)
.logs(List.of(
@@ -152,7 +153,12 @@ private static void writeHclToFile(Command command, Path configPath) throws IOEx
// At the moment, we only support base64 decoding
Map parameters = command.getParameters();
if (parameters != null && parameters.containsKey("Content-Encoding") && "base64".equals(parameters.get("Content-Encoding"))) {
- byte[] decodedBytes = Base64.getDecoder().decode(command.getBody());
+ byte[] decodedBytes;
+ try {
+ decodedBytes = Base64.getDecoder().decode(command.getBody());
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Error decoding base64 content", e);
+ }
Files.write(configPath.resolve(TF_CONFIG_FILENAME), decodedBytes);
} else {
if (parameters == null || !parameters.containsKey("Content-Encoding")) {