From: Ryan Goulding Date: Wed, 6 Jan 2016 17:09:36 +0000 (-0500) Subject: Bug 4577 Allow specification of a distinct schema cache directory per netconf device X-Git-Tag: release/lithium-sr4~25 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=9d92ef8bd4e1faacdd91dda82e7b702b0efde8fc;p=controller.git Bug 4577 Allow specification of a distinct schema cache directory per netconf device A leaf is added to odl-sal-netconf-connector-cfg.yang to allow specification of a schema cache directory relative to the "cache" directory. The leaf defaults to "schema", so the default directory for loaded yang files is "cache/schema". It is useful to specify a distinct cache directory per netconf mount to avoid potential model conflicts. Change-Id: Ie0c6b653d698c91a443d1b1831306da51bffbf8a Signed-off-by: Ryan Goulding --- diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java index 12e4855fbd..20221d788c 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java @@ -11,7 +11,9 @@ import static org.opendaylight.controller.config.api.JmxAttributeValidationExcep import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkNotNull; import com.google.common.base.Optional; +import com.google.common.base.Strings; import io.netty.util.concurrent.EventExecutor; +import java.io.File; import java.math.BigDecimal; import java.net.InetSocketAddress; import java.util.List; @@ -41,7 +43,13 @@ import org.opendaylight.protocol.framework.TimedReconnectStrategy; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory; +import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository; +import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry; +import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache; +import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository; +import org.opendaylight.yangtools.yang.parser.util.TextToASTTransformer; import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,10 +61,21 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co { private static final Logger logger = LoggerFactory.getLogger(NetconfConnectorModule.class); + /** + * Filesystem based caches are stored relative to the cache directory. + */ + private static final String CACHE_DIRECTORY = "cache"; + + /** + * The default cache directory relative to CACHE_DIRECTORY + */ + private static final String DEFAULT_CACHE_DIRECTORY = "schema"; + private BundleContext bundleContext; private Optional userCapabilities; private SchemaSourceRegistry schemaRegistry; private SchemaContextFactory schemaContextFactory; + private String instanceName; public NetconfConnectorModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { super(identifier, dependencyResolver); @@ -141,8 +160,31 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co salFacade = new KeepaliveSalFacade(id, salFacade, executor, keepaliveDelay); } + final String moduleSchemaCacheDirectory = getSchemaCacheDirectory(); + // If a custom schema cache directory is specified, then create the backing Repository, + // SchemaContextFactory and FilesystemSchemaSourceCache. If the default is specified, + // the the defaults are used from NetconfConnectorModuleFactory. + if (!Strings.isNullOrEmpty(moduleSchemaCacheDirectory) && + !moduleSchemaCacheDirectory.equals(DEFAULT_CACHE_DIRECTORY)) { + + final SharedSchemaRepository repository = new SharedSchemaRepository(instanceName); + final SchemaContextFactory schemaContextFactory + = repository.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT); + setSchemaRegistry(repository); + setSchemaContextFactory(schemaContextFactory); + + final FilesystemSchemaSourceCache deviceCache = + createDeviceFilesystemCache(moduleSchemaCacheDirectory); + repository.registerSchemaSourceListener(deviceCache); + logger.info("Netconf connector for device {} will use schema cache directory {} instead of {}", + instanceName, moduleSchemaCacheDirectory, DEFAULT_CACHE_DIRECTORY); + } + + schemaRegistry.registerSchemaSourceListener( + TextToASTTransformer.create((SchemaRepository) schemaRegistry, schemaRegistry)); + final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = - new NetconfDevice.SchemaResourcesDTO(schemaRegistry, schemaContextFactory, new NetconfStateSchemas.NetconfStateSchemasResolverImpl()); + new NetconfDevice.SchemaResourcesDTO(this.schemaRegistry, this.schemaContextFactory, new NetconfStateSchemas.NetconfStateSchemasResolverImpl()); final NetconfDevice device = new NetconfDevice(schemaResourcesDTO, id, salFacade, globalProcessingExecutor, getReconnectOnChangedSchema()); @@ -162,6 +204,17 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co return new SalConnectorCloseable(listener, salFacade); } + /** + * Creates a FilesystemSchemaSourceCache for the custom schema cache directory. + * + * @param schemaCacheDirectory The custom cache directory relative to "cache" + * @return A FilesystemSchemaSourceCache for the custom schema cache directory + */ + private FilesystemSchemaSourceCache createDeviceFilesystemCache(final String schemaCacheDirectory) { + final String relativeSchemaCacheDirectory = CACHE_DIRECTORY + File.separator + schemaCacheDirectory; + return new FilesystemSchemaSourceCache<>(schemaRegistry, YangTextSchemaSource.class, new File(relativeSchemaCacheDirectory)); + } + private boolean shouldSendKeepalive() { return getKeepaliveDelay() > 0; } @@ -274,4 +327,8 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co public void setSchemaContextFactory(final SchemaContextFactory schemaContextFactory) { this.schemaContextFactory = schemaContextFactory; } + + public void setInstanceName(final String instanceName) { + this.instanceName = instanceName; + } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java index b6299697cc..5f5558f65a 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java @@ -26,7 +26,6 @@ import org.osgi.framework.BundleContext; public class NetconfConnectorModuleFactory extends org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModuleFactory { - // TODO this should be injected // Netconf devices have separated schema registry + factory from controller private final SharedSchemaRepository repository = new SharedSchemaRepository(NAME); private final SchemaContextFactory schemaContextFactory @@ -44,7 +43,7 @@ public class NetconfConnectorModuleFactory extends final DynamicMBeanWithInstance old, final BundleContext bundleContext) throws Exception { final NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver, old, bundleContext); - + module.setInstanceName(instanceName); module.setBundleContext(bundleContext); module.setSchemaRegistry(repository); module.setSchemaContextFactory(schemaContextFactory); @@ -55,6 +54,7 @@ public class NetconfConnectorModuleFactory extends public Module createModule(final String instanceName, final DependencyResolver dependencyResolver, final BundleContext bundleContext) { final NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver, bundleContext); + module.setInstanceName(instanceName); module.setBundleContext(bundleContext); module.setSchemaRegistry(repository); module.setSchemaContextFactory(schemaContextFactory); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang b/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang index 799c9c8999..dab02c72c3 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang @@ -58,6 +58,13 @@ module odl-sal-netconf-connector-cfg { type string; } + leaf schema-cache-directory { + type string; + default "schema"; + description "The destination schema repository for yang files relative to the cache directory. This may be specified per netconf mount + so that the loaded yang files are stored to a distinct directory to avoid potential conflict."; + } + container yang-module-capabilities { leaf-list capability { type string;