You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2017/12/27 04:55:08 UTC
[incubator-servicecomb-saga] 01/11: SCB-96 added request interceptor
This is an automated email from the ASF dual-hosted git repository.
ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-saga.git
commit d58529f9587f7cb80980ab9b9278b4e029ec07c1
Author: Eric Lee <da...@huawei.com>
AuthorDate: Mon Dec 25 17:22:34 2017 +0800
SCB-96 added request interceptor
---
.../saga/omega/transaction/TxEndedEvent.java | 4 +-
.../saga/omega/transaction/TxStartedEvent.java | 4 +-
.../omega-transport-resttemplate/pom.xml | 8 ++
.../TransactionHandlerInterceptor.java | 87 ++++++++++++
.../omega/transport/resttemplate/WebConfig.java | 50 +++++++
.../TransactionHandlerInterceptorTest.java | 152 +++++++++++++++++++++
6 files changed, 301 insertions(+), 4 deletions(-)
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEndedEvent.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEndedEvent.java
index 6cc8f79..c24c1b3 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEndedEvent.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEndedEvent.java
@@ -17,8 +17,8 @@
package io.servicecomb.saga.omega.transaction;
-class TxEndedEvent extends TxEvent {
- TxEndedEvent(String globalTxId, String localTxId, String parentTxId) {
+public class TxEndedEvent extends TxEvent {
+ public TxEndedEvent(String globalTxId, String localTxId, String parentTxId) {
super(globalTxId, localTxId, parentTxId);
}
}
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxStartedEvent.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxStartedEvent.java
index 830104f..c278f54 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxStartedEvent.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxStartedEvent.java
@@ -17,9 +17,9 @@
package io.servicecomb.saga.omega.transaction;
-class TxStartedEvent extends TxEvent {
+public class TxStartedEvent extends TxEvent {
- TxStartedEvent(String globalTxId, String localTxId, String parentTxId, Object[] payloads) {
+ public TxStartedEvent(String globalTxId, String localTxId, String parentTxId, Object[] payloads) {
super(globalTxId, localTxId, parentTxId, payloads);
}
}
diff --git a/omega/omega-transport/omega-transport-resttemplate/pom.xml b/omega/omega-transport/omega-transport-resttemplate/pom.xml
index d7115d1..5464337 100644
--- a/omega/omega-transport/omega-transport-resttemplate/pom.xml
+++ b/omega/omega-transport/omega-transport-resttemplate/pom.xml
@@ -38,6 +38,14 @@
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
<dependency>
<groupId>org.springframework</groupId>
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java
new file mode 100644
index 0000000..56df07d
--- /dev/null
+++ b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java
@@ -0,0 +1,87 @@
+/*
+ *
+ * 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.transport.resttemplate;
+
+import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.GLOBAL_TX_ID_KEY;
+import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.LOCAL_TX_ID_KEY;
+
+import java.lang.invoke.MethodHandles;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import io.servicecomb.saga.omega.transaction.MessageSender;
+import io.servicecomb.saga.omega.transaction.MessageSerializer;
+import io.servicecomb.saga.omega.transaction.TxEndedEvent;
+import io.servicecomb.saga.omega.transaction.TxStartedEvent;
+
+public class TransactionHandlerInterceptor implements HandlerInterceptor {
+
+ private static Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+ private final MessageSender sender;
+
+ private final MessageSerializer serializer;
+
+ public TransactionHandlerInterceptor(MessageSender sender, MessageSerializer serializer) {
+ this.sender = sender;
+ this.serializer = serializer;
+ }
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+ String globalTxId = request.getHeader(GLOBAL_TX_ID_KEY);
+ if (globalTxId == null) {
+ LOG.info("no such header: {}", GLOBAL_TX_ID_KEY);
+ }
+ String localTxId = request.getHeader(LOCAL_TX_ID_KEY);
+ if (localTxId == null) {
+ LOG.info("no such header: {}", LOCAL_TX_ID_KEY);
+ }
+ // TODO: 12/25/2017 which content should be inside payloads?
+ sender.send(serializer.serialize(new TxStartedEvent(globalTxId, localTxId, null, null)));
+ return true;
+ }
+
+ @Override
+ public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
+ ModelAndView modelAndView) throws Exception {
+ }
+
+ @Override
+ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o,
+ Exception e) throws Exception {
+ String globalTxId = request.getHeader(GLOBAL_TX_ID_KEY);
+ if (globalTxId == null) {
+ LOG.info("no such header: {}", GLOBAL_TX_ID_KEY);
+ }
+ String localTxId = request.getHeader(LOCAL_TX_ID_KEY);
+ if (localTxId == null) {
+ LOG.info("no such header: {}", LOCAL_TX_ID_KEY);
+ }
+ sender.send(serializer.serialize(new TxEndedEvent(globalTxId, localTxId, null)));
+ }
+}
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/WebConfig.java b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/WebConfig.java
new file mode 100644
index 0000000..7d4fe7f
--- /dev/null
+++ b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/WebConfig.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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.transport.resttemplate;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+import io.servicecomb.saga.omega.transaction.MessageSender;
+import io.servicecomb.saga.omega.transaction.MessageSerializer;
+
+@Configuration
+@EnableWebMvc
+public class WebConfig extends WebMvcConfigurerAdapter {
+
+ private MessageSender sender;
+
+ private MessageSerializer serializer;
+
+ @Autowired
+ public WebConfig(MessageSender sender, MessageSerializer serializer) {
+ this.sender = sender;
+ this.serializer = serializer;
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(new TransactionHandlerInterceptor(sender, serializer));
+ }
+}
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java b/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java
new file mode 100644
index 0000000..6d447f5
--- /dev/null
+++ b/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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.transport.resttemplate;
+
+import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.GLOBAL_TX_ID_KEY;
+import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.LOCAL_TX_ID_KEY;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import io.servicecomb.saga.omega.transaction.MessageSender;
+import io.servicecomb.saga.omega.transaction.MessageSerializer;
+import io.servicecomb.saga.omega.transport.resttemplate.TransactionHandlerInterceptorTest.MessageConfig;
+
+@RunWith(SpringRunner.class)
+@Import({MessageConfig.class})
+public class TransactionHandlerInterceptorTest {
+ private static final String TX_STARTED_EVENT = "TxStartedEvent";
+ private static final String TX_ENDED_EVENT = "TxEndedEvent";
+ private static final String globalTxId = UUID.randomUUID().toString();
+ private static final String localTxId = UUID.randomUUID().toString();
+
+ @Autowired
+ private MessageSender sender;
+
+ @Autowired
+ private MessageSerializer serializer;
+
+ @Autowired
+ private TransactionHandlerInterceptor requestInterceptor;
+
+ @Autowired
+ private List<byte[]> messages;
+
+ private HttpServletRequest request = mock(HttpServletRequest.class);
+
+ private HttpServletResponse response = mock(HttpServletResponse.class);
+
+ @After
+ public void tearDown() throws Exception {
+ messages.clear();
+ }
+
+ @Test
+ public void preInterceptHeaderValueAndSendOut() throws Exception {
+ when(request.getHeader(GLOBAL_TX_ID_KEY)).thenReturn(globalTxId);
+ when(request.getHeader(LOCAL_TX_ID_KEY)).thenReturn(localTxId);
+
+ requestInterceptor.preHandle(request, response, null);
+
+ assertThat(messages.size(), is(1));
+ String deserializedString = new String(messages.get(0));
+ assertThat(deserializedString.contains(TX_STARTED_EVENT), is(true));
+ assertThat(deserializedString.startsWith(globalTxId), is(true));
+ assertThat(deserializedString.contains(localTxId), is(true));
+ }
+
+ @Test
+ public void postInterceptHeaderValueAndSendOut() throws Exception {
+ when(request.getHeader(GLOBAL_TX_ID_KEY)).thenReturn(globalTxId);
+ when(request.getHeader(LOCAL_TX_ID_KEY)).thenReturn(localTxId);
+
+ requestInterceptor.afterCompletion(request, response, null, null);
+
+ assertThat(messages.size(), is(1));
+ String deserializedString = new String(messages.get(0));
+ assertThat(deserializedString.contains(TX_ENDED_EVENT), is(true));
+ assertThat(deserializedString.startsWith(globalTxId), is(true));
+ assertThat(deserializedString.contains(localTxId), is(true));
+ }
+
+ @Configuration
+ static class MessageConfig {
+ private final List<byte[]> messages = new ArrayList<>();
+
+ @Bean
+ List<byte[]> messages() {
+ return messages;
+ }
+
+ @Bean
+ MessageSender sender() {
+ return messages::add;
+ }
+
+ @Bean
+ MessageSerializer serializer() {
+ return event -> {
+ if (TX_STARTED_EVENT.equals(event.type())) {
+ return txStartedEvent(event.globalTxId(),
+ event.localTxId(),
+ event.parentTxId(),
+ event.payloads()).getBytes();
+ }
+ return txEndedEvent(event.globalTxId(),
+ event.localTxId(),
+ event.parentTxId()).getBytes();
+ };
+ }
+
+ @Bean
+ HandlerInterceptor handlerInterceptor(MessageSender sender, MessageSerializer serializer) {
+ return new TransactionHandlerInterceptor(sender, serializer);
+ }
+ }
+
+ private static String txStartedEvent(String globalTxId,
+ String localTxId,
+ String parentTxId,
+ Object[] payloads) {
+ return globalTxId + ":" + localTxId + ":" + parentTxId + ":" + TX_STARTED_EVENT + ":" + Arrays.toString(payloads);
+ }
+
+ private static String txEndedEvent(String globalTxId, String localTxId, String parentTxId) {
+ return globalTxId + ":" + localTxId + ":" + parentTxId + ":" + TX_ENDED_EVENT;
+ }
+}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.