YANG live compiler implementation
Change-Id: Ie8dde5ff0c5e338e294a239180dd25800da045d2
diff --git a/apps/yang/BUCK b/apps/yang/BUCK
index 0a4f8d8..6bc5f06 100644
--- a/apps/yang/BUCK
+++ b/apps/yang/BUCK
@@ -1,37 +1,44 @@
COMPILE_DEPS = [
- '//lib:CORE_DEPS',
- '//lib:onos-yang-model',
- '//lib:onos-yang-compiler-api',
- '//lib:onos-yang-runtime',
- '//lib:onos-yang-serializers-json',
- '//lib:onos-yang-serializers-xml',
- '//lib:onos-yang-serializers-utils',
- '//lib:org.apache.servicemix.bundles.dom4j',
+ '//lib:CORE_DEPS',
+ '//lib:onos-yang-model',
+ '//lib:onos-yang-compiler-api',
+ '//lib:onos-yang-runtime',
+ '//lib:onos-yang-serializers-json',
+ '//lib:onos-yang-serializers-xml',
+ '//lib:onos-yang-serializers-utils',
+ '//lib:org.apache.servicemix.bundles.dom4j',
]
BUNDLES = [
- ':onos-apps-yang',
- '//lib:onos-yang-model',
- '//lib:onos-yang-compiler-api',
- '//lib:onos-yang-runtime',
- '//lib:onos-yang-serializers-json',
- '//lib:onos-yang-serializers-xml',
- '//lib:onos-yang-serializers-utils',
+ '//lib:onos-yang-model',
+ '//lib:onos-yang-compiler-api',
+ '//lib:onos-yang-runtime',
+ '//lib:onos-yang-serializers-json',
+ '//lib:onos-yang-serializers-xml',
+ '//lib:onos-yang-serializers-utils',
+ '//apps/yang:onos-apps-yang',
+ '//apps/yang/web:onos-apps-yang-web',
]
EXCLUDED_BUNDLES = [
- '//lib:org.apache.servicemix.bundles.dom4j',
+ '//lib:org.apache.servicemix.bundles.dom4j',
]
-osgi_jar (
- deps = COMPILE_DEPS,
+TEST_DEPS = [
+ '//lib:TEST_ADAPTERS',
+ '//utils/osgi:onlab-osgi-tests',
+]
+
+osgi_jar_with_tests(
+ deps = COMPILE_DEPS,
+ test_deps = TEST_DEPS,
)
-onos_app (
- title = 'YANG Compiler and Runtime',
- category = 'Utility',
- url = 'http://onosproject.org',
- description = 'Base application to bring in the YANG libraries and assemble them for other apps to use.',
- included_bundles = BUNDLES,
- excluded_bundles = EXCLUDED_BUNDLES,
+onos_app(
+ title = 'YANG Compiler and Runtime',
+ category = 'Utility',
+ url = 'http://onosproject.org',
+ description = 'Base application to bring in the YANG libraries and assemble them for other apps to use.',
+ included_bundles = BUNDLES,
+ excluded_bundles = EXCLUDED_BUNDLES,
)
\ No newline at end of file
diff --git a/apps/yang/pom.xml b/apps/yang/pom.xml
deleted file mode 100644
index 743899f..0000000
--- a/apps/yang/pom.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>onos-apps</artifactId>
- <groupId>org.onosproject</groupId>
- <version>1.10.0-SNAPSHOT</version>
- </parent>
- <artifactId>onos-app-yang</artifactId>
- <packaging>bundle</packaging>
- <description>Onos Yang Extension</description>
- <properties>
- <onos.app.name>org.onosproject.yang</onos.app.name>
- <onos.app.category>Utility</onos.app.category>
- <onos.app.title>Onos Yang Extension</onos.app.title>
- <onos.app.url>http://onosproject.org</onos.app.url>
- <onos.app.readme>Onos Yang Extension.</onos.app.readme>
- <yang.version>1.12.0-b6</yang.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-yang-model</artifactId>
- <version>${yang.version}</version>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-yang-compiler-api</artifactId>
- <version>${yang.version}</version>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-yang-runtime</artifactId>
- <version>${yang.version}</version>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-yang-serializers-json</artifactId>
- <version>${yang.version}</version>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-yang-serializers-xml</artifactId>
- <version>${yang.version}</version>
- </dependency>
- </dependencies>
-</project>
\ No newline at end of file
diff --git a/apps/yang/src/main/java/org/onosproject/yang/YangLiveCompilerManager.java b/apps/yang/src/main/java/org/onosproject/yang/YangLiveCompilerManager.java
index 7bd6f98..322bd94 100644
--- a/apps/yang/src/main/java/org/onosproject/yang/YangLiveCompilerManager.java
+++ b/apps/yang/src/main/java/org/onosproject/yang/YangLiveCompilerManager.java
@@ -45,12 +45,10 @@
private final Logger log = LoggerFactory.getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
- private YangCompilerService compilerService;
@Activate
public void activate() {
coreService.registerApplication(APP_ID);
- // TODO implementation.
log.info("Started");
}
@@ -59,11 +57,11 @@
log.info("Stopped");
}
-
@Override
public YangCompiledOutput compileYangFiles(YangCompilationParam param)
throws IOException, YangCompilerException {
- // TODO implementation.
+ // TODO : uncomment when yang tools new version is released.
+ //return new YangCompilerManager().compileYangFiles(param);
return null;
}
}
diff --git a/apps/yang/web/BUCK b/apps/yang/web/BUCK
new file mode 100644
index 0000000..e6a782f
--- /dev/null
+++ b/apps/yang/web/BUCK
@@ -0,0 +1,21 @@
+COMPILE_DEPS = [
+ '//lib:CORE_DEPS',
+ '//lib:javax.ws.rs-api',
+ '//utils/rest:onlab-rest',
+ '//lib:jersey-media-multipart',
+ '//lib:onos-yang-model',
+ '//lib:onos-yang-compiler-api',
+ '//lib:onos-yang-runtime',
+]
+
+TEST_DEPS = [
+ '//lib:TEST_REST',
+ '//utils/osgi:onlab-osgi-tests',
+ '//web/api:onos-rest-tests',
+]
+
+osgi_jar_with_tests(
+ deps = COMPILE_DEPS,
+ test_deps = TEST_DEPS,
+ web_context = '/onos/yang',
+)
diff --git a/apps/yang/web/src/main/java/org/onosproject/yang/web/YangWebApplication.java b/apps/yang/web/src/main/java/org/onosproject/yang/web/YangWebApplication.java
new file mode 100644
index 0000000..76023b4
--- /dev/null
+++ b/apps/yang/web/src/main/java/org/onosproject/yang/web/YangWebApplication.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017-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.yang.web;
+
+import org.onlab.rest.AbstractWebApplication;
+
+import java.util.Set;
+
+/**
+ * YANG rest api web application.
+ */
+public class YangWebApplication extends AbstractWebApplication {
+ @Override
+ public Set<Class<?>> getClasses() {
+ return getClasses(YangWebResource.class);
+ }
+}
+
diff --git a/apps/yang/web/src/main/java/org/onosproject/yang/web/YangWebResource.java b/apps/yang/web/src/main/java/org/onosproject/yang/web/YangWebResource.java
new file mode 100644
index 0000000..bfe2bfe
--- /dev/null
+++ b/apps/yang/web/src/main/java/org/onosproject/yang/web/YangWebResource.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2017-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.yang.web;
+
+import org.apache.commons.io.IOUtils;
+import org.glassfish.jersey.media.multipart.FormDataBodyPart;
+import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
+import org.glassfish.jersey.media.multipart.FormDataMultiPart;
+import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.yang.compiler.api.YangCompilationParam;
+import org.onosproject.yang.compiler.api.YangCompilerService;
+import org.onosproject.yang.compiler.datamodel.YangNode;
+import org.onosproject.yang.model.YangModel;
+import org.onosproject.yang.runtime.DefaultModelRegistrationParam;
+import org.onosproject.yang.runtime.ModelRegistrationParam;
+import org.onosproject.yang.runtime.YangModelRegistry;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.deSerializeDataModel;
+import static org.onosproject.yang.compiler.utils.io.impl.YangIoUtils.deleteDirectory;
+import static org.onosproject.yang.runtime.helperutils.YangApacheUtils.processYangModel;
+
+//import org.onosproject.yang.compiler.tool.DefaultYangCompilationParam;
+
+/**
+ * Yang files upload resource.
+ */
+@Path("live-compiler")
+public class YangWebResource extends AbstractWebResource {
+ private static final String YANG_FILE_EXTENSION = ".yang";
+ private static final String SER_FILE_EXTENSION = ".ser";
+ private static final String REGISTER = "register";
+ private static final String UNREGISTER = "unregister";
+ private static final String CODE_GEN_DIR = "target/generated-sources/";
+ private static final String META_DATA_DIR = "target/yang/resources/";
+ private static final String SERIALIZED_FILE_NAME = "YangMetaData.ser";
+ private static final String UNKNOWN_KEY = "Key must be either register " +
+ "or unregister.";
+
+ /**
+ * Compiles and registers the given yang files.
+ *
+ * @param formData YANG files or ser files
+ * @return 200 OK
+ * @throws IOException when fails to generate a file
+ */
+ @Path("upload")
+ @POST
+ @Consumes(MediaType.MULTIPART_FORM_DATA)
+ public Response upload(FormDataMultiPart formData) throws IOException {
+ Map<String, List<File>> input = parseInputData(formData);
+
+ for (Map.Entry<String, List<File>> entry : input.entrySet()) {
+ deleteDirectory(CODE_GEN_DIR);
+ deleteDirectory(META_DATA_DIR);
+
+ YangCompilerService liveCompiler = get(YangCompilerService.class);
+ liveCompiler.compileYangFiles(createCompilationParam(
+ entry.getValue()));
+
+ YangModelRegistry modelRegistry = get(YangModelRegistry.class);
+ String key = entry.getKey();
+ if (key.equalsIgnoreCase(REGISTER)) {
+ modelRegistry.registerModel(getModelRegParam());
+ } else if (key.equalsIgnoreCase(UNREGISTER)) {
+ modelRegistry.unregisterModel(getModelRegParam());
+ } else {
+ return Response.serverError().entity(UNKNOWN_KEY).build();
+ }
+ }
+
+ // TODO : create bundles
+
+ return Response.status(200).build();
+ }
+
+ private File getInputFile(InputStream stream, String fileName)
+ throws IOException {
+ byte[] content = IOUtils.toByteArray(stream);
+ File file = new File(fileName);
+ if (!file.exists()) {
+ file.createNewFile();
+ }
+ FileOutputStream fop = new FileOutputStream(file);
+ fop.write(content);
+ fop.flush();
+ fop.close();
+ return file;
+ }
+
+ private Map<String, List<File>> parseInputData(FormDataMultiPart formData)
+ throws IOException {
+ Map<String, List<File>> input = new HashMap<>();
+ Map<String, List<FormDataBodyPart>> fieldsByName = formData.getFields();
+ for (Map.Entry<String, List<FormDataBodyPart>> entry :
+ fieldsByName.entrySet()) {
+ List<File> inputFiles = new LinkedList<>();
+ for (FormDataBodyPart field : entry.getValue()) {
+ InputStream stream = field.getEntityAs(InputStream.class);
+ FormDataContentDisposition content = field
+ .getFormDataContentDisposition();
+ String fileName = content.getFileName();
+ inputFiles.add(getInputFile(stream, fileName));
+ }
+ input.put(entry.getKey(), inputFiles);
+ }
+ return input;
+ }
+
+ private YangCompilationParam createCompilationParam(List<File> inputFiles)
+ throws IOException {
+ // TODO : uncomment when yang tools new verison is released.
+ /*YangCompilationParam param = new DefaultYangCompilationParam();
+ for (File file : inputFiles) {
+ if (file.getName().endsWith(YANG_FILE_EXTENSION)) {
+ param.addYangFile(Paths.get(file.getAbsolutePath()));
+ } else if (file.getName().endsWith(SER_FILE_EXTENSION)) {
+ param.addDependentSchema(Paths.get(file.getAbsolutePath()));
+ }
+ }
+ param.setCodeGenDir(Paths.get(CODE_GEN_DIR));
+ param.setMetadataGenDir(Paths.get(META_DATA_DIR));
+ return param;*/
+ return null;
+ }
+
+ private ModelRegistrationParam getModelRegParam() throws IOException {
+ String metaPath = META_DATA_DIR + SERIALIZED_FILE_NAME;
+ List<YangNode> curNodes = getYangNodes(metaPath);
+ if (curNodes != null && !curNodes.isEmpty()) {
+ YangModel model = processYangModel(metaPath, curNodes);
+ return DefaultModelRegistrationParam.builder()
+ .setYangModel(model).build();
+ }
+ return null;
+ }
+
+ private List<YangNode> getYangNodes(String path) throws IOException {
+ List<YangNode> nodes = new LinkedList<YangNode>();
+ File file = new File(path);
+ if (file.getName().endsWith(SER_FILE_EXTENSION)) {
+ nodes.addAll(deSerializeDataModel(file.toString()));
+ }
+ return nodes;
+ }
+}
diff --git a/apps/yang/web/src/main/java/org/onosproject/yang/web/package-info.java b/apps/yang/web/src/main/java/org/onosproject/yang/web/package-info.java
new file mode 100644
index 0000000..a4b0b3e
--- /dev/null
+++ b/apps/yang/web/src/main/java/org/onosproject/yang/web/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * YANG web to obtain YANG via REST and provide it to live compiler.
+ */
+package org.onosproject.yang.web;
\ No newline at end of file
diff --git a/apps/yang/web/src/main/webapp/WEB-INF/web.xml b/apps/yang/web/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..ae8c3c1
--- /dev/null
+++ b/apps/yang/web/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2017-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.
+ -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ id="ONOS" version="2.5">
+ <display-name>YANG LIVE COMPILER REST API v1.0</display-name>
+
+ <servlet>
+ <servlet-name>JAX-RS Service</servlet-name>
+ <servlet-class>org.glassfish.jersey.servlet.ServletContainer
+ </servlet-class>
+ <init-param>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.onosproject.yang.web.YangWebApplication
+ </param-value>
+ </init-param>
+ <init-param>
+ <param-name>jersey.config.server.provider.classnames</param-name>
+ <param-value>
+ org.glassfish.jersey.filter.LoggingFilter,
+ org.glassfish.jersey.media.multipart.MultiPartFeature,
+ org.onosproject.yang.web.YangWebApplication
+ </param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>JAX-RS Service</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+</web-app>