From f4eaaab4a64566b31187179601d9051298e58a6d Mon Sep 17 00:00:00 2001 From: msunal Date: Mon, 18 Nov 2013 11:05:35 +0100 Subject: [PATCH] fix of Bug 145 - https://bugs.opendaylight.org/show_bug.cgi?id=145 - Broker service is tracked by ServiceTracker Change-Id: I32358e13fa5b356ed77b842c96127a51c29bc018 Signed-off-by: Martin Sunal --- .../sal/rest/impl/RestconfProvider.java | 55 +++++++++++++++++-- .../sal/restconf/impl/BrokerFacade.xtend | 18 +++++- .../sal/restconf/impl/ControllerContext.xtend | 19 ++++++- 3 files changed, 82 insertions(+), 10 deletions(-) diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java index 35b751c73f..53b401e4a2 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java @@ -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 { + public final static String NOT_INITALIZED_MSG = "Restcof is not initialized yet. Please try again later"; + private ListenerRegistration listenerRegistration; + private ServiceTracker 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 getProviderFunctionality() { + return Collections.emptySet(); + } + + @Override + public Broker addingService(ServiceReference reference) { + Broker broker = bundleContext.getService(reference); + broker.registerProvider(this, bundleContext); + return broker; + } + + @Override + public void modifiedService(ServiceReference reference, Broker service) { + // NOOP + } + + @Override + public void removedService(ServiceReference reference, Broker service) { + bundleContext.ungetService(reference); + BrokerFacade.getInstance().setContext(null); + BrokerFacade.getInstance().setDataService(null); + ControllerContext.getInstance().setSchemas(null); } } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend index 3c31c5a313..f5b9132532 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend @@ -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 { @@ -24,31 +26,43 @@ class BrokerFacade implements DataReader { 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 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() diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend index 624178569d..c1ee611e07 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend @@ -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); -- 2.36.6