Create and switch to a concurrent version of LispSouthboundStats 65/47165/4
authorLorand Jakab <lojakab@cisco.com>
Wed, 19 Oct 2016 18:46:53 +0000 (21:46 +0300)
committerLori Jakab <lorand.jakab@gmail.com>
Tue, 25 Oct 2016 15:51:09 +0000 (15:51 +0000)
Change-Id: Ia3961a584f9008b0de54fbbb87ecce33d308f3dc
Signed-off-by: Lorand Jakab <lojakab@cisco.com>
mappingservice/southbound/src/main/java/org/opendaylight/lispflowmapping/southbound/ConcurrentLispSouthboundStats.java [new file with mode: 0644]
mappingservice/southbound/src/main/java/org/opendaylight/lispflowmapping/southbound/LispSouthboundPlugin.java
mappingservice/southbound/src/main/java/org/opendaylight/lispflowmapping/southbound/LispSouthboundRPC.java
mappingservice/southbound/src/main/java/org/opendaylight/lispflowmapping/southbound/lisp/LispSouthboundHandler.java
mappingservice/southbound/src/test/java/org/opendaylight/lispflowmapping/southbound/LispSouthboundRpcTest.java
mappingservice/southbound/src/test/java/org/opendaylight/lispflowmapping/southbound/lisp/LispSouthboundServiceTest.java

diff --git a/mappingservice/southbound/src/main/java/org/opendaylight/lispflowmapping/southbound/ConcurrentLispSouthboundStats.java b/mappingservice/southbound/src/main/java/org/opendaylight/lispflowmapping/southbound/ConcurrentLispSouthboundStats.java
new file mode 100644 (file)
index 0000000..fc8ee16
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.lispflowmapping.southbound;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
+
+/**
+ * Object to hold statistics about LISP southbound events.
+ *
+ * @author Lorand Jakab
+ *
+ */
+public class ConcurrentLispSouthboundStats {
+    public static final int MAX_LISP_TYPES = getMaxMessageTypeValue();
+
+    private long[] rx = new long[MAX_LISP_TYPES + 1];
+    private long[] tx = new long[MAX_LISP_TYPES + 1];
+    private long rxUnknown = 0;
+    private long txErrors = 0;
+    private long cacheHits = 0;
+    private long cacheMisses = 0;
+
+    public ConcurrentLispSouthboundStats() {
+        resetStats();
+    }
+
+    public synchronized void resetStats() {
+        for (int i = 0; i <= MAX_LISP_TYPES; i++) {
+            rx[i] = 0;
+            tx[i] = 0;
+        }
+    }
+
+    public synchronized long[] getRx() {
+        return rx;
+    }
+
+    public synchronized void incrementRx(int type) {
+        this.rx[type] = incrementWithWrap(rx[type]);
+    }
+
+    public synchronized long[] getTx() {
+        return tx;
+    }
+
+    public synchronized void incrementTx(int type) {
+        this.tx[type] = incrementWithWrap(tx[type]);
+    }
+
+    public synchronized long getRxUnknown() {
+        return rxUnknown;
+    }
+
+    public synchronized void incrementRxUnknown() {
+        this.rxUnknown = incrementWithWrap(rxUnknown);
+    }
+
+    public synchronized long getTxErrors() {
+        return txErrors;
+    }
+
+    public synchronized void incrementTxErrors() {
+        this.txErrors = incrementWithWrap(txErrors);
+    }
+
+    public synchronized long getCacheHits() {
+        return cacheHits;
+    }
+
+    public synchronized void incrementCacheHits() {
+        this.cacheHits = incrementWithWrap(cacheHits);
+    }
+
+    public synchronized long getCacheMisses() {
+        return cacheMisses;
+    }
+
+    public synchronized void incrementCacheMisses() {
+        this.cacheMisses = incrementWithWrap(cacheMisses);
+    }
+
+    private static synchronized long incrementWithWrap(long value) {
+        if (value == Long.MAX_VALUE) {
+            return 0;
+        } else {
+            return value + 1;
+        }
+    }
+
+    // TODO move this method to the appropriate helper class if we start using MessageType in other places
+    public static synchronized int getMaxMessageTypeValue() {
+        int max = 0;
+        for (MessageType mt : MessageType.values()) {
+            if (mt.getIntValue() > max) {
+                max = mt.getIntValue();
+            }
+        }
+        return max;
+    }
+}
index 538e0f37ddef747a26b3c9d6c9ef6b1fa5e3d579..d1cf0f1f89afc977189d8a1defbee4701a28b27f 100644 (file)
@@ -74,7 +74,7 @@ public class LispSouthboundPlugin implements IConfigLispSouthboundPlugin, AutoCl
     private Class channelType;
     private volatile int xtrPort = LispMessage.XTR_PORT_NUM;
     private volatile boolean listenOnXtrPort = false;
