diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/provider/interfaces/ISubscriberNotificationRequestLogger.java b/notification-core/src/main/java/org/opengroup/osdu/notification/provider/interfaces/ISubscriberNotificationRequestLogger.java new file mode 100644 index 0000000000000000000000000000000000000000..2690c97fa11fcfc5f51d1d490637ff23c6d95d0a --- /dev/null +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/provider/interfaces/ISubscriberNotificationRequestLogger.java @@ -0,0 +1,23 @@ +// Copyright © Schlumberger +// +// 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 org.opengroup.osdu.notification.provider.interfaces; + +import org.opengroup.osdu.core.common.http.HttpResponse; +import org.opengroup.osdu.core.common.model.notification.Subscription; + +public interface ISubscriberNotificationRequestLogger { + + void log(String notificationId, Subscription subscription, HttpResponse response); +} diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/service/NotificationHandler.java b/notification-core/src/main/java/org/opengroup/osdu/notification/service/NotificationHandler.java index 1f92d0cdbcd69844686b498c7f4f81d25eac9057..ea3c86e78eaafd52ed161e200a131d6e13e46134 100644 --- a/notification-core/src/main/java/org/opengroup/osdu/notification/service/NotificationHandler.java +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/service/NotificationHandler.java @@ -24,6 +24,7 @@ import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.model.notification.*; import org.opengroup.osdu.notification.auth.factory.AuthFactory; import org.opengroup.osdu.notification.auth.interfaces.SecretAuth; +import org.opengroup.osdu.notification.provider.interfaces.ISubscriberNotificationRequestLogger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -45,6 +46,8 @@ public class NotificationHandler { private AuthFactory authFactory; @Value("${app.waitingTime:30000}") private int WAITING_TIME; + @Autowired + private ISubscriberNotificationRequestLogger subscriberNotificationRequestLogger; public HttpResponse notifySubscriber(String notificationId, String pubsubMessage, Map<String, String> headerAttributes) throws Exception { Subscription subscription = subscriptionHandler.getSubscriptionFromCache(notificationId); @@ -76,6 +79,7 @@ public class NotificationHandler { HttpRequest request = HttpRequest.post().url(pushUrl).headers(requestHeader).body(pubsubMessage).connectionTimeout(WAITING_TIME).build(); this.LOGGER.debug("Sending out notification to endpoint: " + endpoint); HttpResponse response = httpClient.send(request); + subscriberNotificationRequestLogger.log(notificationId, subscription, response); return response; } } \ No newline at end of file diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/utils/DefaultSubscriberNotificationRequestLogger.java b/notification-core/src/main/java/org/opengroup/osdu/notification/utils/DefaultSubscriberNotificationRequestLogger.java new file mode 100644 index 0000000000000000000000000000000000000000..99c4d23822e5413d8559294add3c23a457d07942 --- /dev/null +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/utils/DefaultSubscriberNotificationRequestLogger.java @@ -0,0 +1,47 @@ +// Copyright © Schlumberger +// +// 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 org.opengroup.osdu.notification.utils; + +import org.opengroup.osdu.core.common.http.HttpResponse; +import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.core.common.model.http.Request; +import org.opengroup.osdu.core.common.model.notification.Subscription; +import org.opengroup.osdu.notification.provider.interfaces.ISubscriberNotificationRequestLogger; +import org.springframework.stereotype.Component; + +import java.time.Duration; + +@Component +public class DefaultSubscriberNotificationRequestLogger implements ISubscriberNotificationRequestLogger { + + private JaxRsDpsLog logger; + + public DefaultSubscriberNotificationRequestLogger(JaxRsDpsLog logger) { + this.logger = logger; + } + + public void log(String notificationId, Subscription subscription, HttpResponse response) { + this.logger.request("subscriber.request", Request.builder() + .requestMethod("POST") + .latency(Duration.ofMillis(response.getLatency())) + .requestUrl(subscription.getPushEndpoint()) + .Status(response.getResponseCode()) + .build()); + + if (!response.isSuccessCode()) { + this.logger.error(String.format("Subscriber notification request failed. notificationId=%s subscriptionId=%s createdBy=%s response=%s", notificationId, subscription.getId(), subscription.getCreatedBy(), response.getBody())); + } + } +} diff --git a/notification-core/src/test/java/org/opengroup/osdu/notification/service/NotificationHandlerTest.java b/notification-core/src/test/java/org/opengroup/osdu/notification/service/NotificationHandlerTest.java index 3336ef1f2989c40ae27be95682b0ba33e91ae401..cf6c62507007be8d61038a7effbe60448d0866a0 100644 --- a/notification-core/src/test/java/org/opengroup/osdu/notification/service/NotificationHandlerTest.java +++ b/notification-core/src/test/java/org/opengroup/osdu/notification/service/NotificationHandlerTest.java @@ -32,6 +32,8 @@ import org.opengroup.osdu.core.common.model.notification.Subscription; import org.opengroup.osdu.core.common.notification.SubscriptionException; import org.opengroup.osdu.notification.auth.factory.AuthFactory; import org.opengroup.osdu.notification.auth.interfaces.SecretAuth; +import org.opengroup.osdu.notification.provider.interfaces.ISubscriberNotificationRequestLogger; +import org.powermock.modules.junit4.PowerMockRunner; import java.util.HashMap; import java.util.Map; @@ -64,6 +66,8 @@ public class NotificationHandlerTest { @Mock private JaxRsDpsLog log; + @Mock + private ISubscriberNotificationRequestLogger subscriberNotificationRequestLogger; @InjectMocks private NotificationHandler sut; diff --git a/notification-core/src/test/java/org/opengroup/osdu/notification/utils/DefaultSubscriberNotificationRequestLoggerTest.java b/notification-core/src/test/java/org/opengroup/osdu/notification/utils/DefaultSubscriberNotificationRequestLoggerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..dd21b21801ac6b96c020dcbe9f5093ee7eff26ce --- /dev/null +++ b/notification-core/src/test/java/org/opengroup/osdu/notification/utils/DefaultSubscriberNotificationRequestLoggerTest.java @@ -0,0 +1,78 @@ +// Copyright © Schlumberger +// +// 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 org.opengroup.osdu.notification.utils; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.opengroup.osdu.core.common.http.HttpResponse; +import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.core.common.model.http.Request; +import org.opengroup.osdu.core.common.model.notification.Subscription; + +import java.time.Duration; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +@RunWith(MockitoJUnitRunner.class) +public class DefaultSubscriberNotificationRequestLoggerTest { + + private final HttpResponse response = new HttpResponse(); + private static final String NOTIFICATION_ID = "test-notification-id"; + private static Subscription subscription; + + @Mock + private JaxRsDpsLog logger; + @InjectMocks + private DefaultSubscriberNotificationRequestLogger sut; + + @BeforeClass + public static void setup() { + subscription = new Subscription(); + subscription.setName("hamc_test_subscription"); + subscription.setPushEndpoint("http://challenge"); + subscription.setDescription("Description"); + subscription.setTopic("records-changed"); + subscription.setNotificationId(NOTIFICATION_ID); + subscription.setId("id_1"); + subscription.setCreatedBy("test@test.com"); + } + + @Test + public void log_notifySubscriber_success() { + response.setResponseCode(200); + + this.sut.log(NOTIFICATION_ID, subscription, response); + + verify(this.logger, times(1)).request("subscriber.request", Request.builder().requestUrl("http://challenge").requestMethod("POST").latency(Duration.ZERO).Status(200).ip("").build()); + verifyNoMoreInteractions(this.logger); + } + + @Test + public void log_notifySubscriber_failure() { + response.setResponseCode(403); + response.setBody("unauthorized"); + + this.sut.log(NOTIFICATION_ID, subscription, response); + + verify(this.logger, times(1)).request("subscriber.request", Request.builder().requestUrl("http://challenge").requestMethod("POST").latency(Duration.ZERO).Status(403).ip("").build()); + verify(this.logger, times(1)).error("Subscriber notification request failed. notificationId=test-notification-id subscriptionId=id_1 createdBy=test@test.com response=unauthorized"); + } +} diff --git a/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/SubscriberNotificationRequestLogger.java b/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/SubscriberNotificationRequestLogger.java new file mode 100644 index 0000000000000000000000000000000000000000..b8564499ec683ee311a9422113e5541f8d5d6135 --- /dev/null +++ b/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/SubscriberNotificationRequestLogger.java @@ -0,0 +1,52 @@ +// Copyright © Schlumberger +// +// 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 org.opengroup.osdu.notification.provider.azure.util; + +import org.opengroup.osdu.azure.logging.DependencyLogger; +import org.opengroup.osdu.azure.logging.DependencyLoggingOptions; +import org.opengroup.osdu.core.common.http.HttpResponse; +import org.opengroup.osdu.core.common.model.notification.Subscription; +import org.opengroup.osdu.notification.provider.interfaces.ISubscriberNotificationRequestLogger; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; + +@Component +@Primary +public class SubscriberNotificationRequestLogger implements ISubscriberNotificationRequestLogger { + + private final String DEPENDENCY_TYPE = "Notification"; + private final String DEPENDENCY_NAME = "NotifySubscriber"; + private final DependencyLogger dependencyLogger; + + public SubscriberNotificationRequestLogger(DependencyLogger dependencyLogger) { + this.dependencyLogger = dependencyLogger; + } + + public void log(String notificationId, Subscription subscription, HttpResponse response) { + final DependencyLoggingOptions loggingOptions = DependencyLoggingOptions.builder() + .type(DEPENDENCY_TYPE) + .name(DEPENDENCY_NAME) + .target(subscription.getPushEndpoint()) + .timeTakenInMs(response.getLatency()) + .resultCode(response.getResponseCode()) + .success(response.isSuccessCode()) + .build(); + final String data = response.isSuccessCode() + ? String.format("notificationId=%s subscriptionId=%s", notificationId, subscription.getId()) + : String.format("notificationId=%s subscriptionId=%s createdBy=%s response=%s", notificationId, subscription.getId(), subscription.getCreatedBy(), response.getBody()); + loggingOptions.setData(data); + this.dependencyLogger.logDependency(loggingOptions); + } +} diff --git a/provider/notification-azure/src/test/java/org/opengroup/osdu/notification/util/SubscriberNotificationRequestLoggerTest.java b/provider/notification-azure/src/test/java/org/opengroup/osdu/notification/util/SubscriberNotificationRequestLoggerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d8ecdba191ff71f69cafbd10220687460f46f983 --- /dev/null +++ b/provider/notification-azure/src/test/java/org/opengroup/osdu/notification/util/SubscriberNotificationRequestLoggerTest.java @@ -0,0 +1,82 @@ +package org.opengroup.osdu.notification.util; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.opengroup.osdu.azure.logging.DependencyLogger; +import org.opengroup.osdu.azure.logging.DependencyLoggingOptions; +import org.opengroup.osdu.core.common.http.HttpResponse; +import org.opengroup.osdu.core.common.model.notification.HmacSecret; +import org.opengroup.osdu.core.common.model.notification.Subscription; +import org.opengroup.osdu.notification.provider.azure.util.SubscriberNotificationRequestLogger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +@RunWith(MockitoJUnitRunner.class) +public class SubscriberNotificationRequestLoggerTest { + + private final HttpResponse response = new HttpResponse(); + private static final String NOTIFICATION_ID = "test-notification-id"; + private static Subscription subscription; + + @Mock + private DependencyLogger dependencyLogger; + + @InjectMocks + private SubscriberNotificationRequestLogger sut; + + @BeforeClass + public static void setup() { + subscription = new Subscription(); + subscription.setName("hamc_test_subscription"); + subscription.setPushEndpoint("http://challenge"); + subscription.setDescription("Description"); + subscription.setTopic("records-changed"); + subscription.setNotificationId(NOTIFICATION_ID); + subscription.setId("id_1"); + subscription.setCreatedBy("test@test.com"); + HmacSecret secret = new HmacSecret(); + secret.setValue("testsecret"); + subscription.setSecret(secret); + } + + @Test + public void log_notifySubscriber_success() { + response.setResponseCode(200); + + this.sut.log(NOTIFICATION_ID, subscription, response); + + ArgumentCaptor<DependencyLoggingOptions> loggingOptionsArgumentCaptor = ArgumentCaptor.forClass(DependencyLoggingOptions.class); + verify(dependencyLogger, times(1)).logDependency(loggingOptionsArgumentCaptor.capture()); + DependencyLoggingOptions actualLoggingOptions = loggingOptionsArgumentCaptor.getValue(); + verifyDependencyLogging(actualLoggingOptions, "notificationId=test-notification-id subscriptionId=id_1", "http://challenge", 200, true); + } + + @Test + public void log_notifySubscriber_failure() { + response.setResponseCode(403); + response.setBody("unauthorized"); + + this.sut.log(NOTIFICATION_ID, subscription, response); + + ArgumentCaptor<DependencyLoggingOptions> loggingOptionsArgumentCaptor = ArgumentCaptor.forClass(DependencyLoggingOptions.class); + verify(dependencyLogger, times(1)).logDependency(loggingOptionsArgumentCaptor.capture()); + DependencyLoggingOptions actualLoggingOptions = loggingOptionsArgumentCaptor.getValue(); + verifyDependencyLogging(actualLoggingOptions, "notificationId=test-notification-id subscriptionId=id_1 createdBy=test@test.com response=unauthorized", "http://challenge", 403, false); + } + + private void verifyDependencyLogging(DependencyLoggingOptions capturedLoggingOptions, String data, String target, int resultCode, boolean success) { + assertEquals("Notification", capturedLoggingOptions.getType()); + assertEquals("NotifySubscriber", capturedLoggingOptions.getName()); + assertEquals(data, capturedLoggingOptions.getData()); + assertEquals(target, capturedLoggingOptions.getTarget()); + assertEquals(resultCode, capturedLoggingOptions.getResultCode()); + assertEquals(success, capturedLoggingOptions.isSuccess()); + } +}