Refactor ShutdownProvider.shutdown() 53/111853/1
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 23 May 2024 16:25:59 +0000 (18:25 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Sun, 26 May 2024 20:51:55 +0000 (22:51 +0200)
Returning a Boolean is confusing with regard to error reporting:
- users are really ignoring the value and rely on exception cause
- that is not what the code does, as it is confused about mapping,
  running set(true/false) followed by an optional setException()

Change the future type to Void, making it the value does not hold
anything and rely on setException() to deliver the failure cause.

Change-Id: Id6d97580b8d908caf37338f3578045598d2555f1
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 945b2dd05df3c725941fe4c4677f6b2972249256)

openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ShutdownProvider.java
openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderImpl.java
openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandler.java
openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpHandler.java
openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandlerTest.java
openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImplTest.java
openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpHandlerTest.java
openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProvider.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImplTest.java

index b6d6f73fd272fe938f95a24bdea28a185cc5d815..34717e28951ed76308eb31e76909daae6743535a 100644 (file)
@@ -5,13 +5,10 @@
  * 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.openflowjava.protocol.impl.core;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
-
 /**
  * Shutdown provider interface.
  *
@@ -19,5 +16,5 @@ import com.google.common.util.concurrent.ListenableFuture;
  */
 public interface ShutdownProvider {
 
-    ListenableFuture<Boolean> shutdown();
+    ListenableFuture<Void> shutdown();
 }
index a55a638a45354de3b9fb9fde6183e20448aec150..d483830f4f657a321476e3d5c5144cf9b2f7a7d2 100755 (executable)
@@ -135,13 +135,13 @@ public class SwitchConnectionProviderImpl implements SwitchConnectionProvider, C
     }
 
     @Override
