xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-parent</artifactId>
- <version>0.7.0-SNAPSHOT</version>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>binding-parent</artifactId>
+ <version>0.11.0-SNAPSHOT</version>
<relativePath/>
</parent>
<type>pom</type>
<scope>import</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>mdsal-artifacts</artifactId>
+ <version>1.6.0-SNAPSHOT</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
</dependencies>
</dependencyManagement>
<artifactId>powermock-api-mockito</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
-</project>
\ No newline at end of file
+</project>
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.controller.config.yang.yanglib.impl;
-
-import java.io.File;
-import org.opendaylight.controller.config.api.JmxAttributeValidationException;
-import org.opendaylight.yanglib.impl.YangLibProvider;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache;
-import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class YanglibModule extends org.opendaylight.controller.config.yang.yanglib.impl.AbstractYanglibModule {
- private static final Logger LOG = LoggerFactory.getLogger(YanglibModule.class);
-
- public YanglibModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
- org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public YanglibModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
- org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
- org.opendaylight.controller.config.yang.yanglib.impl.YanglibModule oldModule,
- java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void customValidation() {
- JmxAttributeValidationException.checkNotNull(getCacheFolder(), cacheFolderJmxAttribute);
- final File file = new File(getCacheFolder());
- JmxAttributeValidationException
- .checkCondition(file.exists(), "Non existing cache file", cacheFolderJmxAttribute);
- JmxAttributeValidationException
- .checkCondition(file.isDirectory(), "Non directory cache file", cacheFolderJmxAttribute);
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- // Start cache and Text to AST transformer
- final SharedSchemaRepository repository = new SharedSchemaRepository("yang-library");
- YangLibProvider provider = new YangLibProvider(repository, getBindingAddr(), getBindingPort());
-
- final FilesystemSchemaSourceCache<YangTextSchemaSource> cache =
- new FilesystemSchemaSourceCache<>(repository, YangTextSchemaSource.class, new File(getCacheFolder()));
- repository.registerSchemaSourceListener(cache);
- LOG.info("Starting yang library with sources from {}", getCacheFolder());
- getBrokerDependency().registerProvider(provider);
- return provider;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-/*
-* Generated file
-*
-* Generated from: yang module name: yanglib yang module local name: yanglib
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Tue Apr 26 17:33:41 CEST 2016
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.yanglib.impl;
-public class YanglibModuleFactory
- extends org.opendaylight.controller.config.yang.yanglib.impl.AbstractYanglibModuleFactory {
-
-}
package org.opendaylight.yanglib.impl;
+import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
+import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
+import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160409.ModulesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160409.ModulesStateBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160409.module.list.ModuleBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160409.module.list.ModuleKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.YangIdentifier;
-import org.opendaylight.yanglib.api.YangLibRestAppService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.yanglib.impl.rev141210.YanglibConfig;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
import org.opendaylight.yangtools.yang.model.repo.spi.SchemaListenerRegistration;
import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceListener;
+import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache;
import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
* along with source identifier to
* ietf-netconf-yang-library/modules-state/module list.
*/
-public class YangLibProvider implements BindingAwareProvider, AutoCloseable, SchemaSourceListener {
+public class YangLibProvider implements AutoCloseable, SchemaSourceListener {
private static final Logger LOG = LoggerFactory.getLogger(YangLibProvider.class);
private static final OptionalRevision NO_REVISION = new OptionalRevision("");
private static final Predicate<PotentialSchemaSource<?>> YANG_SCHEMA_SOURCE =
input -> YangTextSchemaSource.class.isAssignableFrom(input.getRepresentation());
- protected DataBroker dataBroker;
- protected SchemaListenerRegistration schemaListenerRegistration;
- protected final SharedSchemaRepository schemaRepository;
- private final String bindingAddress;
- private final long bindingPort;
-
- public YangLibProvider(final SharedSchemaRepository schemaRepository,
- final String bindingAddress, final long bindingPort) {
- this.schemaRepository = schemaRepository;
- this.bindingAddress = bindingAddress;
- this.bindingPort = bindingPort;
+ private final DataBroker dataBroker;
+ private final YangLibServiceImpl yangLibService;
+ private final YanglibConfig yanglibConfig;
+ private SchemaListenerRegistration schemaListenerRegistration;
+ private SharedSchemaRepository schemaRepository;
+
+ public YangLibProvider(final YanglibConfig yanglibConfig, final DataBroker dataBroker,
+ final YangLibServiceImpl yangLibService) {
+ this.yanglibConfig = Preconditions.checkNotNull(yanglibConfig);
+ this.dataBroker = Preconditions.checkNotNull(dataBroker);
+ this.yangLibService = Preconditions.checkNotNull(yangLibService);
}
@Override
- public void close() throws Exception {
- dataBroker = null;
- schemaListenerRegistration.close();
+ public void close() {
+ yangLibService.setSchemaRepository(null);
+ if (schemaListenerRegistration != null) {
+ schemaListenerRegistration.close();
+ }
}
- @Override
- public void onSessionInitiated(final BindingAwareBroker.ProviderContext providerContext) {
- this.dataBroker = providerContext.getSALService(DataBroker.class);
+ public void init() {
+ if (Strings.isNullOrEmpty(yanglibConfig.getCacheFolder())) {
+ LOG.info("No cache-folder set in yanglib-config - yang library services will not be available");
+ return;
+ }
+
+ final File cacheFolderFile = new File(yanglibConfig.getCacheFolder());
+ Preconditions.checkArgument(cacheFolderFile.exists(), "cache-folder %s does not exist", cacheFolderFile);
+ Preconditions.checkArgument(cacheFolderFile.isDirectory(), "cache-folder %s is not a directory",
+ cacheFolderFile);
+
+ schemaRepository = new SharedSchemaRepository("yang-library");
+ final FilesystemSchemaSourceCache<YangTextSchemaSource> cache =
+ new FilesystemSchemaSourceCache<>(schemaRepository, YangTextSchemaSource.class, cacheFolderFile);
+ schemaRepository.registerSchemaSourceListener(cache);
+
schemaListenerRegistration = schemaRepository.registerSchemaSourceListener(this);
- getObjectFromBundleContext(YangLibRestAppService.class, YangLibRestAppService.class.getName())
- .getYangLibService().setSchemaRepository(schemaRepository);
+ yangLibService.setSchemaRepository(schemaRepository);
+
+ LOG.info("Started yang library with sources from {}", cacheFolderFile);
}
@Override
private Uri getUrlForModule(final SourceIdentifier sourceIdentifier) {
- return new Uri("http://" + bindingAddress + ':' + bindingPort + "/yanglib/schemas/"
- + sourceIdentifier.getName() + '/' + revString(sourceIdentifier));
+ return new Uri("http://" + yanglibConfig.getBindingAddr() + ':' + yanglibConfig.getBindingPort()
+ + "/yanglib/schemas/" + sourceIdentifier.getName() + '/' + revString(sourceIdentifier));
}
private static String revString(final SourceIdentifier id) {
public class YangLibServiceImpl implements YangLibService {
private static final Logger LOG = LoggerFactory.getLogger(YangLibServiceImpl.class);
- private SchemaRepository schemaRepository;
+ private volatile SchemaRepository schemaRepository;
public YangLibServiceImpl() {
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2017 Inocybe Technologies Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+ odl:use-default-for-reference-types="true">
+
+ <odl:clustered-app-config id="yanglibConfig"
+ binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.yanglib.impl.rev141210.YanglibConfig"/>
+
+ <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"/>
+ <reference id="yangLibRestAppService" interface="org.opendaylight.yanglib.api.YangLibRestAppService"/>
+
+ <bean id="yangLibProvider" class="org.opendaylight.yanglib.impl.YangLibProvider"
+ init-method="init" destroy-method="close">
+ <argument ref="yanglibConfig"/>
+ <argument ref="dataBroker"/>
+ <argument>
+ <bean factory-ref="yangLibRestAppService" factory-method="getYangLibService"/>
+ </argument>
+ </bean>
+
+</blueprint>
namespace "urn:opendaylight:params:xml:ns:yang:controller:yanglib:impl";
prefix "yanglib";
- import config { prefix config; revision-date 2013-04-05; }
- import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
-
description
- "Service definition for yanglib project";
+ "Service configuration for yanglib project";
revision "2014-12-10" {
description
"Initial revision";
}
- identity yanglib {
- base config:module-type;
- config:java-name-prefix Yanglib;
- }
-
- augment "/config:modules/config:module/config:configuration" {
- case yanglib {
- when "/config:modules/config:module/config:type = 'yanglib'";
- container broker {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity md-sal-binding:binding-broker-osgi-registry;
- }
- }
- }
-
- // TODO extracting the schema repositories
- leaf cache-folder {
- type string;
- description "local filesystem folder to use as cache + to load yang models from";
- }
+ container yanglib-config {
+ // TODO extracting the schema repositories
+ leaf cache-folder {
+ mandatory true;
+ type string;
+ description "local filesystem folder to use as cache + to load yang models from";
+ }
- // TODO it would be better if the binding arguments could be located by the app automatically
- leaf binding-addr {
- type string;
- // TODO make this uri
- description "binding address is necessary for generating proper URLS (accessible from the outside world)
- for models present directly in the library";
- }
+ // TODO it would be better if the binding arguments could be located by the app automatically
+ leaf binding-addr {
+ mandatory true;
+ type string;
+ // TODO make this uri
+ description "binding address is necessary for generating proper URLS (accessible from the outside world)
+ for models present directly in the library";
+ }
- leaf binding-port {
- type uint32;
- // TODO proper type
- description "binding port is necessary for generating proper URLS (accessible from the outside world)
- for models present directly in the library";
- }
+ leaf binding-port {
+ mandatory true;
+ type uint32;
+ // TODO proper type
+ description "binding port is necessary for generating proper URLS (accessible from the outside world)
+ for models present directly in the library";
}
}
-}
\ No newline at end of file
+}
import static org.mockito.Mockito.when;
import com.google.common.util.concurrent.Futures;
+import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import org.apache.commons.io.FileUtils;
+import org.junit.AfterClass;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160409.ModulesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160409.ModulesStateBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160409.module.list.ModuleBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160409.module.list.ModuleKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.YangIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.yanglib.impl.rev141210.YanglibConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.yanglib.impl.rev141210.YanglibConfigBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
import org.opendaylight.yangtools.yang.model.repo.api.YinSchemaSourceRepresentation;
import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
-import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
import org.opendaylight.yangtools.yang.parser.util.ASTSchemaSource;
public class YangLibProviderTest {
-
- @Mock
- private BindingAwareBroker.ProviderContext context;
+ private static final File CACHE_DIR = new File("target/yanglib");
@Mock
private DataBroker dataBroker;
@Mock
private WriteTransaction writeTransaction;
- private TestingYangLibProvider yangLibProvider;
+ private YangLibProvider yangLibProvider;
+
+ @BeforeClass
+ public static void staticSetup() {
+ if (!CACHE_DIR.exists() && !CACHE_DIR.mkdirs()) {
+ throw new RuntimeException("Failed to create " + CACHE_DIR);
+ }
+ }
+
+ @AfterClass
+ public static void staticCleanup() {
+ FileUtils.deleteQuietly(CACHE_DIR);
+ }
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- yangLibProvider = new TestingYangLibProvider(new SharedSchemaRepository("test"), "www.fake.com", 300);
- when(context.getSALService(eq(DataBroker.class))).thenReturn(dataBroker);
+
+ try {
+ if (CACHE_DIR.exists()) {
+ FileUtils.cleanDirectory(CACHE_DIR);
+ }
+ } catch (IOException e) {
+ // Ignore
+ }
+
+ final YanglibConfig yanglibConfig = new YanglibConfigBuilder().setBindingAddr("www.fake.com")
+ .setBindingPort(300L).setCacheFolder(CACHE_DIR.getAbsolutePath()).build();
+ yangLibProvider = new YangLibProvider(yanglibConfig, dataBroker, new YangLibServiceImpl());
}
@Test
public void testSchemaSourceRegistered() {
- yangLibProvider.onSessionInitiated(context);
+ yangLibProvider.init();
when(dataBroker.newWriteOnlyTransaction()).thenReturn(writeTransaction);
doNothing().when(writeTransaction)
.merge(eq(LogicalDatastoreType.OPERATIONAL), eq(InstanceIdentifier.create(ModulesState.class)), any());
@Test
public void testFilteringNonYangSchemaSourceRegistered() {
- yangLibProvider.onSessionInitiated(context);
+ yangLibProvider.init();
// test empty list of schema sources registered
List<PotentialSchemaSource<?>> potentialSources = Collections.emptyList();
@Test
public void testNonYangSchemaSourceUnregistered() {
- yangLibProvider.onSessionInitiated(context);
+ yangLibProvider.init();
final PotentialSchemaSource<YinSchemaSourceRepresentation> nonYangSource =
PotentialSchemaSource.create(
@Test
public void testSchemaSourceUnregistered() {
- yangLibProvider.onSessionInitiated(context);
+ yangLibProvider.init();
when(dataBroker.newWriteOnlyTransaction()).thenReturn(writeTransaction);
doNothing().when(writeTransaction)
verify(writeTransaction, times(2)).submit();
}
-
- private static class TestingYangLibProvider extends YangLibProvider {
-
- TestingYangLibProvider(
- SharedSchemaRepository schemaRepository, String bindingAddress, long bindingPort) {
- super(schemaRepository, bindingAddress, bindingPort);
- }
-
- @Override
- public void onSessionInitiated(BindingAwareBroker.ProviderContext providerContext) {
- this.dataBroker = providerContext.getSALService(DataBroker.class);
- schemaListenerRegistration = schemaRepository.registerSchemaSourceListener(this);
- }
- }
-
-
}