Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DATAGO-84853: cema config push resiliency #211

Merged
merged 18 commits into from
Nov 21, 2024

Conversation

mynecker
Copy link
Contributor

What is the purpose of this change?

Adding Solace SEMPv2 delete command support to remove dangling resources when executing configPush jobs

How was this change implemented?

adding Java code

How was this change tested?

IT tests and tests in dev environment

Is there anything the reviewers should focus on/be aware of?

added unit test for TerraformUtils cleanup of config dir
added unit test for TerraformUtils cleanup of config dir
added unit test for TerraformUtils cleanup of config dir
added unit test for TerraformUtils cleanup of config dir
@mynecker mynecker marked this pull request as ready for review November 11, 2024 20:54


@Test
void testBuildTfStateFileDeletionFailureResult(){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -82,6 +82,7 @@ public void reset_mocks() {
Mockito.reset(terraformClient);
}


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary, please remove this line break

private boolean restartSimulated;

@Override
public boolean onPhaseChange(InboundMessage message, PersistentMessageHandlerObserverPhase phase) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have question for this method, I will reach out to you @mynecker

@moodiRealist moodiRealist changed the title Mynecker/datago 84853 cema config push resiliency DATAGO-84853: cema config push resiliency Nov 13, 2024
.logs(List.of())
.build());
} catch(ApiException e) {
ApiException apiException = (ApiException) e;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed,

   } catch(ApiException apiException) {
            log.error("Error executing SEMP delete command: {}", apiException.getResponseBody());
            setCommandError(command, apiException);
        }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second look, basically we can consolidate both exception

} catch (Exception e) {
    if (e instanceof ApiException) {
        ApiException apiException = (ApiException) e;
        log.error("Error executing SEMP delete command: {}", apiException.getResponseBody());
    } else {
        log.error(ERROR_EXECUTING_COMMAND, e);
    }
    setCommandError(command, e);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also have a concern with this log log.error("Error executing SEMP delete command: {}", apiException.getResponseBody());
It can potentially leak sensitive information (such as client username) in plain text

Validate.isTrue(command.getCommandType().equals(semp), "Command type must be semp");
// only delete operation is supported for now and only delete operations are sent from EP
Validate.isTrue(command.getCommand().equals(SEMP_DELETE_OPERATION), "Command operation must be delete");
sempDeleteCommandManager.execute(command, new SempApiProviderImpl(solaceClient));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of creating a new SempApiProviderImpl for each command, we could just change the method signature here as
private void executeSempCommand(Command command, SempApiProviderImplsempApiProvider) {
create a single SempApiProviderImpl on line 138

Copy link
Collaborator

@moodiRealist moodiRealist left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some comments, thanks!

});
try {
configPush(requestBO);
} catch (Exception e) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we log an error under this catch block?

@@ -107,28 +109,51 @@ private void handleError(Exception e, CommandRequest requestBO) {
@SuppressWarnings("PMD")
public void configPush(CommandRequest request) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method has become quite long, would it be possible to break the content into smaller method calls?

if (commandLogStreamingProcessorOpt.isPresent()) {
streamCommandExecutionLogToEpCore(request, command, executionLog);
}
if (command.getCommandType() == semp) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can use switch/case statements against this enum instead.

try {
aclProfileApi.deleteMsgVpnAclProfile(request.getMsgVpn(), request.getAclProfileName());
} catch (ApiException e) {
// If the client username does not exist, we don't want to consider it an error
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the method executeDeleteClientUsername was copy pasted few times since this exact comment shows up 5 times in this PR.

That's a good indication of being able to write a helper method that all these 5 execteDelete{something} methods can call.

You can ask github co-pilot to extract the common code from these 5 methods and refactor them for you.

</configuration>
</execution>
</executions>
</plugin>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to add some exclusions on jacoco reports on ep-core PR as well. Please make sure we will pass the line coverage requirements before merging this PR.


import org.junit.jupiter.api.Test;

public class SempEntityTypeTest {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed

Copy link
Contributor

@rudraneel-chakraborty rudraneel-chakraborty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some comments, most are minor
One thing to point out: In general I think your intellij is not set up with proper formatting style that we use in ep, you can find the instruction here https://sol-jira.atlassian.net/wiki/spaces/MAASF/pages/480870736/MaaS+Code+Style+Reference

Copy link
Collaborator

@moodiRealist moodiRealist left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added more comments

service/application/pom.xml Show resolved Hide resolved
<source>${java.version}</source>
<target>${java.version}</target>
<source>14</source>
<target>14</target>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what was the reason for this change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have the same question, please address this before merging



/**
* private void executeSempDeleteCommand(Command command, SempApiProvider sempApiProvider) throws ApiException, JsonProcessingException {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we keep this commented out code?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not, any code that is not being used MUST be removed

Comment on lines 33 to 36
assertTrue(Files.exists(tempDirectory));
//cleanup
Files.deleteIfExists(tempDirectory);
assertFalse(Files.exists(tempDirectory));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Temp directories are managed by JUnit, you do not need to clean them up

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in other words, line 35-36 must be removed

Comment on lines 74 to 112
private static Command generateCommand(String tfCommand, String body) {
return generateCommand(tfCommand, body, false);
}

private static Command generateCommand(String tfCommand, String body, Boolean ignoreResult) {
return generateCommand(tfCommand, body, ignoreResult,
Map.of("Content-Type", "application/hcl",
"Content-Encoding", "base64"));
}

private static Command generateCommand(String tfCommand, String body, Boolean ignoreResult, Map<String, Object> parameters) {
return Command.builder()
.body(Optional.ofNullable(body)
.map(b -> Base64.getEncoder().encodeToString(b.getBytes(UTF_8)))
.orElse(""))
.command(tfCommand)
.commandType(CommandType.terraform)
.ignoreResult(ignoreResult)
.parameters(parameters)
.build();
}

private static CommandRequest generateCommandRequest(Command commandRequest) {
return generateCommandRequest(List.of(commandRequest), false);
}

private static CommandRequest generateCommandRequest(List<Command> commandRequests, boolean exitOnFailure) {
return CommandRequest.builder()
.commandBundles(List.of(
CommandBundle.builder()
.executionType(ExecutionType.serial)
.exitOnFailure(exitOnFailure)
.commands(commandRequests)
.build()))
.commandCorrelationId("234")
.context("app123")
.serviceId("ms1234")
.build();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am finding it a little difficult to understand the diff here, if I am not wrong, its the exact same code but you pulled it on to the top? @mynecker

Comment on lines 77 to 80
Validate.notNull(request, "request must be provided");
Validate.notEmpty(request.getContext(), "context of request must be provided");
Validate.notEmpty(request.getServiceId(), "serviceId of request must be provided");
Validate.notEmpty(directory, "directory must be provided");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validations can be outside synchronized block. Its in our interest to keep the lock only to the critical section of the code

Copy link
Contributor

@rudraneel-chakraborty rudraneel-chakraborty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am approving the PR but please address @moodiRealist comment https://github.com/SolaceProducts/event-management-agent/pull/211/files#r1849067427 before merging

Copy link

SonarQube Quality Gate

Quality Gate failed

Failed condition 72.3% 72.3% Coverage on New Code (is less than 80%)

See analysis details on SonarQube

@mynecker mynecker merged commit 61df8ed into main Nov 21, 2024
5 of 6 checks passed
@mynecker mynecker deleted the mynecker/DATAGO-84853-CEMA-ConfigPush-Resiliency branch November 21, 2024 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants