diff --git a/examples/src/test/java/io/mosn/layotto/examples/sequencer/Sequencer.java b/examples/src/test/java/io/mosn/layotto/examples/sequencer/Sequencer.java new file mode 100644 index 0000000..a70eaab --- /dev/null +++ b/examples/src/test/java/io/mosn/layotto/examples/sequencer/Sequencer.java @@ -0,0 +1,38 @@ +package io.mosn.layotto.examples.sequencer; + +import io.mosn.layotto.examples.file.File; +import io.mosn.layotto.v1.RuntimeClientBuilder; +import io.mosn.layotto.v1.config.RuntimeProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import spec.sdk.runtime.v1.client.RuntimeClient; +import spec.sdk.runtime.v1.domain.sequencer.GetNextIdRequest; +import spec.sdk.runtime.v1.domain.sequencer.GetNextIdResponse; +import spec.sdk.runtime.v1.domain.sequencer.SequencerOptions; + +public class Sequencer { + + private static final Logger logger = LoggerFactory.getLogger(Sequencer.class.getName()); + + static String storeName = "redis"; + static String key = "examples"; + static SequencerOptions options = new SequencerOptions(); + + public static void main(String[] args) { + options.setOption(SequencerOptions.AutoIncrement.WEAK); + + RuntimeClient client = new RuntimeClientBuilder() + .withPort(RuntimeProperties.DEFAULT_PORT) + .build(); + + GetNextIdRequest getNextIdRequest = new GetNextIdRequest(); + getNextIdRequest.setStoreName(storeName); + getNextIdRequest.setKey(key); + getNextIdRequest.setOptions(options); + + GetNextIdResponse nextId = client.getNextId(getNextIdRequest); + + System.out.println("id :"+nextId.getNextId()); + } + +} diff --git a/sdk/src/main/java/io/mosn/layotto/v1/RuntimeClientGrpc.java b/sdk/src/main/java/io/mosn/layotto/v1/RuntimeClientGrpc.java index 21bf4a8..29cfdf0 100644 --- a/sdk/src/main/java/io/mosn/layotto/v1/RuntimeClientGrpc.java +++ b/sdk/src/main/java/io/mosn/layotto/v1/RuntimeClientGrpc.java @@ -42,6 +42,8 @@ import spec.sdk.runtime.v1.domain.file.PutFileRequest; import spec.sdk.runtime.v1.domain.file.PutFileResponse; import spec.sdk.runtime.v1.domain.invocation.InvokeResponse; +import spec.sdk.runtime.v1.domain.sequencer.GetNextIdRequest; +import spec.sdk.runtime.v1.domain.sequencer.GetNextIdResponse; import spec.sdk.runtime.v1.domain.state.DeleteStateRequest; import spec.sdk.runtime.v1.domain.state.ExecuteStateTransactionRequest; import spec.sdk.runtime.v1.domain.state.GetBulkStateRequest; @@ -990,4 +992,33 @@ private ListFileResponse buildListFileResponse(RuntimeProto.ListFileResp resp) { return result; } + + @Override + public GetNextIdResponse getNextId(GetNextIdRequest req) { + try { + RuntimeProto.SequencerOptions.AutoIncrement autoIncrement = RuntimeProto.SequencerOptions.AutoIncrement.forNumber(req.getOptionsValue()); + + RuntimeProto.SequencerOptions options = RuntimeProto.SequencerOptions.newBuilder() + .setIncrement(autoIncrement) + .build(); + + RuntimeProto.GetNextIdRequest request = RuntimeProto.GetNextIdRequest.newBuilder() + .setKey(req.getKey()) + .setOptions(options) + .setStoreName(req.getStoreName()) + .putAllMetadata(req.getMetaData()) + .build(); + + RuntimeProto.GetNextIdResponse response = stubManager.getBlockingStub() + .getNextId(request); + + GetNextIdResponse getNextIdResponse = new GetNextIdResponse(); + getNextIdResponse.setNextId(response.getNextId()); + + return getNextIdResponse; + } catch (Exception e) { + logger.error("getNextId error ", e); + throw new RuntimeClientException(e); + } + } } diff --git a/sdk/src/main/java/spec/sdk/runtime/v1/domain/SequencerRuntime.java b/sdk/src/main/java/spec/sdk/runtime/v1/domain/SequencerRuntime.java index 46c8bb6..148a955 100644 --- a/sdk/src/main/java/spec/sdk/runtime/v1/domain/SequencerRuntime.java +++ b/sdk/src/main/java/spec/sdk/runtime/v1/domain/SequencerRuntime.java @@ -14,5 +14,11 @@ */ package spec.sdk.runtime.v1.domain; +import spec.sdk.runtime.v1.domain.sequencer.GetNextIdRequest; +import spec.sdk.runtime.v1.domain.sequencer.GetNextIdResponse; + public interface SequencerRuntime { + + GetNextIdResponse getNextId(GetNextIdRequest req); + } diff --git a/sdk/src/main/java/spec/sdk/runtime/v1/domain/sequencer/GetNextIdRequest.java b/sdk/src/main/java/spec/sdk/runtime/v1/domain/sequencer/GetNextIdRequest.java new file mode 100644 index 0000000..4a84c63 --- /dev/null +++ b/sdk/src/main/java/spec/sdk/runtime/v1/domain/sequencer/GetNextIdRequest.java @@ -0,0 +1,59 @@ +package spec.sdk.runtime.v1.domain.sequencer; + +import java.util.HashMap; +import java.util.Map; + +public class GetNextIdRequest { + + private String storeName; + + private String key; + + private SequencerOptions options; + + private Map metaData; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public SequencerOptions getOptions() { + return options; + } + + public void setOptions(SequencerOptions options) { + this.options = options; + } + + public String getStoreName() { + return storeName; + } + + public void setStoreName(String storeName) { + this.storeName = storeName; + } + + public Map getMetaData() { + if (metaData == null) { + metaData = new HashMap<>(); + } + + return metaData; + } + + public void setMetadata(Map metaData) { + this.metaData = metaData; + } + + public Integer getOptionsValue() { + if(options != null && options.getOption() != null){ + return options.getOption().getValue(); + } + + return -1; + } +} diff --git a/sdk/src/main/java/spec/sdk/runtime/v1/domain/sequencer/GetNextIdResponse.java b/sdk/src/main/java/spec/sdk/runtime/v1/domain/sequencer/GetNextIdResponse.java new file mode 100644 index 0000000..3faeff5 --- /dev/null +++ b/sdk/src/main/java/spec/sdk/runtime/v1/domain/sequencer/GetNextIdResponse.java @@ -0,0 +1,14 @@ +package spec.sdk.runtime.v1.domain.sequencer; + +public class GetNextIdResponse { + + private long nextId; + + public long getNextId() { + return nextId; + } + + public void setNextId(long nextId) { + this.nextId = nextId; + } +} diff --git a/sdk/src/main/java/spec/sdk/runtime/v1/domain/sequencer/SequencerOptions.java b/sdk/src/main/java/spec/sdk/runtime/v1/domain/sequencer/SequencerOptions.java new file mode 100644 index 0000000..1442d5a --- /dev/null +++ b/sdk/src/main/java/spec/sdk/runtime/v1/domain/sequencer/SequencerOptions.java @@ -0,0 +1,28 @@ +package spec.sdk.runtime.v1.domain.sequencer; + +public class SequencerOptions { + + private AutoIncrement option; + + public AutoIncrement getOption() { + return option; + } + + public enum AutoIncrement { + WEAK(0), + STRONG(1); + private final Integer value; + + AutoIncrement(Integer value) { + this.value = value; + } + + public Integer getValue() { + return value; + } + } + + public void setOption(AutoIncrement option) { + this.option = option; + } +} diff --git a/sdk/src/test/java/io/mosn/layotto/v1/SequencerTest.java b/sdk/src/test/java/io/mosn/layotto/v1/SequencerTest.java new file mode 100644 index 0000000..5ffd784 --- /dev/null +++ b/sdk/src/test/java/io/mosn/layotto/v1/SequencerTest.java @@ -0,0 +1,69 @@ +package io.mosn.layotto.v1; + +import io.grpc.ManagedChannel; +import io.grpc.inprocess.InProcessChannelBuilder; +import io.grpc.inprocess.InProcessServerBuilder; +import io.grpc.stub.StreamObserver; +import io.grpc.testing.GrpcCleanupRule; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import spec.proto.runtime.v1.RuntimeGrpc; +import spec.proto.runtime.v1.RuntimeProto; +import spec.sdk.runtime.v1.client.RuntimeClient; +import spec.sdk.runtime.v1.domain.sequencer.GetNextIdRequest; +import spec.sdk.runtime.v1.domain.sequencer.GetNextIdResponse; +import spec.sdk.runtime.v1.domain.sequencer.SequencerOptions; + +import static org.junit.Assert.assertEquals; +import static org.mockito.AdditionalAnswers.delegatesTo; +import static org.mockito.Mockito.mock; + +@RunWith(JUnit4.class) +public class SequencerTest { + @Rule + public final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule(); + + private final RuntimeGrpc.RuntimeImplBase serviceImpl = mock(RuntimeGrpc.RuntimeImplBase.class,delegatesTo(new RuntimeGrpc.RuntimeImplBase(){ + @Override + public void getNextId(RuntimeProto.GetNextIdRequest request, StreamObserver responseObserver) { + responseObserver.onNext( + RuntimeProto.GetNextIdResponse + .newBuilder() + .setNextId(1) + .build()); + responseObserver.onCompleted(); + } + })); + + private RuntimeClient client; + + @Before + public void setUp() throws Exception { + String serverName = InProcessServerBuilder.generateName(); + + grpcCleanup.register(InProcessServerBuilder + .forName(serverName).directExecutor().addService(serviceImpl).build().start()); + + ManagedChannel channel = grpcCleanup.register( + InProcessChannelBuilder.forName(serverName).directExecutor().build()); + + client = new RuntimeClientBuilder() + .buildGrpcWithExistingChannel(channel); + } + + @Test + public void getNextId() { + GetNextIdRequest getNextIdRequest = new GetNextIdRequest(); + SequencerOptions sequencerOptions = new SequencerOptions(); + sequencerOptions.setOption(SequencerOptions.AutoIncrement.WEAK); + getNextIdRequest.setStoreName("redis"); + getNextIdRequest.setKey("test"); + getNextIdRequest.setOptions(sequencerOptions); + + GetNextIdResponse nextId = client.getNextId(getNextIdRequest); + assertEquals(nextId.getNextId(), 1); + } +} diff --git a/sdk/src/test/java/io/mosn/layotto/v1/SequencerTestWithRealServer.java b/sdk/src/test/java/io/mosn/layotto/v1/SequencerTestWithRealServer.java new file mode 100644 index 0000000..17e920d --- /dev/null +++ b/sdk/src/test/java/io/mosn/layotto/v1/SequencerTestWithRealServer.java @@ -0,0 +1,68 @@ +package io.mosn.layotto.v1; + +import io.grpc.Server; +import io.grpc.ServerBuilder; +import io.mosn.layotto.v1.grpc.ExceptionHandler; +import io.mosn.layotto.v1.grpc.GrpcRuntimeClient; +import io.mosn.layotto.v1.mock.MyFileService; +import io.mosn.layotto.v1.mock.MySequencerService; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import spec.proto.runtime.v1.RuntimeGrpc; +import spec.proto.runtime.v1.RuntimeProto; +import spec.sdk.runtime.v1.domain.sequencer.*; + +import static org.junit.Assert.assertEquals; + +@RunWith(JUnit4.class) +public class SequencerTestWithRealServer { + + private final RuntimeGrpc.RuntimeImplBase sequencerService = new MySequencerService(); + + private Server srv; + private GrpcRuntimeClient client; + + int port = 9999; + String ip = "127.0.0.1"; + + @Before + public void setUp() throws Exception { + // start grpc server + /* The port on which the server should run */ + srv = ServerBuilder.forPort(port) + .addService(sequencerService) + .intercept(new ExceptionHandler()) + .build() + .start(); + + // build a client + client = new RuntimeClientBuilder() + .withIp(ip) + .withPort(port) + .withConnectionPoolSize(4) + .withTimeout(1000) + .buildGrpc(); + } + + @After + public void shutdown() throws InterruptedException { + client.shutdown(); + srv.shutdownNow(); + } + + @Test + public void getNextId() { + GetNextIdRequest getNextIdRequest = new GetNextIdRequest(); + SequencerOptions sequencerOptions = new SequencerOptions(); + sequencerOptions.setOption(SequencerOptions.AutoIncrement.WEAK); + getNextIdRequest.setStoreName("redis"); + getNextIdRequest.setKey("test"); + getNextIdRequest.setOptions(sequencerOptions); + + GetNextIdResponse nextId = client.getNextId(getNextIdRequest); + assertEquals(nextId.getNextId(), 1); + } +} diff --git a/sdk/src/test/java/io/mosn/layotto/v1/mock/MySequencerService.java b/sdk/src/test/java/io/mosn/layotto/v1/mock/MySequencerService.java new file mode 100644 index 0000000..9e4a591 --- /dev/null +++ b/sdk/src/test/java/io/mosn/layotto/v1/mock/MySequencerService.java @@ -0,0 +1,17 @@ +package io.mosn.layotto.v1.mock; + +import io.grpc.stub.StreamObserver; +import spec.proto.runtime.v1.RuntimeGrpc; +import spec.proto.runtime.v1.RuntimeProto; + +public class MySequencerService extends RuntimeGrpc.RuntimeImplBase{ + + @Override + public void getNextId(RuntimeProto.GetNextIdRequest request, StreamObserver responseObserver) { + RuntimeProto.GetNextIdResponse response = RuntimeProto.GetNextIdResponse.newBuilder() + .setNextId(1) + .build(); + responseObserver.onNext(response); + responseObserver.onCompleted(); + } +}