Skip to content
This repository has been archived by the owner on May 26, 2020. It is now read-only.

Commit

Permalink
Merge 78414ff into 9396737
Browse files Browse the repository at this point in the history
  • Loading branch information
allanmckenzie committed Oct 14, 2019
2 parents 9396737 + 78414ff commit add6268
Show file tree
Hide file tree
Showing 8 changed files with 342 additions and 19 deletions.
8 changes: 7 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
<cpp.repo.name>framework-jmx-command-client</cpp.repo.name>

<framework-api.version>4.1.0</framework-api.version>
<framework.version>6.1.1</framework.version>
<framework.version>6.2.0-M5</framework.version>
<utilities.version>1.20.1</utilities.version>
<maven-common-bom.version>2.4.0</maven-common-bom.version>
</properties>

Expand Down Expand Up @@ -72,6 +73,11 @@
<groupId>org.wildfly</groupId>
<artifactId>wildfly-client-all</artifactId>
</dependency>
<dependency>
<groupId>uk.gov.justice.utils</groupId>
<artifactId>utilities-core</artifactId>
<version>${utilities.version}</version>
</dependency>


<!-- Test Dependencies -->
Expand Down
2 changes: 1 addition & 1 deletion runSystemCommand.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
################################################

FRAMEWORK_JMX_COMMAND_CLIENT_VERSION=2.1.0-SNAPSHOT
FRAMEWORK_JMX_COMMAND_CLIENT_VERSION=2.2.0-SNAPSHOT
CONTEXT_NAME="people"
USER_NAME="admin"
PASSWORD="admin"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package uk.gov.justice.framework.command.client.jmx;

import static java.lang.String.format;
import static java.time.Duration.between;
import static org.apache.commons.lang3.time.DurationFormatUtils.formatDurationHMS;
import static uk.gov.justice.services.jmx.api.domain.CommandState.COMMAND_COMPLETE;
import static uk.gov.justice.services.jmx.api.domain.CommandState.COMMAND_FAILED;

import uk.gov.justice.framework.command.client.io.ToConsolePrinter;
import uk.gov.justice.services.common.util.UtcClock;
import uk.gov.justice.services.jmx.api.domain.CommandState;
import uk.gov.justice.services.jmx.api.domain.SystemCommandStatus;
import uk.gov.justice.services.jmx.api.mbean.SystemCommanderMBean;

import java.time.ZonedDateTime;
import java.util.UUID;

import javax.inject.Inject;

