fix of Bug 145 16/2816/2
authormsunal <msunal@cisco.com>
Mon, 18 Nov 2013 10:05:35 +0000 (11:05 +0100)
committermsunal <msunal@cisco.com>
Tue, 19 Nov 2013 11:10:05 +0000 (12:10 +0100)
- https://bugs.opendaylight.org/show_bug.cgi?id=145
- Broker service is tracked by ServiceTracker

Change-Id: I32358e13fa5b356ed77b842c96127a51c29bc018
Signed-off-by: Martin Sunal <msunal@cisco.com>
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend

index 35b751c..53b401e 100644 (file)
@@ -1,19 +1,31 @@
 package org.opendaylight.controller.sal.rest.impl;
 
-import org.opendaylight.controller.sal.core.api.AbstractProvider;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.core.api.data.DataProviderService;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 
-public class RestconfProvider extends AbstractProvider {
+public class RestconfProvider implements BundleActivator, Provider, ServiceTrackerCustomizer<Broker, Broker> {
 
+    public final static String NOT_INITALIZED_MSG = "Restcof is not initialized yet. Please try again later";
+    
     private ListenerRegistration<SchemaServiceListener> listenerRegistration;
+    private ServiceTracker<Broker, Broker> brokerServiceTrancker;
+    private BundleContext bundleContext;
+    private ProviderSession session;
 
     @Override
     public void onSessionInitiated(ProviderSession session) {
@@ -28,8 +40,14 @@ public class RestconfProvider extends AbstractProvider {
     }
 
     @Override
-    protected void stopImpl(BundleContext context) {
-        super.stopImpl(context);
+    public void start(BundleContext context) throws Exception {
+        bundleContext = context;
+        brokerServiceTrancker = new ServiceTracker<>(context, Broker.class, this);
+        brokerServiceTrancker.open();
+    }
+
+    @Override
+    public void stop(BundleContext context) {
         if (listenerRegistration != null) {
             try {
                 listenerRegistration.close();
@@ -37,5 +55,32 @@ public class RestconfProvider extends AbstractProvider {
                 e.printStackTrace();
             }
         }
+        session.close();
+        brokerServiceTrancker.close();
+    }
+
+    @Override
+    public Collection<ProviderFunctionality> getProviderFunctionality() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public Broker addingService(ServiceReference<Broker> reference) {
+        Broker broker = bundleContext.getService(reference);
+        broker.registerProvider(this, bundleContext);
+        return broker;
+    }
+
+    @Override
+    public void modifiedService(ServiceReference<Broker> reference, Broker service) {
+        // NOOP
+    }
+
+    @Override
+    public void removedService(ServiceReference<Broker> reference, Broker service) {
+        bundleContext.ungetService(reference);
+        BrokerFacade.getInstance().setContext(null);
+        BrokerFacade.getInstance().setDataService(null);
+        ControllerContext.getInstance().setSchemas(null);
     }
 }
index 3c31c5a..f5b9132 100644 (file)
@@ -1,13 +1,15 @@
 package org.opendaylight.controller.sal.restconf.impl
 
+import javax.ws.rs.WebApplicationException
+import javax.ws.rs.core.Response
 import org.opendaylight.controller.md.sal.common.api.data.DataReader
 import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService
+import org.opendaylight.controller.sal.rest.impl.RestconfProvider
 import org.opendaylight.yangtools.yang.common.QName
 import org.opendaylight.yangtools.yang.common.RpcResult
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import static org.opendaylight.controller.sal.restconf.impl.BrokerFacade.*
 
 class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
 
@@ -24,31 +26,43 @@ class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
             throw new IllegalStateException("Already instantiated");
         }
     }
-    
+
     def static BrokerFacade getInstance() {
         return INSTANCE
     }
 
+    private def void checkPreconditions() {
+        if (context == null || dataService == null) {
+            throw new WebApplicationException(Response.status(Response.Status.SERVICE_UNAVAILABLE)
+                    .entity(RestconfProvider::NOT_INITALIZED_MSG).build())
+        }
+    }
+
     override readConfigurationData(InstanceIdentifier path) {
+        checkPreconditions
         return dataService.readConfigurationData(path);
     }
 
     override readOperationalData(InstanceIdentifier path) {
+        checkPreconditions
         return dataService.readOperationalData(path);
     }
 
     def RpcResult<CompositeNode> invokeRpc(QName type, CompositeNode payload) {
+        checkPreconditions
         val future = context.rpc(type, payload);
         return future.get;
     }
 
     def commitConfigurationDataPut(InstanceIdentifier path, CompositeNode payload) {
+        checkPreconditions
         val transaction = dataService.beginTransaction;
         transaction.putConfigurationData(path, payload);
         return transaction.commit()
     }
 
     def commitOperationalDataPut(InstanceIdentifier path, CompositeNode payload) {
+        checkPreconditions
         val transaction = dataService.beginTransaction;
         transaction.putOperationalData(path, payload);
         return transaction.commit()
index 6241785..c1ee611 100644 (file)
@@ -8,6 +8,11 @@ import java.net.URLEncoder
 import java.util.HashMap
 import java.util.List
 import java.util.Map
+import java.util.concurrent.ConcurrentHashMap
+import javax.ws.rs.WebApplicationException
+import javax.ws.rs.core.Response
+import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
+import org.opendaylight.controller.sal.rest.impl.RestconfProvider
 import org.opendaylight.yangtools.yang.common.QName
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder
@@ -21,12 +26,10 @@ import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition
 import org.opendaylight.yangtools.yang.model.api.SchemaContext
 
 import static com.google.common.base.Preconditions.*
-import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition
-import java.util.concurrent.ConcurrentHashMap
 
 class ControllerContext implements SchemaServiceListener {
 
@@ -51,6 +54,13 @@ class ControllerContext implements SchemaServiceListener {
     static def getInstance() {
         return INSTANCE
     }
+    
+    private def void checkPreconditions() {
+        if (schemas == null) {
+            throw new WebApplicationException(Response.status(Response.Status.SERVICE_UNAVAILABLE)
+                    .entity(RestconfProvider::NOT_INITALIZED_MSG).build())
+        }
+    }
 
     public def InstanceIdWithSchemaNode toInstanceIdentifier(String restconfInstance) {
         val ret = InstanceIdentifier.builder();
@@ -69,6 +79,7 @@ class ControllerContext implements SchemaServiceListener {
     }
 
     private def findModule(String restconfInstance) {
+        checkPreconditions
         checkNotNull(restconfInstance);
         val pathArgs = restconfInstance.split("/");
         if (pathArgs.empty) {
@@ -93,6 +104,7 @@ class ControllerContext implements SchemaServiceListener {
     }
 
     def String toFullRestconfIdentifier(InstanceIdentifier path) {
+        checkPreconditions
         val elements = path.path;
         val ret = new StringBuilder();
         val startQName = elements.get(0).nodeType;
@@ -120,6 +132,7 @@ class ControllerContext implements SchemaServiceListener {
     }
 
     def CharSequence toRestconfIdentifier(QName qname) {
+        checkPreconditions
         var module = uriToModuleName.get(qname.namespace)
         if (module == null) {
             val moduleSchema = schemas.findModuleByNamespaceAndRevision(qname.namespace, qname.revision);