From 10f5d7706b66a64cd5616a6adfd31c7f1df5c710 Mon Sep 17 00:00:00 2001 From: Jakub Toth Date: Thu, 24 Aug 2017 12:46:16 +0200 Subject: [PATCH] Bug 8326 - Split out OsgiBundleScanningSchemaService * move osgi part of mdsal-dom broker to new module mdsal-dom-schema-service-osgi (with unit tests) Change-Id: I2eb2e4f96f50456f84982e5de6d439b0306bcc0f Signed-off-by: Jakub Toth Signed-off-by: Robert Varga --- common/artifacts/pom.xml | 12 + common/features/features-mdsal/pom.xml | 6 + common/features/odl-mdsal-dom-broker/pom.xml | 6 + .../odl-mdsal-dom-schema-service-osgi/pom.xml | 63 ++++++ common/features/odl-mdsal-dom/pom.xml | 2 +- common/features/pom.xml | 1 + dom/mdsal-dom-broker/pom.xml | 20 +- .../broker/osgi/SchemaServiceActivator.java | 32 --- .../schema/ScanningSchemaServiceProvider.java | 154 +++++++++++++ .../osgi/SchemaServiceActivatorTest.java | 76 ------- .../ScanningSchemaServiceProviderTest.java | 198 +++++++++++++++++ .../src/test/resources/empty-test1.yang | 9 + .../src/test/resources/empty-test2.yang | 9 + dom/mdsal-dom-schema-service-osgi/pom.xml | 134 +++++++++++ .../osgi/OsgiBundleScanningSchemaService.java | 209 +++++------------- .../blueprint/dom-osgi-schema-service.xml | 12 + .../OsgiBundleScanningSchemaServiceTest.java | 15 +- .../schema/service/osgi/util/TestModel.java | 59 +++++ .../test/resources/odl-datastore-test.yang | 73 ++++++ dom/pom.xml | 1 + 20 files changed, 806 insertions(+), 285 deletions(-) create mode 100644 common/features/odl-mdsal-dom-schema-service-osgi/pom.xml delete mode 100644 dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/osgi/SchemaServiceActivator.java create mode 100644 dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/schema/ScanningSchemaServiceProvider.java delete mode 100644 dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/osgi/SchemaServiceActivatorTest.java create mode 100644 dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/schema/ScanningSchemaServiceProviderTest.java create mode 100644 dom/mdsal-dom-broker/src/test/resources/empty-test1.yang create mode 100644 dom/mdsal-dom-broker/src/test/resources/empty-test2.yang create mode 100644 dom/mdsal-dom-schema-service-osgi/pom.xml rename dom/{mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker => mdsal-dom-schema-service-osgi/src/main/java/org/opendaylight/mdsal/dom/schema/service}/osgi/OsgiBundleScanningSchemaService.java (50%) create mode 100644 dom/mdsal-dom-schema-service-osgi/src/main/resources/org/opendaylight/blueprint/dom-osgi-schema-service.xml rename dom/{mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker => mdsal-dom-schema-service-osgi/src/test/java/org/opendaylight/mdsal/dom/schema/service}/osgi/OsgiBundleScanningSchemaServiceTest.java (90%) create mode 100644 dom/mdsal-dom-schema-service-osgi/src/test/java/org/opendaylight/mdsal/dom/schema/service/osgi/util/TestModel.java create mode 100644 dom/mdsal-dom-schema-service-osgi/src/test/resources/odl-datastore-test.yang diff --git a/common/artifacts/pom.xml b/common/artifacts/pom.xml index 55d2f9468b..ed89321e69 100644 --- a/common/artifacts/pom.xml +++ b/common/artifacts/pom.xml @@ -56,6 +56,11 @@ mdsal-dom-broker ${project.version} + + org.opendaylight.mdsal + mdsal-dom-schema-service-osgi + ${project.version} + org.opendaylight.mdsal mdsal-dom-inmemory-datastore @@ -295,6 +300,13 @@ features xml + + ${project.groupId} + odl-mdsal-dom-schema-service-osgi + ${project.version} + features + xml + diff --git a/common/features/features-mdsal/pom.xml b/common/features/features-mdsal/pom.xml index 8041b7c10d..9794d8513d 100644 --- a/common/features/features-mdsal/pom.xml +++ b/common/features/features-mdsal/pom.xml @@ -125,6 +125,12 @@ features xml + + ${project.groupId} + odl-mdsal-dom-schema-service-osgi + features + xml + diff --git a/common/features/odl-mdsal-dom-broker/pom.xml b/common/features/odl-mdsal-dom-broker/pom.xml index 6444c97b07..a77237a31b 100644 --- a/common/features/odl-mdsal-dom-broker/pom.xml +++ b/common/features/odl-mdsal-dom-broker/pom.xml @@ -74,6 +74,12 @@ ${project.groupId} mdsal-dom-broker + + org.opendaylight.mdsal + odl-mdsal-dom-schema-service-osgi + xml + features + + + 4.0.0 + + + org.opendaylight.odlparent + single-feature-parent + 2.0.5 + + + + org.opendaylight.mdsal + odl-mdsal-dom-schema-service-osgi + 2.4.0-SNAPSHOT + feature + + OpenDaylight :: MD-SAL :: DOM Schema Service OSGi + + + + + org.opendaylight.mdsal + mdsal-artifacts + ${project.version} + pom + import + + + + + + + ${project.groupId} + mdsal-dom-schema-service-osgi + + + + + ${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/ + + + + opendaylight-site + ${nexus.site.url}/${project.artifactId}/ + + + + diff --git a/common/features/odl-mdsal-dom/pom.xml b/common/features/odl-mdsal-dom/pom.xml index e697a594b6..2882ac43b7 100644 --- a/common/features/odl-mdsal-dom/pom.xml +++ b/common/features/odl-mdsal-dom/pom.xml @@ -62,4 +62,4 @@ - \ No newline at end of file + diff --git a/common/features/pom.xml b/common/features/pom.xml index a599b64662..3079b64143 100644 --- a/common/features/pom.xml +++ b/common/features/pom.xml @@ -46,6 +46,7 @@ odl-mdsal-dom odl-mdsal-dom-api odl-mdsal-dom-broker + odl-mdsal-dom-schema-service-osgi odl-mdsal-eos-binding diff --git a/dom/mdsal-dom-broker/pom.xml b/dom/mdsal-dom-broker/pom.xml index 1d6dd7ca31..826535c4d7 100644 --- a/dom/mdsal-dom-broker/pom.xml +++ b/dom/mdsal-dom-broker/pom.xml @@ -41,10 +41,6 @@ - - org.osgi - org.osgi.core - com.google.guava guava @@ -53,6 +49,7 @@ com.lmax disruptor + org.opendaylight.mdsal mdsal-dom-api @@ -65,6 +62,7 @@ org.opendaylight.mdsal mdsal-dom-inmemory-datastore + org.opendaylight.yangtools util @@ -77,6 +75,10 @@ org.opendaylight.yangtools yang-parser-impl + + org.opendaylight.yangtools + yang-model-api + junit @@ -96,16 +98,6 @@ - - org.apache.felix - maven-bundle-plugin - true - - - org.opendaylight.mdsal.dom.broker.osgi.SchemaServiceActivator - - - org.apache.maven.plugins maven-checkstyle-plugin diff --git a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/osgi/SchemaServiceActivator.java b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/osgi/SchemaServiceActivator.java deleted file mode 100644 index 97370baf38..0000000000 --- a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/osgi/SchemaServiceActivator.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2014 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.mdsal.dom.broker.osgi; - -import java.util.Hashtable; -import org.opendaylight.mdsal.dom.api.DOMSchemaService; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; - -public class SchemaServiceActivator implements BundleActivator { - private ServiceRegistration schemaServiceReg; - private OsgiBundleScanningSchemaService schemaService; - - @Override - public void start(final BundleContext context) { - schemaService = OsgiBundleScanningSchemaService.createInstance(context); - schemaServiceReg = context.registerService(DOMSchemaService.class, - schemaService, new Hashtable<>()); - } - - @Override - public void stop(final BundleContext context) { - schemaServiceReg.unregister(); - schemaService.close(); - } -} diff --git a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/schema/ScanningSchemaServiceProvider.java b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/schema/ScanningSchemaServiceProvider.java new file mode 100644 index 0000000000..3ea9b69cf5 --- /dev/null +++ b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/schema/ScanningSchemaServiceProvider.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.dom.broker.schema; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.util.concurrent.CheckedFuture; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.annotation.concurrent.GuardedBy; +import org.opendaylight.mdsal.dom.api.DOMSchemaService; +import org.opendaylight.mdsal.dom.api.DOMSchemaServiceExtension; +import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.util.ListenerRegistry; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; +import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider; +import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException; +import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException; +import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.parser.repo.YangTextSchemaContextResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ScanningSchemaServiceProvider + implements DOMSchemaService, SchemaContextProvider, DOMYangTextSourceProvider, AutoCloseable { + private static final Logger LOG = LoggerFactory.getLogger(ScanningSchemaServiceProvider.class); + + @GuardedBy("lock") + private final ListenerRegistry listeners = new ListenerRegistry<>(); + private final Object lock = new Object(); + private final YangTextSchemaContextResolver contextResolver = YangTextSchemaContextResolver.create("global-bundle"); + + public void tryToUpdateSchemaContext() { + synchronized (lock) { + final Optional schema = contextResolver.getSchemaContext(); + if (schema.isPresent()) { + if (LOG.isDebugEnabled()) { + LOG.debug("Got new SchemaContext: # of modules {}", schema.get().getAllModuleIdentifiers().size()); + } + notifyListeners(schema.get()); + } + } + } + + @VisibleForTesting + @SuppressWarnings("checkstyle:IllegalCatch") + public void notifyListeners(final SchemaContext schemaContext) { + synchronized (lock) { + for (final ListenerRegistration registration : listeners) { + try { + registration.getInstance().onGlobalContextUpdated(schemaContext); + } catch (final Exception e) { + LOG.error("Exception occured during invoking listener", e); + } + } + } + } + + public List registerAvailableYangs(final List yangs) { + final List sourceRegistrator = new ArrayList<>(); + for (final URL url : yangs) { + try { + sourceRegistrator.add(contextResolver.registerSource(url)); + } catch (SchemaSourceException | IOException | YangSyntaxErrorException e) { + LOG.warn("Failed to register {}, ignoring it", url, e); + } + } + return sourceRegistrator; + } + + public void removeListener(final SchemaContextListener schemaContextListener) { + synchronized (lock) { + for (final ListenerRegistration listenerRegistration : listeners.getListeners()) { + if (listenerRegistration.getInstance().equals(schemaContextListener)) { + listenerRegistration.close(); + break; + } + } + } + } + + public boolean hasListeners() { + boolean hasListeners; + synchronized (lock) { + if (Iterables.size(listeners.getListeners()) > 0) { + hasListeners = true; + } else { + hasListeners = false; + } + } + return hasListeners; + } + + @Override + public SchemaContext getSessionContext() { + throw new UnsupportedOperationException(); + } + + @Override + public SchemaContext getGlobalContext() { + return contextResolver.getSchemaContext().orNull(); + } + + @Override + public ListenerRegistration + registerSchemaContextListener(final SchemaContextListener listener) { + synchronized (lock) { + final Optional potentialCtx = contextResolver.getSchemaContext(); + if (potentialCtx.isPresent()) { + listener.onGlobalContextUpdated(potentialCtx.get()); + } + return listeners.register(listener); + } + } + + @Override + public SchemaContext getSchemaContext() { + return getGlobalContext(); + } + + @Override + public CheckedFuture + getSource(final SourceIdentifier sourceIdentifier) { + return contextResolver.getSource(sourceIdentifier); + } + + @Override + public Map, DOMSchemaServiceExtension> getSupportedExtensions() { + return ImmutableMap.of(DOMYangTextSourceProvider.class, this); + } + + @Override + public void close() { + synchronized (lock) { + for (final ListenerRegistration registration : listeners) { + registration.close(); + } + } + } +} diff --git a/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/osgi/SchemaServiceActivatorTest.java b/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/osgi/SchemaServiceActivatorTest.java deleted file mode 100644 index 33ac7641ae..0000000000 --- a/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/osgi/SchemaServiceActivatorTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016 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.mdsal.dom.broker.osgi; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.CALLS_REAL_METHODS; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import java.lang.reflect.Field; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Filter; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; - -public class SchemaServiceActivatorTest { - - @Test - public void basicTest() throws Exception { - final BundleContext bundleContext = mock(BundleContext.class); - doReturn(mock(Filter.class)).when(bundleContext).createFilter(any()); - doNothing().when(bundleContext).addBundleListener(any()); - doReturn(new Bundle[] {}).when(bundleContext).getBundles(); - doNothing().when(bundleContext).addServiceListener(any(), any()); - doReturn(new ServiceReference[] {}).when(bundleContext).getServiceReferences(anyString(), any()); - doReturn(mock(ServiceRegistration.class)).when(bundleContext).registerService(any(Class.class), any(), any()); - doNothing().when(bundleContext).removeBundleListener(any()); - doNothing().when(bundleContext).removeServiceListener(any()); - final SchemaServiceActivator schemaServiceActivator = new SchemaServiceActivator(); - schemaServiceActivator.start(bundleContext); - - final ServiceRegistration registration = mock(ServiceRegistration.class); - final OsgiBundleScanningSchemaService osgiBundle = - mock(OsgiBundleScanningSchemaService.class, CALLS_REAL_METHODS); - - final Field schemaServiceRegField = SchemaServiceActivator.class.getDeclaredField("schemaServiceReg"); - schemaServiceRegField.setAccessible(true); - schemaServiceRegField.set(schemaServiceActivator, registration); - - final Field schemaServiceField = SchemaServiceActivator.class.getDeclaredField("schemaService"); - schemaServiceField.setAccessible(true); - schemaServiceField.set(schemaServiceActivator, osgiBundle); - - doNothing().when(registration).unregister(); - doNothing().when(osgiBundle).close(); - - schemaServiceActivator.stop(bundleContext); - verify(registration).unregister(); - verify(osgiBundle).close(); - } - - @SuppressWarnings("checkstyle:IllegalCatch") - @After - @Before - public void destroyInstance() throws Exception { - try { - OsgiBundleScanningSchemaService.getInstance(); - OsgiBundleScanningSchemaService.destroyInstance(); - } catch (Exception e) { - assertTrue(e instanceof IllegalStateException); - } - } -} \ No newline at end of file diff --git a/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/schema/ScanningSchemaServiceProviderTest.java b/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/schema/ScanningSchemaServiceProviderTest.java new file mode 100644 index 0000000000..80c982119f --- /dev/null +++ b/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/schema/ScanningSchemaServiceProviderTest.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.dom.broker.schema; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import com.google.common.util.concurrent.CheckedFuture; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.internal.util.io.IOUtil; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; +import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier; +import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException; +import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; + +public class ScanningSchemaServiceProviderTest { + + private ArrayList yangs; + private ScanningSchemaServiceProvider schemaService; + + @Before + public void setup() { + yangs = new ArrayList<>(); + addYang("/odl-datastore-test.yang"); + + schemaService = new ScanningSchemaServiceProvider(); + assertNotNull(schemaService); + addYangs(schemaService); + } + + @After + public void close() { + schemaService.close(); + } + + private void addYang(final String yang) { + yangs.add(ScanningSchemaServiceProvider.class.getResource(yang)); + } + + @Test + public void initJarScanningSchemaServiceTest() throws Exception { + assertNotNull(schemaService.getGlobalContext()); + assertNotNull(schemaService.getSchemaContext()); + assertEquals(schemaService.getGlobalContext(), schemaService.getSchemaContext()); + } + + @Test + public void listenersTests() { + assertFalse(schemaService.hasListeners()); + + final SchemaContextHolder actualSchemaCtx = new SchemaContextHolder(); + final SchemaContextListener listener = prepareSchemaCtxListener(actualSchemaCtx); + final ListenerRegistration registerSchemaContextListener = + schemaService.registerSchemaContextListener(listener); + assertEquals(registerSchemaContextListener.getInstance(), listener); + assertEquals(schemaService.getSchemaContext(), actualSchemaCtx.getSchemaContext()); + } + + @Test + public void notifyListenersTest() { + final SchemaContext baseSchemaCtx = schemaService.getGlobalContext(); + assertNotNull(baseSchemaCtx); + assertTrue(baseSchemaCtx.getModules().size() == 1); + + final SchemaContextHolder actualSchemaCtx = new SchemaContextHolder(); + + final SchemaContextListener schemaCtxListener = prepareSchemaCtxListener(actualSchemaCtx); + final ListenerRegistration registerSchemaContextListener = + schemaService.registerSchemaContextListener(schemaCtxListener); + assertEquals(registerSchemaContextListener.getInstance(), schemaCtxListener); + assertNotNull(actualSchemaCtx.getSchemaContext()); + assertEquals(baseSchemaCtx, actualSchemaCtx.getSchemaContext()); + + addYang("/empty-test1.yang"); + addYangs(schemaService); + + final SchemaContext nextSchemaCtx = schemaService.getGlobalContext(); + assertNotNull(nextSchemaCtx); + assertTrue(nextSchemaCtx.getModules().size() == 2); + + assertNotEquals(baseSchemaCtx, nextSchemaCtx); + + schemaService.notifyListeners(nextSchemaCtx); + assertEquals(nextSchemaCtx, actualSchemaCtx.getSchemaContext()); + + addYang("/empty-test2.yang"); + addYangs(schemaService); + + final SchemaContext unregistredListenerSchemaCtx = schemaService.getGlobalContext(); + assertNotNull(unregistredListenerSchemaCtx); + assertTrue(unregistredListenerSchemaCtx.getModules().size() == 3); + + assertNotEquals(baseSchemaCtx, unregistredListenerSchemaCtx); + assertNotEquals(nextSchemaCtx, unregistredListenerSchemaCtx); + + schemaService.removeListener(schemaCtxListener); + schemaService.notifyListeners(unregistredListenerSchemaCtx); + + assertNotEquals(unregistredListenerSchemaCtx, actualSchemaCtx.getSchemaContext()); + assertEquals(nextSchemaCtx, actualSchemaCtx.getSchemaContext()); + + schemaService.registerSchemaContextListener(schemaCtxListener); + assertEquals(unregistredListenerSchemaCtx, actualSchemaCtx.getSchemaContext()); + } + + @Test + public void tryToUpdateSchemaCtxTest() { + final SchemaContext baseSchemaContext = schemaService.getSchemaContext(); + assertNotNull(baseSchemaContext); + assertTrue(baseSchemaContext.getModules().size() == 1); + + final SchemaContextHolder actualSchemaCtx = new SchemaContextHolder(); + final SchemaContextListener schemaCtxListener = prepareSchemaCtxListener(actualSchemaCtx); + + schemaService.registerSchemaContextListener(schemaCtxListener); + + assertEquals(baseSchemaContext, actualSchemaCtx.getSchemaContext()); + + addYang("/empty-test1.yang"); + addYangs(schemaService); + + final SchemaContext nextSchemaContext = schemaService.getSchemaContext(); + assertNotNull(baseSchemaContext); + assertTrue(baseSchemaContext.getModules().size() == 1); + + assertNotEquals(baseSchemaContext, nextSchemaContext); + + schemaService.tryToUpdateSchemaContext(); + assertEquals(nextSchemaContext, actualSchemaCtx.getSchemaContext()); + } + + @SuppressWarnings("deprecation") + @Test + public void getSourceTest() throws Exception { + final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("odl-datastore-test", "2014-03-13"); + final CheckedFuture source = + schemaService.getSource(sourceIdentifier); + final YangTextSchemaSource yangTextSchemaSource = source.checkedGet(); + final Collection lines = IOUtil.readLines(yangTextSchemaSource.openStream()); + assertEquals("module odl-datastore-test {", lines.iterator().next()); + } + + @Test + public void getSupportedExtensionsTest() { + assertEquals(schemaService.getSupportedExtensions().values().iterator().next(), schemaService); + } + + @Test(expected = UnsupportedOperationException.class) + public void getSessionContextTest() { + schemaService.getSessionContext(); + } + + private void addYangs(final ScanningSchemaServiceProvider schemaService) { + final List registerAvailableYangs = schemaService.registerAvailableYangs(yangs); + assertTrue(!registerAvailableYangs.isEmpty()); + } + + private SchemaContextListener prepareSchemaCtxListener(final SchemaContextHolder actualSchemaCtx) { + return new SchemaContextListener() { + + @Override + public void onGlobalContextUpdated(final SchemaContext context) { + actualSchemaCtx.setSchemaContext(context); + } + }; + } + + private class SchemaContextHolder { + + private SchemaContext schemaCtx; + + public void setSchemaContext(final SchemaContext ctx) { + schemaCtx = ctx; + } + + public SchemaContext getSchemaContext() { + return schemaCtx; + } + } +} diff --git a/dom/mdsal-dom-broker/src/test/resources/empty-test1.yang b/dom/mdsal-dom-broker/src/test/resources/empty-test1.yang new file mode 100644 index 0000000000..002239e5e1 --- /dev/null +++ b/dom/mdsal-dom-broker/src/test/resources/empty-test1.yang @@ -0,0 +1,9 @@ +module empty-test1 { + yang-version 1; + namespace "em:tst:1"; + prefix "empty-test-1"; + + revision "2017-09-13" { + description "Initial revision."; + } +} diff --git a/dom/mdsal-dom-broker/src/test/resources/empty-test2.yang b/dom/mdsal-dom-broker/src/test/resources/empty-test2.yang new file mode 100644 index 0000000000..c6e78e8e0b --- /dev/null +++ b/dom/mdsal-dom-broker/src/test/resources/empty-test2.yang @@ -0,0 +1,9 @@ +module empty-test2 { + yang-version 1; + namespace "em:tst:2"; + prefix "empty-test-2"; + + revision "2017-09-13" { + description "Initial revision."; + } +} diff --git a/dom/mdsal-dom-schema-service-osgi/pom.xml b/dom/mdsal-dom-schema-service-osgi/pom.xml new file mode 100644 index 0000000000..11d7a1471a --- /dev/null +++ b/dom/mdsal-dom-schema-service-osgi/pom.xml @@ -0,0 +1,134 @@ + + + + + 4.0.0 + + org.opendaylight.odlparent + bundle-parent + 2.0.5 + + + + org.opendaylight.mdsal + mdsal-dom-schema-service-osgi + 2.4.0-SNAPSHOT + bundle + + + + + org.opendaylight.mdsal + mdsal-artifacts + 2.4.0-SNAPSHOT + pom + import + + + org.opendaylight.yangtools + yangtools-artifacts + 1.2.0-SNAPSHOT + pom + import + + + + + + + org.osgi + org.osgi.core + + + com.google.guava + guava + + + + org.opendaylight.mdsal + mdsal-dom-api + + + org.opendaylight.mdsal + mdsal-dom-broker + + + + org.opendaylight.yangtools + util + + + org.opendaylight.yangtools + yang-data-impl + + + org.opendaylight.yangtools + yang-parser-impl + + + org.opendaylight.yangtools + yang-test-util + + + + junit + junit + + + org.opendaylight.yangtools + mockito-configuration + test + + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + osgiBundleScanningSchema + + *, + org.opendaylight.mdsal.dom.api + + + + + + + + + scm:git:http://git.opendaylight.org/gerrit/controller.git + scm:git:ssh://git.opendaylight.org:29418/controller.git + HEAD + https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Architecture:Clustering + + + + + ${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/ + + + + opendaylight-site + ${nexus.site.url}/${project.artifactId}/ + + + + diff --git a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/osgi/OsgiBundleScanningSchemaService.java b/dom/mdsal-dom-schema-service-osgi/src/main/java/org/opendaylight/mdsal/dom/schema/service/osgi/OsgiBundleScanningSchemaService.java similarity index 50% rename from dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/osgi/OsgiBundleScanningSchemaService.java rename to dom/mdsal-dom-schema-service-osgi/src/main/java/org/opendaylight/mdsal/dom/schema/service/osgi/OsgiBundleScanningSchemaService.java index 35705bf3d2..859f8ffc01 100644 --- a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/osgi/OsgiBundleScanningSchemaService.java +++ b/dom/mdsal-dom-schema-service-osgi/src/main/java/org/opendaylight/mdsal/dom/schema/service/osgi/OsgiBundleScanningSchemaService.java @@ -1,43 +1,28 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.dom.broker.osgi; +package org.opendaylight.mdsal.dom.schema.service.osgi; import static com.google.common.base.Preconditions.checkState; - import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; -import com.google.common.util.concurrent.CheckedFuture; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; -import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Nonnull; import javax.annotation.concurrent.GuardedBy; -import org.opendaylight.mdsal.dom.api.DOMSchemaService; -import org.opendaylight.mdsal.dom.api.DOMSchemaServiceExtension; -import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider; -import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.mdsal.dom.broker.schema.ScanningSchemaServiceProvider; import org.opendaylight.yangtools.concepts.Registration; -import org.opendaylight.yangtools.util.ListenerRegistry; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; -import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider; -import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException; -import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; -import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; -import org.opendaylight.yangtools.yang.parser.repo.YangTextSchemaContextResolver; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; @@ -49,24 +34,21 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class OsgiBundleScanningSchemaService implements SchemaContextProvider, DOMSchemaService, - ServiceTrackerCustomizer, DOMYangTextSourceProvider, - AutoCloseable { - private static final Logger LOG = LoggerFactory.getLogger(OsgiBundleScanningSchemaService.class); +public class OsgiBundleScanningSchemaService extends ScanningSchemaServiceProvider + implements ServiceTrackerCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(OsgiBundleScanningSchemaService.class); private static final AtomicReference GLOBAL_INSTANCE = new AtomicReference<>(); - private static final long FRAMEWORK_BUNDLE_ID = 0; - @GuardedBy("lock") - private final ListenerRegistry listeners = new ListenerRegistry<>(); - private final YangTextSchemaContextResolver contextResolver = YangTextSchemaContextResolver.create("global-bundle"); private final BundleScanner scanner = new BundleScanner(); - private final Object lock = new Object(); private final BundleContext context; - private ServiceTracker listenerTracker; + @GuardedBy("lock") private BundleTracker> bundleTracker; + private final Object lock = new Object(); + + private ServiceTracker listenerTracker; private boolean starting = true; private volatile boolean stopping; @@ -76,44 +58,26 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D } public static @Nonnull OsgiBundleScanningSchemaService createInstance(final BundleContext ctx) { - OsgiBundleScanningSchemaService instance = new OsgiBundleScanningSchemaService(ctx); + final OsgiBundleScanningSchemaService instance = new OsgiBundleScanningSchemaService(ctx); Preconditions.checkState(GLOBAL_INSTANCE.compareAndSet(null, instance)); instance.start(); return instance; } - public static OsgiBundleScanningSchemaService getInstance() { - OsgiBundleScanningSchemaService instance = GLOBAL_INSTANCE.get(); - Preconditions.checkState(instance != null, "Global Instance was not instantiated"); - return instance; - } - - @VisibleForTesting - public static void destroyInstance() { - OsgiBundleScanningSchemaService instance = GLOBAL_INSTANCE.getAndSet(null); - if (instance != null) { - instance.close(); - } - } - - public BundleContext getContext() { - return context; - } - private void start() { checkState(context != null); LOG.debug("start() starting"); listenerTracker = new ServiceTracker<>(context, SchemaContextListener.class, this); - bundleTracker = new BundleTracker<>(context, Bundle.RESOLVED | Bundle.STARTING - | Bundle.STOPPING | Bundle.ACTIVE, scanner); + bundleTracker = new BundleTracker<>(context, + Bundle.RESOLVED | Bundle.STARTING | Bundle.STOPPING | Bundle.ACTIVE, scanner); synchronized (lock) { bundleTracker.open(); LOG.debug("BundleTracker.open() complete"); - if (Iterables.size(listeners.getListeners()) > 0) { + if (!hasListeners()) { tryToUpdateSchemaContext(); } } @@ -124,74 +88,36 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D LOG.debug("start() complete"); } - @Override - public SchemaContext getSchemaContext() { - return getGlobalContext(); - } - - @Override - public SchemaContext getGlobalContext() { - return contextResolver.getSchemaContext().orNull(); + public static OsgiBundleScanningSchemaService getInstance() { + final OsgiBundleScanningSchemaService instance = GLOBAL_INSTANCE.get(); + Preconditions.checkState(instance != null, "Global Instance was not instantiated"); + return instance; } - @Override - public SchemaContext getSessionContext() { - throw new UnsupportedOperationException(); - } + @VisibleForTesting + public static void destroyInstance() throws Exception { + final OsgiBundleScanningSchemaService instance = GLOBAL_INSTANCE.getAndSet(null); + if (instance != null) { - @Override - public ListenerRegistration registerSchemaContextListener( - final SchemaContextListener listener) { - synchronized (lock) { - final Optional potentialCtx = contextResolver.getSchemaContext(); - if (potentialCtx.isPresent()) { - listener.onGlobalContextUpdated(potentialCtx.get()); - } - return listeners.register(listener); + instance.closeInstance(); } } - @Override - public void close() { - synchronized (lock) { - stopping = true; - if (bundleTracker != null) { - bundleTracker.close(); - bundleTracker = null; - } - if (listenerTracker != null) { - listenerTracker.close(); - listenerTracker = null; - } - - for (final ListenerRegistration l : listeners.getListeners()) { - l.close(); - } + private void closeInstance() { + stopping = true; + if (bundleTracker != null) { + bundleTracker.close(); + bundleTracker = null; + } + if (listenerTracker != null) { + listenerTracker.close(); + listenerTracker = null; } + close(); } - @SuppressWarnings("checkstyle:IllegalCatch") - @VisibleForTesting - @GuardedBy("lock") - void notifyListeners(final SchemaContext snapshot) { - final Object[] services = listenerTracker.getServices(); - for (final ListenerRegistration listener : listeners) { - try { - listener.getInstance().onGlobalContextUpdated(snapshot); - } catch (final Exception e) { - LOG.error("Exception occured during invoking listener", e); - } - } - if (services != null) { - for (final Object rawListener : services) { - final SchemaContextListener listener = (SchemaContextListener) rawListener; - try { - listener.onGlobalContextUpdated(snapshot); - } catch (final Exception e) { - LOG.error("Exception occured during invoking listener {}", listener, e); - } - } - } + public BundleContext getContext() { + return context; } @SuppressWarnings("checkstyle:IllegalCatch") @@ -208,24 +134,26 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D return Collections.emptyList(); } - final List urls = new ArrayList<>(); + final List urls = new ArrayList<>(); while (enumeration.hasMoreElements()) { final URL u = enumeration.nextElement(); try { - urls.add(contextResolver.registerSource(u)); + urls.add(u); LOG.debug("Registered {}", u); } catch (final Exception e) { LOG.warn("Failed to register {}, ignoring it", e); } } - if (!urls.isEmpty()) { + final List registrations = registerAvailableYangs(urls); + if (!registrations.isEmpty()) { LOG.debug("Loaded {} new URLs from bundle {}, attempting to rebuild schema context", - urls.size(), bundle.getSymbolicName()); - tryToUpdateSchemaContext(); + registrations.size(), bundle.getSymbolicName()); + if (!starting && !stopping) { + tryToUpdateSchemaContext(); + } } - - return ImmutableList.copyOf(urls); + return ImmutableList.copyOf(registrations); } @Override @@ -240,9 +168,8 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D } /** - * If removing YANG files makes yang store inconsistent, method - * {@link #getYangStoreSnapshot()} will throw exception. There is no - * rollback. + * If removing YANG files makes yang store inconsistent, method {@link #getYangStoreSnapshot()} will + * throw exception. There is no rollback. */ @SuppressWarnings("checkstyle:IllegalCatch") @Override @@ -258,43 +185,23 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D final int numUrls = Iterables.size(urls); if (numUrls > 0) { if (LOG.isDebugEnabled()) { - LOG.debug("removedBundle: {}, state: {}, # urls: {}", bundle.getSymbolicName(), - bundle.getState(), numUrls); + LOG.debug("removedBundle: {}, state: {}, # urls: {}", bundle.getSymbolicName(), bundle.getState(), + numUrls); + } + if (!starting && !stopping) { + tryToUpdateSchemaContext(); } - - tryToUpdateSchemaContext(); } } } @Override public SchemaContextListener addingService(final ServiceReference reference) { - final SchemaContextListener listener = context.getService(reference); - final SchemaContext ctxContext = getGlobalContext(); - if (getContext() != null && ctxContext != null) { - listener.onGlobalContextUpdated(ctxContext); - } + registerSchemaContextListener(listener); return listener; } - public void tryToUpdateSchemaContext() { - if (starting || stopping) { - return; - } - - synchronized (lock) { - final Optional schema = contextResolver.getSchemaContext(); - if (schema.isPresent()) { - if (LOG.isDebugEnabled()) { - LOG.debug("Got new SchemaContext: # of modules {}", schema.get().getAllModuleIdentifiers().size()); - } - - notifyListeners(schema.get()); - } - } - } - @Override public void modifiedService(final ServiceReference reference, final SchemaContextListener service) { @@ -305,16 +212,6 @@ public class OsgiBundleScanningSchemaService implements SchemaContextProvider, D public void removedService(final ServiceReference reference, final SchemaContextListener service) { context.ungetService(reference); - } - - @Override - public Map, DOMSchemaServiceExtension> getSupportedExtensions() { - return ImmutableMap.of(DOMYangTextSourceProvider.class, this); - } - - @Override - public CheckedFuture getSource( - final SourceIdentifier sourceIdentifier) { - return contextResolver.getSource(sourceIdentifier); + removeListener(service); } } diff --git a/dom/mdsal-dom-schema-service-osgi/src/main/resources/org/opendaylight/blueprint/dom-osgi-schema-service.xml b/dom/mdsal-dom-schema-service-osgi/src/main/resources/org/opendaylight/blueprint/dom-osgi-schema-service.xml new file mode 100644 index 0000000000..ae3f347088 --- /dev/null +++ b/dom/mdsal-dom-schema-service-osgi/src/main/resources/org/opendaylight/blueprint/dom-osgi-schema-service.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/osgi/OsgiBundleScanningSchemaServiceTest.java b/dom/mdsal-dom-schema-service-osgi/src/test/java/org/opendaylight/mdsal/dom/schema/service/osgi/OsgiBundleScanningSchemaServiceTest.java similarity index 90% rename from dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/osgi/OsgiBundleScanningSchemaServiceTest.java rename to dom/mdsal-dom-schema-service-osgi/src/test/java/org/opendaylight/mdsal/dom/schema/service/osgi/OsgiBundleScanningSchemaServiceTest.java index 6ee0dd1716..ebd8ecea4a 100644 --- a/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/osgi/OsgiBundleScanningSchemaServiceTest.java +++ b/dom/mdsal-dom-schema-service-osgi/src/test/java/org/opendaylight/mdsal/dom/schema/service/osgi/OsgiBundleScanningSchemaServiceTest.java @@ -1,11 +1,11 @@ /* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.dom.broker.osgi; +package org.opendaylight.mdsal.dom.schema.service.osgi; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -16,11 +16,11 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; - import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.opendaylight.mdsal.dom.broker.util.TestModel; +import org.opendaylight.mdsal.dom.api.DOMSchemaService; +import org.opendaylight.mdsal.dom.schema.service.osgi.util.TestModel; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; import org.osgi.framework.Bundle; @@ -54,14 +54,17 @@ public class OsgiBundleScanningSchemaServiceTest { try { OsgiBundleScanningSchemaService.getInstance(); OsgiBundleScanningSchemaService.destroyInstance(); - } catch (Exception e) { + } catch (final Exception e) { assertTrue(e instanceof IllegalStateException); } } @Test public void basicTest() throws Exception { + assertTrue(osgiService instanceof DOMSchemaService); + final SchemaContext schemaContext = TestModel.createTestContext(); + final SchemaContextListener schemaContextListener = mock(SchemaContextListener.class); doNothing().when(schemaContextListener).onGlobalContextUpdated(schemaContext); osgiService.registerSchemaContextListener(schemaContextListener); @@ -85,4 +88,4 @@ public class OsgiBundleScanningSchemaServiceTest { public void sessionContextTest() throws Exception { osgiService.getSessionContext(); } -} \ No newline at end of file +} diff --git a/dom/mdsal-dom-schema-service-osgi/src/test/java/org/opendaylight/mdsal/dom/schema/service/osgi/util/TestModel.java b/dom/mdsal-dom-schema-service-osgi/src/test/java/org/opendaylight/mdsal/dom/schema/service/osgi/util/TestModel.java new file mode 100644 index 0000000000..752329bb11 --- /dev/null +++ b/dom/mdsal-dom-schema-service-osgi/src/test/java/org/opendaylight/mdsal/dom/schema/service/osgi/util/TestModel.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.dom.schema.service.osgi.util; + +import java.io.InputStream; +import java.util.Collections; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; +import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils; + +public class TestModel { + + public static final QName TEST_QNAME = + QName.create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test", "2014-03-13", "test"); + public static final QName TEST2_QNAME = + QName.create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test", "2014-03-13", "test2"); + public static final QName OUTER_LIST_QNAME = QName.create(TEST_QNAME, "outer-list"); + public static final QName INNER_LIST_QNAME = QName.create(TEST_QNAME, "inner-list"); + public static final QName OUTER_CHOICE_QNAME = QName.create(TEST_QNAME, "outer-choice"); + public static final QName ID_QNAME = QName.create(TEST_QNAME, "id"); + public static final QName NAME_QNAME = QName.create(TEST_QNAME, "name"); + public static final QName VALUE_QNAME = QName.create(TEST_QNAME, "value"); + public static final QName INNER_CONTAINER = QName.create(TEST_QNAME, "inner-container"); + public static final QName ANOTHER_SHARD_CONTAINER = QName.create(TEST_QNAME, "another-shard"); + public static final QName NEW_SHARD_LIST = QName.create(TEST_QNAME, "new-shard-list"); + public static final QName SHARDED_VALUE_1 = QName.create(TEST_QNAME, "sharded-value-1"); + public static final QName SHARDED_VALUE_2 = QName.create(TEST_QNAME, "sharded-value-2"); + public static final QName ANOTHER_SHARD_VALUE = QName.create(TEST_QNAME, "another-shard-value"); + public static final QName TWO_QNAME = QName.create(TEST_QNAME, "two"); + public static final QName THREE_QNAME = QName.create(TEST_QNAME, "three"); + public static final YangInstanceIdentifier TEST_PATH = YangInstanceIdentifier.of(TEST_QNAME); + public static final YangInstanceIdentifier TEST2_PATH = YangInstanceIdentifier.of(TEST2_QNAME); + public static final YangInstanceIdentifier OUTER_LIST_PATH = + YangInstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME).build(); + public static final YangInstanceIdentifier INNER_LIST_PATH = + YangInstanceIdentifier.builder(OUTER_LIST_PATH).node(INNER_LIST_QNAME).build(); + public static final YangInstanceIdentifier INNER_CONTAINER_PATH = + YangInstanceIdentifier.builder(TEST_PATH).node(INNER_CONTAINER).build(); + public static final YangInstanceIdentifier ANOTHER_SHARD_PATH = + YangInstanceIdentifier.builder(INNER_CONTAINER_PATH).node(ANOTHER_SHARD_CONTAINER).build(); + public static final YangInstanceIdentifier NEW_SHARD_LIST_PATH = + YangInstanceIdentifier.builder(ANOTHER_SHARD_PATH).node(NEW_SHARD_LIST).build(); + private static final String DATASTORE_TEST_YANG = "/odl-datastore-test.yang"; + + public static SchemaContext createTestContext() throws ReactorException { + return YangParserTestUtils.parseYangStreams(Collections.singletonList(getInputStream())); + } + + private static InputStream getInputStream() { + return TestModel.class.getResourceAsStream(DATASTORE_TEST_YANG); + } +} diff --git a/dom/mdsal-dom-schema-service-osgi/src/test/resources/odl-datastore-test.yang b/dom/mdsal-dom-schema-service-osgi/src/test/resources/odl-datastore-test.yang new file mode 100644 index 0000000000..dab777d806 --- /dev/null +++ b/dom/mdsal-dom-schema-service-osgi/src/test/resources/odl-datastore-test.yang @@ -0,0 +1,73 @@ +module odl-datastore-test { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test"; + prefix "store-test"; + + revision "2014-03-13" { + description "Initial revision."; + } + + container test { + presence "presence container"; + list outer-list { + key id; + leaf id { + type uint16; + } + choice outer-choice { + case one { + leaf one { + type string; + } + } + case two-three { + leaf two { + type string; + } + leaf three { + type string; + } + } + } + list inner-list { + key name; + leaf name { + type string; + } + leaf value { + type string; + } + } + } + + container inner-container { + + leaf sharded-value-1 { + type string; + } + + leaf sharded-value-2 { + type string; + } + + container another-shard { + list new-shard-list { + key name; + leaf name { + type string; + } + leaf value { + type string; + } + } + + leaf another-shard-value { + type string; + } + } + } + } + + container test2 { + } +} diff --git a/dom/pom.xml b/dom/pom.xml index 5eadc9e6a8..699d60bfe6 100644 --- a/dom/pom.xml +++ b/dom/pom.xml @@ -29,6 +29,7 @@ mdsal-dom-spi mdsal-dom-broker mdsal-dom-inmemory-datastore + mdsal-dom-schema-service-osgi