BUG-2299: allow PCEP extensions to be reconfigured 89/12489/2
authorRobert Varga <rovarga@cisco.com>
Mon, 3 Nov 2014 14:06:56 +0000 (15:06 +0100)
committerDana Kutenicsova <dkutenic@cisco.com>
Mon, 10 Nov 2014 10:10:13 +0000 (11:10 +0100)
The trigger here is a change in the extensions cause the corresponding
context to be re-created from scratch, which leads to the topology
manager to being re-created. This patch implements instance reuse by
adding proper activator hooks.

Change-Id: I5f114b81ceeb26a3943afc4bd2f0c34b678ff029
Signed-off-by: Robert Varga <rovarga@cisco.com>
pcep/spi/src/main/java/org/opendaylight/controller/config/yang/pcep/spi/ReusablePCEPExtensionProviderContext.java [new file with mode: 0644]
pcep/spi/src/main/java/org/opendaylight/controller/config/yang/pcep/spi/SimplePCEPExtensionProviderContextModule.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPTopologyProvider.java

diff --git a/pcep/spi/src/main/java/org/opendaylight/controller/config/yang/pcep/spi/ReusablePCEPExtensionProviderContext.java b/pcep/spi/src/main/java/org/opendaylight/controller/config/yang/pcep/spi/ReusablePCEPExtensionProviderContext.java
new file mode 100644 (file)
index 0000000..a613879
--- /dev/null
@@ -0,0 +1,212 @@
+package org.opendaylight.controller.config.yang.pcep.spi;
+
+import java.util.List;
+import org.opendaylight.protocol.pcep.spi.EROSubobjectParser;
+import org.opendaylight.protocol.pcep.spi.EROSubobjectRegistry;
+import org.opendaylight.protocol.pcep.spi.EROSubobjectSerializer;
+import org.opendaylight.protocol.pcep.spi.LabelParser;
+import org.opendaylight.protocol.pcep.spi.LabelRegistry;
+import org.opendaylight.protocol.pcep.spi.LabelSerializer;
+import org.opendaylight.protocol.pcep.spi.MessageParser;
+import org.opendaylight.protocol.pcep.spi.MessageRegistry;
+import org.opendaylight.protocol.pcep.spi.MessageSerializer;
+import org.opendaylight.protocol.pcep.spi.ObjectParser;
+import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
+import org.opendaylight.protocol.pcep.spi.ObjectSerializer;
+import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderActivator;
+import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderContext;
+import org.opendaylight.protocol.pcep.spi.RROSubobjectParser;
+import org.opendaylight.protocol.pcep.spi.RROSubobjectRegistry;
+import org.opendaylight.protocol.pcep.spi.RROSubobjectSerializer;
+import org.opendaylight.protocol.pcep.spi.TlvParser;
+import org.opendaylight.protocol.pcep.spi.TlvRegistry;
+import org.opendaylight.protocol.pcep.spi.TlvSerializer;
+import org.opendaylight.protocol.pcep.spi.VendorInformationObjectRegistry;
+import org.opendaylight.protocol.pcep.spi.VendorInformationTlvRegistry;
+import org.opendaylight.protocol.pcep.spi.XROSubobjectParser;
+import org.opendaylight.protocol.pcep.spi.XROSubobjectRegistry;
+import org.opendaylight.protocol.pcep.spi.XROSubobjectSerializer;
+import org.opendaylight.protocol.pcep.spi.pojo.SimplePCEPExtensionProviderContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.iana.rev130816.EnterpriseNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Tlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.EnterpriseSpecificInformation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.basic.explicit.route.subobjects.SubobjectType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.label.subobject.LabelType;
+
+public class ReusablePCEPExtensionProviderContext implements AutoCloseable, PCEPExtensionProviderContext {
+    private final PCEPExtensionProviderContext delegate = new SimplePCEPExtensionProviderContext();
+    private List<PCEPExtensionProviderActivator> currentExtensionDependency;
+
+    @Override
+    public void close() {
+        for (final PCEPExtensionProviderActivator e : this.currentExtensionDependency) {
+            e.stop();
+        }
+    }
+
+    public void start(final List<PCEPExtensionProviderActivator> extensionDependency) {
+        for (final PCEPExtensionProviderActivator e : extensionDependency) {
+            e.start(this.delegate);
+        }
+        this.currentExtensionDependency = extensionDependency;
+    }
+
+    public void reconfigure(final List<PCEPExtensionProviderActivator> extensionDependency) {
+        // Shutdown old ones first
+        for (final PCEPExtensionProviderActivator e : this.currentExtensionDependency) {
+            if (!extensionDependency.contains(e)) {
+                e.stop();
+            }
+        }
+        // Start new ones
+        for (final PCEPExtensionProviderActivator e : extensionDependency) {
+            if (!this.currentExtensionDependency.contains(e)) {
+                e.start(this.delegate);
+            }
+        }
+        this.currentExtensionDependency = extensionDependency;
+    }
+
+    @Override
+    public LabelRegistry getLabelHandlerRegistry() {
+        return this.delegate.getLabelHandlerRegistry();
+    }
+
+    @Override
+    public MessageRegistry getMessageHandlerRegistry() {
+        return this.delegate.getMessageHandlerRegistry();
+    }
+
+    @Override
+    public ObjectRegistry getObjectHandlerRegistry() {
+        return this.delegate.getObjectHandlerRegistry();
+    }
+
+    @Override
+    public EROSubobjectRegistry getEROSubobjectHandlerRegistry() {
+        return this.delegate.getEROSubobjectHandlerRegistry();
+    }
+
+    @Override
+    public RROSubobjectRegistry getRROSubobjectHandlerRegistry() {
+        return this.delegate.getRROSubobjectHandlerRegistry();
+    }
+
+    @Override
+    public XROSubobjectRegistry getXROSubobjectHandlerRegistry() {
+        return this.delegate.getXROSubobjectHandlerRegistry();
+    }
+
+    @Override
+    public TlvRegistry getTlvHandlerRegistry() {
+        return this.delegate.getTlvHandlerRegistry();
+    }
+
+    @Override
+    public VendorInformationTlvRegistry getVendorInformationTlvRegistry() {
+        return this.delegate.getVendorInformationTlvRegistry();
+    }
+
+    @Override
+    public VendorInformationObjectRegistry getVendorInformationObjectRegistry() {
+        return this.delegate.getVendorInformationObjectRegistry();
+    }
+
+    @Override
+    public AutoCloseable registerLabelSerializer(final Class<? extends LabelType> labelClass, final LabelSerializer serializer) {
+        return this.delegate.registerLabelSerializer(labelClass, serializer);
+    }
+
+    @Override
+    public AutoCloseable registerLabelParser(final int cType, final LabelParser parser) {
+        return this.delegate.registerLabelParser(cType, parser);
+    }
+
+    @Override
+    public AutoCloseable registerEROSubobjectParser(final int subobjectType, final EROSubobjectParser parser) {
+        return this.delegate.registerEROSubobjectParser(subobjectType, parser);
+    }
+
+    @Override
+    public AutoCloseable registerEROSubobjectSerializer(final Class<? extends SubobjectType> subobjectClass,
+            final EROSubobjectSerializer serializer) {
+        return this.delegate.registerEROSubobjectSerializer(subobjectClass, serializer);
+    }
+
+    @Override
+    public AutoCloseable registerMessageParser(final int messageType, final MessageParser parser) {
+        return this.delegate.registerMessageParser(messageType, parser);
+    }
+
+    @Override
+    public AutoCloseable registerMessageSerializer(final Class<? extends Message> msgClass, final MessageSerializer serializer) {
+        return this.delegate.registerMessageSerializer(msgClass, serializer);
+    }
+
+    @Override
+    public AutoCloseable registerObjectParser(final int objectClass, final int objectType, final ObjectParser parser) {
+        return this.delegate.registerObjectParser(objectClass, objectType, parser);
+    }
+
+    @Override
+    public AutoCloseable registerObjectSerializer(final Class<? extends Object> objClass, final ObjectSerializer serializer) {
+        return this.delegate.registerObjectSerializer(objClass, serializer);
+    }
+
+    @Override
+    public AutoCloseable registerRROSubobjectParser(final int subobjectType, final RROSubobjectParser parser) {
+        return this.delegate.registerRROSubobjectParser(subobjectType, parser);
+    }
+
+    @Override
+    public AutoCloseable registerRROSubobjectSerializer(
+            final Class<? extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.record.route.subobjects.SubobjectType> subobjectClass,
+            final RROSubobjectSerializer serializer) {
+        return this.delegate.registerRROSubobjectSerializer(subobjectClass, serializer);
+    }
+
+    @Override
+    public AutoCloseable registerTlvSerializer(final Class<? extends Tlv> tlvClass, final TlvSerializer serializer) {
+        return this.delegate.registerTlvSerializer(tlvClass, serializer);
+    }
+
+    @Override
+    public AutoCloseable registerTlvParser(final int tlvType, final TlvParser parser) {
+        return this.delegate.registerTlvParser(tlvType, parser);
+    }
+
+    @Override
+    public AutoCloseable registerVendorInformationTlvSerializer(
+            final Class<? extends EnterpriseSpecificInformation> esInformationClass, final TlvSerializer serializer) {
+        return this.delegate.registerVendorInformationTlvSerializer(esInformationClass, serializer);
+    }
+
+    @Override
+    public AutoCloseable registerVendorInformationTlvParser(final EnterpriseNumber enterpriseNumber, final TlvParser parser) {
+        return this.delegate.registerVendorInformationTlvParser(enterpriseNumber, parser);
+    }
+
+    @Override
+    public AutoCloseable registerXROSubobjectSerializer(final Class<? extends SubobjectType> subobjectClass,
+            final XROSubobjectSerializer serializer) {
+        return this.delegate.registerXROSubobjectSerializer(subobjectClass, serializer);
+    }
+
+    @Override
+    public AutoCloseable registerXROSubobjectParser(final int subobjectType, final XROSubobjectParser parser) {
+        return this.delegate.registerXROSubobjectParser(subobjectType, parser);
+    }
+
+    @Override
+    public AutoCloseable registerVendorInformationObjectSerializer(
+            final Class<? extends EnterpriseSpecificInformation> esInformationClass, final ObjectSerializer serializer) {
+        return this.delegate.registerVendorInformationObjectSerializer(esInformationClass, serializer);
+    }
+
+    @Override
+    public AutoCloseable registerVendorInformationObjectParser(final EnterpriseNumber enterpriseNumber, final ObjectParser parser) {
+        return this.delegate.registerVendorInformationObjectParser(enterpriseNumber, parser);
+    }
+}
index 4a63522b772f739ff9a827e00c7291ef31faf5fb..b2dba188f67938b17d7fcaa7ff3f36d0633655a5 100644 (file)
@@ -16,8 +16,6 @@
  */
 package org.opendaylight.controller.config.yang.pcep.spi;
 
