Skip to content

Commit

Permalink
feat(ForkStatus): returns status=NOT_AVAILABLE when channel to a chan…
Browse files Browse the repository at this point in the history
…nel is not established
  • Loading branch information
TonyWu3027 committed Aug 27, 2023
1 parent 4d377b6 commit e6c46f9
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import org.hyperledger.fabric.client.GatewayException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;
import uk.ac.ic.doc.blocc.dashboard.forkstatus.model.ForkStatusResponse;

@RestController
@CrossOrigin(origins = "*")
Expand All @@ -25,12 +25,9 @@ public ForkStatusController(ForkStatusService service) {
}

@GetMapping
public boolean getForkStatus(@RequestParam int containerNum) throws GatewayException {
try {
return service.getForkStatus(containerNum);
} catch (IllegalArgumentException e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, e.getMessage());
}
public ResponseEntity<ForkStatusResponse> getForkStatus(@RequestParam int containerNum)
throws GatewayException {
return ResponseEntity.ok(new ForkStatusResponse(service.getForkStatus(containerNum)));
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package uk.ac.ic.doc.blocc.dashboard.forkstatus;

import com.google.gson.Gson;
import io.grpc.Status.Code;
import org.hyperledger.fabric.client.Contract;
import org.hyperledger.fabric.client.GatewayException;
import org.hyperledger.fabric.client.Network;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import uk.ac.ic.doc.blocc.dashboard.fabric.BloccConnections;
import uk.ac.ic.doc.blocc.dashboard.forkstatus.model.ForkStatus;

@Service
@Profile("prod")
Expand All @@ -21,11 +23,21 @@ public ForkStatusService(BloccConnections connections) {
this.connections = connections;
}

public boolean getForkStatus(int containerNum) throws GatewayException {
public ForkStatus getForkStatus(int containerNum) throws GatewayException {
Network channel = connections.getChannel(containerNum);
Contract bscc = channel.getContract("bscc");
byte[] checkForkStatuses = bscc.evaluateTransaction("CheckForkStatus",
String.format("channel%d", containerNum));
return gson.fromJson(new String(checkForkStatuses), Boolean.class);
try {
byte[] checkForkStatuses = bscc.evaluateTransaction("CheckForkStatus",
String.format("channel%d", containerNum));
return gson.fromJson(new String(checkForkStatuses), Boolean.class) ? ForkStatus.FORKED
: ForkStatus.NORMAL;
} catch (GatewayException e) {
if (e.getStatus().getCode() == Code.UNAVAILABLE) {
return ForkStatus.NOT_AVAILABLE;
} else {
throw e;
}
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package uk.ac.ic.doc.blocc.dashboard.forkstatus.model;

public enum ForkStatus {
FORKED,
NORMAL,
NOT_AVAILABLE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package uk.ac.ic.doc.blocc.dashboard.forkstatus.model;

public class ForkStatusResponse {

private final ForkStatus status;

public ForkStatusResponse(ForkStatus forkStatus) {
status = forkStatus;
}

public ForkStatus getStatus() {
return status;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import uk.ac.ic.doc.blocc.dashboard.forkstatus.model.ForkStatus;

@WebMvcTest(ForkStatusController.class)
@ActiveProfiles("fork-status-controller-test")
Expand All @@ -25,36 +26,36 @@ public class ForkStatusControllerTest {
@Test
public void returnsTrueIfForkDetected() throws Exception {
int containerNum = 5;
when(service.getForkStatus(containerNum)).thenReturn(true);
when(service.getForkStatus(containerNum)).thenReturn(ForkStatus.FORKED);

mockMvc.perform(get("/api/v1/forkStatus")
.header("Origin", "http://localhost:3000")
.param("containerNum", String.valueOf(containerNum)))
.andExpect(status().isOk())
.andExpect(content().string("true"));
.andExpect(content().json("{\"status\":\"FORKED\"}"));
}

@Test
public void returnsFalseIfForkNotDetected() throws Exception {
int containerNum = 5;
when(service.getForkStatus(containerNum)).thenReturn(false);
when(service.getForkStatus(containerNum)).thenReturn(ForkStatus.NORMAL);

mockMvc.perform(get("/api/v1/forkStatus")
.header("Origin", "http://localhost:4000")
.param("containerNum", String.valueOf(containerNum)))
.andExpect(status().isOk())
.andExpect(content().string("false"));
.andExpect(content().json("{\"status\":\"NORMAL\"}"));
}

@Test
public void returnsNotFoundWhenIllegalArgumentExceptionThrown() throws Exception {
public void returnsNotAvailableWhenChannelIsNotAvailable() throws Exception {
int containerNum = 5;
when(service.getForkStatus(containerNum)).thenThrow(
new IllegalArgumentException("Entity not found"));
when(service.getForkStatus(containerNum)).thenReturn(ForkStatus.NOT_AVAILABLE);

mockMvc.perform(get("/api/v1/forkStatus")
.header("Origin", "https://example.com:8000")
.param("containerNum", String.valueOf(containerNum)))
.andExpect(status().isNotFound());
.andExpect(status().isOk())
.andExpect(content().json("{\"status\":\"NOT_AVAILABLE\"}"));
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package uk.ac.ic.doc.blocc.dashboard.forkstatus;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;

import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import org.hyperledger.fabric.client.Contract;
import org.hyperledger.fabric.client.GatewayException;
import org.hyperledger.fabric.client.Network;
Expand All @@ -13,6 +16,7 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import uk.ac.ic.doc.blocc.dashboard.fabric.BloccConnections;
import uk.ac.ic.doc.blocc.dashboard.forkstatus.model.ForkStatus;

public class ForkStatusServiceTest {

Expand Down Expand Up @@ -41,9 +45,9 @@ public void returnsTrueIfForkDetected() throws GatewayException {
when(bscc.evaluateTransaction("CheckForkStatus", "channel5"))
.thenReturn("true".getBytes());

boolean result = service.getForkStatus(containerNum);
ForkStatus result = service.getForkStatus(containerNum);

assertTrue(result);
assertSame(ForkStatus.FORKED, result);
}

@Test
Expand All @@ -54,8 +58,36 @@ public void returnsFalseIfForkNotDetected() throws GatewayException {
when(bscc.evaluateTransaction("CheckForkStatus", "channel5"))
.thenReturn("false".getBytes());

boolean result = service.getForkStatus(containerNum);
ForkStatus result = service.getForkStatus(containerNum);

assertFalse(result);
assertSame(ForkStatus.NORMAL, result);
}

@Test
public void returnsNotAvailableIfChannelIsUnAvailable() throws GatewayException {
int containerNum = 5;
when(connections.getChannel(containerNum)).thenReturn(channel);
when(channel.getContract("bscc")).thenReturn(bscc);
when(bscc.evaluateTransaction("CheckForkStatus", "channel5"))
.thenThrow(new GatewayException(new StatusRuntimeException(Status.UNAVAILABLE)));

ForkStatus result = service.getForkStatus(containerNum);

assertSame(ForkStatus.NOT_AVAILABLE, result);
}

@Test
public void throwExceptionForOtherStatusRuntimeException() throws GatewayException {
int containerNum = 5;
GatewayException e = new GatewayException(new StatusRuntimeException(Status.UNKNOWN));
when(connections.getChannel(containerNum)).thenReturn(channel);
when(channel.getContract("bscc")).thenReturn(bscc);
when(bscc.evaluateTransaction("CheckForkStatus", "channel5"))
.thenThrow(e);

Throwable thrownException = assertThrows(GatewayException.class,
() -> service.getForkStatus(containerNum));

assertEquals(e, thrownException);
}
}

0 comments on commit e6c46f9

Please sign in to comment.