public class CommandChecker {

@Inject
private ToConsolePrinter toConsolePrinter;

@Inject
private UtcClock clock;

public boolean commandComplete(final SystemCommanderMBean systemCommanderMBean, final UUID commandId, final ZonedDateTime startTime) {

final SystemCommandStatus commandStatus = systemCommanderMBean.getCommandStatus(commandId);


final CommandState commandState = commandStatus.getCommandState();
if (commandState == COMMAND_COMPLETE ) {

final ZonedDateTime endTime = clock.now();
final long durationMillis = between(startTime, endTime).toMillis();

final String duration = formatDurationHMS(durationMillis);
toConsolePrinter.println(format("Command %s complete", commandStatus.getSystemCommandName()));
toConsolePrinter.println(format("%s duration %s (hours:minutes:seconds:milliseconds)", commandStatus.getSystemCommandName(), duration));
return true;
}

if(commandState == COMMAND_FAILED) {
final long durationMillis = between(startTime, clock.now()).toMillis();

final String duration = formatDurationHMS(durationMillis);
toConsolePrinter.println(format("ERROR: Command %s failed", commandStatus.getSystemCommandName()));
toConsolePrinter.println(format("ERROR: %s", commandStatus.getMessage()));
toConsolePrinter.println(format("%s duration %s (hours:minutes:seconds:milliseconds)", commandStatus.getSystemCommandName(), duration));
return true;
}

return false;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package uk.gov.justice.framework.command.client.jmx;

import static java.lang.String.format;
import static java.time.Duration.between;

import uk.gov.justice.framework.command.client.io.ToConsolePrinter;
import uk.gov.justice.services.common.util.Sleeper;
import uk.gov.justice.services.common.util.UtcClock;
import uk.gov.justice.services.jmx.api.command.SystemCommand;
import uk.gov.justice.services.jmx.api.mbean.SystemCommanderMBean;

import java.time.ZonedDateTime;
import java.util.UUID;

import javax.inject.Inject;

public class CommandPoller {

@Inject
private CommandChecker commandChecker;

@Inject
private UtcClock clock;

@Inject
private Sleeper sleeper;

@Inject
private ToConsolePrinter toConsolePrinter;

public void runUntilComplete(final SystemCommanderMBean systemCommanderMBean, final UUID commandId, final SystemCommand systemCommand) {

final ZonedDateTime startTime = clock.now();

int count = 0;
while (! commandChecker.commandComplete(systemCommanderMBean, commandId, startTime)) {
sleeper.sleepFor(1_000);
count++;

if (count % 10 == 0) {
final long seconds = between(startTime, clock.now()).getSeconds();
toConsolePrinter.println(format("%s running for %d seconds", systemCommand.getName(), seconds));
}
}
}

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package uk.gov.justice.framework.command.client.jmx;

import static uk.gov.justice.services.jmx.api.domain.CommandState.COMMAND_COMPLETE;
import static uk.gov.justice.services.jmx.api.domain.CommandState.COMMAND_FAILED;

import uk.gov.justice.framework.command.client.io.ToConsolePrinter;
import uk.gov.justice.services.jmx.api.SystemCommandFailedException;
import uk.gov.justice.services.jmx.api.UnsupportedSystemCommandException;
import uk.gov.justice.services.jmx.api.command.SystemCommand;
import uk.gov.justice.services.jmx.api.domain.CommandState;
import uk.gov.justice.services.jmx.api.domain.SystemCommandStatus;
import uk.gov.justice.services.jmx.api.mbean.SystemCommanderMBean;
import uk.gov.justice.services.jmx.system.command.client.SystemCommanderClient;
import uk.gov.justice.services.jmx.system.command.client.SystemCommanderClientFactory;
import uk.gov.justice.services.jmx.system.command.client.connection.JmxParameters;

import java.util.UUID;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

Expand All @@ -18,6 +25,9 @@ public class SystemCommandInvoker {
@Inject
private SystemCommanderClientFactory systemCommanderClientFactory;

@Inject
private CommandPoller commandPoller;

@Inject
private ToConsolePrinter toConsolePrinter;

Expand All @@ -32,13 +42,13 @@ public void runSystemCommand(final SystemCommand systemCommand, final JmxParamet
jmxParameters.getCredentials().ifPresent(credentials -> toConsolePrinter.printf("Connecting with credentials for user '%s'", credentials.getUsername()));

try (final SystemCommanderClient systemCommanderClient = systemCommanderClientFactory.create(jmxParameters)) {
final SystemCommanderMBean systemCommanderMBean = systemCommanderClient.getRemote(contextName);

toConsolePrinter.printf("Connected to %s context", contextName);

systemCommanderMBean.call(systemCommand);

toConsolePrinter.printf("System command '%s' successfully sent to %s", commandName, contextName);
final SystemCommanderMBean systemCommanderMBean = systemCommanderClient.getRemote(contextName);
final UUID commandId = systemCommanderMBean.call(systemCommand);
toConsolePrinter.printf("System command '%s' with id '%s' successfully sent to %s", commandName, commandId, contextName);
commandPoller.runUntilComplete(systemCommanderMBean, commandId, systemCommand);

} catch (final UnsupportedSystemCommandException e) {
toConsolePrinter.printf("The command '%s' is not supported on this %s context", commandName, contextName);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package uk.gov.justice.framework.command.client.jmx;

import static java.util.UUID.randomUUID;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static uk.gov.justice.services.jmx.api.domain.CommandState.COMMAND_COMPLETE;
import static uk.gov.justice.services.jmx.api.domain.CommandState.COMMAND_FAILED;
import static uk.gov.justice.services.jmx.api.domain.CommandState.COMMAND_IN_PROGRESS;

import uk.gov.justice.framework.command.client.io.ToConsolePrinter;
import uk.gov.justice.services.common.util.UtcClock;
import uk.gov.justice.services.jmx.api.domain.SystemCommandStatus;
import uk.gov.justice.services.jmx.api.mbean.SystemCommanderMBean;

import java.time.ZonedDateTime;
import java.util.UUID;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class CommandCheckerTest {

@Mock
private ToConsolePrinter toConsolePrinter;

@Mock
private UtcClock clock;

@InjectMocks
private CommandChecker commandChecker;

@Test
public void shouldLogAndReturnTrueIfTheCommandIsComplete() throws Exception {

final UUID commandId = randomUUID();

final ZonedDateTime startTime = new UtcClock().now();
final ZonedDateTime endedAt = startTime.plusMinutes(83);

final SystemCommanderMBean systemCommanderMBean = mock(SystemCommanderMBean.class);
final SystemCommandStatus systemCommandStatus = mock(SystemCommandStatus.class);

when(clock.now()).thenReturn(endedAt);
when(systemCommanderMBean.getCommandStatus(commandId)).thenReturn(systemCommandStatus);
when(systemCommandStatus.getCommandState()).thenReturn(COMMAND_COMPLETE);
when(systemCommandStatus.getSystemCommandName()).thenReturn("CATCHUP");

assertThat(commandChecker.commandComplete(systemCommanderMBean, commandId, startTime), is(true));

verify(toConsolePrinter).println("Command CATCHUP complete");
verify(toConsolePrinter).println("CATCHUP duration 01:23:00.000 (hours:minutes:seconds:milliseconds)");
}

@Test
public void shouldLogAndReturnTrueIfTheCommandFails() throws Exception {

final UUID commandId = randomUUID();

final String errorMessage = "CATCHUP failed with 23 errors";

final ZonedDateTime startTime = new UtcClock().now();
final ZonedDateTime endedAt = startTime.plusMinutes(83);

final SystemCommanderMBean systemCommanderMBean = mock(SystemCommanderMBean.class);
final SystemCommandStatus systemCommandStatus = mock(SystemCommandStatus.class);

when(clock.now()).thenReturn(endedAt);
when(systemCommanderMBean.getCommandStatus(commandId)).thenReturn(systemCommandStatus);
when(systemCommandStatus.getCommandState()).thenReturn(COMMAND_FAILED);
when(systemCommandStatus.getSystemCommandName()).thenReturn("CATCHUP");
when(systemCommandStatus.getMessage()).thenReturn(errorMessage);

assertThat(commandChecker.commandComplete(systemCommanderMBean, commandId, startTime), is(true));

verify(toConsolePrinter).println("ERROR: Command CATCHUP failed");
verify(toConsolePrinter).println("ERROR: CATCHUP failed with 23 errors");
verify(toConsolePrinter).println("CATCHUP duration 01:23:00.000 (hours:minutes:seconds:milliseconds)");
}

@Test
public void shouldReturnFalseIfTheCommandIsNeitherCompleteNorFailed() throws Exception {

final UUID commandId = randomUUID();

final ZonedDateTime startTime = new UtcClock().now();

final SystemCommanderMBean systemCommanderMBean = mock(SystemCommanderMBean.class);
final SystemCommandStatus systemCommandStatus = mock(SystemCommandStatus.class);

when(systemCommanderMBean.getCommandStatus(commandId)).thenReturn(systemCommandStatus);
when(systemCommandStatus.getCommandState()).thenReturn(COMMAND_IN_PROGRESS);

assertThat(commandChecker.commandComplete(systemCommanderMBean, commandId, startTime), is(false));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package uk.gov.justice.framework.command.client.jmx;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import uk.gov.justice.framework.command.client.io.ToConsolePrinter;
import uk.gov.justice.services.common.util.Sleeper;
import uk.gov.justice.services.common.util.UtcClock;
import uk.gov.justice.services.jmx.api.command.EventCatchupCommand;
import uk.gov.justice.services.jmx.api.command.SystemCommand;
import uk.gov.justice.services.jmx.api.mbean.SystemCommanderMBean;

import java.time.ZonedDateTime;
import java.util.UUID;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class CommandPollerTest {

@Mock
private CommandChecker commandChecker;

@Mock
private UtcClock clock;

@Mock
private Sleeper sleeper;

@Mock
private ToConsolePrinter toConsolePrinter;

@InjectMocks
private CommandPoller commandPoller;

@Test
public void shouldCheckCommandUntilComplete() throws Exception {

final UUID commandId = UUID.randomUUID();
final SystemCommand systemCommand = new EventCatchupCommand();

final ZonedDateTime startTime = new UtcClock().now();

final SystemCommanderMBean systemCommanderMBean = mock(SystemCommanderMBean.class);

when(clock.now()).thenReturn(startTime);
when(commandChecker.commandComplete(systemCommanderMBean, commandId, startTime)).thenReturn(false, false, true);

commandPoller.runUntilComplete(systemCommanderMBean, commandId, systemCommand);

verify(sleeper, times(2)).sleepFor(1_000);
verifyZeroInteractions(toConsolePrinter);
}

@Test
public void shouldLogProgressEveryTenthCall() throws Exception {

final UUID commandId = UUID.randomUUID();
final SystemCommand systemCommand = new EventCatchupCommand();

final ZonedDateTime startTime = new UtcClock().now();
final ZonedDateTime now = startTime.plusSeconds(10);

final SystemCommanderMBean systemCommanderMBean = mock(SystemCommanderMBean.class);

when(clock.now()).thenReturn(startTime, now);
when(commandChecker.commandComplete(systemCommanderMBean, commandId, startTime)).thenReturn(false, false, false, false, false, false, false, false, false, false, true);

commandPoller.runUntilComplete(systemCommanderMBean, commandId, systemCommand);

verify(sleeper, times(10)).sleepFor(1_000);
verify(toConsolePrinter).println("CATCHUP running for 10 seconds");
}
}
Loading

0 comments on commit add6268

Please sign in to comment.