-import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderActivator;
-import org.opendaylight.protocol.pcep.spi.pojo.SimplePCEPExtensionProviderContext;
 
 /**
  *
@@ -37,26 +35,21 @@ public final class SimplePCEPExtensionProviderContextModule extends
     }
 
     @Override
-    protected void customValidation() {
-        // Add custom validation for module attributes here.
+    public boolean canReuseInstance(final AbstractSimplePCEPExtensionProviderContextModule oldModule) {
+        return oldModule.getInstance().getClass().equals(ReusablePCEPExtensionProviderContext.class);
+    };
+
+    @Override
+    public java.lang.AutoCloseable reuseInstance(final java.lang.AutoCloseable oldInstance) {
+        final ReusablePCEPExtensionProviderContext ctx = (ReusablePCEPExtensionProviderContext) oldInstance;
+        ctx.reconfigure(getExtensionDependency());
+        return ctx;
     }
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final class PCEPExtensionProviderContextImplCloseable extends SimplePCEPExtensionProviderContext implements AutoCloseable {
-            @Override
-            public void close() {
-                for (PCEPExtensionProviderActivator e : getExtensionDependency()) {
-                    e.stop();
-                }
-            }
-        }
-
-        final PCEPExtensionProviderContextImplCloseable ret = new PCEPExtensionProviderContextImplCloseable();
-        for (PCEPExtensionProviderActivator e : getExtensionDependency()) {
-            e.start(ret);
-        }
-
-        return ret;
+        final ReusablePCEPExtensionProviderContext ctx = new ReusablePCEPExtensionProviderContext();
+        ctx.start(getExtensionDependency());
+        return ctx;
     }
 }
index e85737a86c9c60380ce883bd45184fbc7d32f63e..4efccc8aac0a88e62cdf1e2bbf63a0600b1d1b5c 100644 (file)
@@ -53,7 +53,7 @@ public final class PCEPTopologyProvider extends DefaultTopologyReference impleme
     public static PCEPTopologyProvider create(final PCEPDispatcher dispatcher, final InetSocketAddress address, final KeyMapping keys,
             final InstructionScheduler scheduler, final DataBroker dataBroker, final RpcProviderRegistry rpcRegistry,
             final InstanceIdentifier<Topology> topology, final TopologySessionListenerFactory listenerFactory,
-            Optional<PCEPTopologyProviderRuntimeRegistrator> runtimeRootRegistrator) throws InterruptedException,
+            final Optional<PCEPTopologyProviderRuntimeRegistrator> runtimeRootRegistrator) throws InterruptedException,
             ExecutionException, ReadFailedException, TransactionCommitFailedException {
 
         final ServerSessionManager manager = new ServerSessionManager(dataBroker, topology, listenerFactory);
@@ -75,30 +75,30 @@ public final class PCEPTopologyProvider extends DefaultTopologyReference impleme
     }
 
     @Override
-    public void close() {
-        LOG.debug("Closing server channel {}", channel);
+    public void close() throws InterruptedException {
+        LOG.debug("Closing server channel {}", this.channel);
 
-        channel.close().addListener(new ChannelFutureListener() {
+        this.channel.close().addListener(new ChannelFutureListener() {
             @Override
             public void operationComplete(final ChannelFuture f) {
                 LOG.debug("Server channel {} closed", f.channel());
 
                 try {
-                    network.close();
-                } catch (Exception e) {
+                    PCEPTopologyProvider.this.network.close();
+                } catch (final Exception e) {
                     LOG.error("Failed to unregister network-level RPCs", e);
                 }
                 try {
-                    element.close();
-                } catch (Exception e) {
+                    PCEPTopologyProvider.this.element.close();
+                } catch (final Exception e) {
                     LOG.error("Failed to unregister element-level RPCs", e);
                 }
                 try {
-                    manager.close();
-                } catch (Exception e) {
+                    PCEPTopologyProvider.this.manager.close();
+                } catch (final Exception e) {
                     LOG.error("Failed to shutdown session manager", e);
                 }
             }
-        });
+        }).await();
     }
 }