-    private LispSouthboundStats statistics = new LispSouthboundStats();
+    private ConcurrentLispSouthboundStats statistics = new ConcurrentLispSouthboundStats();
     private Bootstrap bootstrap = new Bootstrap();
     private Bootstrap xtrBootstrap = new Bootstrap();
     private ThreadFactory threadFactory = new DefaultThreadFactory("lisp-sb");
@@ -250,7 +250,7 @@ public class LispSouthboundPlugin implements IConfigLispSouthboundPlugin, AutoCl
         return null;
     }
 
-    public LispSouthboundStats getStats() {
+    public ConcurrentLispSouthboundStats getStats() {
         return statistics;
     }
 
index a9d0c7a8d1ba4416b812f29611a7417500ac8c74..6e32befde99b0789c8b13cad11f37b5f699c8410 100644 (file)
@@ -116,7 +116,7 @@ public class LispSouthboundRPC implements OdlLispSbService {
 
         RpcResultBuilder<GetStatsOutput> rpcResultBuilder;
 
-        LispSouthboundStats stats = lispSbPlugin.getStats();
+        ConcurrentLispSouthboundStats stats = lispSbPlugin.getStats();
 
         if (stats == null) {
             rpcResultBuilder = RpcResultBuilder.<GetStatsOutput>failed()
@@ -131,7 +131,7 @@ public class LispSouthboundRPC implements OdlLispSbService {
     public Future<RpcResult<Void>> resetStats() {
         LOG.trace("resetStats called!!");
 
-        LispSouthboundStats stats = lispSbPlugin.getStats();
+        ConcurrentLispSouthboundStats stats = lispSbPlugin.getStats();
 
         if (stats == null) {
             return Futures.immediateFuture(RpcResultBuilder.<Void>failed()
@@ -143,7 +143,7 @@ public class LispSouthboundRPC implements OdlLispSbService {
         }
     }
 
-    private static GetStatsOutput createGetStatsOutput(LispSouthboundStats stats) {
+    private static GetStatsOutput createGetStatsOutput(ConcurrentLispSouthboundStats stats) {
         long[] rxStats = stats.getRx();
         long[] txStats = stats.getTx();
 
@@ -152,7 +152,7 @@ public class LispSouthboundRPC implements OdlLispSbService {
         cmsb.setTxErrors(stats.getTxErrors());
 
         List<ControlMessage> messages = new ArrayList<ControlMessage>();
-        for (int i = 0; i <= LispSouthboundStats.MAX_LISP_TYPES; i++) {
+        for (int i = 0; i <= ConcurrentLispSouthboundStats.MAX_LISP_TYPES; i++) {
             if (MessageType.forValue(i) == null) {
                 continue;
             }
index 8e7b49acbe7ecae00f5682cc5246d445ede26a2c..0ba084a8bb9bd463581ea69448079010d32752aa 100644 (file)
@@ -34,8 +34,8 @@ import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
 import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
 import org.opendaylight.lispflowmapping.lisp.util.MapRequestUtil;
 import org.opendaylight.lispflowmapping.mapcache.SimpleMapCache;
+import org.opendaylight.lispflowmapping.southbound.ConcurrentLispSouthboundStats;
 import org.opendaylight.lispflowmapping.southbound.LispSouthboundPlugin;
-import org.opendaylight.lispflowmapping.southbound.LispSouthboundStats;
 import org.opendaylight.lispflowmapping.southbound.lisp.cache.MapRegisterCache;
 import org.opendaylight.lispflowmapping.southbound.lisp.cache.MapRegisterPartialDeserializer;
 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
@@ -84,7 +84,7 @@ public class LispSouthboundHandler extends SimpleChannelInboundHandler<DatagramP
     //TODO: think whether this field can be accessed through mappingservice or some other configuration parameter
     private boolean authenticationEnabled = true;
     private final LispSouthboundPlugin lispSbPlugin;
-    private LispSouthboundStats lispSbStats = null;
+    private ConcurrentLispSouthboundStats lispSbStats = null;
     private SimpleMapCache smc;
     private AuthenticationKeyDataListener authenticationKeyDataListener;
     private DataStoreBackEnd dsbe;
@@ -478,7 +478,7 @@ public class LispSouthboundHandler extends SimpleChannelInboundHandler<DatagramP
 
     private void handleStats(int type) {
         if (lispSbStats != null) {
-            if (type <= LispSouthboundStats.MAX_LISP_TYPES) {
+            if (type <= ConcurrentLispSouthboundStats.MAX_LISP_TYPES) {
                 lispSbStats.incrementRx(type);
             } else {
                 lispSbStats.incrementRxUnknown();
@@ -535,7 +535,7 @@ public class LispSouthboundHandler extends SimpleChannelInboundHandler<DatagramP
         this.dsbe = dsbe;
     }
 
-    public void setStats(LispSouthboundStats lispSbStats) {
+    public void setStats(ConcurrentLispSouthboundStats lispSbStats) {
         this.lispSbStats = lispSbStats;
     }
 
index 976cb76d76ba2aba01eead417c936d5ac446f4ff..3f6213d4bc44415c2f7e9e92e7b5775bf69f425d 100644 (file)
@@ -182,7 +182,7 @@ public class LispSouthboundRpcTest {
      */
     @Test
     public void getStatsTest() throws ExecutionException, InterruptedException {
-        final LispSouthboundStats stats = new LispSouthboundStats();
+        final ConcurrentLispSouthboundStats stats = new ConcurrentLispSouthboundStats();
         incrementAll(stats);
         Mockito.when(lispSouthboundPlugin.getStats()).thenReturn(stats);
 
@@ -220,7 +220,7 @@ public class LispSouthboundRpcTest {
      */
     @Test
     public void resetStatsTest() throws ExecutionException, InterruptedException {
-        final LispSouthboundStats stats = new LispSouthboundStats();
+        final ConcurrentLispSouthboundStats stats = new ConcurrentLispSouthboundStats();
         incrementAll(stats);
         Mockito.when(lispSouthboundPlugin.getStats()).thenReturn(stats);
 
@@ -267,7 +267,7 @@ public class LispSouthboundRpcTest {
                 .setMappingRecordItem(Lists.newArrayList(getDefaultMappingRecordItem()));
     }
 
-    private static void incrementAll(LispSouthboundStats stats) {
+    private static void incrementAll(ConcurrentLispSouthboundStats stats) {
         for (MessageType type : MessageType.values()) {
             stats.incrementRx(type.getIntValue());
         }
index a11063920913a413eec7ee6f42f8b5541d14d050..fa11429ed1c25c2076ea1c852b86b53d6f90ac0a 100644 (file)
@@ -51,8 +51,8 @@ import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
 import org.opendaylight.lispflowmapping.lisp.util.MapNotifyBuilderHelper;
 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
 import org.opendaylight.lispflowmapping.mapcache.SimpleMapCache;
+import org.opendaylight.lispflowmapping.southbound.ConcurrentLispSouthboundStats;
 import org.opendaylight.lispflowmapping.southbound.LispSouthboundPlugin;
-import org.opendaylight.lispflowmapping.southbound.LispSouthboundStats;
 import org.opendaylight.lispflowmapping.southbound.lisp.cache.MapRegisterCache;
 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
 import org.opendaylight.lispflowmapping.tools.junit.BaseTestCase;
@@ -99,7 +99,7 @@ public class LispSouthboundServiceTest extends BaseTestCase {
     private MappingRecordBuilder mappingRecordBuilder;
     private MapRegisterCache mapRegisterCache;
     private LispSouthboundPlugin mockLispSouthboundPlugin;
-    private LispSouthboundStats lispSouthboundStats;
+    private ConcurrentLispSouthboundStats lispSouthboundStats;
     private static final long CACHE_RECORD_TIMEOUT = 90000;
 
     private static SimpleMapCache smc;
@@ -152,7 +152,6 @@ public class LispSouthboundServiceTest extends BaseTestCase {
         // mapResolver = context.mock(IMapResolver.class);
         // mapServer = context.mock(IMapServer.class);
         mockLispSouthboundPlugin = mock(LispSouthboundPlugin.class);
-        Mockito.when(mockLispSouthboundPlugin.getStats()).thenReturn(Mockito.mock(LispSouthboundStats.class));
         Mockito.when(mockLispSouthboundPlugin.isMapRegisterCacheEnabled()).thenReturn(true);
         testedLispService = new LispSouthboundHandler(mockLispSouthboundPlugin);
         testedLispService.setMapRegisterCacheTimeout(90000);
@@ -164,7 +163,7 @@ public class LispSouthboundServiceTest extends BaseTestCase {
         testedLispService.setDataStoreBackEnd(Mockito.mock(DataStoreBackEnd.class));
         nps = context.mock(NotificationPublishService.class);
         testedLispService.setNotificationProvider(nps);
-        lispSouthboundStats = new LispSouthboundStats();
+        lispSouthboundStats = new ConcurrentLispSouthboundStats();
         testedLispService.setStats(lispSouthboundStats);
         lispNotificationSaver = new ValueSaverAction<Notification>();
         // mapRegisterSaver = new ValueSaverAction<MapRegister>();