From 28c23ae15a668110458465b6181c5b66978ce2cd Mon Sep 17 00:00:00 2001 From: Dmitriy-Yugay Date: Fri, 18 Mar 2022 10:37:56 +0400 Subject: [PATCH 1/9] moved error message from the name to the body of the event --- .../exactpro/th2/conn/ServiceListener.java | 5 +- .../th2/conn/TestServiceListener.java | 91 +++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/exactpro/th2/conn/TestServiceListener.java diff --git a/src/main/java/com/exactpro/th2/conn/ServiceListener.java b/src/main/java/com/exactpro/th2/conn/ServiceListener.java index aa246d9..189c426 100644 --- a/src/main/java/com/exactpro/th2/conn/ServiceListener.java +++ b/src/main/java/com/exactpro/th2/conn/ServiceListener.java @@ -25,6 +25,7 @@ import com.exactpro.sf.services.ServiceHandlerRoute; import com.exactpro.th2.common.event.Event; import com.exactpro.th2.common.event.Event.Status; +import com.exactpro.th2.common.event.EventUtils; import com.exactpro.th2.conn.events.EventDispatcher; import com.exactpro.th2.conn.events.EventHolder; import com.exactpro.th2.conn.utility.EventStoreExtensions; @@ -144,11 +145,13 @@ public void onMessage(IServiceProxy service, IMessage message, boolean rejected, @Override public void onEvent(IServiceProxy service, ServiceEvent serviceEvent) { LOGGER.info("Session '{}' emitted service event '{}'", sessionAlias, serviceEvent); + String eventName = "Service [" + serviceEvent.getServiceName().getServiceName() + "] emitted event with status " + serviceEvent.getLevel(); try { Event event = Event.start().endTimestamp() - .name(serviceEvent.getMessage()) + .name(eventName) .status(serviceEvent.getLevel() == Level.ERROR ? Status.FAILED : Status.PASSED) .type("Service event") + .bodyData(EventUtils.createMessageBean(serviceEvent.getMessage())) .description(serviceEvent.getDetails()); eventDispatcher.store(EventHolder.createServiceEvent(event)); diff --git a/src/test/java/com/exactpro/th2/conn/TestServiceListener.java b/src/test/java/com/exactpro/th2/conn/TestServiceListener.java new file mode 100644 index 0000000..bb1fc1f --- /dev/null +++ b/src/test/java/com/exactpro/th2/conn/TestServiceListener.java @@ -0,0 +1,91 @@ +/* + * Copyright 2022 Exactpro (Exactpro Systems Limited) + * + * Licensed 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 com.exactpro.th2.conn; + +import com.exactpro.sf.common.services.ServiceName; +import com.exactpro.sf.externalapi.IServiceProxy; +import com.exactpro.sf.services.ServiceEvent; +import com.exactpro.sf.services.ServiceEventFactory; +import com.exactpro.th2.common.event.Event; +import com.exactpro.th2.common.grpc.Direction; +import com.exactpro.th2.conn.events.EventDispatcher; +import com.exactpro.th2.conn.events.EventHolder; +import com.fasterxml.jackson.core.JsonProcessingException; +import io.reactivex.rxjava3.processors.FlowableProcessor; +import io.reactivex.rxjava3.processors.UnicastProcessor; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; + +import static org.mockito.Mockito.mock; + +public class TestServiceListener { + + + @Test + public void onEventTest() throws JsonProcessingException { + + FlowableProcessor processor = UnicastProcessor.create(); + MyEventDispatcher eventDispatcher = new MyEventDispatcher(); + + ServiceListener serviceListener = new ServiceListener(Map.of(Direction.FIRST, new AtomicLong(1)), + "SessionAlias", processor, eventDispatcher); + + ServiceEvent serviceEvent = ServiceEventFactory.createEventInfo(ServiceName.parse("serviceName"), ServiceEvent.Type.INFO, + "Warn: incoming message with missing field: 45: Required " + + "tag missing, field=45: 8=FIXT.1.1\0019=112\00135=j\00134=3783\00149=FGW" + + "\00152=20210203-12:30:48.238\00156=DEMO-CONN1\00158=Unknown SecurityID" + + "\001371=48\001372=D\001379=9741113\001380=2\00110=019\001", null); + + IServiceProxy serviceProxy = mock(IServiceProxy.class); + serviceListener.onEvent(serviceProxy, serviceEvent); + + Event event = eventDispatcher.getEvent(); + com.exactpro.th2.common.grpc.Event grpcEvent = event.toProto(null); + + String name = grpcEvent.getName(); + Assertions.assertEquals("Service [serviceName] emitted event with status INFO", name); + + String body = grpcEvent.getBody().toStringUtf8(); + Assertions.assertEquals("[{\"data\":\"Warn: incoming message with missing field: 45: Required " + + "tag missing, field=45: 8=FIXT.1.1\\u00019=112\\u000135=j\\u000134=3783\\u000149=FGW" + + "\\u000152=20210203-12:30:48.238\\u000156=DEMO-CONN1\\u000158=Unknown SecurityID" + + "\\u0001371=48\\u0001372=D\\u0001379=9741113\\u0001380=2\\u000110=019\\u0001\",\"type\":\"message\"}]", body); + } + + + public static class MyEventDispatcher implements EventDispatcher { + + Event event; + + @Override + public void store(@NotNull EventHolder eventHolder) { + this.event = eventHolder.getEvent(); + } + + @Override + public void store(@NotNull Event event, @NotNull String parentId) { + this.event = event; + } + + public Event getEvent() { + return event; + } + } +} From 5df812c66dc5a7a55a50d413c0f25442e44070ac Mon Sep 17 00:00:00 2001 From: Dmitriy-Yugay Date: Fri, 18 Mar 2022 12:24:53 +0400 Subject: [PATCH 2/9] updated version + readme --- README.md | 6 +++++- gradle.properties | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3e2e403..8986d1f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Connect (3.10.1) +# Connect (3.10.2) The "Connect" component is responsible for the communication with a target system. This component implements the logic of the interaction protocol, receiving and sending messages from and to the system, respectively. @@ -119,6 +119,10 @@ spec: ## Release notes +### 3.10.2 + ++ Events are made more convenient. Error message moved from the name to the body of the event. + ### 3.10.1 + Update `sailfish-core` version from `3.2.1674` to `3.2.1741` diff --git a/gradle.properties b/gradle.properties index 45efc1f..36f4a18 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -release_version = 3.10.1 \ No newline at end of file +release_version = 3.10.2 \ No newline at end of file From d9ac60ba4542927c292818011a04d4b2b6928978 Mon Sep 17 00:00:00 2001 From: Dmitriy-Yugay Date: Fri, 25 Mar 2022 18:31:23 +0400 Subject: [PATCH 3/9] minor fixes --- README.md | 6 +++++- gradle.properties | 2 +- .../com/exactpro/th2/conn/TestServiceListener.java | 12 +++--------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 3e2e403..8986d1f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Connect (3.10.1) +# Connect (3.10.2) The "Connect" component is responsible for the communication with a target system. This component implements the logic of the interaction protocol, receiving and sending messages from and to the system, respectively. @@ -119,6 +119,10 @@ spec: ## Release notes +### 3.10.2 + ++ Events are made more convenient. Error message moved from the name to the body of the event. + ### 3.10.1 + Update `sailfish-core` version from `3.2.1674` to `3.2.1741` diff --git a/gradle.properties b/gradle.properties index 45efc1f..36f4a18 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -release_version = 3.10.1 \ No newline at end of file +release_version = 3.10.2 \ No newline at end of file diff --git a/src/test/java/com/exactpro/th2/conn/TestServiceListener.java b/src/test/java/com/exactpro/th2/conn/TestServiceListener.java index bb1fc1f..18b4bec 100644 --- a/src/test/java/com/exactpro/th2/conn/TestServiceListener.java +++ b/src/test/java/com/exactpro/th2/conn/TestServiceListener.java @@ -48,25 +48,19 @@ public void onEventTest() throws JsonProcessingException { "SessionAlias", processor, eventDispatcher); ServiceEvent serviceEvent = ServiceEventFactory.createEventInfo(ServiceName.parse("serviceName"), ServiceEvent.Type.INFO, - "Warn: incoming message with missing field: 45: Required " + - "tag missing, field=45: 8=FIXT.1.1\0019=112\00135=j\00134=3783\00149=FGW" + - "\00152=20210203-12:30:48.238\00156=DEMO-CONN1\00158=Unknown SecurityID" + - "\001371=48\001372=D\001379=9741113\001380=2\00110=019\001", null); + "Warn: incoming message with missing field: 45", null); IServiceProxy serviceProxy = mock(IServiceProxy.class); serviceListener.onEvent(serviceProxy, serviceEvent); Event event = eventDispatcher.getEvent(); - com.exactpro.th2.common.grpc.Event grpcEvent = event.toProto(null); + var grpcEvent = event.toProto(null); String name = grpcEvent.getName(); Assertions.assertEquals("Service [serviceName] emitted event with status INFO", name); String body = grpcEvent.getBody().toStringUtf8(); - Assertions.assertEquals("[{\"data\":\"Warn: incoming message with missing field: 45: Required " + - "tag missing, field=45: 8=FIXT.1.1\\u00019=112\\u000135=j\\u000134=3783\\u000149=FGW" + - "\\u000152=20210203-12:30:48.238\\u000156=DEMO-CONN1\\u000158=Unknown SecurityID" + - "\\u0001371=48\\u0001372=D\\u0001379=9741113\\u0001380=2\\u000110=019\\u0001\",\"type\":\"message\"}]", body); + Assertions.assertEquals("[{\"data\":\"Warn: incoming message with missing field: 45\",\"type\":\"message\"}]", body); } From af377fbd1ec9768a660271271ef9e6be6514f9f6 Mon Sep 17 00:00:00 2001 From: Dmitriy-Yugay <86191842+Dmitriy-Yugay@users.noreply.github.com> Date: Wed, 20 Apr 2022 10:31:05 +0400 Subject: [PATCH 4/9] Th2 1881 2 (#123) * updated Readme * changed dummy implementation of MessageRouter on Mock * changed dummy eventDispatcher on Mock * changed dummy implementation of MessageRouter on Mock * changed dummy eventDispatcher on Mock * minor fixes Co-authored-by: Oleg Smirnov --- README.md | 2 +- .../com/exactpro/th2/conn/MessageSender.java | 8 +- .../java/com/exactpro/th2/conn/TestEvent.java | 153 ++++++++++++++++++ 3 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 src/test/java/com/exactpro/th2/conn/TestEvent.java diff --git a/README.md b/README.md index 8986d1f..b6d7352 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ spec: ### 3.10.2 -+ Events are made more convenient. Error message moved from the name to the body of the event. ++ Events are made more convenient. Added event names and error logs. Error message moved from the name to the body of the event. ### 3.10.1 diff --git a/src/main/java/com/exactpro/th2/conn/MessageSender.java b/src/main/java/com/exactpro/th2/conn/MessageSender.java index 15c7e19..044bf70 100644 --- a/src/main/java/com/exactpro/th2/conn/MessageSender.java +++ b/src/main/java/com/exactpro/th2/conn/MessageSender.java @@ -103,7 +103,7 @@ private void sendMessage(RawMessage protoMsg) throws InterruptedException { logger.debug("Message sent. Base64 view: {}", Base64.getEncoder().encodeToString(data)); } } catch (Exception ex) { - Event errorEvent = createErrorEvent("SendError") + Event errorEvent = createErrorEvent("SendError", ex) .bodyData(EventUtils.createMessageBean("Cannot send message. Message body in base64:")) .bodyData(EventUtils.createMessageBean(Base64.getEncoder().encodeToString(data))); EventStoreExtensions.addException(errorEvent, ex); @@ -124,10 +124,12 @@ private void storeErrorEvent(Event errorEvent, @Nullable EventID parentId) { } } - private Event createErrorEvent(String eventType) { + private Event createErrorEvent(String eventType, Exception e) { return Event.start().endTimestamp() .status(Status.FAILED) - .type(eventType); + .type(eventType) + .name("Failed to send raw message") + .exception(e, true); } private IMetadata toSailfishMetadata(RawMessage protoMsg) { diff --git a/src/test/java/com/exactpro/th2/conn/TestEvent.java b/src/test/java/com/exactpro/th2/conn/TestEvent.java new file mode 100644 index 0000000..555da05 --- /dev/null +++ b/src/test/java/com/exactpro/th2/conn/TestEvent.java @@ -0,0 +1,153 @@ +/* + * Copyright 2022 Exactpro (Exactpro Systems Limited) + * + * Licensed 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 com.exactpro.th2.conn; + +import com.exactpro.sf.externalapi.IServiceProxy; +import com.exactpro.th2.common.event.Event; +import com.exactpro.th2.common.event.EventUtils; +import com.exactpro.th2.common.grpc.EventBatch; +import com.exactpro.th2.common.grpc.EventID; +import com.exactpro.th2.common.grpc.RawMessage; +import com.exactpro.th2.common.grpc.RawMessageBatch; +import com.exactpro.th2.common.schema.message.MessageListener; +import com.exactpro.th2.common.schema.message.MessageRouter; +import com.exactpro.th2.common.schema.message.SubscriberMonitor; +import com.exactpro.th2.conn.events.EventDispatcher; +import com.exactpro.th2.conn.events.EventHolder; +import com.exactpro.th2.conn.events.EventType; +import com.google.protobuf.ByteString; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.Map; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; + +public class TestEvent { + + private static final String rootID = "rootID"; + private static final Map parentIds = Map.of(EventType.ERROR, "errorEventID"); + + private static IServiceProxy serviceProxy; + private static EventDispatcher eventDispatcher; + private static MessageSender messageSender; + private static MessageListener messageListener; + private static Event event; + private static String parentId; + + @BeforeAll + public static void initMessages() throws IOException { + serviceProxy = mock(IServiceProxy.class); + MessageRouter router = mock(MessageRouter.class); + + doAnswer(invocation -> { + messageListener = invocation.getArgument(0); + return (SubscriberMonitor) () -> { + }; + }).when(router).subscribeAll(any(), any()); + + eventDispatcher = mock(EventDispatcher.class); + doAnswer(invocation -> { + EventHolder eventHolder = invocation.getArgument(0); + EventType eventType = eventHolder.getType(); + + eventDispatcher.store(eventHolder.getEvent(), + parentIds.get(eventType) != null ? parentIds.get(eventType) : rootID); + return null; + }).when(eventDispatcher).store(any()); + + doAnswer(invocation -> { + event = invocation.getArgument(0); + parentId = invocation.getArgument(1); + return null; + }).when(eventDispatcher).store(any(), any()); + + messageSender = new MessageSender(serviceProxy, router, eventDispatcher, + EventID.newBuilder().setId("stubID").build()); + messageSender.start(); + } + + @AfterEach + public void clear() { + event = null; + parentId = null; + } + + public void sendIncorrectMessage() throws Exception { + RawMessageBatch rawMessageBatch = RawMessageBatch.newBuilder() + .addMessages(RawMessage.newBuilder().build()) + .build(); + + doThrow(new IllegalStateException("error")).when(serviceProxy).sendRaw(any(), any()); + messageListener.handler("stubValue", rawMessageBatch); + } + + @Test + public void eventHasBodyTest() throws Exception { + sendIncorrectMessage(); + + ByteString body = event.toProto(EventUtils.toEventID(parentId)).getBody(); + Assertions.assertEquals("[{\"data\":\"java.lang.IllegalStateException: error\",\"type\":\"message\"}," + + "{\"data\":\"Cannot send message. Message body in base64:\",\"type\":\"message\"},{\"data\":\"\"," + + "\"type\":\"message\"},{\"data\":\"java.lang.IllegalStateException: error\",\"type\":\"message\"}]", body.toStringUtf8()); + } + + @Test + public void eventHasNameTest() throws Exception { + sendIncorrectMessage(); + + String name = event.toProto(EventUtils.toEventID(parentId)).getName(); + Assertions.assertEquals("Failed to send raw message", name); + } + + @Test + public void sentMessageWithParentEventIDTest() throws Exception { + RawMessageBatch rawMessageBatch = RawMessageBatch.newBuilder() + .addMessages(RawMessage.newBuilder() + .setParentEventId(EventID.newBuilder() + .setId("RawMessageParentEventID")).build()) + .build(); + + doThrow(new IllegalStateException("error")).when(serviceProxy).sendRaw(any(), any()); + messageListener.handler("stubValue", rawMessageBatch); + + event.addSubEvent(Event.start()); + + EventBatch eventBatch = event.toBatchProto(EventUtils.toEventID(parentId)); + Assertions.assertEquals("RawMessageParentEventID", eventBatch.getParentEventId().getId()); + } + + @Test + public void sentMessageWithoutParentEventIDTest() throws Exception { + sendIncorrectMessage(); + event.addSubEvent(Event.start()); + + EventBatch eventBatch = event.toBatchProto(EventUtils.toEventID(parentId)); + Assertions.assertEquals("errorEventID", eventBatch.getParentEventId().getId()); + } + + @AfterAll + private static void close() throws IOException { + messageSender.stop(); + } +} \ No newline at end of file From 2916f38c0059f22432d5839b4e18cea71b225798 Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Thu, 9 Jun 2022 14:56:10 +0300 Subject: [PATCH 5/9] [TH2-3799] Use temporal directory as last saiflish's layer (#136) * [TH2-3799] Add temporal directory as a last workspace layer * [TH2-3799] Remove file creation from log config * [TH2-3799] Update readme --- README.md | 1 + src/main/java/com/exactpro/th2/conn/MicroserviceMain.java | 4 +++- src/main/resources/log4j.properties | 7 +------ 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b6d7352..2dd2fa7 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,7 @@ spec: ### 3.10.2 + Events are made more convenient. Added event names and error logs. Error message moved from the name to the body of the event. ++ Use temporal directory for last layer in sailfish's workspace ### 3.10.1 diff --git a/src/main/java/com/exactpro/th2/conn/MicroserviceMain.java b/src/main/java/com/exactpro/th2/conn/MicroserviceMain.java index d6bbd34..141c3f4 100644 --- a/src/main/java/com/exactpro/th2/conn/MicroserviceMain.java +++ b/src/main/java/com/exactpro/th2/conn/MicroserviceMain.java @@ -29,6 +29,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; import java.time.Instant; import java.util.Deque; import java.util.Map; @@ -128,7 +129,8 @@ public static void main(String[] args) { processor.onComplete(); }); - IServiceFactory serviceFactory = new ServiceFactory(workspaceFolder); + IServiceFactory serviceFactory = new ServiceFactory(workspaceFolder, + Files.createTempDirectory("sailfish-workspace").toFile()); disposer.register(() -> { LOGGER.info("Close service factory"); serviceFactory.close(); diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties index 5429812..d6d73c8 100644 --- a/src/main/resources/log4j.properties +++ b/src/main/resources/log4j.properties @@ -13,12 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. ################################################################################ -log4j.rootLogger=INFO, FILE, CON -log4j.appender.FILE=org.apache.log4j.FileAppender -log4j.appender.FILE.File=evolution_all.log -log4j.appender.FILE.Append=false -log4j.appender.FILE.layout=org.apache.log4j.PatternLayout -log4j.appender.FILE.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss,SSS} %-6p [%-15t] %c - %m%n +log4j.rootLogger=INFO, CON log4j.appender.CON=org.apache.log4j.ConsoleAppender log4j.appender.CON.layout=org.apache.log4j.PatternLayout From f00414e209eea6ee9cd69eb0ca6a0b2588b11e49 Mon Sep 17 00:00:00 2001 From: "ivan.druzhinin" Date: Thu, 29 Sep 2022 11:33:09 +0400 Subject: [PATCH 6/9] [TH2-4251] Add option to control batching window --- README.md | 8 +++++++- gradle.properties | 2 +- .../com/exactpro/th2/conn/MicroserviceMain.java | 13 +++++++------ .../configuration/ConnectivityConfiguration.java | 10 ++++++++-- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 2dd2fa7..2319e7a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Connect (3.10.2) +# Connect (3.11.0) The "Connect" component is responsible for the communication with a target system. This component implements the logic of the interaction protocol, receiving and sending messages from and to the system, respectively. @@ -28,6 +28,7 @@ Parameters: + name - the service name that will be displayed in the events inside the report; + settings - the parameters that will be transformed to the actual service's settings specified in the **services.xml** file. + maxMessageBatchSize - the limitation for message batch size which connect sends to the first and to the second publish pins with. The default value is set to 100. ++ maxMessageFlushTime - defines maximum time between outgoing message batches in milliseconds. The default value is set to 1000. + enableMessageSendingEvent - if this option is set to `true`, connect sends a separate event for every message sent which incomes from the pin with the send attribute. The default value is set to true ## Metrics @@ -102,6 +103,7 @@ spec: type: "th2_service:Your_Service_Type" name: "your_service" maxMessageBatchSize: 100 + maxMessageFlushTime: 1000 enableMessageSendingEvent: true settings: param1: "value1" @@ -119,6 +121,10 @@ spec: ## Release notes +### 3.11.0 + ++ Added `maxMessageFlushTime` option + ### 3.10.2 + Events are made more convenient. Added event names and error logs. Error message moved from the name to the body of the event. diff --git a/gradle.properties b/gradle.properties index 36f4a18..0d3de53 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -release_version = 3.10.2 \ No newline at end of file +release_version=3.11.0 diff --git a/src/main/java/com/exactpro/th2/conn/MicroserviceMain.java b/src/main/java/com/exactpro/th2/conn/MicroserviceMain.java index 141c3f4..5f5e87a 100644 --- a/src/main/java/com/exactpro/th2/conn/MicroserviceMain.java +++ b/src/main/java/com/exactpro/th2/conn/MicroserviceMain.java @@ -84,7 +84,6 @@ public class MicroserviceMain { private static final Logger LOGGER = LoggerFactory.getLogger(MicroserviceMain.class); - public static final int MAX_MESSAGES_COUNT = 100; public static final long NANOSECONDS_IN_SECOND = 1_000_000_000L; public static final String PASSWORD_PARAMETER = "password"; public static final String DEFAULT_PASSWORD_PARAMETER = "default"; @@ -183,7 +182,7 @@ public static void main(String[] args) { }); createPipeline(processor, processor::onComplete, eventBatchRouter, rawMessageRouter, - configuration.getMaxMessageBatchSize(), configuration.isEnableMessageSendingEvent()) + configuration.getMaxMessageBatchSize(), configuration.getMaxMessageFlushTime(), configuration.isEnableMessageSendingEvent()) .blockingSubscribe(new TermibnationSubscriber<>(serviceProxy, messageSender)); } catch (SailfishURIException | WorkspaceSecurityException e) { LOGGER.error(e.getMessage(), e); exitCode = 2; } catch (IOException e) { LOGGER.error(e.getMessage(), e); exitCode = 3; @@ -213,7 +212,9 @@ private static Object getParamValue(ISettingsProxy settings, String parameterNam Flowable flowable, Action terminateFlowable, MessageRouter eventBatchRouter, MessageRouter rawMessageRouter, - int maxMessageBatchSize, boolean enableMessageSendingEvent) { + int maxMessageBatchSize, + long maxMessageFlushTime, + boolean enableMessageSendingEvent) { LOGGER.info("AvailableProcessors '{}'", Runtime.getRuntime().availableProcessors()); return flowable @@ -240,7 +241,7 @@ private static Object getParamValue(ISettingsProxy settings, String parameterNam if (enableMessageSendingEvent && direction == Direction.SECOND) { subscribeToSendMessage(eventBatchRouter, messageConnectable); } - createPackAndPublishPipeline(direction, messageConnectable, rawMessageRouter, maxMessageBatchSize); + createPackAndPublishPipeline(direction, messageConnectable, rawMessageRouter, maxMessageBatchSize, maxMessageFlushTime); return messageConnectable; }); @@ -275,7 +276,7 @@ private static void subscribeToSendMessage(MessageRouter eventBatchR } private static void createPackAndPublishPipeline(Direction direction, Flowable messageConnectable, - MessageRouter rawMessageRouter, int maxMessageBatchSize) { + MessageRouter rawMessageRouter, int maxMessageBatchSize, long maxMessageFlushTime) { LOGGER.info("Map group {}", direction); Flowable batchConnectable = messageConnectable @@ -284,7 +285,7 @@ private static void createPackAndPublishPipeline(Direction direction, Flowable !list.isEmpty()) .map(ConnectivityBatch::new) diff --git a/src/main/java/com/exactpro/th2/conn/configuration/ConnectivityConfiguration.java b/src/main/java/com/exactpro/th2/conn/configuration/ConnectivityConfiguration.java index 691017b..a002491 100644 --- a/src/main/java/com/exactpro/th2/conn/configuration/ConnectivityConfiguration.java +++ b/src/main/java/com/exactpro/th2/conn/configuration/ConnectivityConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 Exactpro (Exactpro Systems Limited) + * Copyright 2020-2022 Exactpro (Exactpro Systems Limited) * Licensed 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 @@ -22,10 +22,12 @@ public class ConnectivityConfiguration { private int maxMessageBatchSize = 100; + private long maxMessageFlushTime = 1000; + @JsonProperty(value = "session-alias", required = true) private String sessionAlias; - @JsonProperty(value = "workspace",required = true) + @JsonProperty(value = "workspace", required = true) private String workspaceFolder; @JsonProperty(required = true) @@ -45,6 +47,10 @@ public int getMaxMessageBatchSize() { return maxMessageBatchSize; } + public long getMaxMessageFlushTime() { + return maxMessageFlushTime; + } + public String getSessionAlias() { return sessionAlias; } From b9613c6fc77d04bc2ab63ae07e09c50acac06061 Mon Sep 17 00:00:00 2001 From: Oleg Date: Mon, 10 Oct 2022 14:40:27 +0400 Subject: [PATCH 7/9] [TS-1168] Migrate to sf 3.3. Update dependencies with vulnerabilities --- README.md | 2 + build.gradle | 44 +++++++++++++------ .../java/com/exactpro/th2/conn/TestEvent.java | 9 ++-- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 2319e7a..28e6bed 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,8 @@ spec: ### 3.11.0 + Added `maxMessageFlushTime` option ++ Dependencies with vulnerabilities were updated: + + Sailfish updated from `3.2.1741` to `3.3.13` ### 3.10.2 diff --git a/build.gradle b/build.gradle index 7e90ed1..2fc87e9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,12 @@ plugins { id 'com.palantir.docker' version '0.25.0' - id 'org.jetbrains.kotlin.jvm' version '1.5.30' + id 'org.jetbrains.kotlin.jvm' version '1.6.21' id 'application' } ext { sharedDir = file("${project.rootDir}/shared") - sailfishVersion = '3.2.1741' + sailfishVersion = '3.3.13' } group = 'com.exactpro.th2' @@ -17,19 +17,35 @@ repositories { name 'MavenLocal' url sharedDir } - - mavenCentral() + + // ignoreGradleMetadataRedirection is used for sonatype because + // Sailfish dependencies have constrains that interfere with our BOM + // so we exclude Gradle metadata for this repositories maven { name 'Sonatype_snapshots' url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' + metadataSources { + mavenPom() + artifact() + ignoreGradleMetadataRedirection() + } } - maven { name 'Sonatype_releases' url 'https://s01.oss.sonatype.org/content/repositories/releases/' + metadataSources { + mavenPom() + artifact() + ignoreGradleMetadataRedirection() + } + } + mavenCentral { + metadataSources { + mavenPom() + artifact() + } } - mavenLocal() configurations.all { @@ -64,12 +80,11 @@ compileTestKotlin { } dependencies { - api platform('com.exactpro.th2:bom:3.0.0') + api platform('com.exactpro.th2:bom:4.0.1') - implementation 'com.exactpro.th2:common:3.33.0' - implementation "com.exactpro.th2:sailfish-utils:3.8.0" + implementation 'com.exactpro.th2:common:3.42.0-dev-3174619150-SNAPSHOT' + implementation 'com.exactpro.th2:sailfish-utils:3.13.0-dev-3204703314-SNAPSHOT' - implementation "org.slf4j:slf4j-log4j12" implementation "org.slf4j:slf4j-api" implementation group: 'io.reactivex.rxjava3', name: 'rxjava', version: '3.0.4' @@ -78,7 +93,10 @@ dependencies { implementation("com.exactpro.sf:sailfish-core:${sailfishVersion}") - testImplementation 'org.junit.jupiter:junit-jupiter:5.7.1' + testImplementation('org.apache.logging.log4j:log4j-slf4j-impl') { + because('logging in testing') + } + testImplementation 'org.junit.jupiter:junit-jupiter:5.9.0' } test { @@ -86,13 +104,13 @@ test { } application { - mainClassName 'com.exactpro.th2.conn.MicroserviceMain' + mainClass.set('com.exactpro.th2.conn.MicroserviceMain') } applicationName = 'service' distTar { - archiveName "${applicationName}.tar" + archiveFileName.set("${applicationName}.tar") } dockerPrepare { diff --git a/src/test/java/com/exactpro/th2/conn/TestEvent.java b/src/test/java/com/exactpro/th2/conn/TestEvent.java index 555da05..3518a86 100644 --- a/src/test/java/com/exactpro/th2/conn/TestEvent.java +++ b/src/test/java/com/exactpro/th2/conn/TestEvent.java @@ -56,8 +56,9 @@ public class TestEvent { private static String parentId; @BeforeAll - public static void initMessages() throws IOException { + static void initMessages() throws IOException { serviceProxy = mock(IServiceProxy.class); + @SuppressWarnings("unchecked") MessageRouter router = mock(MessageRouter.class); doAnswer(invocation -> { @@ -72,7 +73,7 @@ public static void initMessages() throws IOException { EventType eventType = eventHolder.getType(); eventDispatcher.store(eventHolder.getEvent(), - parentIds.get(eventType) != null ? parentIds.get(eventType) : rootID); + parentIds.get(eventType) == null ? rootID : parentIds.get(eventType)); return null; }).when(eventDispatcher).store(any()); @@ -88,7 +89,7 @@ public static void initMessages() throws IOException { } @AfterEach - public void clear() { + void clear() { event = null; parentId = null; } @@ -147,7 +148,7 @@ public void sentMessageWithoutParentEventIDTest() throws Exception { } @AfterAll - private static void close() throws IOException { + static void close() throws IOException { messageSender.stop(); } } \ No newline at end of file From f287caf67c67bd68e7a08f1155701bb216d568ff Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Wed, 4 Oct 2023 11:52:27 +0400 Subject: [PATCH 8/9] [TS-1574] Sailfish updated from `3.3.132` to `3.3.144` --- Dockerfile | 2 +- README.md | 24 ++++++++++++++---------- build.gradle | 4 ++-- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index 84d6f55..5e8af41 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM gradle:6.6-jdk11 AS build +FROM gradle:7.6-jdk11 AS build ARG release_version COPY ./ . RUN gradle --no-daemon clean build dockerPrepare -Prelease_version=${release_version} diff --git a/README.md b/README.md index 2f3a14a..63c45a0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Connect (3.11.1) +# Connect (3.11.2) The "Connect" component is responsible for the communication with a target system. This component implements the logic of the interaction protocol, receiving and sending messages from and to the system, respectively. @@ -121,6 +121,10 @@ spec: ## Release notes +### 3.11.2 + ++ Sailfish updated from `3.3.132` to `3.3.144` + ### 3.11.1 + Updated `sailfish-core` version from `3.3.54` to `3.3.132` @@ -140,7 +144,7 @@ spec: ### 3.10.1 -+ Update `sailfish-core` version from `3.2.1674` to `3.2.1741` ++ Updated `sailfish-core` version from `3.2.1674` to `3.2.1741` + Add exception for checking the property in `IMetadata` + Added synchronization by processor to `ServiceListener.onMessage()` otherwise processor sometimes misses some sequences + Added log about missed sequences @@ -148,15 +152,15 @@ spec: ### 3.10.0 -+ Update `th2-common` version from `3.25.1` to `3.33.0` -+ Update `org.jetbrains.kotlin.jvm` version from `1.3.72` to `1.5.30` ++ Updated `th2-common` version from `3.25.1` to `3.33.0` ++ Updated `org.jetbrains.kotlin.jvm` version from `1.3.72` to `1.5.30` ### 3.9.0 -+ Update `sailfish-core` version from `3.2.1650` to `3.2.1674` ++ Updated `sailfish-core` version from `3.2.1650` to `3.2.1674` + Embedded Sailfish service based on MINA decodes the message as sender during sending. This approach is important for protocols in which a pair of messages have the same protocol message type and different structures depending on the direction. -+ Update `th2-common` version from `3.16.5` to `3.25.1` -+ Update `th2-sailfish-utils` version from `3.4.0` to `3.8.0` ++ Updated `th2-common` version from `3.16.5` to `3.25.1` ++ Updated `th2-sailfish-utils` version from `3.4.0` to `3.8.0` ### 3.8.1 @@ -168,11 +172,11 @@ spec: ### 3.7.2 -+ Update Sailfish version to 3.2.1603 ++ Updated Sailfish version to 3.2.1603 ### 3.7.1 -+ Update Sailfish version to 3.2.1572 (unwraps the EvolutionBatch when sending raw message) ++ Updated Sailfish version to 3.2.1572 (unwraps the EvolutionBatch when sending raw message) ### 3.7.0 @@ -200,7 +204,7 @@ spec: + reads dictionaries from the /var/th2/config/dictionary folder. + uses mq_router, grpc_router, cradle_manager optional JSON configs from the /var/th2/config folder + tries to load log4j.properties files from sources in order: '/var/th2/config', '/home/etc', configured path via cmd, default configuration -+ update Cradle version. Introduce async API for storing events ++ updated Cradle version. Introduce async API for storing events ### 3.4.1 diff --git a/build.gradle b/build.gradle index 3671f53..5a358f4 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ dependencyCheck { } ext { - sailfishVersion = '3.3.132' + sailfishVersion = '3.3.144' } ext.excludeSailfish = { rcd -> @@ -63,7 +63,7 @@ repositories { mavenCentral() mavenLocal() - configurations.all { + configurations.configureEach { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds' } diff --git a/gradle.properties b/gradle.properties index 9e655ad..f8a1209 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -release_version = 3.11.1 \ No newline at end of file +release_version = 3.11.2 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d97373f..bdf0ae0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -15,7 +15,7 @@ # #Tue Jun 09 10:46:12 MSK 2020 -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStorePath=wrapper/dists From caf81c5bf38cf79e2825aa424758503e27afcaf0 Mon Sep 17 00:00:00 2001 From: "nikita.smirnov" Date: Fri, 6 Oct 2023 12:08:49 +0400 Subject: [PATCH 9/9] [TS-1574] corrected after review --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 63c45a0..fb2b710 100644 --- a/README.md +++ b/README.md @@ -124,14 +124,14 @@ spec: ### 3.11.2 + Sailfish updated from `3.3.132` to `3.3.144` ++ Added `maxMessageFlushTime` option ++ Use temporal directory for last layer in sailfish's workspace ### 3.11.1 + Updated `sailfish-core` version from `3.3.54` to `3.3.132` ### 3.11.0 -+ Added `maxMessageFlushTime` option - + Updated `sailfish-core` version from `3.2.1741` to `3.3.54` + Updated `common` from `3.33.0` to `3.44.0` + Updated `kotlin` form `1.5.30` to `1.6.21` @@ -140,7 +140,6 @@ spec: ### 3.10.2 + Events are made more convenient. Added event names and error logs. Error message moved from the name to the body of the event. -+ Use temporal directory for last layer in sailfish's workspace ### 3.10.1