Merge branch 'stable-3.0' into stable-3.1
* stable-3.0:
Log websessions when they are produced and consumed
Change-Id: If95735b9fcff9040596e8116fced01eb2c20eaba
diff --git a/src/main/java/com/googlesource/gerrit/plugins/websession/broker/BrokerBasedWebSession.java b/src/main/java/com/googlesource/gerrit/plugins/websession/broker/BrokerBasedWebSession.java
index fbd0882..733581c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/websession/broker/BrokerBasedWebSession.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/websession/broker/BrokerBasedWebSession.java
@@ -27,9 +27,12 @@
import com.google.gerrit.server.events.EventTypes;
import com.google.inject.Inject;
import com.google.inject.Provider;
+import com.google.inject.Scopes;
import com.google.inject.internal.UniqueAnnotations;
import com.google.inject.servlet.RequestScoped;
import com.google.inject.servlet.ServletScopes;
+import com.googlesource.gerrit.plugins.websession.broker.log.Log4jWebSessionLogger;
+import com.googlesource.gerrit.plugins.websession.broker.log.WebSessionLogger;
import java.lang.annotation.Annotation;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -49,6 +52,9 @@
listener(BrokerBasedWebSessionCache.class);
listener(BrokerBasedWebSessionCacheCleaner.class);
+ listener(Log4jWebSessionLogger.class);
+
+ bind(WebSessionLogger.class).to(Log4jWebSessionLogger.class).in(Scopes.SINGLETON);
}
private void listener(Class<? extends LifecycleListener> classObj) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/websession/broker/BrokerBasedWebSessionCache.java b/src/main/java/com/googlesource/gerrit/plugins/websession/broker/BrokerBasedWebSessionCache.java
index 6dc1689..147fa93 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/websession/broker/BrokerBasedWebSessionCache.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/websession/broker/BrokerBasedWebSessionCache.java
@@ -31,6 +31,8 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
+import com.googlesource.gerrit.plugins.websession.broker.log.WebSessionLogger;
+import com.googlesource.gerrit.plugins.websession.broker.log.WebSessionLogger.Direction;
import com.googlesource.gerrit.plugins.websession.broker.util.TimeMachine;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -40,6 +42,7 @@
import java.time.Instant;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
@@ -56,6 +59,7 @@
String webSessionTopicName;
DynamicItem<BrokerApi> brokerApi;
TimeMachine timeMachine;
+ private final WebSessionLogger webSessionLogger;
@Inject
public BrokerBasedWebSessionCache(
@@ -63,11 +67,13 @@
DynamicItem<BrokerApi> brokerApi,
TimeMachine timeMachine,
PluginConfigFactory cfg,
- @PluginName String pluginName) {
+ @PluginName String pluginName,
+ WebSessionLogger webSessionLogger) {
this.cache = cache;
this.brokerApi = brokerApi;
this.timeMachine = timeMachine;
this.webSessionTopicName = getWebSessionTopicName(cfg, pluginName);
+ this.webSessionLogger = webSessionLogger;
}
protected void processMessage(EventMessage message) {
@@ -84,6 +90,8 @@
try (ByteArrayInputStream in = new ByteArrayInputStream(event.payload);
ObjectInputStream inputStream = new ObjectInputStream(in)) {
Val value = (Val) inputStream.readObject();
+
+ webSessionLogger.log(Direction.CONSUME, webSessionTopicName, event, Optional.of(value));
Instant expires = Instant.ofEpochMilli(value.getExpiresAt());
if (expires.isAfter(timeMachine.now())) {
cache.put(event.key, value);
@@ -96,6 +104,8 @@
break;
case REMOVE:
cache.invalidate(event.key);
+ webSessionLogger.log(Direction.CONSUME, webSessionTopicName, event, Optional.empty());
+
break;
default:
logger.atWarning().log(
@@ -181,18 +191,19 @@
objectOutputStream.writeObject(value);
out.flush();
byte[] serializedObject = out.toByteArray();
- EventMessage message =
- brokerApi
- .get()
- .newMessage(UUID.randomUUID(), new WebSessionEvent(key, serializedObject, operation));
+ WebSessionEvent webSessionEvent = new WebSessionEvent(key, serializedObject, operation);
+ EventMessage message = brokerApi.get().newMessage(UUID.randomUUID(), webSessionEvent);
succeeded = brokerApi.get().send(webSessionTopicName, message);
+ if (succeeded) {
+ webSessionLogger.log(
+ Direction.PUBLISH, webSessionTopicName, webSessionEvent, Optional.ofNullable(value));
+ } else {
+ logger.atSevere().log(
+ "Cannot send web-session message for '%s Topic: '%s'", key, webSessionTopicName);
+ }
} catch (IOException e) {
logger.atSevere().withCause(e).log(
"Cannot serialize event for account id '%s': [Exception: %s]", value.getAccountId());
- } finally {
- if (!succeeded)
- logger.atSevere().log(
- "Cannot send web-session message for '%s Topic: '%s'", key, webSessionTopicName);
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/websession/broker/log/Log4jWebSessionLogger.java b/src/main/java/com/googlesource/gerrit/plugins/websession/broker/log/Log4jWebSessionLogger.java
new file mode 100644
index 0000000..f10a3bf
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/websession/broker/log/Log4jWebSessionLogger.java
@@ -0,0 +1,58 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.websession.broker.log;
+
+import com.google.gerrit.extensions.systemstatus.ServerInformation;
+import com.google.gerrit.httpd.WebSessionManager.Val;
+import com.google.gerrit.server.util.PluginLogFile;
+import com.google.gerrit.server.util.SystemLog;
+import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.websession.broker.BrokerBasedWebSessionCache.WebSessionEvent;
+import java.util.Optional;
+import org.apache.log4j.PatternLayout;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Log4jWebSessionLogger extends PluginLogFile implements WebSessionLogger {
+ private static final String LOG_NAME = "websession_log";
+ private final Logger msgLog;
+
+ @Inject
+ public Log4jWebSessionLogger(SystemLog systemLog, ServerInformation serverInfo) {
+ super(systemLog, serverInfo, LOG_NAME, new PatternLayout("[%d{ISO8601}] [%t] %-5p : %m%n"));
+ this.msgLog = LoggerFactory.getLogger(LOG_NAME);
+ }
+
+ @Override
+ public void log(Direction direction, String topic, WebSessionEvent event, Optional<Val> payload) {
+ msgLog.info("{} {} {} {}", direction, topic, formatEvent(event), formatSession(payload));
+ }
+
+ private Object formatEvent(WebSessionEvent event) {
+ return String.format(
+ "{ \"operation\":\"%s\", \"key\":\"%s\", \"eventCreatedOn\":%d }",
+ event.operation, event.key, event.eventCreatedOn);
+ }
+
+ private Object formatSession(Optional<Val> payload) {
+ return payload
+ .map(
+ session ->
+ String.format(
+ "{ \"accountId\":%d, \"expiresAt\":%d }",
+ session.getAccountId().get(), session.getExpiresAt()))
+ .orElse("");
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/websession/broker/log/WebSessionLogger.java b/src/main/java/com/googlesource/gerrit/plugins/websession/broker/log/WebSessionLogger.java
new file mode 100644
index 0000000..37b04c2
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/websession/broker/log/WebSessionLogger.java
@@ -0,0 +1,29 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.websession.broker.log;
+
+import com.google.gerrit.httpd.WebSessionManager.Val;
+import com.googlesource.gerrit.plugins.websession.broker.BrokerBasedWebSessionCache.WebSessionEvent;
+import java.util.Optional;
+
+public interface WebSessionLogger {
+
+ public enum Direction {
+ PUBLISH,
+ CONSUME;
+ }
+
+ public void log(Direction direction, String topic, WebSessionEvent event, Optional<Val> payload);
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/websession/broker/BrokerBasedWebSessionCacheTest.java b/src/test/java/com/googlesource/gerrit/plugins/websession/broker/BrokerBasedWebSessionCacheTest.java
index 746d3e6..60e995e 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/websession/broker/BrokerBasedWebSessionCacheTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/websession/broker/BrokerBasedWebSessionCacheTest.java
@@ -35,6 +35,7 @@
import com.google.gerrit.server.events.Event;
import com.googlesource.gerrit.plugins.websession.broker.BrokerBasedWebSessionCache.WebSessionEvent;
import com.googlesource.gerrit.plugins.websession.broker.BrokerBasedWebSessionCache.WebSessionEvent.Operation;
+import com.googlesource.gerrit.plugins.websession.broker.log.WebSessionLogger;
import com.googlesource.gerrit.plugins.websession.broker.util.TimeMachine;
import java.time.Instant;
import java.util.UUID;
@@ -72,6 +73,7 @@
@Mock TimeMachine timeMachine;
@Mock PluginConfigFactory cfg;
@Mock PluginConfig pluginConfig;
+ @Mock WebSessionLogger webSessionLogger;
@Captor ArgumentCaptor<EventMessage> eventCaptor;
@Captor ArgumentCaptor<Val> valCaptor;
@@ -84,7 +86,9 @@
when(cfg.getFromGerritConfig(PLUGIN_NAME)).thenReturn(pluginConfig);
when(timeMachine.now()).thenReturn(Instant.EPOCH);
DynamicItem<BrokerApi> item = DynamicItem.itemOf(BrokerApi.class, brokerApi);
- objectUnderTest = new BrokerBasedWebSessionCache(cache, item, timeMachine, cfg, PLUGIN_NAME);
+ objectUnderTest =
+ new BrokerBasedWebSessionCache(
+ cache, item, timeMachine, cfg, PLUGIN_NAME, webSessionLogger);
}
@Test