-    public ListenableFuture<Boolean> shutdown() {
+    public ListenableFuture<Void> shutdown() {
         LOG.debug("Shutdown summoned");
         if (serverFacade == null) {
             LOG.warn("Can not shutdown - not configured or started");
             throw new IllegalStateException("SwitchConnectionProvider is not started or not configured.");
         }
-        ListenableFuture<Boolean> serverFacadeShutdownFuture = serverFacade.shutdown();
+        final var serverFacadeShutdownFuture = serverFacade.shutdown();
         Executors.shutdownAndAwaitTermination(listeningExecutorService);
         return serverFacadeShutdownFuture;
     }
index ca797a4d12236636fa5ba908fd2267893488814f..97fe5abb1eec331628bf44e235932c5362c32f7e 100644 (file)
@@ -152,14 +152,16 @@ public class TcpHandler implements ServerFacade {
      * Shuts down {@link TcpHandler}}.
      */
     @Override
-    public ListenableFuture<Boolean> shutdown() {
-        final SettableFuture<Boolean> result = SettableFuture.create();
+    public ListenableFuture<Void> shutdown() {
+        final var result = SettableFuture.<Void>create();
         workerGroup.shutdownGracefully();
         // boss will shutdown as soon, as worker is down
         bossGroup.shutdownGracefully().addListener(downResult -> {
-            result.set(downResult.isSuccess());
-            if (downResult.cause() != null) {
-                result.setException(downResult.cause());
+            final var cause = downResult.cause();
+            if (cause != null) {
+                result.setException(cause);
+            } else {
+                result.set(null);
             }
         });
         return result;
index 1c59efd7cd154c53e7e03741b63422c2de6d8c23..472db5fc565c40d7ea0746b47c30a44bcbf98f47 100644 (file)
@@ -107,12 +107,14 @@ public final class UdpHandler implements ServerFacade {
     }
 
     @Override
-    public ListenableFuture<Boolean> shutdown() {
-        final SettableFuture<Boolean> result = SettableFuture.create();
+    public ListenableFuture<Void> shutdown() {
+        final var result = SettableFuture.<Void>create();
         group.shutdownGracefully().addListener(downResult -> {
-            result.set(downResult.isSuccess());
-            if (downResult.cause() != null) {
-                result.setException(downResult.cause());
+            final var cause = downResult.cause();
+            if (cause != null) {
+                result.setException(cause);
+            } else {
+                result.set(null);
             }
         });
         return result;
index 700b376f2077047df24242eb708315b7a877d07f..9d3f1cee64fc7d57f0a3895013aa7c8e23670bc9 100644 (file)
@@ -5,13 +5,12 @@
  * 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.openflowjava.protocol.impl.core;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
-import com.google.common.util.concurrent.ListenableFuture;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.unix.Errors;
 import java.io.IOException;
@@ -35,15 +34,20 @@ import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFa
  */
 @RunWith(MockitoJUnitRunner.class)
 public class TcpHandlerTest {
+    private final InetAddress serverAddress = InetAddress.getLoopbackAddress();
 
-    private final InetAddress serverAddress = InetAddress.getLoopbackAddress() ;
-    @Mock ChannelHandlerContext mockChHndlrCtx ;
-    @Mock TcpChannelInitializer mockChannelInitializer;
-    @Mock SwitchConnectionHandler mockSwitchConnHndler ;
-    @Mock SerializationFactory mockSerializationFactory ;
-    @Mock DeserializationFactory mockDeserializationFactory ;
+    @Mock
+    ChannelHandlerContext mockChHndlrCtx;
+    @Mock
+    TcpChannelInitializer mockChannelInitializer;
+    @Mock
+    SwitchConnectionHandler mockSwitchConnHndler;
+    @Mock
+    SerializationFactory mockSerializationFactory;
+    @Mock
+    DeserializationFactory mockDeserializationFactory;
 
-    TcpHandler tcpHandler ;
+    TcpHandler tcpHandler;
 
     /**
      * Test run with null address set.
@@ -181,11 +185,8 @@ public class TcpHandlerTest {
      * Trigger the server shutdown and wait 2 seconds for completion.
      */
     private void shutdownServer() throws InterruptedException, ExecutionException {
-        ListenableFuture<Boolean> shutdownRet = tcpHandler.shutdown() ;
-        while (shutdownRet.isDone() != true) {
-            Thread.sleep(100) ;
-        }
-        assertEquals("shutdown failed", true, shutdownRet.get());
+        final var shutdownRet = tcpHandler.shutdown() ;
+        assertNull(shutdownRet.get());
     }
 
     private Boolean startupServer(final boolean isEpollEnabled) throws InterruptedException {
index 5987de64d5f20ed09802d3807d77820aabbca7ca..970d99d63964f27664d6564daed85a82e8cf11b4 100644 (file)
@@ -10,8 +10,8 @@ package org.opendaylight.openflowjava.protocol.impl.core.connection;
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -163,6 +163,6 @@ public class SwitchConnectionProviderImplTest {
     public void testShutdown() throws Exception {
         startUp(TransportProtocol.TCP);
         provider.startup(handler).get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS);
-        assertTrue("Failed to stop", provider.shutdown().get(5 * WAIT_TIMEOUT, TimeUnit.MILLISECONDS));
+        assertNull("Failed to stop", provider.shutdown().get(5 * WAIT_TIMEOUT, TimeUnit.MILLISECONDS));
     }
 }
index cb2e53fb8cfdc1776acab482ad8d079ca97d7cd2..dbcd31079385cd6f7a6ee360d01e6676d1a04a8c 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.openflowjava.protocol.impl.core.connection;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.net.InetAddress;
@@ -113,6 +114,6 @@ public class UdpHandlerTest {
 
     private void shutdownServer() throws InterruptedException, ExecutionException, TimeoutException {
         final var shutdownRet = udpHandler.shutdown() ;
-        assertTrue("Wrong - shutdown failed", shutdownRet.get(10, TimeUnit.SECONDS));
+        assertNull("Wrong - shutdown failed", shutdownRet.get(10, TimeUnit.SECONDS));
     }
 }
index 481fc56dd10128e2a248a6259e6af2973c0e9160..b68200d1cf15bfcebfbc3c73c415d522686939e1 100644 (file)
@@ -38,7 +38,7 @@ public interface SwitchConnectionProvider extends SerializerExtensionProvider, D
     /**
      * Stop listening to switches.
      *
-     * @return future, triggered to true, when all listening channels are down
+     * @return future completing when all channels are down
      */
-    ListenableFuture<Boolean> shutdown();
+    ListenableFuture<Void> shutdown();
 }
index 708a5bb203fd040c79605bb41497600fc52da636..56d903e8db08f2be347554e07247f3fe93d497ac 100644 (file)
@@ -236,21 +236,21 @@ public final class OpenFlowPluginProviderImpl
         return fullyStarted;
     }
 
-    private ListenableFuture<List<Boolean>> shutdownSwitchConnections() {
-        final ListenableFuture<List<Boolean>> listListenableFuture =
-                Futures.allAsList(switchConnectionProviders.stream().map(switchConnectionProvider -> {
-                    // Revert deserializers to their original state
-                    if (config.getUseSingleLayerSerialization()) {
-                        DeserializerInjector.revertDeserializers(switchConnectionProvider);
-                    }
-
-                    // Shutdown switch connection provider
-                    return switchConnectionProvider.shutdown();
-                }).collect(Collectors.toSet()));
-
-        Futures.addCallback(listListenableFuture, new FutureCallback<List<Boolean>>() {
+    private ListenableFuture<List<Void>> shutdownSwitchConnections() {
+        final var listListenableFuture = Futures.allAsList(switchConnectionProviders.stream()
+            .map(switchConnectionProvider -> {
+                // Revert deserializers to their original state
+                if (config.getUseSingleLayerSerialization()) {
+                    DeserializerInjector.revertDeserializers(switchConnectionProvider);
+                }
+
+                // Shutdown switch connection provider
+                return switchConnectionProvider.shutdown();
+            }).collect(Collectors.toList()));
+
+        Futures.addCallback(listListenableFuture, new FutureCallback<>() {
             @Override
-            public void onSuccess(final List<Boolean> result) {
+            public void onSuccess(final List<Void> result) {
                 LOG.info("All switchConnectionProviders were successfully shut down ({}).", result.size());
             }
 
index 6c7bae1855ab93f7765bf1d69ab549af60d0e2b7..012d39aa89647e9441b8a37c7fc865d8f80f7cfa 100644 (file)
@@ -77,8 +77,8 @@ public class OpenFlowPluginProviderImplTest {
         when(dataBroker.newWriteOnlyTransaction()).thenReturn(writeTransaction);
         doReturn(CommitInfo.emptyFluentFuture()).when(writeTransaction).commit();
         when(entityOwnershipService.registerListener(any(), any())).thenReturn(entityOwnershipListenerRegistration);
-        when(switchConnectionProvider.startup(any())).thenReturn(Futures.immediateFuture(null));
-        when(switchConnectionProvider.shutdown()).thenReturn(Futures.immediateFuture(true));
+        when(switchConnectionProvider.startup(any())).thenReturn(Futures.immediateVoidFuture());
+        when(switchConnectionProvider.shutdown()).thenReturn(Futures.immediateVoidFuture());
         when(configurationService.getProperty(eq(ConfigurationProperty.USE_SINGLE_LAYER_SERIALIZATION.toString()),
                 any())).thenReturn(USE_SINGLE_LAYER_SERIALIZATION);
         when(configurationService.getProperty(eq(ConfigurationProperty.THREAD_POOL_MIN_THREADS.toString()), any()))