BUG 7799: Implement agent RPCs for singleton rapid un-registration testing 16/52216/8
authorTomas Cere <tcere@cisco.com>
Thu, 23 Feb 2017 15:15:23 +0000 (16:15 +0100)
committerTom Pantelis <tpanteli@brocade.com>
Tue, 7 Mar 2017 17:34:55 +0000 (17:34 +0000)
Change-Id: I080a8af30c2a47e2046b0235ea75055e4c4a51cf
Signed-off-by: Tomas Cere <tcere@cisco.com>
opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/MdsalLowLevelTestProvider.java
opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/FlappingSingletonService.java [new file with mode: 0644]

index 9b3446c93b4c365fdf83191be64e2429b7f6ba22..bdc2d2f22468821604e4610bd42f92dc8ced4b3e 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.util.concurrent.Futures;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Future;
+import org.opendaylight.controller.clustering.it.provider.impl.FlappingSingletonService;
 import org.opendaylight.controller.clustering.it.provider.impl.GetConstantService;
 import org.opendaylight.controller.clustering.it.provider.impl.RoutedGetConstantService;
 import org.opendaylight.controller.clustering.it.provider.impl.SingletonGetConstantService;
@@ -41,6 +42,7 @@ import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.l
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.SubscribeYnlInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterBoundConstantInput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterFlappingSingletonOutput;
+import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnregisterFlappingSingletonOutputBuilder;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeDdtlOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeDtclOutput;
 import org.opendaylight.yang.gen.v1.tag.opendaylight.org._2017.controller.yang.lowlevel.control.rev170215.UnsubscribeYnlInput;
@@ -72,6 +74,7 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
 
     private DOMRpcImplementationRegistration<GetConstantService> globalGetConstantRegistration = null;
     private ClusterSingletonServiceRegistration getSingletonConstantRegistration;
+    private FlappingSingletonService flappingSingletonService;
 
     public MdsalLowLevelTestProvider(final RpcProviderRegistry rpcRegistry,
                                      final DOMRpcProviderService domRpcService,
@@ -212,7 +215,23 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
 
     @Override
     public Future<RpcResult<UnregisterFlappingSingletonOutput>> unregisterFlappingSingleton() {
-        return null;
+        LOG.debug("unregister-flapping-singleton received.");
+
+        if (flappingSingletonService == null) {
+            final RpcError rpcError = RpcResultBuilder
+                    .newError(ErrorType.APPLICATION, "missing-registration", "No flapping-singleton registration present.");
+            final RpcResult<UnregisterFlappingSingletonOutput> result =
+                    RpcResultBuilder.<UnregisterFlappingSingletonOutput>failed().withRpcError(rpcError).build();
+            return Futures.immediateFuture(result);
+        }
+
+        final long flapCount = flappingSingletonService.setInactive();
+        flappingSingletonService = null;
+
+        final UnregisterFlappingSingletonOutput output =
+                new UnregisterFlappingSingletonOutputBuilder().setFlapCount(flapCount).build();
+
+        return Futures.immediateFuture(RpcResultBuilder.success(output).build());
     }
 
     @Override
@@ -257,7 +276,17 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
 
     @Override
     public Future<RpcResult<Void>> registerFlappingSingleton() {
-        return null;
+        LOG.debug("Received register-flapping-singleton.");
+
+        if (flappingSingletonService != null) {
+            final RpcError error = RpcResultBuilder.newError(
+                    ErrorType.RPC, "Registration present.", "flappin-singleton already registered");
+            return Futures.immediateFuture(RpcResultBuilder.<Void>failed().withRpcError(error).build());
+        }
+
+        flappingSingletonService = new FlappingSingletonService(singletonService);
+
+        return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
     }
 
     @Override
diff --git a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/FlappingSingletonService.java b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/FlappingSingletonService.java
new file mode 100644 (file)
index 0000000..21e6acf
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 Cisco Systems, Inc. and others.  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.controller.clustering.it.provider.impl;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FlappingSingletonService implements ClusterSingletonService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(FlappingSingletonService.class);
+
+    private static final ServiceGroupIdentifier SERVICE_GROUP_IDENTIFIER =
+            ServiceGroupIdentifier.create("flapping-singleton-service");
+
+    private final ClusterSingletonServiceProvider singletonServiceProvider;
+
+    private volatile long flapCount = 0;
+    private AtomicBoolean active = new AtomicBoolean(true);
+
+    private volatile ClusterSingletonServiceRegistration registration;
+
+    private static ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor();
+
+    public FlappingSingletonService(final ClusterSingletonServiceProvider singletonServiceProvider) {
+        LOG.debug("Registering flapping-singleton-service.");
+
+        this.singletonServiceProvider = singletonServiceProvider;
+        registration = singletonServiceProvider.registerClusterSingletonService(this);
+    }
+
+    @Override
+    public void instantiateServiceInstance() {
+        LOG.debug("Instantiating flapping-singleton-service.");
+
+        // TODO direct registration/close seem to trigger a bug in singleton state transitions,
+        // remove the whole executor shenanigans after it's fixed.
+        EXECUTOR.submit(() -> {
+            try {
+                registration.close();
+                registration = null;
+            } catch (final Exception e) {
+                LOG.warn("There was a problem closing flapping singleton service.", e);
+                flapCount = -flapCount;
+            }
+        });
+    }
+
+    @Override
+    public ListenableFuture<Void> closeServiceInstance() {
+        LOG.debug("Closing flapping-singleton-service, flapCount: {}", flapCount);
+
+        flapCount++;
+        if (active.get()) {
+            // TODO direct registration/close seem to trigger a bug in singleton state transitions,
+            // remove  whole executor shenanigans after it's fixed.
+            // Needs to be delayed slightly otherwise it's triggered as well.
+            EXECUTOR.schedule(() -> {
+                LOG.debug("Running registration");
+                registration =
+                        singletonServiceProvider.registerClusterSingletonService(this);
+
+            }, 200, TimeUnit.MILLISECONDS);
+        }
+
+        return Futures.immediateFuture(null);
+    }
+
+    @Override
+    public ServiceGroupIdentifier getIdentifier() {
+        return SERVICE_GROUP_IDENTIFIER;
+    }
+
+    public long setInactive() {
+        LOG.debug("Setting flapping-singleton-service to inactive, flap-count: {}", flapCount);
+
+        active.set(false);
+        return flapCount;
+    }
+}