Skip to content
Snippets Groups Projects
Commit 54240204 authored by OZGCloud's avatar OZGCloud
Browse files

Merge pull request 'OZG-4392: Timeout + Exception, wenn Command mit einem...

Merge pull request 'OZG-4392: Timeout + Exception, wenn Command mit einem Fehler abgeschlossen' (#4) from OZG-4392-Antwort-von-VorgangProcessor-verarbeiten into master

Reviewed-on: https://git.ozg-sh.de/mgm/ozgcloud-api-lib/pulls/4
parents fff47494 a5301275
Branches
Tags
No related merge requests found
package de.ozgcloud.apilib.common.command.grpc; package de.ozgcloud.apilib.common.command.grpc;
import de.itvsh.kop.common.errorhandling.TechnicalException;
import de.itvsh.ozg.pluto.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; import de.itvsh.ozg.pluto.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub;
import de.itvsh.ozg.pluto.grpc.command.GrpcGetCommandRequest; import de.itvsh.ozg.pluto.grpc.command.GrpcGetCommandRequest;
import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextAttachingInterceptor; import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextAttachingInterceptor;
...@@ -7,6 +8,7 @@ import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider; ...@@ -7,6 +8,7 @@ import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
import de.ozgcloud.apilib.common.command.OzgCloudCommand; import de.ozgcloud.apilib.common.command.OzgCloudCommand;
import de.ozgcloud.apilib.common.command.OzgCloudCommandId; import de.ozgcloud.apilib.common.command.OzgCloudCommandId;
import de.ozgcloud.apilib.common.command.OzgCloudCommandService; import de.ozgcloud.apilib.common.command.OzgCloudCommandService;
import de.ozgcloud.apilib.common.command.OzgCloudCommandStatus;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import net.devh.boot.grpc.client.inject.GrpcClient; import net.devh.boot.grpc.client.inject.GrpcClient;
...@@ -14,6 +16,7 @@ import net.devh.boot.grpc.client.inject.GrpcClient; ...@@ -14,6 +16,7 @@ import net.devh.boot.grpc.client.inject.GrpcClient;
public class GrpcOzgCloudCommandService implements OzgCloudCommandService { public class GrpcOzgCloudCommandService implements OzgCloudCommandService {
private static final int WAIT_TIME_MS = 500; private static final int WAIT_TIME_MS = 500;
public static final int DEFAULT_COMMAND_REQUEST_THRESHOLD_MILLIS = 10000;
@GrpcClient("command-manager") @GrpcClient("command-manager")
private final CommandServiceBlockingStub commandServiceStub; private final CommandServiceBlockingStub commandServiceStub;
...@@ -22,6 +25,8 @@ public class GrpcOzgCloudCommandService implements OzgCloudCommandService { ...@@ -22,6 +25,8 @@ public class GrpcOzgCloudCommandService implements OzgCloudCommandService {
private final OzgCloudCallContextProvider contextProvider; private final OzgCloudCallContextProvider contextProvider;
private final int commandRequestThresholdMillis;
@Override @Override
public OzgCloudCommand createAndWaitUntilDone(OzgCloudCommand commandToCreate) { public OzgCloudCommand createAndWaitUntilDone(OzgCloudCommand commandToCreate) {
return waitUntilDone(create(commandToCreate)); return waitUntilDone(create(commandToCreate));
...@@ -34,8 +39,8 @@ public class GrpcOzgCloudCommandService implements OzgCloudCommandService { ...@@ -34,8 +39,8 @@ public class GrpcOzgCloudCommandService implements OzgCloudCommandService {
OzgCloudCommand waitUntilDone(OzgCloudCommand commandToWaitFor) { OzgCloudCommand waitUntilDone(OzgCloudCommand commandToWaitFor) {
var command = commandToWaitFor; var command = commandToWaitFor;
// TODO timeout var timeout = System.currentTimeMillis() + commandRequestThresholdMillis;
while (!command.getStatus().isFinalState()) { while (!command.getStatus().isFinalState() && System.currentTimeMillis() < timeout) {
synchronized (this) { synchronized (this) {
try { try {
wait(WAIT_TIME_MS); wait(WAIT_TIME_MS);
...@@ -45,10 +50,11 @@ public class GrpcOzgCloudCommandService implements OzgCloudCommandService { ...@@ -45,10 +50,11 @@ public class GrpcOzgCloudCommandService implements OzgCloudCommandService {
} }
} }
} }
verifyCommand(command);
return command; return command;
} }
private OzgCloudCommand reloadCommand(OzgCloudCommandId commandId) { OzgCloudCommand reloadCommand(OzgCloudCommandId commandId) {
GrpcGetCommandRequest request = GrpcGetCommandRequest.newBuilder().setId(commandId.toString()).build(); GrpcGetCommandRequest request = GrpcGetCommandRequest.newBuilder().setId(commandId.toString()).build();
return mapper.fromGrpc(getCommandServiceStub().getCommand(request)); return mapper.fromGrpc(getCommandServiceStub().getCommand(request));
} }
...@@ -56,4 +62,10 @@ public class GrpcOzgCloudCommandService implements OzgCloudCommandService { ...@@ -56,4 +62,10 @@ public class GrpcOzgCloudCommandService implements OzgCloudCommandService {
CommandServiceBlockingStub getCommandServiceStub() { CommandServiceBlockingStub getCommandServiceStub() {
return commandServiceStub.withInterceptors(new OzgCloudCallContextAttachingInterceptor(contextProvider)); return commandServiceStub.withInterceptors(new OzgCloudCallContextAttachingInterceptor(contextProvider));
} }
void verifyCommand(OzgCloudCommand command) {
if (command.getStatus() == OzgCloudCommandStatus.ERROR) {
throw new TechnicalException("Command (id=%s) failed: %s".formatted(command.getId(), command.getErrorMessage()));
}
}
} }
package de.ozgcloud.apilib.common.command.grpc; package de.ozgcloud.apilib.common.command.grpc;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*; import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Spy; import org.mockito.Mockito;
import de.itvsh.kop.common.errorhandling.TechnicalException;
import de.itvsh.ozg.pluto.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; import de.itvsh.ozg.pluto.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub;
import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider;
import de.ozgcloud.apilib.common.command.OzgCloudCommand; import de.ozgcloud.apilib.common.command.OzgCloudCommand;
import de.ozgcloud.apilib.common.command.OzgCloudCommandStatus;
class GrpcOzgCloudCommandServiceTest { class GrpcOzgCloudCommandServiceTest {
@Spy
@InjectMocks
private GrpcOzgCloudCommandService service; private GrpcOzgCloudCommandService service;
@Mock @Mock
private CommandServiceBlockingStub serviceStub; private CommandServiceBlockingStub serviceStub;
@Mock @Mock
private CommandMapper mapper; private CommandMapper mapper;
@Mock
private OzgCloudCallContextProvider contextProvider;
@BeforeEach
void init() {
service = spy(new GrpcOzgCloudCommandService(serviceStub, mapper, contextProvider, 600));
}
@Nested @Nested
class TestCreateAndWaitUntilDone { class TestCreateAndWaitUntilDone {
...@@ -49,6 +58,23 @@ class GrpcOzgCloudCommandServiceTest { ...@@ -49,6 +58,23 @@ class GrpcOzgCloudCommandServiceTest {
verify(service).waitUntilDone(created); verify(service).waitUntilDone(created);
} }
@Test
void shouldTerminateByTimeout() {
var command = OzgCloudCommandTestFactory.createBuilder().status(OzgCloudCommandStatus.PENDING).build();
doReturn(command).when(service).reloadCommand(any());
service.waitUntilDone(command);
Mockito.verify(service, Mockito.times(2)).reloadCommand(command.getId());
}
@Test
void shouldCallVerifyCommand() {
service.waitUntilDone(command);
verify(service).verifyCommand(command);
}
@Nested @Nested
class Create { class Create {
...@@ -94,4 +120,15 @@ class GrpcOzgCloudCommandServiceTest { ...@@ -94,4 +120,15 @@ class GrpcOzgCloudCommandServiceTest {
} }
} }
@Nested
class TestStatus {
@Test
void shouldThrowException() {
var command = OzgCloudCommandTestFactory.createBuilder().status(OzgCloudCommandStatus.ERROR).build();
assertThrows(TechnicalException.class, () -> service.verifyCommand(command));
}
}
} }
\ No newline at end of file
...@@ -142,7 +142,8 @@ public class OzgCloudClientAutoConfiguration { ...@@ -142,7 +142,8 @@ public class OzgCloudClientAutoConfiguration {
@ConditionalOnProperty("ozgcloud.command-manager.address") @ConditionalOnProperty("ozgcloud.command-manager.address")
OzgCloudCommandService grpcOzgCloudCommandService(@GrpcClient("command-manager") CommandServiceBlockingStub commandServiceStub, OzgCloudCommandService grpcOzgCloudCommandService(@GrpcClient("command-manager") CommandServiceBlockingStub commandServiceStub,
CommandMapper commandMapper, OzgCloudCallContextProvider contextProvider) { CommandMapper commandMapper, OzgCloudCallContextProvider contextProvider) {
return new GrpcOzgCloudCommandService(commandServiceStub, commandMapper, contextProvider); return new GrpcOzgCloudCommandService(commandServiceStub, commandMapper, contextProvider,
GrpcOzgCloudCommandService.DEFAULT_COMMAND_REQUEST_THRESHOLD_MILLIS);
} }
@Bean @Bean
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment