aboutsummaryrefslogtreecommitdiffstats
path: root/service-monitor
diff options
context:
space:
mode:
authorHåkon Hallingstad <hakon@oath.com>2017-09-29 08:57:20 +0200
committerHåkon Hallingstad <hakon@oath.com>2017-09-29 12:38:31 +0200
commit4d29c806e4d3a85a0c91aea0862b1fd2f4b86eef (patch)
tree8122ca15f6b8e7dc7731fc1f8f17c7abdb4f8fb4 /service-monitor
parentea33246cad6196a6b43266099df509993e83ae85 (diff)
Adds listener for SuperModel changes
Diffstat (limited to 'service-monitor')
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceMonitorImpl.java44
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/SuperModelListenerImpl.java67
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/monitor/SuperModelListenerImplTest.java29
3 files changed, 140 insertions, 0 deletions
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceMonitorImpl.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceMonitorImpl.java
new file mode 100644
index 00000000000..3468644169d
--- /dev/null
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceMonitorImpl.java
@@ -0,0 +1,44 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.service.monitor;
+
+import com.google.inject.Inject;
+import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.config.model.api.SuperModelProvider;
+import com.yahoo.config.provision.Zone;
+import com.yahoo.vespa.applicationmodel.ApplicationInstance;
+import com.yahoo.vespa.applicationmodel.ApplicationInstanceReference;
+
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+public class ServiceMonitorImpl implements ServiceMonitor {
+ private static final Logger logger = Logger.getLogger(ServiceMonitorImpl.class.getName());
+
+ private final Zone zone;
+ private final List<String> configServerHostnames;
+ private final SlobrokMonitor2 slobrokMonitor = new SlobrokMonitor2();
+ private final SuperModelListenerImpl superModelListener =
+ new SuperModelListenerImpl(slobrokMonitor);
+
+ @Inject
+ public ServiceMonitorImpl(SuperModelProvider superModelProvider,
+ ConfigserverConfig configserverConfig) {
+ this.zone = superModelProvider.getZone();
+ this.configServerHostnames = configserverConfig.zookeeperserver().stream()
+ .map(server -> server.hostname())
+ .collect(Collectors.toList());
+ superModelListener.start(superModelProvider);
+ }
+
+ @Override
+ public Map<ApplicationInstanceReference,
+ ApplicationInstance<ServiceMonitorStatus>> queryStatusOfAllApplicationInstances() {
+ // If we ever need to optimize this method, then consider reusing ServiceModel snapshots
+ // for up to X ms.
+ ServiceModel serviceModel =
+ superModelListener.createServiceModelSnapshot(zone, configServerHostnames);
+ return serviceModel.getAllApplicationInstances();
+ }
+}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/SuperModelListenerImpl.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/SuperModelListenerImpl.java
new file mode 100644
index 00000000000..8beb90c382a
--- /dev/null
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/SuperModelListenerImpl.java
@@ -0,0 +1,67 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.service.monitor;
+
+import com.yahoo.config.model.api.SuperModel;
+import com.yahoo.config.model.api.SuperModelListener;
+import com.yahoo.config.model.api.SuperModelProvider;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.Zone;
+
+import java.util.List;
+import java.util.logging.Logger;
+
+public class SuperModelListenerImpl implements SuperModelListener {
+ private static final Logger logger = Logger.getLogger(SuperModelListenerImpl.class.getName());
+
+ // Guard for updating superModel and slobrokMonitor exclusively and atomically:
+ // - superModel and slobrokMonitor must be updated in combination (exclusively and atomically)
+ // - Anyone may take a snapshot of superModel for reading purposes, hence volatile.
+ private final Object monitor = new Object();
+ private final SlobrokMonitor2 slobrokMonitor;
+ private volatile SuperModel superModel;
+
+ SuperModelListenerImpl(SlobrokMonitor2 slobrokMonitor) {
+ this.slobrokMonitor = slobrokMonitor;
+ }
+
+ void start(SuperModelProvider superModelProvider) {
+ synchronized (monitor) {
+ // This snapshot() call needs to be within the synchronized block,
+ // since applicationActivated()/applicationRemoved() may be called
+ // asynchronously even before snapshot() returns.
+ SuperModel snapshot = superModelProvider.snapshot(this);
+ exclusiveUpdate(snapshot);
+ }
+ }
+
+ @Override
+ public void applicationActivated(SuperModel superModel, ApplicationId applicationId) {
+ synchronized (monitor) {
+ exclusiveUpdate(superModel);
+ }
+ }
+
+ @Override
+ public void applicationRemoved(SuperModel superModel, ApplicationId id) {
+ synchronized (monitor) {
+ exclusiveUpdate(superModel);
+ }
+ }
+
+ ServiceModel createServiceModelSnapshot(Zone zone, List<String> configServerHostnames) {
+ // Save a snapshot of volatile this.superModel outside of synchronized block.
+ SuperModel superModelSnapshot = this.superModel;
+
+ ModelGenerator modelGenerator = new ModelGenerator();
+ return modelGenerator.toServiceModel(
+ superModelSnapshot,
+ zone,
+ configServerHostnames,
+ slobrokMonitor);
+ }
+
+ private void exclusiveUpdate(SuperModel superModel) {
+ this.superModel = superModel;
+ slobrokMonitor.updateSlobrokList(superModel);
+ }
+} \ No newline at end of file
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/SuperModelListenerImplTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/SuperModelListenerImplTest.java
new file mode 100644
index 00000000000..07e84b22d72
--- /dev/null
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/SuperModelListenerImplTest.java
@@ -0,0 +1,29 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+package com.yahoo.vespa.service.monitor;
+
+import com.yahoo.config.model.api.SuperModel;
+import com.yahoo.config.provision.ApplicationId;
+import org.junit.Test;
+
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+
+public class SuperModelListenerImplTest {
+ private final SlobrokMonitor2 slobrokMonitor = mock(SlobrokMonitor2.class);
+ private final SuperModel superModel = mock(SuperModel.class);
+ private final ApplicationId applicationId = ApplicationId.defaultId();
+ private final SuperModelListenerImpl listener = new SuperModelListenerImpl(slobrokMonitor);
+
+ @Test
+ public void testActivateApplication() {
+ listener.applicationActivated(superModel, applicationId);
+ doNothing().when(slobrokMonitor).updateSlobrokList(superModel);
+ }
+
+ @Test
+ public void testRemoveApplication() {
+ listener.applicationRemoved(superModel, applicationId);
+ doNothing().when(slobrokMonitor).updateSlobrokList(superModel);
+ }
+} \ No newline at end of file