[ONOS-5084],[ONOS-5083] YANG schema registry for YMS
Change-Id: I88394307cb9be30237be0bb17e013d7af88a607c
diff --git a/apps/yms/BUCK b/apps/yms/BUCK
index 163d67e..73eef6f 100644
--- a/apps/yms/BUCK
+++ b/apps/yms/BUCK
@@ -1,6 +1,5 @@
BUNDLES = [
'//apps/yms/api:onos-apps-yms-api',
- '//apps/yms/app:onos-apps-yms-app',
]
onos_app(
diff --git a/apps/yms/api/src/main/java/org/onosproject/yms/ymsm/YmsService.java b/apps/yms/api/src/main/java/org/onosproject/yms/ymsm/YmsService.java
index d651859..264a191 100644
--- a/apps/yms/api/src/main/java/org/onosproject/yms/ymsm/YmsService.java
+++ b/apps/yms/api/src/main/java/org/onosproject/yms/ymsm/YmsService.java
@@ -26,6 +26,7 @@
import org.onosproject.yms.ydt.YdtWalker;
import org.onosproject.yms.ydt.YmsOperationType;
import org.onosproject.yms.ynh.YangNotificationService;
+import org.onosproject.yms.ysr.YangModuleIdentifier;
import org.onosproject.yms.ysr.YangModuleLibrary;
/**
@@ -310,11 +311,11 @@
* The server can optionally support retrieval of the YANG modules it
* supports.
*
- * @param moduleName YANG module name.
- * @param moduleNamespace namespace in which the module is defined.
+ *
+ * @param moduleIdentifier module's identifier
* @return YANG file contents of the requested YANG module.
*/
- String getYangFile(String moduleName, String moduleNamespace);
+ String getYangFile(YangModuleIdentifier moduleIdentifier);
/**
* Register protocol specific default CODEC. This is can be used by 1st
diff --git a/apps/yms/api/src/main/java/org/onosproject/yms/ysr/YangModuleIdentifier.java b/apps/yms/api/src/main/java/org/onosproject/yms/ysr/YangModuleIdentifier.java
index 6b02720..acae603 100644
--- a/apps/yms/api/src/main/java/org/onosproject/yms/ysr/YangModuleIdentifier.java
+++ b/apps/yms/api/src/main/java/org/onosproject/yms/ysr/YangModuleIdentifier.java
@@ -28,11 +28,11 @@
*
* @return the name of the YANG module
*/
- String getModuleName();
+ String moduleName();
/**
* Retrieves revision of the YANG module.
- *
+ * <p>
* Reference RFC 7895
* Each YANG module and submodule within the library has a
* revision. This is derived from the most recent revision statement
@@ -42,5 +42,5 @@
*
* @return revision of the YANG module
*/
- String getRevision();
+ String revision();
}
diff --git a/apps/yms/api/src/main/java/org/onosproject/yms/ysr/YangModuleInformation.java b/apps/yms/api/src/main/java/org/onosproject/yms/ysr/YangModuleInformation.java
index f9c3114..e9f79b3 100644
--- a/apps/yms/api/src/main/java/org/onosproject/yms/ysr/YangModuleInformation.java
+++ b/apps/yms/api/src/main/java/org/onosproject/yms/ysr/YangModuleInformation.java
@@ -48,7 +48,7 @@
*
* @return YANG modules identifier
*/
- YangModuleIdentifier getModuleIdentifier();
+ YangModuleIdentifier moduleIdentifier();
/**
* Retrieves the YANG modules namespace.
@@ -56,7 +56,7 @@
*
* @return YANG modules namespace
*/
- String getNamespace();
+ String namespace();
/**
* Reference RFC 7895
@@ -66,7 +66,7 @@
*
* @return list of YANG features
*/
- List<String> getFeatureList();
+ List<String> featureList();
/**
* Retrieves the list of submodules in the module.
@@ -78,5 +78,5 @@
*
* @return list of submodules in the module
*/
- List<YangModuleIdentifier> getSubModuleIdentifier();
+ List<YangModuleIdentifier> subModuleIdentifiers();
}
diff --git a/apps/yms/api/src/main/java/org/onosproject/yms/ysr/YangModuleLibrary.java b/apps/yms/api/src/main/java/org/onosproject/yms/ysr/YangModuleLibrary.java
index 284ae86..696d973 100644
--- a/apps/yms/api/src/main/java/org/onosproject/yms/ysr/YangModuleLibrary.java
+++ b/apps/yms/api/src/main/java/org/onosproject/yms/ysr/YangModuleLibrary.java
@@ -63,7 +63,7 @@
*
* @return module set id of the YANG library
*/
- String getModuleSetId();
+ String moduleSetId();
/**
* Retrieves the current list of YANG modules supported in the server.
@@ -80,5 +80,5 @@
*
* @return the current list of YANG modules supported in the server
*/
- List<YangModuleInformation> getYangModuleList();
+ List<YangModuleInformation> yangModuleList();
}
diff --git a/apps/yms/app/BUCK b/apps/yms/app/BUCK
deleted file mode 100644
index 8da70d1..0000000
--- a/apps/yms/app/BUCK
+++ /dev/null
@@ -1,8 +0,0 @@
-COMPILE_DEPS = [
- '//lib:CORE_DEPS',
- '//apps/yms/api:onos-apps-yms-api',
-]
-
-osgi_jar_with_tests(
- deps = COMPILE_DEPS,
-)
diff --git a/apps/yms/app/pom.xml b/apps/yms/app/pom.xml
index edb9bbf..dc88d6b 100644
--- a/apps/yms/app/pom.xml
+++ b/apps/yms/app/pom.xml
@@ -34,23 +34,87 @@
<dependencies>
<dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.framework</artifactId>
+ <version>4.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.4</version>
+ </dependency>
+ <dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-app-yms-api</artifactId>
<version>${project.version}</version>
</dependency>
-
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-yang-maven-plugin</artifactId>
+ <version>1.8</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-yang-datamodel</artifactId>
+ <version>1.8</version>
+ </dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onlab-junit</artifactId>
<scope>test</scope>
</dependency>
-
<dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-api</artifactId>
- <classifier>tests</classifier>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-osgi</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <!-- https://mvnrepository.com/artifact/org.springframework.osgi/spring-osgi-mock -->
+ <dependency>
+ <groupId>org.springframework.osgi</groupId>
+ <artifactId>spring-osgi-mock</artifactId>
+ <version>1.2.1</version>
+ </dependency>
+
</dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>3.2.0</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Private-Package>
+ org.onosproject.yangutils.datamodel.*,
+ org.onosproject.yangutils.translator.*,
+ org.onosproject.yangutils.linker.*,
+ org.onosproject.yangutils.utils.*
+ </Private-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-yang-maven-plugin</artifactId>
+ <version>1.8</version>
+ <configuration>
+ <yangFilesDir>src/test/resources/</yangFilesDir>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>yang2java</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
</project>
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/YmsManager.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/YmsManager.java
new file mode 100644
index 0000000..f4030ce
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/YmsManager.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ymsm;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.yms.app.ynh.YangNotificationExtendedService;
+import org.onosproject.yms.app.ysr.DefaultYangSchemaRegistry;
+import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+import org.onosproject.yms.ych.YangCodecHandler;
+import org.onosproject.yms.ych.YangDataTreeCodec;
+import org.onosproject.yms.ych.YangProtocolEncodingFormat;
+import org.onosproject.yms.ydt.YdtBuilder;
+import org.onosproject.yms.ydt.YdtResponse;
+import org.onosproject.yms.ydt.YdtWalker;
+import org.onosproject.yms.ydt.YmsOperationType;
+import org.onosproject.yms.ymsm.YmsService;
+import org.onosproject.yms.ynh.YangNotificationService;
+import org.onosproject.yms.ysr.YangModuleIdentifier;
+import org.onosproject.yms.ysr.YangModuleLibrary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static org.onlab.util.Tools.groupedThreads;
+
+/**
+ * Represents implementation of YANG management system manager.
+ */
+@Service
+@Component(immediate = true)
+public class YmsManager
+ implements YmsService {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private static final String APP_ID = "org.onosproject.app.yms";
+ private static final String MODULE_ID = "module-id";
+ private ApplicationId appId;
+ private YangSchemaRegistry schemaRegistry;
+ //module id generator should be used to generate a new module id for
+ //each YSR instance. So YCH also should generate it.
+ private IdGenerator moduleIdGenerator;
+ private ExecutorService schemaRegistryExecutor;
+ private YangNotificationExtendedService ynhExtendedService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Activate
+ public void activate() {
+ appId = coreService.registerApplication(APP_ID);
+ moduleIdGenerator = coreService.getIdGenerator(MODULE_ID);
+ schemaRegistry = new DefaultYangSchemaRegistry(String.valueOf(
+ moduleIdGenerator.getNewId()));
+ schemaRegistryExecutor =
+ Executors.newSingleThreadExecutor(groupedThreads(
+ "onos/apps/yang-management-system/schema-registry",
+ "schema-registry-handler", log));
+ log.info("Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ ((DefaultYangSchemaRegistry) schemaRegistry).flushYsrData();
+ schemaRegistryExecutor.shutdown();
+
+ // TODO implementation for other components.
+ log.info("Stopped");
+ }
+
+ @Override
+ public YdtBuilder getYdtBuilder(String logicalRootName,
+ String rootNamespace,
+ YmsOperationType operationType) {
+ return null;
+ }
+
+ @Override
+ public YdtBuilder getYdtBuilder(String logicalRootName,
+ String rootNamespace,
+ YmsOperationType operationType,
+ Object schemaRegistryForYdt) {
+ return null;
+ }
+
+ @Override
+ public YdtWalker getYdtWalker() {
+ return null;
+ }
+
+ @Override
+ public YdtResponse executeOperation(YdtBuilder operationRequest) {
+ return null;
+ }
+
+ @Override
+ public YangNotificationService getYangNotificationService() {
+ return ynhExtendedService;
+ }
+
+ /**
+ * Returns YANG notification extended service.
+ *
+ * @return YANG notification extended service
+ */
+ private YangNotificationExtendedService getYnhExtendedService() {
+ return ynhExtendedService;
+ }
+
+ @Override
+ public YangModuleLibrary getYangModuleLibrary() {
+ return ((DefaultYangSchemaRegistry) schemaRegistry).getLibrary();
+ }
+
+ @Override
+ public String getYangFile(YangModuleIdentifier moduleIdentifier) {
+ return ((DefaultYangSchemaRegistry) schemaRegistry)
+ .getYangFile(moduleIdentifier);
+ }
+
+ @Override
+ public void registerDefaultCodec(YangDataTreeCodec defaultCodec,
+ YangProtocolEncodingFormat dataFormat) {
+
+ }
+
+ @Override
+ public void registerService(Object yangManager, Class<?> yangService,
+ List<String> supportedFeatureList) {
+
+ //perform registration of service
+ schemaRegistryExecutor.execute(() -> schemaRegistry
+ .registerApplication(yangManager, yangService,
+ getYnhExtendedService()));
+ }
+
+ @Override
+ public void unRegisterService(Object appManager, Class<?> yangService) {
+ schemaRegistry.unRegisterApplication(appManager, yangService);
+ }
+
+ @Override
+ public YangCodecHandler getYangCodecHandler() {
+ return null;
+ }
+
+ /**
+ * Returns schema registry.
+ *
+ * @return schema registry
+ */
+ public YangSchemaRegistry getSchemaRegistry() {
+ return schemaRegistry;
+ }
+
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/package-info.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/package-info.java
new file mode 100644
index 0000000..2d29667
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Provides implementation of YANG application management system manager. YMSM is manager
+ * of the YANG Core, it manages interaction between application and protocols.
+ */
+package org.onosproject.yms.app.ymsm;
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ynh/YangNotificationExtendedService.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ynh/YangNotificationExtendedService.java
new file mode 100644
index 0000000..690eae4
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ynh/YangNotificationExtendedService.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2015-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ynh;
+
+import org.onosproject.event.ListenerService;
+import org.onosproject.yms.ynh.YangNotificationService;
+
+/**
+ * Abstraction of an entity which provides interfaces to YANG extended notification
+ * service. It provides extended interfaces required by YMS internal modules.
+ * Application registers their schema with YMSM, YMSM delegates the registration
+ * request to YSR. YSR then looks for the presence of notification in application
+ * schema, presence of notification will trigger YSR to ask YANG extended notification
+ * service to register it as a listener to that application events.
+ */
+public interface YangNotificationExtendedService extends YangNotificationService {
+
+ /**
+ * Registers as listener with application. This is called by YSR when it
+ * detects notification presence in application YANG file at the time when
+ * application registers it's schema with YMS.
+ *
+ * @param appObject application object
+ */
+ void registerAsListener(ListenerService appObject);
+
+ // TODO handle scenario when multiple services are implemented by single manager.
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ynh/package-info.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ynh/package-info.java
new file mode 100644
index 0000000..1815ef7
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ynh/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Provides implementation of YANG notification handler. YNH handles notification
+ * from the application and provide it to the protocols.
+ */
+package org.onosproject.yms.app.ynh;
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleIdentifier.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleIdentifier.java
new file mode 100644
index 0000000..e98e982
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleIdentifier.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ysr;
+
+import org.onosproject.yms.ysr.YangModuleIdentifier;
+
+import java.util.Comparator;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Representation of default YANG module identifier.
+ */
+class DefaultYangModuleIdentifier implements YangModuleIdentifier,
+ Comparator<YangModuleIdentifier> {
+
+ private final String moduleName;
+ private final String revision;
+
+ /**
+ * Creates an instance of YANG module identifier.
+ *
+ * @param moduleName module's name
+ * @param revision module's revision
+ */
+ DefaultYangModuleIdentifier(String moduleName, String revision) {
+ this.moduleName = moduleName;
+ this.revision = revision;
+ }
+
+ @Override
+ public String moduleName() {
+ return moduleName;
+ }
+
+ @Override
+ public String revision() {
+ return revision;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(moduleName, revision);
+ }
+
+ @Override
+ public int compare(YangModuleIdentifier id1, YangModuleIdentifier id2) {
+ int compare = id1.moduleName().compareTo(id2.moduleName());
+ if (compare != 0) {
+ return compare;
+ }
+ return id1.revision().compareTo(id2.revision());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultYangModuleIdentifier) {
+ DefaultYangModuleIdentifier that = (DefaultYangModuleIdentifier) obj;
+ return Objects.equals(moduleName, that.moduleName) &&
+ Objects.equals(revision, that.revision);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("moduleName", moduleName)
+ .add("revision", revision)
+ .toString();
+ }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleInformation.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleInformation.java
new file mode 100644
index 0000000..79778f7
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleInformation.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ysr;
+
+import com.google.common.collect.ImmutableList;
+import org.onosproject.yms.ysr.YangModuleIdentifier;
+import org.onosproject.yms.ysr.YangModuleInformation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Representation of default YANG module information.
+ */
+class DefaultYangModuleInformation implements YangModuleInformation {
+
+ private final YangModuleIdentifier moduleIdentifier;
+ private final String nameSpace;
+ private final List<String> features;
+ private final List<YangModuleIdentifier> subModuleIdentifiers;
+
+ /**
+ * Creates an instance of YANG module information.
+ *
+ * @param moduleIdentifier module identifier
+ * @param nameSpace name space of module
+ */
+ DefaultYangModuleInformation(YangModuleIdentifier moduleIdentifier,
+ String nameSpace) {
+ this.moduleIdentifier = moduleIdentifier;
+ this.nameSpace = nameSpace;
+ subModuleIdentifiers = new ArrayList<>();
+ features = new ArrayList<>();
+ }
+
+ @Override
+ public YangModuleIdentifier moduleIdentifier() {
+ return moduleIdentifier;
+ }
+
+ @Override
+ public String namespace() {
+ return nameSpace;
+ }
+
+ @Override
+ public List<String> featureList() {
+ return ImmutableList.copyOf(features);
+ }
+
+ @Override
+ public List<YangModuleIdentifier> subModuleIdentifiers() {
+ return ImmutableList.copyOf(subModuleIdentifiers);
+ }
+
+ /**
+ * Adds to YANG sub module identifier list.
+ *
+ * @param subModuleIdentifier YANG sub module identifier
+ */
+ void addSubModuleIdentifiers(YangModuleIdentifier subModuleIdentifier) {
+ subModuleIdentifiers.add(subModuleIdentifier);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(moduleIdentifier, subModuleIdentifiers, nameSpace, features);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultYangModuleInformation) {
+ DefaultYangModuleInformation that = (DefaultYangModuleInformation) obj;
+ return Objects.equals(moduleIdentifier, that.moduleIdentifier) &&
+ Objects.equals(nameSpace, that.nameSpace) &&
+ Objects.equals(features, that.features) &&
+ Objects.equals(subModuleIdentifiers, that.subModuleIdentifiers);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("yangModuleIdentifier", moduleIdentifier)
+ .add("nameSpace", nameSpace)
+ .add("features", features)
+ .add("yangModuleIdentifiers", subModuleIdentifiers)
+ .toString();
+ }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleLibrary.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleLibrary.java
new file mode 100644
index 0000000..4187746
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleLibrary.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ysr;
+
+import com.google.common.collect.ImmutableList;
+import org.onosproject.yms.ysr.YangModuleInformation;
+import org.onosproject.yms.ysr.YangModuleLibrary;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Representation of default YANG module library.
+ */
+class DefaultYangModuleLibrary implements YangModuleLibrary {
+
+ private final String moduleSetId;
+ private final List<YangModuleInformation> moduleInformation;
+
+ /**
+ * Creates an instance of YANG module library.
+ *
+ * @param moduleSetId module id
+ */
+ DefaultYangModuleLibrary(String moduleSetId) {
+ this.moduleSetId = moduleSetId;
+ moduleInformation = new ArrayList<>();
+ }
+
+ @Override
+ public String moduleSetId() {
+ return moduleSetId;
+ }
+
+ @Override
+ public List<YangModuleInformation> yangModuleList() {
+ return ImmutableList.copyOf(moduleInformation);
+ }
+
+ /**
+ * Adds module information.
+ *
+ * @param information module information
+ */
+ void addModuleInformation(YangModuleInformation information) {
+ moduleInformation.add(information);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(moduleInformation, moduleSetId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultYangModuleLibrary) {
+ DefaultYangModuleLibrary that = (DefaultYangModuleLibrary) obj;
+ return Objects.equals(moduleInformation, that.moduleInformation) &&
+ Objects.equals(moduleSetId, that.moduleSetId);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("moduleInformation", moduleInformation)
+ .add("moduleId", moduleSetId)
+ .toString();
+ }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangSchemaRegistry.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangSchemaRegistry.java
new file mode 100644
index 0000000..370e9cc
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangSchemaRegistry.java
@@ -0,0 +1,1116 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ysr;
+
+import org.onosproject.event.ListenerService;
+import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
+import org.onosproject.yangutils.datamodel.YangInclude;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+import org.onosproject.yangutils.datamodel.YangSubModule;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yms.app.ynh.YangNotificationExtendedService;
+import org.onosproject.yms.ysr.YangModuleIdentifier;
+import org.onosproject.yms.ysr.YangModuleInformation;
+import org.onosproject.yms.ysr.YangModuleLibrary;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.regex.Pattern;
+
+import static org.apache.commons.io.FileUtils.deleteDirectory;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.parseJarFile;
+import static org.onosproject.yangutils.utils.UtilConstants.DEFAULT;
+import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
+import static org.onosproject.yangutils.utils.UtilConstants.EVENT_STRING;
+import static org.onosproject.yangutils.utils.UtilConstants.OP_PARAM;
+import static org.onosproject.yangutils.utils.UtilConstants.PERIOD;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
+import static org.osgi.framework.FrameworkUtil.getBundle;
+
+
+/**
+ * Representation of default YANG schema registry. Yang schema registry
+ * provides interface to an application to register its YANG schema
+ * with YMS. It provides YANG schema nodes to YDT, YNB and YSB.
+ */
+public class DefaultYangSchemaRegistry
+ implements YangSchemaRegistry {
+
+ private static final String SYSTEM = File.separator + "system" +
+ File.separator;
+ private static final String MAVEN = "mvn:";
+ private static final String HYPHEN = "-";
+ private static final String DELIMITER = ".";
+ private static final String SERVICE = "Service";
+ private static final String JAR = ".jar";
+ private static final String USER_DIRECTORY = "user.dir";
+ private static final String SLASH = File.separator;
+ private static final String AT = "@";
+ private static final String DATE_FORMAT = "yyyy-mm-dd";
+ private static final Logger log =
+ LoggerFactory.getLogger(DefaultYangSchemaRegistry.class);
+
+ /*
+ * Map for storing app objects.
+ */
+ private final ConcurrentMap<String, YsrAppContext> appObjectStore;
+
+ /*
+ * Map for storing YANG schema nodes.
+ */
+ private final ConcurrentMap<String, YsrAppContext> yangSchemaStore;
+
+ /*
+ * Map for storing YANG schema nodes with respect to root's generated
+ * interface file name.
+ */
+ private final ConcurrentMap<String, YsrAppContext>
+ yangSchemaStoreForRootInterface;
+
+ /*
+ * Map for storing YANG schema nodes root's generated op param file name.
+ */
+ private final ConcurrentMap<String, YsrAppContext>
+ yangSchemaStoreForRootOpParam;
+
+ /*
+ * Map for storing YANG schema nodes with respect to notifications.
+ */
+ private final ConcurrentMap<String, YsrAppContext>
+ yangRootSchemaStoreForNotification;
+
+ /*
+ * Map for storing registered classes.
+ */
+ private final ConcurrentMap<String, Class<?>> registerClassStore;
+
+ /*
+ * Map for storing YANG file details.
+ */
+ private final ConcurrentMap<YangModuleIdentifier, String> yangFileStore;
+
+ /*
+ * Context of application which is registering with YMS.
+ */
+ private YsrAppContext ysrAppContext;
+
+ /*
+ * Context of application which is registering with YMS with multiple
+ * revision.
+ */
+ private YsrAppContext ysrContextForSchemaStore;
+
+ /*
+ * Context of application which is registering with YMS with multiple
+ * manager object.
+ */
+ private YsrAppContext ysrContextForAppStore;
+
+ /*
+ * Class loader of service application.
+ */
+ private ClassLoader classLoader;
+
+ /**
+ * YANG module library.
+ */
+ private final YangModuleLibrary library;
+
+ /**
+ * Creates an instance of default YANG schema registry.
+ *
+ * @param moduleId module set id of YSR module library
+ */
+ public DefaultYangSchemaRegistry(String moduleId) {
+ appObjectStore = new ConcurrentHashMap<>();
+ yangSchemaStore = new ConcurrentHashMap<>();
+ yangSchemaStoreForRootInterface = new ConcurrentHashMap<>();
+ yangSchemaStoreForRootOpParam = new ConcurrentHashMap<>();
+ yangRootSchemaStoreForNotification = new ConcurrentHashMap<>();
+ registerClassStore = new ConcurrentHashMap<>();
+ yangFileStore = new ConcurrentHashMap<>();
+ library = new DefaultYangModuleLibrary(moduleId);
+ }
+
+
+ @Override
+ public void registerApplication(Object appObject, Class<?> serviceClass,
+ YangNotificationExtendedService
+ notificationExtendedService) {
+
+ BundleContext bundleContext = getBundle(serviceClass)
+ .getBundleContext();
+ String jarPath = getJarPathFromBundleLocation(
+ bundleContext.getBundle().getLocation(),
+ bundleContext.getProperty(USER_DIRECTORY));
+ // process application registration.
+ processRegistration(serviceClass, appObject, jarPath);
+ //process notification registration.
+ processNotificationRegistration(serviceClass, appObject,
+ notificationExtendedService);
+ }
+
+ /**
+ * Process application registration.
+ *
+ * @param serviceClass service class
+ * @param appObject application object
+ * @param jarPath jar path
+ */
+ void processRegistration(Class<?> serviceClass, Object appObject,
+ String jarPath) {
+
+ // set class loader for service class.
+ setClassLoader(serviceClass.getClassLoader());
+
+ //Check if service should be registered?
+ if (appObject != null) {
+ verifyApplicationRegistration(appObject, serviceClass);
+ }
+ //Add app class to registered service store.
+ if (!registerClassStore.containsKey(serviceClass.getName())) {
+ updateServiceClass(serviceClass);
+ }
+
+ // process storing operations.
+ if (!verifyIfApplicationAlreadyRegistered(serviceClass)) {
+ List<YangNode> curNodes =
+ processJarParsingOperations(jarPath);
+
+ if (curNodes != null) {
+ for (YangNode schemaNode : curNodes) {
+ //Process application context for registrations.
+ processApplicationContext(schemaNode);
+ //Update YANG file store.
+ updateYangFileStore(schemaNode, jarPath);
+ //Process module library operation for current node list.
+ processModuleLibrary(schemaNode);
+ }
+ //Set jar path for app context.
+ ysrAppContext.jarPath(jarPath);
+ ysrContextForSchemaStore.jarPath(jarPath);
+ ysrContextForAppStore.jarPath(jarPath);
+ }
+ }
+
+ //Verifies if object is updated for app store.
+ updateApplicationObject(appObject, serviceClass);
+ }
+
+ /**
+ * Verifies if service class should be registered or not.
+ *
+ * @param appObject application object
+ * @param appClass application class
+ */
+ private void verifyApplicationRegistration(Object appObject,
+ Class<?> appClass) {
+ Class<?> managerClass = appObject.getClass();
+ Class<?>[] services = managerClass.getInterfaces();
+ List<Class<?>> classes = new ArrayList<>();
+ Collections.addAll(classes, services);
+ if (!classes.contains(appClass)) {
+ throw new RuntimeException("service class " + appClass.getName() +
+ "is not being implemented by " +
+ managerClass.getName());
+ }
+ }
+
+ /**
+ * Verifies if application is already registered with YMS.
+ *
+ * @param appClass application class
+ * @return true if application already registered
+ */
+ private boolean verifyIfApplicationAlreadyRegistered(Class<?> appClass) {
+ String simpleName = appClass.getSimpleName();
+ String appName = appClass.getName();
+ if (!appObjectStore.containsKey(appName)) {
+ if (simpleName.contains(OP_PARAM)) {
+ return yangSchemaStoreForRootOpParam
+ .containsKey(appName);
+ } else {
+ return yangSchemaStoreForRootInterface
+ .containsKey(appName);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Verifies if service is being implemented by some new object.
+ *
+ * @param appObject application's object
+ * @param appClass application's class
+ */
+ private void updateApplicationObject(Object appObject, Class<?> appClass) {
+ YsrAppContext appContext =
+ appObjectStore.get(appClass.getName());
+ if (appContext != null) {
+ YangSchemaNode schemaNode = appContext.curNode();
+ String name = getInterfaceClassName(schemaNode);
+ if (appContext.appObject() == null) {
+ //update in application store.
+ appContext.appObject(appObject);
+ //Update app object for schema store for root interface.
+ appContext = yangSchemaStoreForRootInterface.get(name);
+ if (appContext != null) {
+ appContext.appObject(appObject);
+ }
+ // Update app object for schema store for root op param
+ appContext = yangSchemaStoreForRootOpParam.get(name + OP_PARAM);
+ if (appContext != null) {
+ appContext.appObject(appObject);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void unRegisterApplication(Object managerObject,
+ Class<?> serviceClass) {
+ YangSchemaNode curNode = null;
+ String serviceName = serviceClass.getName();
+
+ //Check if service should be unregistered?
+ if (managerObject != null) {
+ verifyApplicationRegistration(managerObject, serviceClass);
+ }
+ //Remove registered class from store.
+ registerClassStore.remove(serviceName);
+
+ //check if service is in app store.
+ if (appObjectStore.containsKey(serviceName)) {
+ curNode = retrieveNodeForUnregister(serviceName, appObjectStore,
+ managerObject);
+ } else if (yangSchemaStoreForRootInterface.containsKey(serviceName)) {
+ //check if service is in interface store.
+ curNode = retrieveNodeForUnregister(serviceName,
+ yangSchemaStoreForRootInterface,
+ managerObject);
+ } else if (yangSchemaStoreForRootOpParam.containsKey(serviceName)) {
+ //check if service is in op param store.
+ curNode = retrieveNodeForUnregister(serviceName,
+ yangSchemaStoreForRootOpParam,
+ managerObject);
+ }
+ if (curNode != null) {
+ String javaName = getInterfaceClassName(curNode);
+ removeFromYangSchemaStore(curNode);
+ removeFromYangNotificationStore(curNode);
+ removeFromAppSchemaStore(serviceName);
+ removeFromYangSchemaNodeForRootInterface(javaName);
+ removeFromYangSchemaNodeForRootOpParam(javaName);
+ removeYangFileInfoFromStore(curNode);
+ log.info(" service {} is unregistered.",
+ serviceClass.getSimpleName());
+ } else {
+ throw new RuntimeException(serviceClass.getSimpleName() +
+ " service was not registered.");
+ }
+ }
+
+ @Override
+ public Object getRegisteredApplication(YangSchemaNode schemaNode) {
+ if (schemaNode != null) {
+ String name = getInterfaceClassName(schemaNode);
+ if (yangSchemaStoreForRootInterface.containsKey(name)) {
+ return yangSchemaStoreForRootInterface.get(name)
+ .appObject();
+ }
+ log.error("{} not found.", name);
+ }
+ return null;
+ }
+
+ @Override
+ public YangSchemaNode getYangSchemaNodeUsingSchemaName(String schemaName) {
+ return getSchemaNodeUsingSchemaNameWithRev(schemaName);
+ }
+
+ @Override
+ public YangSchemaNode getYangSchemaNodeUsingAppName(String appName) {
+ YsrAppContext appContext = appObjectStore.get(appName);
+ if (appContext != null) {
+ return appContext.curNode();
+ }
+ log.error("{} not found.", appName);
+ return null;
+ }
+
+ @Override
+ public YangSchemaNode
+ getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(String name) {
+ YsrAppContext appContext = yangSchemaStoreForRootInterface.get(name);
+ if (appContext != null) {
+ return appContext.curNode();
+ }
+ log.error("{} not found.", name);
+ return null;
+ }
+
+ @Override
+ public YangSchemaNode getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ String name) {
+ YsrAppContext appContext = yangSchemaStoreForRootOpParam.get(name);
+ if (appContext != null) {
+ return appContext.curNode();
+ }
+ log.error("{} not found.", name);
+ return null;
+ }
+
+ @Override
+ public YangSchemaNode getRootYangSchemaNodeForNotification(String name) {
+ YsrAppContext appContext = yangRootSchemaStoreForNotification.get(name);
+ if (appContext != null) {
+ return appContext.curNode();
+ }
+ log.error("{} not found.", name);
+ return null;
+ }
+
+ @Override
+ public Class<?> getRegisteredClass(YangSchemaNode schemaNode,
+ String appName) {
+ String interfaceName = getInterfaceClassName(schemaNode);
+ String serviceName = getServiceName(schemaNode);
+ String defaultClass;
+ if (schemaNode instanceof RpcNotificationContainer) {
+ defaultClass = getOpParamClassName(schemaNode);
+ } else {
+ defaultClass = getDefaultClassName(schemaNode);
+ }
+ //If application class is registered.
+ if (registerClassStore.containsKey(appName)) {
+ return registerClassStore.get(appName);
+ } else if (registerClassStore.containsKey(interfaceName)) {
+ //If interface class is registered.
+ return registerClassStore.get(interfaceName);
+ } else if (registerClassStore.containsKey(serviceName)) {
+ //If service class is registered.
+ return registerClassStore.get(serviceName);
+ } else if (registerClassStore.containsKey(defaultClass)) {
+ //If default class is registered.
+ return registerClassStore.get(defaultClass);
+ }
+ return null;
+ }
+
+ /**
+ * Returns YANG file path for module identifier.
+ *
+ * @param moduleIdentifier module identifier
+ * @return YANG file path for module identifier
+ */
+ public String getYangFile(YangModuleIdentifier moduleIdentifier) {
+ if (yangFileStore.containsKey(moduleIdentifier)) {
+ return yangFileStore.get(moduleIdentifier);
+ }
+ log.error("YANG files for corresponding module identifier {} not " +
+ "found", moduleIdentifier);
+ return null;
+ }
+
+ /**
+ * Updates service class store.
+ *
+ * @param serviceClass service class
+ */
+ void updateServiceClass(Class<?> serviceClass) {
+ registerClassStore.put(serviceClass.getName(), serviceClass);
+ }
+
+ /**
+ * Updates application object store.
+ *
+ * @param appName application name
+ */
+ private void updateAppObjectStore(String appName) {
+ if (verifyClassExistence(appName)) {
+ appObjectStore.put(appName, ysrContextForAppStore);
+ }
+ }
+
+ /**
+ * Updates YANG schema object store.
+ *
+ * @param schemaNode application's schema node
+ */
+ private void updateYangSchemaStore(YangSchemaNode schemaNode) {
+ addSchemaNodeUsingSchemaNameWithRev(schemaNode);
+ }
+
+ /**
+ * Updates YANG schema notification object store.
+ *
+ * @param name application's notification name
+ */
+ private void updateYangNotificationStore(String name) {
+ if (verifyClassExistence(name)) {
+ yangRootSchemaStoreForNotification.put(name, ysrAppContext);
+ }
+ }
+
+ /**
+ * Updates YANG schema object store for root interface file name.
+ *
+ * @param name name of generated interface file for root
+ * node
+ */
+ private void updateYangSchemaForRootInterfaceFileNameStore(String name) {
+ if (verifyClassExistence(name)) {
+ yangSchemaStoreForRootInterface.put(name, ysrAppContext);
+ }
+ }
+
+ /**
+ * Updates YANG schema object store for root op param file name.
+ *
+ * @param name name of generated op param file for root node
+ */
+ private void updateYangSchemaForRootOpParamFileNameStore(String name) {
+ if (verifyClassExistence(name)) {
+ yangSchemaStoreForRootOpParam.put(name, ysrAppContext);
+ }
+ }
+
+ /**
+ * Updates yang file store for YANG node.
+ *
+ * @param node YANG node
+ * @param jarPath jar file path
+ */
+ private void updateYangFileStore(YangNode node, String jarPath) {
+ //FIXME: fix when yang tools support for file name.
+ //yangFileStore.put(getModuleIdentifier(node),
+ // getYangFilePath(jarPath, node.getFileName()));
+ }
+
+ /**
+ * Returns yang file path.
+ *
+ * @param jarPath jar path
+ * @param metaDataFileName name of yang file from metadata
+ * @return yang file path
+ */
+ private String getYangFilePath(String jarPath, String metaDataFileName) {
+ String[] metaData = metaDataFileName.split(SLASH);
+ return jarPath + SLASH + metaData[metaData.length - 1];
+ }
+
+ /**
+ * Process jar file for fetching YANG nodes.
+ *
+ * @param path jar file path
+ * @return YANG schema nodes
+ */
+ private List<YangNode> processJarParsingOperations(String path) {
+ //Deserialize data model and get the YANG node set.
+ try {
+ return parseJarFile(path + JAR, path);
+ } catch (IOException e) {
+ log.error(" failed to parse the jar file in path {} : {} ", path,
+ e.getMessage());
+ }
+ return null;
+ }
+
+ /**
+ * Process an application an updates the maps for YANG schema registry.
+ *
+ * @param appNode application YANG schema nodes
+ */
+ void processApplicationContext(YangSchemaNode appNode) {
+
+ String appName = getInterfaceClassName(appNode);
+
+ //Create a new instance of ysr app context for each node.
+ ysrAppContext = new YsrAppContext();
+ ysrContextForSchemaStore = new YsrAppContext();
+ ysrContextForAppStore = new YsrAppContext();
+
+ //add cur node to app context.
+ ysrAppContext.curNode(appNode);
+ ysrContextForAppStore.curNode(appNode);
+
+ //Updates maps wih schema nodes.
+ updateAppObjectStore(getServiceName(appNode));
+
+ // Updates schema store.
+ updateYangSchemaStore(appNode);
+ // update interface store.
+ updateYangSchemaForRootInterfaceFileNameStore(appName);
+ //update op param store.
+ updateYangSchemaForRootOpParamFileNameStore(getOpParamClassName(appNode));
+ //Checks if notification is present then update notification store map.
+ String eventSubject = null;
+ try {
+ if (appNode.isNotificationPresent()) {
+ eventSubject = getEventClassName(appNode);
+ }
+ } catch (DataModelException e) {
+ log.error("failed to search notification from schema map : {}",
+ e.getLocalizedMessage());
+ }
+ if (eventSubject != null) {
+ updateYangNotificationStore(eventSubject);
+ }
+ log.info("successfully registered this application {}{}", appName,
+ SERVICE);
+
+ }
+
+ /**
+ * Returns jar path from bundle mvnLocationPath.
+ *
+ * @param mvnLocationPath mvnLocationPath of bundle
+ * @return path of jar
+ */
+ private String getJarPathFromBundleLocation(String mvnLocationPath,
+ String currentDirectory) {
+ String path = currentDirectory + SYSTEM;
+ String[] strArray = mvnLocationPath.split(MAVEN);
+ String[] split = strArray[1].split(File.separator);
+ String[] groupId = split[0].split(Pattern.quote(DELIMITER));
+
+ return path + groupId[0] + SLASH + groupId[1] + SLASH + split[1] +
+ SLASH + split[2] + SLASH + split[1] + HYPHEN + split[2];
+ }
+
+ /**
+ * Returns de-serializes YANG data-model nodes.
+ *
+ * @param serializedFileInfo serialized File Info
+ * @return de-serializes YANG data-model nodes
+ */
+ Set<YangSchemaNode> deSerializeDataModel(String serializedFileInfo) {
+
+ Set<YangSchemaNode> nodes = new HashSet<>();
+ Object readValue;
+ try {
+ FileInputStream fileInputStream =
+ new FileInputStream(serializedFileInfo);
+ ObjectInputStream objectInputStream =
+ new ObjectInputStream(fileInputStream);
+ readValue = objectInputStream.readObject();
+ if (readValue instanceof Set<?>) {
+ for (Object obj : (Set<?>) readValue) {
+ if (obj instanceof YangSchemaNode) {
+ nodes.add((YangSchemaNode) obj);
+ } else {
+ throw new RuntimeException(
+ "deserialize object is not an instance of " +
+ "YANG schema node" + obj);
+ }
+ }
+ } else {
+ throw new RuntimeException(
+ "deserialize object is not an instance of set of" +
+ "YANG schema node" + readValue);
+ }
+ objectInputStream.close();
+ fileInputStream.close();
+ } catch (IOException | ClassNotFoundException e) {
+ log.error(" {} not found.: {}", serializedFileInfo,
+ e.getLocalizedMessage());
+ }
+
+ return nodes;
+ }
+
+ /**
+ * Returns ysr app context.
+ *
+ * @return ysr app context
+ */
+ YsrAppContext ysrAppContext() {
+ return ysrAppContext;
+ }
+
+ /**
+ * Returns schema node based on the revision.
+ *
+ * @param name name of the schema node
+ * @return schema node based on the revision
+ */
+ private YangSchemaNode getSchemaNodeUsingSchemaNameWithRev(String name) {
+ YsrAppContext appContext;
+ YangSchemaNode schemaNode;
+ if (name.contains(AT)) {
+ String[] revArray = name.split(AT);
+ appContext = yangSchemaStore.get(revArray[0]);
+ schemaNode = appContext.getSchemaNodeForRevisionStore(name);
+ if (schemaNode != null) {
+ return schemaNode;
+ }
+ return appContext.curNode();
+ }
+ if (yangSchemaStore.containsKey(name)) {
+ appContext = yangSchemaStore.get(name);
+ if (appContext != null) {
+ Iterator<YangSchemaNode> iterator = appContext
+ .getYangSchemaNodeForRevisionStore().values()
+ .iterator();
+ if (iterator.hasNext()) {
+ return appContext.getYangSchemaNodeForRevisionStore()
+ .values().iterator().next();
+ } else {
+ return null;
+ }
+ }
+ }
+ log.error("{} not found.", name);
+ return null;
+ }
+
+ /**
+ * Adds schema node when different revision of node has received.
+ *
+ * @param schemaNode schema node
+ */
+ private void addSchemaNodeUsingSchemaNameWithRev(
+ YangSchemaNode schemaNode) {
+
+ String date = getDateInStringFormat(schemaNode);
+ String name = schemaNode.getName();
+ if (!date.equals(EMPTY_STRING)) {
+ name = name + AT + date;
+ }
+ //check if already present.
+ if (!yangSchemaStore.containsKey(schemaNode.getName())) {
+ ysrContextForSchemaStore.curNode(schemaNode);
+ //if revision is not present no need to add in revision store.
+ ysrContextForSchemaStore
+ .addSchemaNodeWithRevisionStore(name, schemaNode);
+ yangSchemaStore.put(schemaNode.getName(),
+ ysrContextForSchemaStore);
+ } else {
+ YsrAppContext appContext =
+ yangSchemaStore.get(schemaNode.getName());
+ appContext.addSchemaNodeWithRevisionStore(name, schemaNode);
+ appContext.curNode(schemaNode);
+ }
+ }
+
+ /**
+ * Returns date in string format.
+ *
+ * @param schemaNode schema node
+ * @return date in string format
+ */
+ String getDateInStringFormat(YangSchemaNode schemaNode) {
+ if (schemaNode != null) {
+ if (((YangNode) schemaNode).getRevision() != null) {
+ return new SimpleDateFormat(DATE_FORMAT)
+ .format(((YangNode) schemaNode).getRevision()
+ .getRevDate());
+ }
+ }
+ return EMPTY_STRING;
+ }
+
+ /**
+ * Removes schema node from schema map.
+ *
+ * @param removableNode schema node which needs to be removed
+ */
+ private void removeSchemaNode(YangSchemaNode removableNode) {
+
+ String name = removableNode.getName();
+ String date = getDateInStringFormat(removableNode);
+
+ if (!date.isEmpty()) {
+ name = removableNode.getName() + AT +
+ getDateInStringFormat(removableNode);
+ }
+ YsrAppContext appContext = yangSchemaStore
+ .get(removableNode.getName());
+ if (appContext != null &&
+ !appContext.getYangSchemaNodeForRevisionStore().isEmpty() &&
+ appContext.getYangSchemaNodeForRevisionStore().size() != 1) {
+ appContext.removeSchemaNodeForRevisionStore(name);
+ } else {
+ yangSchemaStore.remove(removableNode.getName());
+ }
+ }
+
+ /**
+ * Verifies if the manager object is already registered with notification
+ * handler.
+ *
+ * @param serviceClass service class
+ * @return true if the manager object is already registered with
+ * notification handler
+ */
+ boolean verifyNotificationObject(Class<?> serviceClass) {
+ YangSchemaNode schemaNode = null;
+ String serviceName = serviceClass.getName();
+ if (appObjectStore.containsKey(serviceName)) {
+ schemaNode = getYangSchemaNodeUsingAppName(serviceName);
+ } else if (yangSchemaStoreForRootInterface.containsKey(serviceName)) {
+ schemaNode =
+ getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ serviceName);
+ } else if (yangSchemaStoreForRootOpParam.containsKey(serviceName)) {
+ schemaNode = getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ serviceName);
+ }
+
+ if (schemaNode != null) {
+ String name = getEventClassName(schemaNode);
+
+ YsrAppContext appContext =
+ yangRootSchemaStoreForNotification.get(name);
+ if (appContext != null && !appContext.isNotificationRegistered()) {
+ appContext.setNotificationRegistered(true);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns schema node's generated interface class name.
+ *
+ * @param schemaNode schema node
+ * @return schema node's generated interface class name
+ */
+ private String getInterfaceClassName(YangSchemaNode schemaNode) {
+ return schemaNode.getJavaPackage() + PERIOD +
+ getCapitalCase(schemaNode.getJavaClassNameOrBuiltInType());
+ }
+
+ /**
+ * Returns schema node's generated op param class name.
+ *
+ * @param schemaNode schema node
+ * @return schema node's generated op param class name
+ */
+ private String getOpParamClassName(YangSchemaNode schemaNode) {
+ return getInterfaceClassName(schemaNode) + OP_PARAM;
+ }
+
+ /**
+ * Returns schema node's generated op param class name.
+ *
+ * @param schemaNode schema node
+ * @return schema node's generated op param class name
+ */
+ private String getDefaultClassName(YangSchemaNode schemaNode) {
+ return schemaNode.getJavaPackage() + PERIOD + getCapitalCase(DEFAULT) +
+ getCapitalCase(schemaNode.getJavaClassNameOrBuiltInType());
+ }
+
+ /**
+ * Returns schema node's generated event class name.
+ *
+ * @param schemaNode schema node
+ * @return schema node's generated event class name
+ */
+ private String getEventClassName(YangSchemaNode schemaNode) {
+ return getInterfaceClassName(schemaNode).toLowerCase() + PERIOD +
+ getCapitalCase(schemaNode.getJavaClassNameOrBuiltInType()) +
+ EVENT_STRING;
+ }
+
+ /**
+ * Returns schema node's generated service class name.
+ *
+ * @param schemaNode schema node
+ * @return schema node's generated service class name
+ */
+ private String getServiceName(YangSchemaNode schemaNode) {
+ return getInterfaceClassName(schemaNode) + SERVICE;
+ }
+
+ /**
+ * Returns YSR application context for schema map.
+ *
+ * @return YSR application context for schema map
+ */
+ YsrAppContext ysrContextForSchemaStore() {
+ return ysrContextForSchemaStore;
+ }
+
+ /**
+ * Sets YSR application context for schema map.
+ *
+ * @param context YSR application context for
+ * schema map
+ */
+ void ysrContextForSchemaStore(YsrAppContext context) {
+ ysrContextForSchemaStore = context;
+ }
+
+ /**
+ * Returns YSR app context for application store.
+ *
+ * @return YSR app context for application store
+ */
+ YsrAppContext ysrContextForAppStore() {
+ return ysrContextForAppStore;
+ }
+
+ /**
+ * Retrieves schema node from the store and deletes jar file path.
+ *
+ * @param appName application name
+ * @param store YSR stores
+ * @param appObject applications object
+ * @return schema node from the store
+ */
+ private YangSchemaNode retrieveNodeForUnregister(
+ String appName,
+ ConcurrentMap<String, YsrAppContext> store, Object appObject) {
+
+ YsrAppContext curContext = store.get(appName);
+ boolean isValidObject;
+ if (curContext != null) {
+ isValidObject = verifyAppObject(appObject, curContext.appObject());
+ if (isValidObject) {
+ YangSchemaNode curNode = curContext.curNode();
+ //Delete all the generated ysr information in application's
+ // package.
+ removeYsrGeneratedTemporaryResources(curContext.jarPath(),
+ appName);
+ return curNode;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Verifies the application object which needs to be unregistered.
+ *
+ * @param appObject current received application object
+ * @param context stored application object
+ * @return true if objects are equal
+ */
+ private boolean verifyAppObject(Object appObject, Object context) {
+ if (appObject != null && context != null) {
+ return appObject.equals(context);
+ }
+ return appObject == null && context == null;
+ }
+
+ /**
+ * Removes YSR generated temporary resources.
+ *
+ * @param rscPath resource path
+ * @param appName application name
+ */
+ private void removeYsrGeneratedTemporaryResources(String rscPath,
+ String appName) {
+ if (rscPath != null) {
+ File jarPath = new File(rscPath);
+ if (jarPath.exists()) {
+ try {
+ deleteDirectory(jarPath);
+ } catch (IOException e) {
+ log.error("failed to delete ysr resources for {} : {}",
+ appName, e.getLocalizedMessage());
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes from YANG schema store.
+ *
+ * @param curNode schema node
+ */
+ private void removeFromYangSchemaStore(YangSchemaNode curNode) {
+ removeSchemaNode(curNode);
+ }
+
+ /**
+ * Removes from YANG schema notification store.
+ *
+ * @param curNode schema node
+ */
+ private void removeFromYangNotificationStore(YangSchemaNode curNode) {
+ yangRootSchemaStoreForNotification
+ .remove(getEventClassName(curNode));
+ }
+
+ /**
+ * Removes from app store.
+ *
+ * @param appName application name
+ */
+ private void removeFromAppSchemaStore(String appName) {
+ appObjectStore.remove(appName);
+ }
+
+ /**
+ * Removes from interface store.
+ *
+ * @param appName application name
+ */
+ private void removeFromYangSchemaNodeForRootInterface(String appName) {
+ yangSchemaStoreForRootInterface.remove(appName);
+ }
+
+ /**
+ * Removes from op param store.
+ *
+ * @param appName application name
+ */
+ private void removeFromYangSchemaNodeForRootOpParam(String appName) {
+ yangSchemaStoreForRootOpParam.remove(appName + OP_PARAM);
+ }
+
+ /**
+ * Removes YANG file information from file store.
+ *
+ * @param schemaNode schema node
+ */
+ private void removeYangFileInfoFromStore(YangSchemaNode schemaNode) {
+ yangFileStore.remove(getModuleIdentifier(schemaNode));
+ }
+
+ /**
+ * Verifies if class with given name exists.
+ *
+ * @param appName application name
+ * @return true if class exists
+ */
+ boolean verifyClassExistence(String appName) {
+ try {
+ classLoader.loadClass(appName);
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Process notification registration for manager class object.
+ *
+ * @param yangService yang service
+ * @param yangManager yang manager
+ * @param ynhService notification extended service
+ */
+ private void processNotificationRegistration(
+ Class<?> yangService, Object yangManager,
+ YangNotificationExtendedService ynhService) {
+
+ if (yangManager != null && yangManager instanceof ListenerService) {
+ if (verifyNotificationObject(yangService)) {
+ ynhService.registerAsListener(
+ (ListenerService) yangManager);
+ }
+ }
+ }
+
+ /**
+ * Clears database for YSR.
+ */
+ public void flushYsrData() {
+ appObjectStore.clear();
+ yangSchemaStore.clear();
+ yangRootSchemaStoreForNotification.clear();
+ yangSchemaStoreForRootOpParam.clear();
+ yangSchemaStoreForRootInterface.clear();
+ registerClassStore.clear();
+ yangFileStore.clear();
+ }
+
+ /**
+ * Sets class loader of registered class.
+ *
+ * @param classLoader class loader of registered class
+ */
+ void setClassLoader(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+ /**
+ * Process module library for a registered service.
+ *
+ * @param node YANG schema nodes
+ */
+ private void processModuleLibrary(YangNode node) {
+ YangModuleInformation moduleInformation =
+ new DefaultYangModuleInformation(getModuleIdentifier(node),
+ node.getNameSpace());
+ addSubModuleIdentifier(node, (
+ DefaultYangModuleInformation) moduleInformation);
+ //TODO: add feature list to module information.
+ ((DefaultYangModuleLibrary) library)
+ .addModuleInformation(moduleInformation);
+ }
+
+ /**
+ * Adds sub module identifier.
+ *
+ * @param node schema node
+ * @param information module information
+ */
+ private void addSubModuleIdentifier(
+ YangSchemaNode node, DefaultYangModuleInformation information) {
+ List<YangInclude> includeList = new ArrayList<>();
+ if (node instanceof YangModule) {
+ includeList = ((YangModule) node).getIncludeList();
+ } else if (node instanceof YangSubModule) {
+ includeList = ((YangSubModule) node).getIncludeList();
+ }
+ for (YangInclude include : includeList) {
+ information.addSubModuleIdentifiers(getModuleIdentifier(
+ include.getIncludedNode()));
+ }
+ }
+
+ /**
+ * Returns module identifier for schema node.
+ *
+ * @param schemaNode schema node
+ * @return module identifier for schema node
+ */
+ private YangModuleIdentifier getModuleIdentifier(
+ YangSchemaNode schemaNode) {
+ return new DefaultYangModuleIdentifier(
+ schemaNode.getName(), getDateInStringFormat(schemaNode));
+ }
+
+ /**
+ * Returns module library.
+ *
+ * @return module library
+ */
+ public YangModuleLibrary getLibrary() {
+ return library;
+ }
+
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/YangSchemaRegistry.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/YangSchemaRegistry.java
new file mode 100644
index 0000000..1812f04
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/YangSchemaRegistry.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ysr;
+
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+import org.onosproject.yms.app.ynh.YangNotificationExtendedService;
+
+/**
+ * Abstraction of entity which provides interfaces to YANG schema registry.
+ */
+public interface YangSchemaRegistry {
+
+ /**
+ * Registers applications to YMS.
+ *
+ * @param managerObject application's object
+ * @param serviceClass service class which needs to be
+ * registered
+ * @param notificationExtendedService notification extended service to
+ * register application object with YNH
+ */
+ void registerApplication(Object managerObject, Class<?> serviceClass,
+ YangNotificationExtendedService
+ notificationExtendedService);
+
+ /**
+ * Unregisters applications to YMS.
+ *
+ * @param managerObject application's object
+ * @param serviceClass service class which needs to be unregistered
+ */
+ void unRegisterApplication(Object managerObject, Class<?> serviceClass);
+
+ /**
+ * Returns application's implementation's class object.
+ *
+ * @param yangSchemaNode application's schema node
+ * @return application's implementation's class object
+ */
+ Object getRegisteredApplication(YangSchemaNode yangSchemaNode);
+
+ /**
+ * Returns YANG schema node using schema name.
+ *
+ * @param schemaName module name.
+ * @return YANG schema node using schema name
+ */
+ YangSchemaNode getYangSchemaNodeUsingSchemaName(String schemaName);
+
+ /**
+ * Returns YANG schema nodes using application name.
+ *
+ * @param appName application's service name
+ * @return YANG schema nodes using application name
+ */
+ YangSchemaNode getYangSchemaNodeUsingAppName(String appName);
+
+ /**
+ * Returns YANG schema nodes using root interface file name.
+ *
+ * @param rootInterfaceFileName name of generated interface file
+ * for root node
+ * @return YANG schema nodes using root interface file name
+ */
+ YangSchemaNode
+ getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ String rootInterfaceFileName);
+
+ /**
+ * Returns YANG schema nodes using root op param file name.
+ *
+ * @param rootOpParamFileName name of generated op param file for root node
+ * @return YANG schema nodes using root op param file name
+ */
+ YangSchemaNode
+ getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ String rootOpParamFileName);
+
+ /**
+ * Returns YANG schema node of root for notifications.
+ *
+ * @param eventSubject event subject
+ * @return YANG schema node of root for notifications
+ */
+ YangSchemaNode getRootYangSchemaNodeForNotification(String eventSubject);
+
+ /**
+ * Returns registered service class.
+ *
+ * @param schemaNode YANG schema node
+ * @param appName application's name
+ * @return registered service class
+ */
+ Class<?> getRegisteredClass(YangSchemaNode schemaNode, String appName);
+
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/YsrAppContext.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/YsrAppContext.java
new file mode 100644
index 0000000..4f076ab
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/YsrAppContext.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ysr;
+
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * Represents registered application's context for YANG schema registry.
+ */
+public class YsrAppContext {
+
+ /**
+ * Current application's YANG schema node.
+ */
+ private YangSchemaNode curNode;
+
+ /**
+ * Current application's YANG schema node with different revision store.
+ */
+ private final ConcurrentMap<String, YangSchemaNode>
+ multiRevisionSchemaNodeStore;
+
+ /**
+ * Current application's object.
+ */
+ private Object appObject;
+
+ /**
+ * Jar file path.
+ */
+ private String jarPath;
+
+ /**
+ * If for current object notification is registered.
+ */
+ private boolean isNotificationRegistered;
+
+ /**
+ * Creates an instance of YANG schema registry application context.
+ */
+ YsrAppContext() {
+ multiRevisionSchemaNodeStore = new ConcurrentHashMap<>();
+ }
+
+ /**
+ * Returns current application's object.
+ *
+ * @return current application's object
+ */
+ Object appObject() {
+ return appObject;
+ }
+
+ /**
+ * Sets current application's object.
+ *
+ * @param appObject current application's object
+ */
+ void appObject(Object appObject) {
+ this.appObject = appObject;
+ }
+
+ /**
+ * Returns current application's YANG schema node.
+ *
+ * @return current application's YANG schema node
+ */
+ YangSchemaNode curNode() {
+ return curNode;
+ }
+
+ /**
+ * Sets current application's schema node.
+ *
+ * @param node current schema's node
+ */
+ void curNode(YangSchemaNode node) {
+ curNode = node;
+ }
+
+ /**
+ * Returns jar file path.
+ *
+ * @return jar file path
+ */
+ String jarPath() {
+ return jarPath;
+ }
+
+ /**
+ * Sets jar file path.
+ *
+ * @param jarPath jar file path
+ */
+ void jarPath(String jarPath) {
+ this.jarPath = jarPath;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(curNode, appObject);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof YsrAppContext) {
+ YsrAppContext that = (YsrAppContext) obj;
+ return Objects.equals(curNode, that.curNode) &&
+ Objects.equals(appObject, that.appObject);
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if for application object notification is registered.
+ *
+ * @return true if for application object notification is registered
+ */
+ boolean isNotificationRegistered() {
+ return isNotificationRegistered;
+ }
+
+ /**
+ * Sets true if for application object notification is registered.
+ *
+ * @param notificationRegistered true if for application object notification is registered
+ */
+ void setNotificationRegistered(boolean notificationRegistered) {
+ isNotificationRegistered = notificationRegistered;
+ }
+
+ /**
+ * Returns YANG schema node store for specific revision.
+ *
+ * @return YANG schema node store for specific revision
+ */
+ Map<String, YangSchemaNode> getYangSchemaNodeForRevisionStore() {
+ return ImmutableMap.copyOf(multiRevisionSchemaNodeStore);
+ }
+
+ /**
+ * Returns a schema node for specific revision from store.
+ *
+ * @param nodeNameWithRevision schema node name for specific revision
+ * @return schema node for specific revision.
+ */
+ YangSchemaNode getSchemaNodeForRevisionStore(String nodeNameWithRevision) {
+ return multiRevisionSchemaNodeStore.get(nodeNameWithRevision);
+ }
+
+ /**
+ * Removes a schema node of specific revision from store.
+ *
+ * @param nodeNameWithRevision schema node name for specific revision
+ */
+ void removeSchemaNodeForRevisionStore(String nodeNameWithRevision) {
+ multiRevisionSchemaNodeStore.remove(nodeNameWithRevision);
+ }
+
+ /**
+ * Adds schema node with revision from store.
+ *
+ * @param nodeNameWithRevision schema node name for specific revision
+ * @param schemaNode schema node for specific revision
+ */
+ void addSchemaNodeWithRevisionStore(String nodeNameWithRevision, YangSchemaNode schemaNode) {
+ multiRevisionSchemaNodeStore.put(nodeNameWithRevision, schemaNode);
+ }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/package-info.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/package-info.java
new file mode 100644
index 0000000..2b86091
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Provides implementation of YANG Schema Registry. YSR maintains the schema
+ * information registry corresponding to registered app.
+ */
+package org.onosproject.yms.app.ysr;
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/ysr/DefaultYangSchemaRegistryTest.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/ysr/DefaultYangSchemaRegistryTest.java
new file mode 100644
index 0000000..a4a7f0e
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/ysr/DefaultYangSchemaRegistryTest.java
@@ -0,0 +1,675 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ysr;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network1.rev20151208.IetfNetwork1;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network1.rev20151208.IetfNetwork1OpParam;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network1.rev20151208.IetfNetwork1Service;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network2.rev20151208.IetfNetwork2Service;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+
+import java.io.IOException;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+/**
+ * Unit test case for default schema registry.
+ */
+public class DefaultYangSchemaRegistryTest {
+
+ private static final String SERVICE_NAME_1 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network1.rev20151208.IetfNetwork1Service";
+ private static final String SCHEMA_NAME_1 = "ietf-network1";
+ private static final String EVENT_NAME_1 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network1.rev20151208.ietfnetwork1.IetfNetwork1Event";
+ private static final String INTERFACE_NAME_1 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network1.rev20151208.IetfNetwork1";
+ private static final String OP_PARAM_NAME_1 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network1.rev20151208.IetfNetwork1OpParam";
+
+ private static final String SERVICE_NAME_2 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network2.rev20151208.IetfNetwork2Service";
+ private static final String SCHEMA_NAME_2 = "ietf-network2";
+ private static final String EVENT_NAME_2 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network2.rev20151208.ietfnetwork2.IetfNetwork2Event";
+ private static final String INTERFACE_NAME_2 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network2.rev20151208.IetfNetwork2";
+ private static final String OP_PARAM_NAME_2 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network2.rev20151208.IetfNetwork2OpParam";
+
+ private static final String SERVICE_NAME_3 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network3.rev20151208.IetfNetwork3Service";
+ private static final String SCHEMA_NAME_3 = "ietf-network3";
+ private static final String EVENT_NAME_3 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network3.rev20151208.ietfnetwork3.IetfNetwork3Event";
+ private static final String INTERFACE_NAME_3 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network3.rev20151208.IetfNetwork3";
+ private static final String OP_PARAM_NAME_3 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network3.rev20151208.IetfNetwork3OpParam";
+
+ private static final String SCHEMA_NAME_4 = "ietf-network4";
+ private static final String SERVICE_NAME_REV_14 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20141208.IetfNetwork4Service";
+ private static final String EVENT_NAME_REV_14 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20141208.ietfnetwork4.IetfNetwork4Event";
+ private static final String INTERFACE_NAME_REV_14 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20141208.IetfNetwork4";
+ private static final String OP_PARAM_NAME_REV_14 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20141208.IetfNetwork4OpParam";
+
+ private static final String SERVICE_NAME_REV_15 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20151208.IetfNetwork4Service";
+ private static final String EVENT_NAME_REV_15 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20151208.ietfnetwork4.IetfNetwork4Event";
+ private static final String INTERFACE_NAME_REV_15 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20151208.IetfNetwork4";
+ private static final String OP_PARAM_NAME_REV_15 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20151208.IetfNetwork4OpParam";
+
+ private static final String SERVICE_NAME_REV_16 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20161208.IetfNetwork4Service";
+
+ private static final String EVENT_NAME_REV_16 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20161208.ietfnetwork4.IetfNetwork4Event";
+ private static final String INTERFACE_NAME_REV_16 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20161208.IetfNetwork4";
+ private static final String OP_PARAM_NAME_REV_16 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20161208.IetfNetwork4OpParam";
+
+ private static final String SERVICE_NAME_REV_17 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20171208.IetfNetwork4Service";
+ private static final String EVENT_NAME_REV_17 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20171208.ietfnetwork4.IetfNetwork4Event";
+ private static final String INTERFACE_NAME_REV_17 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20171208.IetfNetwork4";
+ private static final String OP_PARAM_NAME_REV_17 =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.rev20171208.IetfNetwork4OpParam";
+
+ private static final String SERVICE_NAME_NO_REV =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.IetfNetwork4Service";
+ private static final String EVENT_NAME_NO_REV =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.ietfnetwork4.IetfNetwork4Event";
+ private static final String INTERFACE_NAME_NO_REV =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.IetfNetwork4";
+ private static final String OP_PARAM_NAME_NO_REV =
+ "org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf" +
+ ".network4.IetfNetwork4OpParam";
+
+ private static final String DATE = "2014-00-08";
+ private static final String SCHEMA_NAME_WITH_DATE =
+ "ietf-network4@2014-00-08";
+
+ private static final String UN_REG_SCHEMA_NAME = "ietf-routing";
+ private static final String UN_REG_INTERFACE_NAME = "IetfRouting";
+ private static final String UN_REG_OP_PARAM_NAME = "IetfRoutingOpParam";
+ private static final String UN_REG_SERVICE_NAME = "IetfRoutingService";
+ private static final String UN_REG_EVENT_NAME = "IetfRoutingEvent";
+
+ private final TestYangSchemaNodeProvider testYangSchemaNodeProvider =
+ new TestYangSchemaNodeProvider();
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ /**
+ * Unit test case in which schema node should be present.
+ *
+ * @throws IOException when fails to do IO operation
+ */
+ @Test
+ public void testForGetSchemaNode()
+ throws IOException {
+
+ testYangSchemaNodeProvider.processSchemaRegistry(null);
+
+ DefaultYangSchemaRegistry registry =
+ testYangSchemaNodeProvider.getDefaultYangSchemaRegistry();
+
+ YangSchemaNode yangNode =
+ registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_1);
+ assertThat(true, is(SCHEMA_NAME_1.equals(yangNode.getName())));
+
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_1);
+ assertThat(true, is(SCHEMA_NAME_1.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ INTERFACE_NAME_1);
+ assertThat(true, is(SCHEMA_NAME_1.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ OP_PARAM_NAME_1);
+ assertThat(true, is(SCHEMA_NAME_1.equals(yangNode.getName())));
+
+ yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_1);
+ assertThat(true, is(SCHEMA_NAME_1.equals(yangNode.getName())));
+
+ //As we have not registered an application this object should be null.
+ Object object = registry.getRegisteredApplication(yangNode);
+ assertThat(true, is(object == null));
+ testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_1);
+
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_1);
+ assertThat(true, is(yangNode == null));
+
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_1);
+ assertThat(true, is(yangNode == null));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ INTERFACE_NAME_1);
+ assertThat(true, is(yangNode == null));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ OP_PARAM_NAME_1);
+ assertThat(true, is(yangNode == null));
+
+ yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_1);
+ assertThat(true, is(yangNode == null));
+
+ //As we have not registered an application this object should be null.
+ object = registry.getRegisteredApplication(yangNode);
+ assertThat(true, is(object == null));
+
+ //With second service.
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_2);
+ assertThat(true, is(SCHEMA_NAME_2.equals(yangNode.getName())));
+
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_2);
+ assertThat(true, is(SCHEMA_NAME_2.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ INTERFACE_NAME_2);
+ assertThat(true, is(SCHEMA_NAME_2.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ OP_PARAM_NAME_2);
+ assertThat(true, is(SCHEMA_NAME_2.equals(yangNode.getName())));
+
+ yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_2);
+ assertThat(true, is(SCHEMA_NAME_2.equals(yangNode.getName())));
+
+ //As we have not registered an application this object should be null.
+ object = registry.getRegisteredApplication(yangNode);
+ assertThat(true, is(object == null));
+
+ testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_2);
+
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_2);
+ assertThat(true, is(yangNode == null));
+
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_2);
+ assertThat(true, is(yangNode == null));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ INTERFACE_NAME_2);
+ assertThat(true, is(yangNode == null));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ OP_PARAM_NAME_2);
+ assertThat(true, is(yangNode == null));
+
+ yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_2);
+ assertThat(true, is(yangNode == null));
+
+ //As we have not registered an application this object should be null.
+ object = registry.getRegisteredApplication(yangNode);
+ assertThat(true, is(object == null));
+
+ //With third service.
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_3);
+ assertThat(true, is(SCHEMA_NAME_3.equals(yangNode.getName())));
+
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_3);
+ assertThat(true, is(SCHEMA_NAME_3.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ INTERFACE_NAME_3);
+ assertThat(true, is(SCHEMA_NAME_3.equals(yangNode.getName())));
+
+ yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_3);
+ assertThat(true, is(yangNode == null));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ OP_PARAM_NAME_3);
+ assertThat(true, is(SCHEMA_NAME_3.equals(yangNode.getName())));
+
+ //As we have not registered an application this object should be null.
+ object = registry.getRegisteredApplication(yangNode);
+ assertThat(true, is(object == null));
+
+ testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_3);
+
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_3);
+ assertThat(true, is(yangNode == null));
+
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_3);
+ assertThat(true, is(yangNode == null));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ INTERFACE_NAME_3);
+ assertThat(true, is(yangNode == null));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ OP_PARAM_NAME_3);
+ assertThat(true, is(yangNode == null));
+
+ yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_3);
+ assertThat(true, is(yangNode == null));
+
+ //As we have not registered an application this object should be null.
+ object = registry.getRegisteredApplication(yangNode);
+ assertThat(true, is(object == null));
+ }
+
+ /**
+ * Unit test case in which schema node should not be present.
+ *
+ * @throws IOException when fails to do IO operation
+ */
+ @Test
+ public void testForDoNotGetSchemaNode()
+ throws IOException {
+
+ DefaultYangSchemaRegistry registry =
+ testYangSchemaNodeProvider.getDefaultYangSchemaRegistry();
+
+ // here all nodes should be null as we have not done any registration
+ // for this application.
+ YangSchemaNode yangNode =
+ registry.getYangSchemaNodeUsingAppName(UN_REG_SERVICE_NAME);
+ assertThat(true, is(yangNode == null));
+
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(UN_REG_SCHEMA_NAME);
+ assertThat(true, is(yangNode == null));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ UN_REG_INTERFACE_NAME);
+ assertThat(true, is(yangNode == null));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ UN_REG_OP_PARAM_NAME);
+ assertThat(true, is(yangNode == null));
+
+ yangNode = registry.getRootYangSchemaNodeForNotification(
+ UN_REG_EVENT_NAME);
+ assertThat(true, is(yangNode == null));
+
+ //As we have not registered an application this object should be null.
+ Object object = registry.getRegisteredApplication(yangNode);
+ assertThat(true, is(object == null));
+
+ }
+
+ /**
+ * Unit test case in which schema node should be present with multi
+ * revisions.
+ *
+ * @throws IOException when fails to do IO operation
+ */
+ @Test
+ public void testForGetSchemaNodeWhenNoRevision()
+ throws IOException {
+
+ testYangSchemaNodeProvider.processSchemaRegistry(null);
+ DefaultYangSchemaRegistry registry =
+ testYangSchemaNodeProvider.getDefaultYangSchemaRegistry();
+
+ //Service with rev.
+ YangSchemaNode yangNode =
+ registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_15);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ INTERFACE_NAME_REV_15);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ OP_PARAM_NAME_REV_15);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode = registry.getRootYangSchemaNodeForNotification(
+ EVENT_NAME_REV_15);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ //As we have not registered an application this object should be null.
+ Object object = registry.getRegisteredApplication(yangNode);
+ assertThat(true, is(object == null));
+ testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_REV_15);
+
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_15);
+ assertThat(true, is(yangNode == null));
+
+ //Here the yangNode should be the node which does not have revision.
+ // asset should pass with false.
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
+ assertThat(true, is(((YangNode) yangNode).getRevision() != null));
+
+ //Service no revision.
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_NO_REV);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ INTERFACE_NAME_NO_REV);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ OP_PARAM_NAME_NO_REV);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_NO_REV);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ //As we have not registered an application this object should be null.
+ object = registry.getRegisteredApplication(yangNode);
+ assertThat(true, is(object == null));
+ testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_NO_REV);
+
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_NO_REV);
+ assertThat(true, is(yangNode == null));
+
+ //Here the yangNode should be the node which have different revision.
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
+ assertThat(true, is(((YangNode) yangNode).getRevision() != null));
+ }
+
+ /**
+ * Unit test case in which schema node should be present with multi
+ * revisions.
+ *
+ * @throws IOException when fails to do IO operation
+ */
+ @Test
+ public void testForGetSchemaNodeWhenMultiRevision()
+ throws IOException {
+
+ testYangSchemaNodeProvider.processSchemaRegistry(null);
+ DefaultYangSchemaRegistry registry =
+ testYangSchemaNodeProvider.getDefaultYangSchemaRegistry();
+
+ //Service with rev.
+ YangSchemaNode yangNode =
+ registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_15);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ INTERFACE_NAME_REV_15);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ OP_PARAM_NAME_REV_15);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode = registry.getRootYangSchemaNodeForNotification(
+ EVENT_NAME_REV_15);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ //As we have not registered an application this object should be null.
+ Object object = registry.getRegisteredApplication(yangNode);
+ assertThat(true, is(object == null));
+ testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_REV_15);
+
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_15);
+ assertThat(true, is(yangNode == null));
+
+ //Here the yangNode should be the node which does not have revision.
+ // asset should pass with false.
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
+ assertThat(true, is(((YangNode) yangNode).getRevision() != null));
+
+ //Service with different revision.
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_16);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ INTERFACE_NAME_REV_16);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ OP_PARAM_NAME_REV_16);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode = registry.getRootYangSchemaNodeForNotification(EVENT_NAME_REV_16);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ //As we have not registered an application this object should be null.
+ object = registry.getRegisteredApplication(yangNode);
+ assertThat(true, is(object == null));
+ testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_REV_16);
+
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_16);
+ assertThat(true, is(yangNode == null));
+
+ //Here the yangNode should be the node which have different revision.
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
+ assertThat(true, is(((YangNode) yangNode).getRevision() != null));
+
+ //Service with different revision.
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_17);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ INTERFACE_NAME_REV_17);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ OP_PARAM_NAME_REV_17);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode = registry.getRootYangSchemaNodeForNotification(
+ EVENT_NAME_REV_17);
+ assertThat(true, is(yangNode == null));
+
+ //As we have not registered an application this object should be null.
+ object = registry.getRegisteredApplication(yangNode);
+ assertThat(true, is(object == null));
+ testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_REV_17);
+
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_17);
+ assertThat(true, is(yangNode == null));
+
+ //Here the yangNode should be the node which have different revision.
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
+ assertThat(true, is(((YangNode) yangNode).getRevision() == null));
+
+ //Service with different revision.
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_14);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+ INTERFACE_NAME_REV_14);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode =
+ registry.getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+ OP_PARAM_NAME_REV_14);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ yangNode = registry.getRootYangSchemaNodeForNotification(
+ EVENT_NAME_REV_14);
+ assertThat(true, is(SCHEMA_NAME_4.equals(yangNode.getName())));
+
+ //As we have not registered an application this object should be null.
+ object = registry.getRegisteredApplication(yangNode);
+ assertThat(true, is(object == null));
+ testYangSchemaNodeProvider.unregisterService(SERVICE_NAME_REV_14);
+
+ yangNode = registry.getYangSchemaNodeUsingAppName(SERVICE_NAME_REV_14);
+ assertThat(true, is(yangNode == null));
+
+ //Here the yangNode should be the node which does not have revision.
+ // asset should pass with false.
+ yangNode = registry.getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_4);
+ assertThat(true, is(yangNode != null));
+
+ }
+
+ /**
+ * Unit test case should generate exceptions.
+ */
+ @Test
+ public void testRegistration() {
+ thrown.expect(RuntimeException.class);
+ testYangSchemaNodeProvider.processSchemaRegistry(null);
+ testYangSchemaNodeProvider.processRegistrationOfApp();
+ }
+
+ /**
+ * Unit test case should not generate any exceptions and should
+ * return specific revision node.
+ */
+ @Test
+ public void testGetWithSpecificRevision() {
+ testYangSchemaNodeProvider.processSchemaRegistry(null);
+ YangSchemaNode schemaNode = testYangSchemaNodeProvider
+ .getDefaultYangSchemaRegistry()
+ .getYangSchemaNodeUsingSchemaName(SCHEMA_NAME_WITH_DATE);
+
+ assertThat(true, is(schemaNode.getName().equals(SCHEMA_NAME_4)));
+ String date = testYangSchemaNodeProvider
+ .getDefaultYangSchemaRegistry()
+ .getDateInStringFormat(schemaNode);
+ assertThat(true, is(date.equals(DATE)));
+ }
+
+ /**
+ * Unit test case should not generate any exceptions
+ * verify notification should be checked for registration.
+ */
+ @Test
+ public void testNotification() {
+ testYangSchemaNodeProvider.processSchemaRegistry(null);
+ boolean isRegWithNotification =
+ testYangSchemaNodeProvider.getDefaultYangSchemaRegistry()
+ .verifyNotificationObject(IetfNetwork1Service.class);
+ assertThat(true, is(isRegWithNotification));
+ isRegWithNotification = testYangSchemaNodeProvider
+ .getDefaultYangSchemaRegistry()
+ .verifyNotificationObject(IetfNetwork1.class);
+ assertThat(false, is(isRegWithNotification));
+ isRegWithNotification = testYangSchemaNodeProvider
+ .getDefaultYangSchemaRegistry()
+ .verifyNotificationObject(IetfNetwork1OpParam.class);
+ assertThat(false, is(isRegWithNotification));
+ }
+
+ /**
+ * Unit test case should not generate any exceptions.
+ */
+ @Test
+ public void testNotificationRegistrationInYnh() {
+ testYangSchemaNodeProvider.processSchemaRegistry(null);
+ testYangSchemaNodeProvider.getDefaultYangSchemaRegistry()
+ .verifyNotificationObject(IetfNetwork1Service.class);
+ testYangSchemaNodeProvider.getDefaultYangSchemaRegistry()
+ .verifyNotificationObject(IetfNetwork1.class);
+ testYangSchemaNodeProvider.getDefaultYangSchemaRegistry()
+ .verifyNotificationObject(IetfNetwork1OpParam.class);
+
+ boolean isRegWithNotification = testYangSchemaNodeProvider
+ .getDefaultYangSchemaRegistry()
+ .verifyNotificationObject(IetfNetwork2Service.class);
+
+ //Register should work.
+ assertThat(true, is(isRegWithNotification));
+ isRegWithNotification = testYangSchemaNodeProvider
+ .getDefaultYangSchemaRegistry()
+ .verifyNotificationObject(IetfNetwork2Service.class);
+
+ //Re register should not happen
+ assertThat(false, is(isRegWithNotification));
+ }
+
+}
+
+
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/ysr/MockIetfManager.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/ysr/MockIetfManager.java
new file mode 100644
index 0000000..1126cdf
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/ysr/MockIetfManager.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ysr;
+
+import org.onosproject.event.ListenerRegistry;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network2.rev20151208.IetfNetwork2;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network2.rev20151208.IetfNetwork2OpParam;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network2.rev20151208.IetfNetwork2Service;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network2.rev20151208.ietfnetwork2.IetfNetwork2Event;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network2.rev20151208.ietfnetwork2.IetfNetwork2EventListener;
+
+/**
+ * Represent mock implementation for services.
+ */
+public class MockIetfManager
+ extends ListenerRegistry<IetfNetwork2Event, IetfNetwork2EventListener>
+ implements IetfNetwork2Service {
+
+ @Override
+ public IetfNetwork2 getIetfNetwork2(IetfNetwork2OpParam ietfNetwork2) {
+ return null;
+ }
+
+ @Override
+ public void setIetfNetwork2(IetfNetwork2OpParam ietfNetwork2) {
+
+ }
+
+}
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/ysr/TestYangSchemaNodeProvider.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/ysr/TestYangSchemaNodeProvider.java
new file mode 100644
index 0000000..778afd7
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/ysr/TestYangSchemaNodeProvider.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ysr;
+
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network1.rev20151208.IetfNetwork1Service;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+
+import static org.onosproject.yangutils.utils.UtilConstants.PERIOD;
+import static org.onosproject.yangutils.utils.UtilConstants.TEMP;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
+
+/**
+ * Represents mock bundle context. provides bundle context for YSR to do unit
+ * testing.
+ */
+public class TestYangSchemaNodeProvider {
+
+ private static final String FS = File.separator;
+ private static final String PATH = System.getProperty("user.dir") +
+ FS + "target" + FS + "classes" + FS;
+ private static final String SER_FILE_PATH = "yang" + FS + "resources" +
+ FS + "YangMetaData.ser";
+ private static final String TEMP_FOLDER_PATH = PATH + TEMP;
+ private final DefaultYangSchemaRegistry defaultYangSchemaRegistry =
+ new DefaultYangSchemaRegistry("module-id");
+
+ /**
+ * Creates an instance of mock bundle context.
+ */
+ public TestYangSchemaNodeProvider() {
+ }
+
+ /**
+ * Process YANG schema node for a application.
+ *
+ * @param appObject application object
+ */
+ public void processSchemaRegistry(Object appObject) {
+
+ Set<YangSchemaNode> appNode = defaultYangSchemaRegistry
+ .deSerializeDataModel(PATH + SER_FILE_PATH);
+ YsrAppContext appContext = new YsrAppContext();
+ defaultYangSchemaRegistry.ysrContextForSchemaStore(appContext);
+ defaultYangSchemaRegistry
+ .setClassLoader(this.getClass().getClassLoader());
+ String appName;
+ for (YangSchemaNode node : appNode) {
+ defaultYangSchemaRegistry.processApplicationContext(node);
+ defaultYangSchemaRegistry.ysrAppContext().appObject(appObject);
+ defaultYangSchemaRegistry.ysrContextForAppStore()
+ .appObject(appObject);
+ defaultYangSchemaRegistry.ysrContextForSchemaStore()
+ .appObject(appObject);
+ appName = node.getJavaPackage() + PERIOD +
+ getCapitalCase(node.getJavaClassNameOrBuiltInType());
+ storeClasses(appName);
+ }
+
+ try {
+ deleteDirectory(TEMP_FOLDER_PATH);
+ } catch (IOException e) {
+ }
+ }
+
+ /**
+ * Stores test generated class to YSR store.
+ *
+ * @param name name of class
+ */
+ private void storeClasses(String name) {
+ ClassLoader classLoader = this.getClass().getClassLoader();
+ if (getDefaultYangSchemaRegistry().verifyClassExistence(name)) {
+ try {
+ Class<?> nodeClass = classLoader.loadClass(name);
+ getDefaultYangSchemaRegistry().updateServiceClass(nodeClass);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Unregisters services.
+ *
+ * @param appName application name
+ */
+ public void unregisterService(String appName) {
+
+ if (getDefaultYangSchemaRegistry().verifyClassExistence(appName)) {
+ try {
+ Class<?> curClass = Class.forName(appName);
+ getDefaultYangSchemaRegistry()
+ .unRegisterApplication(null, curClass);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Returns schema registry.
+ *
+ * @return schema registry
+ */
+ public DefaultYangSchemaRegistry getDefaultYangSchemaRegistry() {
+ return defaultYangSchemaRegistry;
+ }
+
+ /**
+ * Process registration of a service.
+ */
+ public void processRegistrationOfApp() {
+ getDefaultYangSchemaRegistry()
+ .processRegistration(IetfNetwork1Service.class,
+ new MockIetfManager(), "target");
+
+ }
+
+}
diff --git a/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/norev.yang b/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/norev.yang
new file mode 100644
index 0000000..23eaaba
--- /dev/null
+++ b/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/norev.yang
@@ -0,0 +1,85 @@
+ module ietf-network4 {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network4";
+ prefix nd;
+
+ organization
+ "IETF I2RS (Interface to the Routing System) Working Group";
+
+ contact
+ "WG Web: <http://tools.ietf.org/wg/i2rs/>
+ WG List: <mailto:i2rs@ietf.org>
+
+ WG Chair: Susan Hares
+ <mailto:shares@ndzh.com>
+
+ WG Chair: Jeffrey Haas
+ <mailto:jhaas@pfrc.org>
+
+ Editor: Alexander Clemm
+ <mailto:alex@cisco.com>
+
+ Editor: Jan Medved
+ <mailto:jmedved@cisco.com>
+
+ Editor: Robert Varga
+ <mailto:rovarga@cisco.com>
+
+ Editor: Tony Tkacik
+ <mailto:ttkacik@cisco.com>
+
+ Editor: Nitin Bahadur
+ <mailto:nitin_bahadur@yahoo.com>
+
+ Editor: Hariharan Ananthakrishnan
+ <mailto:hari@packetdesign.com>";
+
+ description
+ "This module defines a common base model for a collection
+ of nodes in a network. Node definitions are further used
+ in network topologies and inventories.
+
+ Copyright (c) 2015 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of
+ draft-ietf-i2rs-yang-network-topo-02;
+ see the RFC itself for full legal notices.
+
+ NOTE TO RFC EDITOR: Please replace above reference to
+ draft-ietf-i2rs-yang-network-topo-02 with RFC
+ number when published (i.e. RFC xxxx).";
+
+ notification network-up {
+ container networks {
+ leaf id {
+ type int32;
+ }
+ container network {
+ leaf ip-address {
+ type int32;
+ }
+ }
+ }
+ }
+ notification network-down {
+ container networks {
+ leaf id {
+ type int32;
+ }
+ container network {
+ leaf ip-address {
+ type int32;
+ }
+ }
+ }
+ }
+
+}
diff --git a/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/withrev.yang b/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/withrev.yang
new file mode 100644
index 0000000..ab0cffa
--- /dev/null
+++ b/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/withrev.yang
@@ -0,0 +1,95 @@
+ module ietf-network4 {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network4";
+ prefix nd;
+
+ organization
+ "IETF I2RS (Interface to the Routing System) Working Group";
+
+ contact
+ "WG Web: <http://tools.ietf.org/wg/i2rs/>
+ WG List: <mailto:i2rs@ietf.org>
+
+ WG Chair: Susan Hares
+ <mailto:shares@ndzh.com>
+
+ WG Chair: Jeffrey Haas
+ <mailto:jhaas@pfrc.org>
+
+ Editor: Alexander Clemm
+ <mailto:alex@cisco.com>
+
+ Editor: Jan Medved
+ <mailto:jmedved@cisco.com>
+
+ Editor: Robert Varga
+ <mailto:rovarga@cisco.com>
+
+ Editor: Tony Tkacik
+ <mailto:ttkacik@cisco.com>
+
+ Editor: Nitin Bahadur
+ <mailto:nitin_bahadur@yahoo.com>
+
+ Editor: Hariharan Ananthakrishnan
+ <mailto:hari@packetdesign.com>";
+
+ description
+ "This module defines a common base model for a collection
+ of nodes in a network. Node definitions are further used
+ in network topologies and inventories.
+
+ Copyright (c) 2015 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of
+ draft-ietf-i2rs-yang-network-topo-02;
+ see the RFC itself for full legal notices.
+
+ NOTE TO RFC EDITOR: Please replace above reference to
+ draft-ietf-i2rs-yang-network-topo-02 with RFC
+ number when published (i.e. RFC xxxx).";
+
+ revision 2015-12-08 {
+ description
+ "Initial revision.
+ NOTE TO RFC EDITOR: Please replace the following reference
+ to draft-ietf-i2rs-yang-network-topo-02 with
+ RFC number when published (i.e. RFC xxxx).";
+ reference
+ "draft-ietf-i2rs-yang-network-topo-02";
+ }
+
+ notification network-up {
+ container networks {
+ leaf id {
+ type int32;
+ }
+ container network {
+ leaf ip-address {
+ type int32;
+ }
+ }
+ }
+ }
+ notification network-down {
+ container networks {
+ leaf id {
+ type int32;
+ }
+ container network {
+ leaf ip-address {
+ type int32;
+ }
+ }
+ }
+ }
+
+}
diff --git a/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/withrev2.yang b/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/withrev2.yang
new file mode 100644
index 0000000..f7c9a16
--- /dev/null
+++ b/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/withrev2.yang
@@ -0,0 +1,95 @@
+ module ietf-network4 {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network4";
+ prefix nd;
+
+ organization
+ "IETF I2RS (Interface to the Routing System) Working Group";
+
+ contact
+ "WG Web: <http://tools.ietf.org/wg/i2rs/>
+ WG List: <mailto:i2rs@ietf.org>
+
+ WG Chair: Susan Hares
+ <mailto:shares@ndzh.com>
+
+ WG Chair: Jeffrey Haas
+ <mailto:jhaas@pfrc.org>
+
+ Editor: Alexander Clemm
+ <mailto:alex@cisco.com>
+
+ Editor: Jan Medved
+ <mailto:jmedved@cisco.com>
+
+ Editor: Robert Varga
+ <mailto:rovarga@cisco.com>
+
+ Editor: Tony Tkacik
+ <mailto:ttkacik@cisco.com>
+
+ Editor: Nitin Bahadur
+ <mailto:nitin_bahadur@yahoo.com>
+
+ Editor: Hariharan Ananthakrishnan
+ <mailto:hari@packetdesign.com>";
+
+ description
+ "This module defines a common base model for a collection
+ of nodes in a network. Node definitions are further used
+ in network topologies and inventories.
+
+ Copyright (c) 2015 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of
+ draft-ietf-i2rs-yang-network-topo-02;
+ see the RFC itself for full legal notices.
+
+ NOTE TO RFC EDITOR: Please replace above reference to
+ draft-ietf-i2rs-yang-network-topo-02 with RFC
+ number when published (i.e. RFC xxxx).";
+
+ revision 2016-12-08 {
+ description
+ "Initial revision.
+ NOTE TO RFC EDITOR: Please replace the following reference
+ to draft-ietf-i2rs-yang-network-topo-02 with
+ RFC number when published (i.e. RFC xxxx).";
+ reference
+ "draft-ietf-i2rs-yang-network-topo-02";
+ }
+
+ notification network-up {
+ container networks {
+ leaf id {
+ type int32;
+ }
+ container network {
+ leaf ip-address {
+ type int32;
+ }
+ }
+ }
+ }
+ notification network-down {
+ container networks {
+ leaf id {
+ type int32;
+ }
+ container network {
+ leaf ip-address {
+ type int32;
+ }
+ }
+ }
+ }
+
+}
diff --git a/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/withrev3.yang b/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/withrev3.yang
new file mode 100644
index 0000000..f4abc06
--- /dev/null
+++ b/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/withrev3.yang
@@ -0,0 +1,95 @@
+ module ietf-network4 {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network4";
+ prefix nd;
+
+ organization
+ "IETF I2RS (Interface to the Routing System) Working Group";
+
+ contact
+ "WG Web: <http://tools.ietf.org/wg/i2rs/>
+ WG List: <mailto:i2rs@ietf.org>
+
+ WG Chair: Susan Hares
+ <mailto:shares@ndzh.com>
+
+ WG Chair: Jeffrey Haas
+ <mailto:jhaas@pfrc.org>
+
+ Editor: Alexander Clemm
+ <mailto:alex@cisco.com>
+
+ Editor: Jan Medved
+ <mailto:jmedved@cisco.com>
+
+ Editor: Robert Varga
+ <mailto:rovarga@cisco.com>
+
+ Editor: Tony Tkacik
+ <mailto:ttkacik@cisco.com>
+
+ Editor: Nitin Bahadur
+ <mailto:nitin_bahadur@yahoo.com>
+
+ Editor: Hariharan Ananthakrishnan
+ <mailto:hari@packetdesign.com>";
+
+ description
+ "This module defines a common base model for a collection
+ of nodes in a network. Node definitions are further used
+ in network topologies and inventories.
+
+ Copyright (c) 2015 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of
+ draft-ietf-i2rs-yang-network-topo-02;
+ see the RFC itself for full legal notices.
+
+ NOTE TO RFC EDITOR: Please replace above reference to
+ draft-ietf-i2rs-yang-network-topo-02 with RFC
+ number when published (i.e. RFC xxxx).";
+
+ revision 2014-12-08 {
+ description
+ "Initial revision.
+ NOTE TO RFC EDITOR: Please replace the following reference
+ to draft-ietf-i2rs-yang-network-topo-02 with
+ RFC number when published (i.e. RFC xxxx).";
+ reference
+ "draft-ietf-i2rs-yang-network-topo-02";
+ }
+
+ notification network-up {
+ container networks {
+ leaf id {
+ type int32;
+ }
+ container network {
+ leaf ip-address {
+ type int32;
+ }
+ }
+ }
+ }
+ notification network-down {
+ container networks {
+ leaf id {
+ type int32;
+ }
+ container network {
+ leaf ip-address {
+ type int32;
+ }
+ }
+ }
+ }
+
+}
diff --git a/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/withrev4.yang b/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/withrev4.yang
new file mode 100644
index 0000000..9352fb4
--- /dev/null
+++ b/apps/yms/app/src/test/resources/ysrTestYangFiles/multiRevisions/withrev4.yang
@@ -0,0 +1,76 @@
+ module ietf-network4 {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network4";
+ prefix nd;
+
+ organization
+ "IETF I2RS (Interface to the Routing System) Working Group";
+
+ contact
+ "WG Web: <http://tools.ietf.org/wg/i2rs/>
+ WG List: <mailto:i2rs@ietf.org>
+
+ WG Chair: Susan Hares
+ <mailto:shares@ndzh.com>
+
+ WG Chair: Jeffrey Haas
+ <mailto:jhaas@pfrc.org>
+
+ Editor: Alexander Clemm
+ <mailto:alex@cisco.com>
+
+ Editor: Jan Medved
+ <mailto:jmedved@cisco.com>
+
+ Editor: Robert Varga
+ <mailto:rovarga@cisco.com>
+
+ Editor: Tony Tkacik
+ <mailto:ttkacik@cisco.com>
+
+ Editor: Nitin Bahadur
+ <mailto:nitin_bahadur@yahoo.com>
+
+ Editor: Hariharan Ananthakrishnan
+ <mailto:hari@packetdesign.com>";
+
+ description
+ "This module defines a common base model for a collection
+ of nodes in a network. Node definitions are further used
+ in network topologies and inventories.
+
+ Copyright (c) 2015 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of
+ draft-ietf-i2rs-yang-network-topo-02;
+ see the RFC itself for full legal notices.
+
+ NOTE TO RFC EDITOR: Please replace above reference to
+ draft-ietf-i2rs-yang-network-topo-02 with RFC
+ number when published (i.e. RFC xxxx).";
+
+ revision 2017-12-08 {
+ description
+ "Initial revision.
+ NOTE TO RFC EDITOR: Please replace the following reference
+ to draft-ietf-i2rs-yang-network-topo-02 with
+ RFC number when published (i.e. RFC xxxx).";
+ reference
+ "draft-ietf-i2rs-yang-network-topo-02";
+ }
+
+ container network {
+ leaf ip {
+ type int32;
+ }
+ }
+
+}
diff --git a/apps/yms/app/src/test/resources/ysrTestYangFiles/withNotification/ysr1.yang b/apps/yms/app/src/test/resources/ysrTestYangFiles/withNotification/ysr1.yang
new file mode 100644
index 0000000..a58e99d
--- /dev/null
+++ b/apps/yms/app/src/test/resources/ysrTestYangFiles/withNotification/ysr1.yang
@@ -0,0 +1,95 @@
+ module ietf-network1 {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network1";
+ prefix nd;
+
+ organization
+ "IETF I2RS (Interface to the Routing System) Working Group";
+
+ contact
+ "WG Web: <http://tools.ietf.org/wg/i2rs/>
+ WG List: <mailto:i2rs@ietf.org>
+
+ WG Chair: Susan Hares
+ <mailto:shares@ndzh.com>
+
+ WG Chair: Jeffrey Haas
+ <mailto:jhaas@pfrc.org>
+
+ Editor: Alexander Clemm
+ <mailto:alex@cisco.com>
+
+ Editor: Jan Medved
+ <mailto:jmedved@cisco.com>
+
+ Editor: Robert Varga
+ <mailto:rovarga@cisco.com>
+
+ Editor: Tony Tkacik
+ <mailto:ttkacik@cisco.com>
+
+ Editor: Nitin Bahadur
+ <mailto:nitin_bahadur@yahoo.com>
+
+ Editor: Hariharan Ananthakrishnan
+ <mailto:hari@packetdesign.com>";
+
+ description
+ "This module defines a common base model for a collection
+ of nodes in a network. Node definitions are further used
+ in network topologies and inventories.
+
+ Copyright (c) 2015 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of
+ draft-ietf-i2rs-yang-network-topo-02;
+ see the RFC itself for full legal notices.
+
+ NOTE TO RFC EDITOR: Please replace above reference to
+ draft-ietf-i2rs-yang-network-topo-02 with RFC
+ number when published (i.e. RFC xxxx).";
+
+ revision 2015-12-08 {
+ description
+ "Initial revision.
+ NOTE TO RFC EDITOR: Please replace the following reference
+ to draft-ietf-i2rs-yang-network-topo-02 with
+ RFC number when published (i.e. RFC xxxx).";
+ reference
+ "draft-ietf-i2rs-yang-network-topo-02";
+ }
+
+ notification network-up {
+ container networks {
+ leaf id {
+ type int32;
+ }
+ container network {
+ leaf ip-address {
+ type int32;
+ }
+ }
+ }
+ }
+ notification network-down {
+ container networks {
+ leaf id {
+ type int32;
+ }
+ container network {
+ leaf ip-address {
+ type int32;
+ }
+ }
+ }
+ }
+
+}
diff --git a/apps/yms/app/src/test/resources/ysrTestYangFiles/withNotification/ysr2.yang b/apps/yms/app/src/test/resources/ysrTestYangFiles/withNotification/ysr2.yang
new file mode 100644
index 0000000..c241068
--- /dev/null
+++ b/apps/yms/app/src/test/resources/ysrTestYangFiles/withNotification/ysr2.yang
@@ -0,0 +1,95 @@
+ module ietf-network2 {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network2";
+ prefix nd;
+
+ organization
+ "IETF I2RS (Interface to the Routing System) Working Group";
+
+ contact
+ "WG Web: <http://tools.ietf.org/wg/i2rs/>
+ WG List: <mailto:i2rs@ietf.org>
+
+ WG Chair: Susan Hares
+ <mailto:shares@ndzh.com>
+
+ WG Chair: Jeffrey Haas
+ <mailto:jhaas@pfrc.org>
+
+ Editor: Alexander Clemm
+ <mailto:alex@cisco.com>
+
+ Editor: Jan Medved
+ <mailto:jmedved@cisco.com>
+
+ Editor: Robert Varga
+ <mailto:rovarga@cisco.com>
+
+ Editor: Tony Tkacik
+ <mailto:ttkacik@cisco.com>
+
+ Editor: Nitin Bahadur
+ <mailto:nitin_bahadur@yahoo.com>
+
+ Editor: Hariharan Ananthakrishnan
+ <mailto:hari@packetdesign.com>";
+
+ description
+ "This module defines a common base model for a collection
+ of nodes in a network. Node definitions are further used
+ in network topologies and inventories.
+
+ Copyright (c) 2015 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of
+ draft-ietf-i2rs-yang-network-topo-02;
+ see the RFC itself for full legal notices.
+
+ NOTE TO RFC EDITOR: Please replace above reference to
+ draft-ietf-i2rs-yang-network-topo-02 with RFC
+ number when published (i.e. RFC xxxx).";
+
+ revision 2015-12-08 {
+ description
+ "Initial revision.
+ NOTE TO RFC EDITOR: Please replace the following reference
+ to draft-ietf-i2rs-yang-network-topo-02 with
+ RFC number when published (i.e. RFC xxxx).";
+ reference
+ "draft-ietf-i2rs-yang-network-topo-02";
+ }
+
+ notification network-up {
+ container networks {
+ leaf id {
+ type int32;
+ }
+ container network {
+ leaf ip-address {
+ type int32;
+ }
+ }
+ }
+ }
+ notification network-down {
+ container networks {
+ leaf id {
+ type int32;
+ }
+ container network {
+ leaf ip-address {
+ type int32;
+ }
+ }
+ }
+ }
+
+}
diff --git a/apps/yms/app/src/test/resources/ysrTestYangFiles/withoutNotification/ysr3.yang b/apps/yms/app/src/test/resources/ysrTestYangFiles/withoutNotification/ysr3.yang
new file mode 100644
index 0000000..0e86062
--- /dev/null
+++ b/apps/yms/app/src/test/resources/ysrTestYangFiles/withoutNotification/ysr3.yang
@@ -0,0 +1,81 @@
+ module ietf-network3 {
+ yang-version 1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-network3";
+ prefix nd;
+
+ organization
+ "IETF I2RS (Interface to the Routing System) Working Group";
+
+ contact
+ "WG Web: <http://tools.ietf.org/wg/i2rs/>
+ WG List: <mailto:i2rs@ietf.org>
+
+ WG Chair: Susan Hares
+ <mailto:shares@ndzh.com>
+
+ WG Chair: Jeffrey Haas
+ <mailto:jhaas@pfrc.org>
+
+ Editor: Alexander Clemm
+ <mailto:alex@cisco.com>
+
+ Editor: Jan Medved
+ <mailto:jmedved@cisco.com>
+
+ Editor: Robert Varga
+ <mailto:rovarga@cisco.com>
+
+ Editor: Tony Tkacik
+ <mailto:ttkacik@cisco.com>
+
+ Editor: Nitin Bahadur
+ <mailto:nitin_bahadur@yahoo.com>
+
+ Editor: Hariharan Ananthakrishnan
+ <mailto:hari@packetdesign.com>";
+
+ description
+ "This module defines a common base model for a collection
+ of nodes in a network. Node definitions are further used
+ in network topologies and inventories.
+
+ Copyright (c) 2015 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of
+ draft-ietf-i2rs-yang-network-topo-02;
+ see the RFC itself for full legal notices.
+
+ NOTE TO RFC EDITOR: Please replace above reference to
+ draft-ietf-i2rs-yang-network-topo-02 with RFC
+ number when published (i.e. RFC xxxx).";
+
+ revision 2015-12-08 {
+ description
+ "Initial revision.
+ NOTE TO RFC EDITOR: Please replace the following reference
+ to draft-ietf-i2rs-yang-network-topo-02 with
+ RFC number when published (i.e. RFC xxxx).";
+ reference
+ "draft-ietf-i2rs-yang-network-topo-02";
+ }
+
+ container networks {
+ leaf id {
+ type int32;
+ }
+ container network {
+ leaf ip-address {
+ type int32;
+ }
+ }
+ }
+
+}