You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by se...@apache.org on 2017/12/29 09:18:18 UTC
[incubator-servicecomb-saga] 01/05: SCB-138 replace thrift with grpc
This is an automated email from the ASF dual-hosted git repository.
seanyinx pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-saga.git
commit b4ced3e24bfdf3cc23eb8a8bdaf37bde30e9587b
Author: Eric Lee <da...@huawei.com>
AuthorDate: Thu Dec 28 20:53:51 2017 +0800
SCB-138 replace thrift with grpc
Signed-off-by: Eric Lee <da...@huawei.com>
---
alpha/alpha-server/pom.xml | 13 ++++-
.../servicecomb/saga/alpha/server/AlphaConfig.java | 20 +++++--
.../{ThriftStartable.java => GrpcStartable.java} | 42 ++++++++------
.../saga/alpha/server/GrpcTxEventEndpointImpl.java | 54 ++++++++++++++++++
.../saga/alpha/server/ServerStartable.java | 9 ++-
.../saga/alpha/server/ThriftStartable.java | 5 +-
.../saga/alpha/server/AlphaIntegrationTest.java | 52 +++++++++++++-----
.../omega-connector-grpc}/pom.xml | 43 ++++++++++++---
.../connector/grpc/GrpcClientMessageSender.java | 61 +++++++++++++++++++++
.../connector/grpc/GrpcTxEventEndpointImpl.java} | 23 +++++++-
.../grpc/GrpcClientMessageSenderTest.java} | 64 +++++++++++++---------
.../connector/thrift/ThriftMessageSenderTest.java | 22 +++++---
omega/omega-connector/pom.xml | 1 +
.../saga/omega/format/NativeMessageFormat.java | 13 ++++-
omega/omega-spring-starter/pom.xml | 12 ++++
.../saga/omega/spring/OmegaSpringConfig.java | 34 +++++++++++-
.../saga/omega/transaction/MessageSerializer.java | 2 +
.../pack-contract-grpc}/pom.xml | 36 ++++++++----
.../pack/contract/grpc/GrpcTxEventEndpoint.java | 9 ++-
.../src/main/proto/GrpcTxEvent.proto | 37 +++++++++++++
pack-contracts/pom.xml | 1 +
pom.xml | 44 +++++++++++++++
22 files changed, 494 insertions(+), 103 deletions(-)
diff --git a/alpha/alpha-server/pom.xml b/alpha/alpha-server/pom.xml
index 774883d..0c30904 100644
--- a/alpha/alpha-server/pom.xml
+++ b/alpha/alpha-server/pom.xml
@@ -54,6 +54,18 @@
<artifactId>pack-contract-thrift</artifactId>
</dependency>
<dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-protobuf</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-netty</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.servicecomb.saga</groupId>
+ <artifactId>pack-contract-grpc</artifactId>
+ </dependency>
+ <dependency>
<groupId>io.servicecomb.saga</groupId>
<artifactId>alpha-core</artifactId>
</dependency>
@@ -84,7 +96,6 @@
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
</dependency>
-
</dependencies>
<build>
diff --git a/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaConfig.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaConfig.java
index d443fa7..a453c81 100644
--- a/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaConfig.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaConfig.java
@@ -43,15 +43,27 @@ class AlphaConfig {
TxEventRepository eventRepository = new SpringTxEventRepository(eventRepo);
- ThriftStartable startable = new ThriftStartable(
+ ServerStartable startable = buildGrpc(port, omegaCallback, eventRepository);
+ CompletableFuture.runAsync(startable::start);
+
+ return eventRepository;
+ }
+
+ private ServerStartable buildThrift(int port, OmegaCallback omegaCallback, TxEventRepository eventRepository) {
+ return new ThriftStartable(
port,
new SwiftTxEventEndpointImpl(
new TxConsistentService(
eventRepository,
omegaCallback)));
+ }
- CompletableFuture.runAsync(startable::start);
-
- return eventRepository;
+ private ServerStartable buildGrpc(int port, OmegaCallback omegaCallback, TxEventRepository eventRepository) {
+ return new GrpcStartable(
+ port,
+ new GrpcTxEventEndpointImpl(
+ new TxConsistentService(
+ eventRepository,
+ omegaCallback)));
}
}
diff --git a/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/ThriftStartable.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/GrpcStartable.java
similarity index 51%
copy from alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/ThriftStartable.java
copy to alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/GrpcStartable.java
index 71acc2f..6affb62 100644
--- a/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/ThriftStartable.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/GrpcStartable.java
@@ -1,4 +1,5 @@
/*
+ *
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
@@ -13,31 +14,40 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
+ *
+ *
*/
package io.servicecomb.saga.alpha.server;
-import java.util.Collections;
+import java.io.IOException;
+import java.util.Arrays;
+
+import io.grpc.BindableService;
+import io.grpc.Server;
+import io.grpc.ServerBuilder;
-import com.facebook.swift.codec.ThriftCodecManager;
-import com.facebook.swift.service.ThriftServer;
-import com.facebook.swift.service.ThriftServerConfig;
-import com.facebook.swift.service.ThriftServiceProcessor;
+class GrpcStartable implements ServerStartable {
-class ThriftStartable {
- private final ThriftServer server;
+ private final Server server;
- ThriftStartable(int port, Object... services) {
- server = new ThriftServer(
- new ThriftServiceProcessor(new ThriftCodecManager(),
- Collections.emptyList(),
- services),
- new ThriftServerConfig().setPort(port));
+ GrpcStartable(int port, BindableService... services) {
+ ServerBuilder<?> serverBuilder = ServerBuilder.forPort(port);
+ Arrays.stream(services).forEach(serverBuilder::addService);
+ server = serverBuilder.build();
}
- void start() {
- Runtime.getRuntime().addShutdownHook(new Thread(server::close));
+ @Override
+ public void start() {
+ Runtime.getRuntime().addShutdownHook(new Thread(server::shutdown));
- server.start();
+ try {
+ server.start();
+ server.awaitTermination();
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to start grpc server.", e);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
}
}
diff --git a/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/GrpcTxEventEndpointImpl.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/GrpcTxEventEndpointImpl.java
new file mode 100644
index 0000000..278183c
--- /dev/null
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/GrpcTxEventEndpointImpl.java
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+
+package io.servicecomb.saga.alpha.server;
+
+import java.util.Date;
+
+import io.grpc.stub.StreamObserver;
+import io.servicecomb.saga.alpha.core.TxConsistentService;
+import io.servicecomb.saga.alpha.core.TxEvent;
+import io.servicecomb.saga.pack.contract.grpc.GrpcEmpty;
+import io.servicecomb.saga.pack.contract.grpc.GrpcTxEvent;
+import io.servicecomb.saga.pack.contract.grpc.TxEventServiceGrpc.TxEventServiceImplBase;
+
+class GrpcTxEventEndpointImpl extends TxEventServiceImplBase {
+
+ private final TxConsistentService txConsistentService;
+
+ GrpcTxEventEndpointImpl(TxConsistentService txConsistentService) {
+ this.txConsistentService = txConsistentService;
+ }
+
+ @Override
+ public void reportEvent(GrpcTxEvent message, StreamObserver<GrpcEmpty> responseObserver) {
+ txConsistentService.handle(new TxEvent(
+ new Date(message.getTimestamp()),
+ message.getGlobalTxId(),
+ message.getLocalTxId(),
+ message.getParentTxId(),
+ message.getType(),
+ message.getPayloads().toByteArray()
+ ));
+ GrpcEmpty reply = GrpcEmpty.newBuilder().build();
+ responseObserver.onNext(reply);
+ responseObserver.onCompleted();
+ }
+}
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/ServerStartable.java
similarity index 87%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java
copy to alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/ServerStartable.java
index b1eb7fd..4657cec 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/ServerStartable.java
@@ -1,4 +1,5 @@
/*
+ *
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
@@ -13,10 +14,12 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
+ *
+ *
*/
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.alpha.server;
-public interface MessageSerializer {
- byte[] serialize(TxEvent event);
+interface ServerStartable {
+ void start();
}
diff --git a/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/ThriftStartable.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/ThriftStartable.java
index 71acc2f..0da6a5c 100644
--- a/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/ThriftStartable.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/ThriftStartable.java
@@ -24,7 +24,7 @@ import com.facebook.swift.service.ThriftServer;
import com.facebook.swift.service.ThriftServerConfig;
import com.facebook.swift.service.ThriftServiceProcessor;
-class ThriftStartable {
+class ThriftStartable implements ServerStartable {
private final ThriftServer server;
ThriftStartable(int port, Object... services) {
@@ -35,7 +35,8 @@ class ThriftStartable {
new ThriftServerConfig().setPort(port));
}
- void start() {
+ @Override
+ public void start() {
Runtime.getRuntime().addShutdownHook(new Thread(server::close));
server.start();
diff --git a/alpha/alpha-server/src/test/java/io/servicecomb/saga/alpha/server/AlphaIntegrationTest.java b/alpha/alpha-server/src/test/java/io/servicecomb/saga/alpha/server/AlphaIntegrationTest.java
index f7ec33c..1be42f9 100644
--- a/alpha/alpha-server/src/test/java/io/servicecomb/saga/alpha/server/AlphaIntegrationTest.java
+++ b/alpha/alpha-server/src/test/java/io/servicecomb/saga/alpha/server/AlphaIntegrationTest.java
@@ -17,7 +17,6 @@
package io.servicecomb.saga.alpha.server;
-import static com.google.common.net.HostAndPort.fromParts;
import static io.servicecomb.saga.alpha.core.EventType.TxAbortedEvent;
import static io.servicecomb.saga.alpha.core.EventType.TxEndedEvent;
import static io.servicecomb.saga.alpha.core.EventType.TxStartedEvent;
@@ -45,23 +44,31 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringRunner;
-import com.facebook.nifty.client.FramedClientConnector;
-import com.facebook.swift.service.ThriftClientManager;
+import com.google.protobuf.ByteString;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
import io.servicecomb.saga.alpha.core.EventType;
import io.servicecomb.saga.alpha.core.OmegaCallback;
import io.servicecomb.saga.alpha.core.TxEvent;
import io.servicecomb.saga.alpha.server.AlphaIntegrationTest.OmegaCallbackConfig;
+import io.servicecomb.saga.pack.contract.grpc.GrpcTxEvent;
+import io.servicecomb.saga.pack.contract.grpc.TxEventServiceGrpc;
+import io.servicecomb.saga.pack.contract.grpc.TxEventServiceGrpc.TxEventServiceBlockingStub;
import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEvent;
-import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEventEndpoint;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {AlphaApplication.class, OmegaCallbackConfig.class}, properties = "alpha.server.port=8090")
public class AlphaIntegrationTest {
- private static final ThriftClientManager clientManager = new ThriftClientManager();
- private static final String payload = "hello world";
+ private static final int port = 8090;
+
+ // private static final ThriftClientManager clientManager = new ThriftClientManager();
+ private static ManagedChannel clientChannel = ManagedChannelBuilder
+ .forAddress("localhost", port).usePlaintext(true).build();
- private final int port = 8090;
+ private TxEventServiceBlockingStub stub = TxEventServiceGrpc.newBlockingStub(clientChannel);
+
+ private static final String payload = "hello world";
private final String globalTxId = UUID.randomUUID().toString();
private final String localTxId = UUID.randomUUID().toString();
@@ -74,27 +81,30 @@ public class AlphaIntegrationTest {
@Autowired
private List<CompensationContext> compensationContexts;
- private final FramedClientConnector connector = new FramedClientConnector(fromParts("localhost", port));
- private SwiftTxEventEndpoint endpoint;
+// private final FramedClientConnector connector = new FramedClientConnector(fromParts("localhost", port));
+// private SwiftTxEventEndpoint endpoint;
+
@AfterClass
public static void tearDown() throws Exception {
- clientManager.close();
+ clientChannel.shutdown();
+// clientManager.close();
}
@Before
- public void setUp() throws Exception {
- endpoint = clientManager.createClient(connector, SwiftTxEventEndpoint.class).get();
+ public void before() throws Exception {
+// endpoint = clientManager.createClient(connector, SwiftTxEventEndpoint.class).get();
}
@After
public void after() throws Exception {
- endpoint.close();
+// endpoint.close();
}
@Test
public void persistsEvent() throws Exception {
- endpoint.handle(someEvent(TxStartedEvent));
+// endpoint.handle(someEvent(TxStartedEvent));
+ stub.reportEvent(someGrpcEvent(TxStartedEvent));
TxEventEnvelope envelope = eventRepo.findByEventGlobalTxId(globalTxId);
@@ -117,7 +127,8 @@ public class AlphaIntegrationTest {
eventRepo.save(eventEnvelopeOf(TxStartedEvent, localTxId1, UUID.randomUUID().toString(), "service b".getBytes()));
eventRepo.save(eventEnvelopeOf(TxEndedEvent, new byte[0]));
- endpoint.handle(someEvent(TxAbortedEvent));
+// endpoint.handle(someEvent(TxAbortedEvent));
+ stub.reportEvent(someGrpcEvent(TxAbortedEvent));
await().atMost(1, SECONDS).until(() -> compensationContexts.size() > 1);
assertThat(compensationContexts, containsInAnyOrder(
@@ -137,6 +148,17 @@ public class AlphaIntegrationTest {
payload.getBytes());
}
+ private GrpcTxEvent someGrpcEvent(EventType type) {
+ return GrpcTxEvent.newBuilder()
+ .setTimestamp(System.currentTimeMillis())
+ .setGlobalTxId(this.globalTxId)
+ .setLocalTxId(this.localTxId)
+ .setParentTxId(this.parentTxId)
+ .setType(type.name())
+ .setPayloads(ByteString.copyFrom(payload.getBytes()))
+ .build();
+ }
+
private TxEventEnvelope eventEnvelopeOf(EventType eventType, byte[] payloads) {
return eventEnvelopeOf(eventType, UUID.randomUUID().toString(), UUID.randomUUID().toString(), payloads);
}
diff --git a/omega/omega-spring-starter/pom.xml b/omega/omega-connector/omega-connector-grpc/pom.xml
similarity index 59%
copy from omega/omega-spring-starter/pom.xml
copy to omega/omega-connector/omega-connector-grpc/pom.xml
index 59b81f8..a6cf1a2 100644
--- a/omega/omega-spring-starter/pom.xml
+++ b/omega/omega-connector/omega-connector-grpc/pom.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
+ ~
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
@@ -14,33 +15,59 @@
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
+ ~
+ ~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
- <artifactId>omega</artifactId>
+ <artifactId>omega-connector</artifactId>
<groupId>io.servicecomb.saga</groupId>
<version>0.0.3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
- <artifactId>omega-spring-starter</artifactId>
+ <artifactId>omega-connector-grpc</artifactId>
<dependencies>
<dependency>
- <groupId>io.servicecomb.saga</groupId>
- <artifactId>omega-spring-tx</artifactId>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-protobuf</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-netty</artifactId>
</dependency>
<dependency>
<groupId>io.servicecomb.saga</groupId>
- <artifactId>omega-connector-thrift</artifactId>
+ <artifactId>omega-transaction</artifactId>
</dependency>
<dependency>
<groupId>io.servicecomb.saga</groupId>
- <artifactId>omega-format</artifactId>
+ <artifactId>pack-contract-grpc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
</dependency>
- </dependencies>
-</project>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.github.seanyinx</groupId>
+ <artifactId>unit-scaffolding</artifactId>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git a/omega/omega-connector/omega-connector-grpc/src/main/java/io/servicecomb/saga/omega/connector/grpc/GrpcClientMessageSender.java b/omega/omega-connector/omega-connector-grpc/src/main/java/io/servicecomb/saga/omega/connector/grpc/GrpcClientMessageSender.java
new file mode 100644
index 0000000..25f6223
--- /dev/null
+++ b/omega/omega-connector/omega-connector-grpc/src/main/java/io/servicecomb/saga/omega/connector/grpc/GrpcClientMessageSender.java
@@ -0,0 +1,61 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+
+package io.servicecomb.saga.omega.connector.grpc;
+
+import com.google.protobuf.ByteString;
+
+import io.servicecomb.saga.omega.transaction.MessageSender;
+import io.servicecomb.saga.omega.transaction.MessageSerializer;
+import io.servicecomb.saga.omega.transaction.TxEvent;
+import io.servicecomb.saga.pack.contract.grpc.GrpcTxEvent;
+import io.servicecomb.saga.pack.contract.grpc.GrpcTxEvent.Builder;
+import io.servicecomb.saga.pack.contract.grpc.GrpcTxEventEndpoint;
+
+public class GrpcClientMessageSender implements MessageSender {
+
+ private final GrpcTxEventEndpoint eventService;
+
+ private final MessageSerializer serializer;
+
+ public GrpcClientMessageSender(GrpcTxEventEndpoint eventService, MessageSerializer serializer) {
+ this.eventService = eventService;
+ this.serializer = serializer;
+ }
+
+ @Override
+ public void send(TxEvent event) {
+ eventService.reportEvent(convertEvent(event));
+ }
+
+ private GrpcTxEvent convertEvent(TxEvent event) {
+ ByteString payloads = ByteString.copyFrom(serializer.serialize(event.payloads()));
+ Builder builder = GrpcTxEvent.newBuilder()
+ .setTimestamp(event.timestamp())
+ .setGlobalTxId(event.globalTxId())
+ .setLocalTxId(event.localTxId())
+ .setType(event.type())
+ .setPayloads(payloads);
+ if (event.parentTxId() != null) {
+ builder.setParentTxId(event.parentTxId());
+ }
+ return builder.build();
+ }
+}
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java b/omega/omega-connector/omega-connector-grpc/src/main/java/io/servicecomb/saga/omega/connector/grpc/GrpcTxEventEndpointImpl.java
similarity index 57%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java
copy to omega/omega-connector/omega-connector-grpc/src/main/java/io/servicecomb/saga/omega/connector/grpc/GrpcTxEventEndpointImpl.java
index b1eb7fd..b3f2b26 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java
+++ b/omega/omega-connector/omega-connector-grpc/src/main/java/io/servicecomb/saga/omega/connector/grpc/GrpcTxEventEndpointImpl.java
@@ -1,4 +1,5 @@
/*
+ *
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
@@ -13,10 +14,26 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
+ *
+ *
*/
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.omega.connector.grpc;
+
+import io.servicecomb.saga.pack.contract.grpc.GrpcTxEvent;
+import io.servicecomb.saga.pack.contract.grpc.GrpcTxEventEndpoint;
+import io.servicecomb.saga.pack.contract.grpc.TxEventServiceGrpc.TxEventServiceBlockingStub;
+
+public class GrpcTxEventEndpointImpl implements GrpcTxEventEndpoint {
+
+ private final TxEventServiceBlockingStub stub;
+
+ public GrpcTxEventEndpointImpl(TxEventServiceBlockingStub stub) {
+ this.stub = stub;
+ }
-public interface MessageSerializer {
- byte[] serialize(TxEvent event);
+ @Override
+ public void reportEvent(GrpcTxEvent event) {
+ stub.reportEvent(event);
+ }
}
diff --git a/omega/omega-connector/omega-connector-thrift/src/test/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSenderTest.java b/omega/omega-connector/omega-connector-grpc/src/test/java/io/servicecomb/saga/omega/connector/grpc/GrpcClientMessageSenderTest.java
similarity index 55%
copy from omega/omega-connector/omega-connector-thrift/src/test/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSenderTest.java
copy to omega/omega-connector/omega-connector-grpc/src/test/java/io/servicecomb/saga/omega/connector/grpc/GrpcClientMessageSenderTest.java
index 05f984c..ca4f034 100644
--- a/omega/omega-connector/omega-connector-thrift/src/test/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSenderTest.java
+++ b/omega/omega-connector/omega-connector-grpc/src/test/java/io/servicecomb/saga/omega/connector/grpc/GrpcClientMessageSenderTest.java
@@ -1,4 +1,5 @@
/*
+ *
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
@@ -13,9 +14,11 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
+ *
+ *
*/
-package io.servicecomb.saga.omega.connector.thrift;
+package io.servicecomb.saga.omega.connector.grpc;
import static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;
import static org.hamcrest.core.Is.is;
@@ -28,53 +31,60 @@ import org.junit.Test;
import io.servicecomb.saga.omega.transaction.MessageSerializer;
import io.servicecomb.saga.omega.transaction.TxEvent;
-import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEvent;
-import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEventEndpoint;
-
-public class ThriftMessageSenderTest {
+import io.servicecomb.saga.pack.contract.grpc.GrpcTxEvent;
+import io.servicecomb.saga.pack.contract.grpc.GrpcTxEventEndpoint;
+public class GrpcClientMessageSenderTest {
private final String globalTxId = uniquify("global tx id");
+
private final String localTxId = uniquify("local tx id");
+
private final String parentTxId = uniquify("parent tx id");
+
private final String payload1 = uniquify("payload1");
+
private final String payload2 = uniquify("payload2");
- private SwiftTxEvent swiftTxEvent;
+ private GrpcTxEvent grpcTxEvent;
- private final MessageSerializer serializer = (event) -> {
- try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
- for (Object o : event.payloads()) {
- stream.write(o.toString().getBytes());
- }
- return stream.toByteArray();
- } catch (IOException e) {
- throw new IllegalStateException(e);
+ private final MessageSerializer serializer = new MessageSerializer() {
+ @Override
+ public byte[] serialize(TxEvent event) {
+ return serialize(event.payloads());
}
- };
- private final SwiftTxEventEndpoint eventService = new SwiftTxEventEndpoint() {
@Override
- public void handle(SwiftTxEvent message) {
- swiftTxEvent = message;
+ public byte[] serialize(Object[] objects) {
+ try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
+ for (Object o : objects) {
+ stream.write(o.toString().getBytes());
+ }
+ return stream.toByteArray();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
}
+ };
+
+ private final GrpcTxEventEndpoint eventService = new GrpcTxEventEndpoint() {
@Override
- public void close() throws Exception {
+ public void reportEvent(GrpcTxEvent event) {
+ grpcTxEvent = event;
}
};
- private final ThriftMessageSender messageSender = new ThriftMessageSender(eventService, serializer);
+ private final GrpcClientMessageSender messageSender = new GrpcClientMessageSender(eventService, serializer);
@Test
public void sendSerializedEvent() throws Exception {
- TxEvent event = new TxEvent(globalTxId, localTxId, parentTxId, getClass().getCanonicalName(), payload1, payload2);
+ TxEvent event = new TxEvent(globalTxId, localTxId, parentTxId, payload1, payload2);
messageSender.send(event);
- assertThat(swiftTxEvent.globalTxId(), is(event.globalTxId()));
- assertThat(swiftTxEvent.localTxId(), is(event.localTxId()));
- assertThat(swiftTxEvent.parentTxId(), is(event.parentTxId()));
- assertThat(swiftTxEvent.compensationMethod(), is(event.compensationMethod()));
- assertThat(swiftTxEvent.payloads(), is(serializer.serialize(event)));
+ assertThat(grpcTxEvent.getGlobalTxId(), is(event.globalTxId()));
+ assertThat(grpcTxEvent.getLocalTxId(), is(event.localTxId()));
+ assertThat(grpcTxEvent.getParentTxId(), is(event.parentTxId()));
+ assertThat(grpcTxEvent.getPayloads().toByteArray(), is(serializer.serialize(event)));
}
-}
+}
\ No newline at end of file
diff --git a/omega/omega-connector/omega-connector-thrift/src/test/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSenderTest.java b/omega/omega-connector/omega-connector-thrift/src/test/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSenderTest.java
index 05f984c..7b5288f 100644
--- a/omega/omega-connector/omega-connector-thrift/src/test/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSenderTest.java
+++ b/omega/omega-connector/omega-connector-thrift/src/test/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSenderTest.java
@@ -41,14 +41,22 @@ public class ThriftMessageSenderTest {
private SwiftTxEvent swiftTxEvent;
- private final MessageSerializer serializer = (event) -> {
- try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
- for (Object o : event.payloads()) {
- stream.write(o.toString().getBytes());
+ private final MessageSerializer serializer = new MessageSerializer() {
+ @Override
+ public byte[] serialize(TxEvent event) {
+ return serialize(event.payloads());
+ }
+
+ @Override
+ public byte[] serialize(Object[] objects) {
+ try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
+ for (Object o : objects) {
+ stream.write(o.toString().getBytes());
+ }
+ return stream.toByteArray();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
}
- return stream.toByteArray();
- } catch (IOException e) {
- throw new IllegalStateException(e);
}
};
diff --git a/omega/omega-connector/pom.xml b/omega/omega-connector/pom.xml
index 21203b3..63ceda6 100644
--- a/omega/omega-connector/pom.xml
+++ b/omega/omega-connector/pom.xml
@@ -30,6 +30,7 @@
<packaging>pom</packaging>
<modules>
<module>omega-connector-thrift</module>
+ <module>omega-connector-grpc</module>
</modules>
diff --git a/omega/omega-format/src/main/java/io/servicecomb/saga/omega/format/NativeMessageFormat.java b/omega/omega-format/src/main/java/io/servicecomb/saga/omega/format/NativeMessageFormat.java
index 14b1d29..60b4a74 100644
--- a/omega/omega-format/src/main/java/io/servicecomb/saga/omega/format/NativeMessageFormat.java
+++ b/omega/omega-format/src/main/java/io/servicecomb/saga/omega/format/NativeMessageFormat.java
@@ -32,13 +32,22 @@ public class NativeMessageFormat implements MessageSerializer, MessageDeserializ
@Override
public byte[] serialize(TxEvent event) {
try {
+ return serialize(event.payloads());
+ } catch (OmegaException e) {
+ throw new OmegaException("Unable to serialize event with global tx id " + event.globalTxId(), e);
+ }
+ }
+
+ @Override
+ public byte[] serialize(Object[] objects) {
+ try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (ObjectOutputStream outputStream = new ObjectOutputStream(out)) {
- outputStream.writeObject(event.payloads());
+ outputStream.writeObject(objects);
return out.toByteArray();
}
} catch (IOException e) {
- throw new OmegaException("Unable to serialize event with global tx id " + event.globalTxId(), e);
+ throw new OmegaException("Unable to serialize object", e);
}
}
diff --git a/omega/omega-spring-starter/pom.xml b/omega/omega-spring-starter/pom.xml
index 59b81f8..40767ba 100644
--- a/omega/omega-spring-starter/pom.xml
+++ b/omega/omega-spring-starter/pom.xml
@@ -41,6 +41,18 @@
<groupId>io.servicecomb.saga</groupId>
<artifactId>omega-format</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-netty</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-stub</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.servicecomb.saga</groupId>
+ <artifactId>omega-connector-grpc</artifactId>
+ </dependency>
</dependencies>
</project>
diff --git a/omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/OmegaSpringConfig.java b/omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/OmegaSpringConfig.java
index 5f62884..3f3460c 100644
--- a/omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/OmegaSpringConfig.java
+++ b/omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/OmegaSpringConfig.java
@@ -36,6 +36,10 @@ import org.springframework.context.annotation.Configuration;
import com.facebook.nifty.client.FramedClientConnector;
import com.facebook.swift.service.ThriftClientManager;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.servicecomb.saga.omega.connector.grpc.GrpcClientMessageSender;
+import io.servicecomb.saga.omega.connector.grpc.GrpcTxEventEndpointImpl;
import io.servicecomb.saga.omega.connector.thrift.ThriftMessageSender;
import io.servicecomb.saga.omega.context.IdGenerator;
import io.servicecomb.saga.omega.context.OmegaContext;
@@ -43,6 +47,8 @@ import io.servicecomb.saga.omega.context.UniqueIdGenerator;
import io.servicecomb.saga.omega.format.NativeMessageFormat;
import io.servicecomb.saga.omega.transaction.MessageSender;
import io.servicecomb.saga.omega.transaction.MessageSerializer;
+import io.servicecomb.saga.pack.contract.grpc.TxEventServiceGrpc;
+import io.servicecomb.saga.pack.contract.grpc.TxEventServiceGrpc.TxEventServiceBlockingStub;
import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEventEndpoint;
@Configuration
@@ -51,6 +57,8 @@ class OmegaSpringConfig {
private final ThriftClientManager clientManager = new ThriftClientManager();
private final List<AutoCloseable> closeables = new ArrayList<>();
+ private ManagedChannel clientChannel;
+
@Bean
IdGenerator<String> idGenerator() {
return new UniqueIdGenerator();
@@ -61,7 +69,7 @@ class OmegaSpringConfig {
return new OmegaContext(idGenerator);
}
- @Bean
+ // @Bean
MessageSender messageSender(@Value("${alpha.cluster.address}") String[] addresses) {
// TODO: 2017/12/26 connect to the one with lowest latency
for (String address : addresses) {
@@ -105,5 +113,29 @@ class OmegaSpringConfig {
}
clientManager.close();
+ clientChannel.shutdown();
+ }
+
+ @Bean
+ MessageSender grpcMessageSender(@Value("${alpha.cluster.address}") String[] addresses) {
+ // TODO: 2017/12/26 connect to the one with lowest latency
+ for (String address : addresses) {
+ try {
+ String[] pair = address.split(":");
+ return createMessageSender(pair[0], Integer.parseInt(pair[1]), new NativeMessageFormat());
+ } catch (Exception e) {
+ log.error("Unable to connect to alpha at {}", address, e);
+ }
+ }
+
+ throw new IllegalArgumentException(
+ "None of the alpha cluster is reachable: " + Arrays.toString(addresses));
+ }
+
+ private GrpcClientMessageSender createMessageSender(String host, int port, MessageSerializer serializer) {
+ clientChannel = ManagedChannelBuilder.forAddress(host, port).usePlaintext(true).build();
+ TxEventServiceBlockingStub stub = TxEventServiceGrpc.newBlockingStub(clientChannel);
+ GrpcTxEventEndpointImpl eventService = new GrpcTxEventEndpointImpl(stub);
+ return new GrpcClientMessageSender(eventService, serializer);
}
}
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java
index b1eb7fd..2148eb6 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java
@@ -19,4 +19,6 @@ package io.servicecomb.saga.omega.transaction;
public interface MessageSerializer {
byte[] serialize(TxEvent event);
+
+ byte[] serialize(Object[] objects);
}
diff --git a/omega/omega-spring-starter/pom.xml b/pack-contracts/pack-contract-grpc/pom.xml
similarity index 66%
copy from omega/omega-spring-starter/pom.xml
copy to pack-contracts/pack-contract-grpc/pom.xml
index 59b81f8..388c5aa 100644
--- a/omega/omega-spring-starter/pom.xml
+++ b/pack-contracts/pack-contract-grpc/pom.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
+ ~
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
@@ -14,33 +15,46 @@
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
+ ~
+ ~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
- <artifactId>omega</artifactId>
+ <artifactId>pack-contracts</artifactId>
<groupId>io.servicecomb.saga</groupId>
<version>0.0.3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
- <artifactId>omega-spring-starter</artifactId>
+ <artifactId>pack-contract-grpc</artifactId>
<dependencies>
<dependency>
- <groupId>io.servicecomb.saga</groupId>
- <artifactId>omega-spring-tx</artifactId>
- </dependency>
- <dependency>
- <groupId>io.servicecomb.saga</groupId>
- <artifactId>omega-connector-thrift</artifactId>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-protobuf</artifactId>
</dependency>
<dependency>
- <groupId>io.servicecomb.saga</groupId>
- <artifactId>omega-format</artifactId>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-stub</artifactId>
</dependency>
</dependencies>
-</project>
+ <build>
+ <extensions>
+ <extension>
+ <groupId>kr.motd.maven</groupId>
+ <artifactId>os-maven-plugin</artifactId>
+ <version>1.5.0.Final</version>
+ </extension>
+ </extensions>
+ <plugins>
+ <plugin>
+ <groupId>org.xolstice.maven.plugins</groupId>
+ <artifactId>protobuf-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java b/pack-contracts/pack-contract-grpc/src/main/java/io/servicecomb/saga/pack/contract/grpc/GrpcTxEventEndpoint.java
similarity index 85%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java
copy to pack-contracts/pack-contract-grpc/src/main/java/io/servicecomb/saga/pack/contract/grpc/GrpcTxEventEndpoint.java
index b1eb7fd..32a3b6b 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java
+++ b/pack-contracts/pack-contract-grpc/src/main/java/io/servicecomb/saga/pack/contract/grpc/GrpcTxEventEndpoint.java
@@ -1,4 +1,5 @@
/*
+ *
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
@@ -13,10 +14,12 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
+ *
+ *
*/
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.pack.contract.grpc;
-public interface MessageSerializer {
- byte[] serialize(TxEvent event);
+public interface GrpcTxEventEndpoint {
+ void reportEvent(GrpcTxEvent message);
}
diff --git a/pack-contracts/pack-contract-grpc/src/main/proto/GrpcTxEvent.proto b/pack-contracts/pack-contract-grpc/src/main/proto/GrpcTxEvent.proto
new file mode 100644
index 0000000..41ffb81
--- /dev/null
+++ b/pack-contracts/pack-contract-grpc/src/main/proto/GrpcTxEvent.proto
@@ -0,0 +1,37 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+option java_package = "io.servicecomb.saga.pack.contract.grpc";
+option java_outer_classname = "TxEventProto";
+
+service TxEventService {
+ rpc ReportEvent (GrpcTxEvent) returns (GrpcEmpty) {}
+}
+
+message GrpcTxEvent {
+ int64 timestamp = 1;
+ string globalTxId = 2;
+ string localTxId = 3;
+ string parentTxId = 4;
+ string type = 5;
+ bytes payloads = 6;
+}
+
+message GrpcEmpty {}
\ No newline at end of file
diff --git a/pack-contracts/pom.xml b/pack-contracts/pom.xml
index cc035dd..b6ad03c 100644
--- a/pack-contracts/pom.xml
+++ b/pack-contracts/pom.xml
@@ -30,6 +30,7 @@
<packaging>pom</packaging>
<modules>
<module>pack-contract-thrift</module>
+ <module>pack-contract-grpc</module>
</modules>
</project>
diff --git a/pom.xml b/pom.xml
index 6668b59..8fb9f63 100755
--- a/pom.xml
+++ b/pom.xml
@@ -51,6 +51,7 @@
<akka.version>2.5.6</akka.version>
<rat.version>0.12</rat.version>
<maven.failsafe.version>2.19.1</maven.failsafe.version>
+ <grpc.version>1.8.0</grpc.version>
</properties>
<name>ServiceComb Saga</name>
@@ -158,6 +159,11 @@
</dependency>
<dependency>
<groupId>io.servicecomb.saga</groupId>
+ <artifactId>omega-connector-grpc</artifactId>
+ <version>0.0.3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>io.servicecomb.saga</groupId>
<artifactId>omega-spring-starter</artifactId>
<version>0.0.3-SNAPSHOT</version>
</dependency>
@@ -182,6 +188,11 @@
<version>0.0.3-SNAPSHOT</version>
</dependency>
<dependency>
+ <groupId>io.servicecomb.saga</groupId>
+ <artifactId>pack-contract-grpc</artifactId>
+ <version>0.0.3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
@@ -321,6 +332,21 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-netty</artifactId>
+ <version>${grpc.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-protobuf</artifactId>
+ <version>${grpc.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-stub</artifactId>
+ <version>${grpc.version}</version>
+ </dependency>
<!-- test dependencies -->
<dependency>
@@ -528,6 +554,24 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.xolstice.maven.plugins</groupId>
+ <artifactId>protobuf-maven-plugin</artifactId>
+ <version>0.5.0</version>
+ <configuration>
+ <protocArtifact>com.google.protobuf:protoc:3.5.0:exe:${os.detected.classifier}</protocArtifact>
+ <pluginId>grpc-java</pluginId>
+ <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.8.0:exe:${os.detected.classifier}</pluginArtifact>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>compile</goal>
+ <goal>compile-custom</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</pluginManagement>
<!-- enable the rat check by default -->
--
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.