diff --git a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/plugin/manager/YangPluginUtils.java b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/plugin/manager/YangPluginUtils.java index ef218d5a96..ccb43e35f2 100644 --- a/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/plugin/manager/YangPluginUtils.java +++ b/utils/yangutils/plugin/src/main/java/org/onosproject/yangutils/plugin/manager/YangPluginUtils.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; + import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.model.Dependency; import org.apache.maven.model.Resource; @@ -192,8 +193,9 @@ public final class YangPluginUtils { StringBuilder path = new StringBuilder(); List jarPaths = new ArrayList<>(); - for (Dependency dependency : project.getDependencies()) { + for (Object obj : project.getDependencies()) { + Dependency dependency = (Dependency) obj; path.append(localRepository.getBasedir()); path.append(SLASH); path.append(getPackageDirPathFromJavaJPackage(dependency.getGroupId())); diff --git a/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/InterJarLinkerTest.java b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/InterJarLinkerTest.java new file mode 100644 index 0000000000..5efc477f16 --- /dev/null +++ b/utils/yangutils/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/InterJarLinkerTest.java @@ -0,0 +1,353 @@ +/* + * 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.yangutils.plugin.manager; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.project.MavenProject; +import org.junit.Test; +import org.onosproject.yangutils.datamodel.YangContainer; +import org.onosproject.yangutils.datamodel.YangDerivedInfo; +import org.onosproject.yangutils.datamodel.YangGrouping; +import org.onosproject.yangutils.datamodel.YangLeaf; +import org.onosproject.yangutils.datamodel.YangNode; +import org.onosproject.yangutils.utils.io.impl.YangFileScanner; +import org.onosproject.yangutils.utils.io.impl.YangPluginConfig; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED; +import static org.onosproject.yangutils.datamodel.YangDataTypes.STRING; +import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED; +import static org.onosproject.yangutils.plugin.manager.YangPluginUtils.deSerializeDataModel; +import static org.onosproject.yangutils.plugin.manager.YangPluginUtils.parseJarFile; +import static org.onosproject.yangutils.plugin.manager.YangPluginUtils.serializeDataModel; +import static org.onosproject.yangutils.utils.UtilConstants.SLASH; +import static org.onosproject.yangutils.utils.UtilConstants.TEMP; +import static org.onosproject.yangutils.utils.UtilConstants.YANG_RESOURCES; +import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory; + +/** + * Unit test case for inter jar linker. + */ +public class InterJarLinkerTest { + + private final YangUtilManager utilManager = new YangUtilManager(); + + private static final String TARGET = "target/interJarFileLinking/"; + private static final String YANG_FILES_DIR = "src/test/resources/interJarFileLinking/yangFiles/"; + private static final String TARGET_RESOURCE_PATH = SLASH + TEMP + SLASH + YANG_RESOURCES + SLASH; + private static final String JAR_FILE_NAME = "onlab-test-1.7.0-SNAPSHOT.jar"; + private static final String SER_FILE_NAME = "portPair.ser"; + + private static final String FLOW_CLASSIFIER_FOLDER = "target/interJarFileLinking/org/onosproject" + + "/yang/gen/v1/sfc/flowclassifier/rev20160524"; + private static final String PORT_PAIR_FOLDER = "target/interJarFileLinking/org/onosproject" + + "/yang/gen/v1/sfc/portpair/rev20160524"; + private static final String FLOW_CLASSIFIER_MANAGER = FLOW_CLASSIFIER_FOLDER + SLASH + "FlowClassifierManager.java"; + + /** + * Unit test case for a single jar dependency. + * + * @throws IOException when fails to do IO operations + * @throws MojoExecutionException when fails to do mojo operations + */ + @Test + public void processSingleJarLinking() + throws IOException, MojoExecutionException { + utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(YANG_FILES_DIR)); + + int size1 = utilManager.getYangFileInfoSet().size(); + utilManager.parseYangFileInfoSet(); + + provideTestJarFile(); + utilManager.setYangFileInfoSet(removeFileInfoFromSet(utilManager.getYangFileInfoSet())); + + for (String file : getListOfTestJar(TARGET)) { + addInterJarRootNodes(file); + } + + utilManager.resolveDependenciesUsingLinker(); + + int size2 = utilManager.getYangFileInfoSet().size(); + assertThat(true, is(size1 != size2)); + assertThat(true, is(parseFileInfoSet(utilManager.getYangFileInfoSet().iterator()))); + + deleteDirectory(TARGET); + deleteTestSerFile(); + } + + /** + * Unit test case for a multiple jar dependency. + * + * @throws IOException when fails to do IO operations + * @throws MojoExecutionException when fails to do mojo operations + */ + @Test + public void processMultipleJarLinking() + throws IOException, MojoExecutionException { + utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(YANG_FILES_DIR)); + + int size1 = utilManager.getYangFileInfoSet().size(); + utilManager.parseYangFileInfoSet(); + + provideTestJarFile(); + utilManager.setYangFileInfoSet(removeFileInfoFromSet(utilManager.getYangFileInfoSet())); + for (String file : getListOfTestJar(TARGET)) { + addInterJarRootNodes(file); + } + + utilManager.resolveDependenciesUsingLinker(); + int size2 = utilManager.getYangFileInfoSet().size(); + assertThat(true, is(size1 != size2)); + assertThat(true, is(parseFileInfoSet(utilManager.getYangFileInfoSet().iterator()))); + assertThat(true, is(parseFileInfoSet(utilManager.getYangFileInfoSet().iterator()))); + + /* + * grouping flow-classifier { + * container flow-classifier { + * leaf id { + * type flow-classifier-id; + * } + * + * leaf tenant-id { + * type port-pair:tenant-id; + * } + * . + * . + * . + * + */ + + Iterator yangFileInfoIterator = utilManager.getYangFileInfoSet().iterator(); + + YangFileInfo yangFileInfo = yangFileInfoIterator.next(); + + while (yangFileInfoIterator.hasNext()) { + if (yangFileInfo.getRootNode().getName().equals("flow-classifier")) { + break; + } + yangFileInfo = yangFileInfoIterator.next(); + } + + YangNode node = yangFileInfo.getRootNode(); + node = node.getChild(); + while (node != null) { + if (node instanceof YangGrouping) { + break; + } + node = node.getNextSibling(); + } + + node = node.getChild(); + ListIterator leafIterator = ((YangContainer) node).getListOfLeaf().listIterator(); + YangLeaf leafInfo = leafIterator.next(); + + assertThat(leafInfo.getName(), is("id")); + assertThat(leafInfo.getDataType().getDataTypeName(), is("flow-classifier-id")); + assertThat(leafInfo.getDataType().getDataType(), is(DERIVED)); + + leafInfo = leafIterator.next(); + + assertThat(leafInfo.getName(), is("tenant-id")); + assertThat(leafInfo.getDataType().getDataType(), is(DERIVED)); + + assertThat(true, is(((YangDerivedInfo) leafInfo.getDataType().getDataTypeExtendedInfo()).getReferredTypeDef() + .getName().equals("tenant-id"))); + + assertThat(leafInfo.getDataType().getResolvableStatus(), is(RESOLVED)); + + YangDerivedInfo derivedInfo = (YangDerivedInfo) leafInfo.getDataType().getDataTypeExtendedInfo(); + + // Check for the effective built-in type. + assertThat(derivedInfo.getEffectiveBuiltInType(), is(STRING)); + + YangPluginConfig yangPluginConfig = new YangPluginConfig(); + yangPluginConfig.setCodeGenDir(TARGET); + + utilManager.translateToJava(utilManager.getYangFileInfoSet(), yangPluginConfig); + + testIfFlowClassifierFilesExists(); + testIfPortPairFileDoesNotExist(); + deleteDirectory(TARGET); + deleteTestSerFile(); + } + + /** + * Test if flow classifier code is generated. + */ + private void testIfFlowClassifierFilesExists() { + File folder = new File(System.getProperty("user.dir") + SLASH + FLOW_CLASSIFIER_FOLDER); + File file = new File(System.getProperty("user.dir") + SLASH + FLOW_CLASSIFIER_MANAGER); + assertThat(true, is(folder.exists())); + assertThat(true, is(file.exists())); + } + + /** + * Tests if port pair code is not generated. + */ + private void testIfPortPairFileDoesNotExist() { + File folder = new File(System.getProperty("user.dir") + SLASH + PORT_PAIR_FOLDER); + assertThat(false, is(folder.exists())); + } + + /** + * Need to remove port-pair YANG file info from the set so , serialized file info can be + * tested. + * + * @param fileInfoSet YANG file info set + * @return updated file info set + */ + private Set removeFileInfoFromSet(Set fileInfoSet) { + String portPairFile = System.getProperty("user.dir") + SLASH + YANG_FILES_DIR + "portpair.yang"; + for (YangFileInfo fileInfo : fileInfoSet) { + if (fileInfo.getYangFileName().equals(portPairFile)) { + fileInfoSet.remove(fileInfo); + return fileInfoSet; + } + } + return fileInfoSet; + } + + /** + * Provides test jar files for linker. + * + * @throws IOException when fails to do IO operations + */ + private void provideTestJarFile() throws IOException { + + MavenProject project = new MavenProject(); + serializeDataModel(TARGET, utilManager.getYangFileInfoSet(), project, false); + createTestJar(); + } + + /** + * Deletes serialized file. + */ + private void deleteTestSerFile() { + File ser = new File(System.getProperty("user.dir") + SLASH + YANG_FILES_DIR + SER_FILE_NAME); + ser.delete(); + } + + /** + * Parses file info list and returns true if file info list contains the serialized file info. + * + * @param yangFileInfoIterator file info list iterator + * @return true if present + */ + private boolean parseFileInfoSet(Iterator yangFileInfoIterator) { + YangFileInfo yangFileInfo = yangFileInfoIterator.next(); + while (yangFileInfoIterator.hasNext()) { + if (yangFileInfo.getRootNode().getName().equals("port-pair")) { + return true; + } else if (yangFileInfo.getRootNode().getName().equals("flow-classifier")) { + return true; + } + yangFileInfo = yangFileInfoIterator.next(); + } + return false; + + } + + /** + * Returns list of test jar files. + * + * @param searchdir search directory + * @return list of test jar files + */ + private List getListOfTestJar(String searchdir) { + List jarFiles = new ArrayList<>(); + + File directory = new File(searchdir + "/"); + File[] files = directory.listFiles(); + + for (File file : files) { + if (!file.isDirectory()) { + jarFiles.add(file.toString()); + } + } + + return jarFiles; + } + + /** + * Adds data model nodes of jar to file info set. + * + * @param jarFile jar file name + * @throws IOException when fails to do IO operations + */ + private void addInterJarRootNodes(String jarFile) throws IOException { + try { + List interJarResolvedNodes = deSerializeDataModel(parseJarFile(jarFile, TARGET)); + + for (YangNode node : interJarResolvedNodes) { + YangFileInfo dependentFileInfo = new YangFileInfo(); + dependentFileInfo.setRootNode(node); + dependentFileInfo.setForTranslator(false); + dependentFileInfo.setYangFileName(node.getName()); + utilManager.getYangFileInfoSet().add(dependentFileInfo); + } + } catch (IOException e) { + throw new IOException("failed to resolve in interjar scenario."); + } + } + + /** + * Creates a temporary test jar files. + */ + private void createTestJar() { + + File file = new File(TARGET + TARGET_RESOURCE_PATH); + File[] files = file.listFiles(); + + String[] source = new String[files.length]; + + for (int i = 0; i < files.length; i++) { + source[i] = files[i].toString(); + } + byte[] buf = new byte[1024]; + + try { + String target = TARGET + JAR_FILE_NAME; + JarOutputStream out = new JarOutputStream(new FileOutputStream(target)); + for (String element : source) { + FileInputStream in = new FileInputStream(element); + out.putNextEntry(new JarEntry(element)); + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + out.closeEntry(); + in.close(); + } + out.close(); + } catch (IOException e) { + } + } + +} diff --git a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/multi/onlab-test1-1.7.0-SNAPSHOT.jar b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/multi/onlab-test1-1.7.0-SNAPSHOT.jar deleted file mode 100644 index 7e8459b90e..0000000000 Binary files a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/multi/onlab-test1-1.7.0-SNAPSHOT.jar and /dev/null differ diff --git a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/multi/onlab-test2-1.7.0-SNAPSHOT.jar b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/multi/onlab-test2-1.7.0-SNAPSHOT.jar deleted file mode 100644 index 22cbdb9e8f..0000000000 Binary files a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/multi/onlab-test2-1.7.0-SNAPSHOT.jar and /dev/null differ diff --git a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/single/onlab-test1-1.7.0-SNAPSHOT.jar b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/single/onlab-test1-1.7.0-SNAPSHOT.jar deleted file mode 100644 index 7e8459b90e..0000000000 Binary files a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/jarFiles/single/onlab-test1-1.7.0-SNAPSHOT.jar and /dev/null differ diff --git a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/flowclassifier.yang b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/flowclassifier.yang new file mode 100644 index 0000000000..0fa3ba1780 --- /dev/null +++ b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/flowclassifier.yang @@ -0,0 +1,175 @@ +module flow-classifier { + + yang-version 1; + + namespace "sfc.flowclassifier"; + + prefix "flow-classifier"; + + import "port-pair" { + prefix "port-pair"; + } + + organization "ON-LAB"; + + description "This submodule defines for flow classifier."; + + revision "2016-05-24" { + description "Initial revision."; + } + + typedef flow-classifier-id { + type port-pair:uuid; + } + + typedef IpPrefix { + type string; + } + + typedef VirtualPortId { + type string; + } + + grouping flow-classifier { + container flow-classifier { + leaf id { + type flow-classifier-id; + } + + leaf tenant-id { + type port-pair:tenant-id; + } + + leaf name { + type string; + } + + leaf description { + type string; + } + + leaf etherType { + type string; + } + + leaf protocol { + type string; + } + + leaf priority { + type int32; + } + + leaf minSrcPortRange { + type int32; + } + + leaf maxSrcPortRange { + type int32; + } + + leaf minDstPortRange { + type int32; + } + + leaf maxDstPortRange { + type int32; + } + + leaf srcIpPrefix { + type IpPrefix; + } + + leaf dstIpPrefix { + type IpPrefix; + } + + leaf srcPort { + type VirtualPortId; + } + + leaf dstPort { + type VirtualPortId; + } + } + } + rpc exists { + input { + leaf id { + type flow-classifier-id; + } + } + output { + leaf is-present { + type boolean; + } + } + } + + rpc get-flow-classifier-count { + + output { + leaf count { + type int32; + } + } + } + + rpc get-flow-classifier { + input { + leaf id { + type flow-classifier-id; + } + } + output { + uses flow-classifier; + } + } + + rpc create-flow-classifier { + input { + uses flow-classifier; + } + output { + leaf is-created { + type boolean; + } + } + } + + rpc update-flow-classifier { + input { + uses flow-classifier; + } + output { + leaf is-updated { + type boolean; + } + } + } + + rpc remove-flow-classifier { + input { + leaf id { + type flow-classifier-id; + } + } + output { + leaf is-removed { + type boolean; + } + } + } + + notification Flow-Classifier-Put { + uses flow-classifier; + } + + notification Flow-Classifier-Delete { + uses flow-classifier; + } + + notification Flow-Classifier-Update { + uses flow-classifier; + } +} diff --git a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/portpair.yang b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/portpair.yang new file mode 100644 index 0000000000..ee67c62f78 --- /dev/null +++ b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/portpair.yang @@ -0,0 +1,137 @@ +module port-pair { + + yang-version 1; + + namespace "sfc.portpair"; + + prefix "port-pair"; + + organization "Huawei india pvt. ltd.."; + + description "This submodule defines for port pair."; + + revision "2016-05-24" { + description "Initial revision."; + } + + typedef uuid { + type string; + } + + typedef port-pair-id { + type uuid; + } + + typedef tenant-id { + type uuid; + } + + grouping port-pair { + container port-pair { + + leaf name { + type string; + } + + leaf id { + type port-pair-id; + } + + leaf tenantIdentifier { + type tenant-id; + } + + leaf description { + type string; + } + + leaf ingress { + type uuid; + } + + leaf egress { + type uuid; + } + } + } + rpc exists { + input { + leaf id { + type port-pair-id; + } + } + output { + leaf is-present { + type boolean; + } + } + } + + rpc get-port-pair-count { + + output { + leaf count { + type int32; + } + } + } + + rpc get-port-pair { + input { + leaf id { + type port-pair-id; + } + } + output { + uses port-pair; + } + } + + rpc create-port-pair { + input { + uses port-pair; + } + output { + leaf is-created { + type boolean; + } + } + } + + rpc update-port-pair { + input { + uses port-pair; + } + output { + leaf is-updated { + type boolean; + } + } + } + + rpc remove-port-pair { + input { + leaf id { + type port-pair-id; + } + } + output { + leaf is-removed { + type boolean; + } + } + } + + + notification port-pair-put { + uses port-pair; + } + + notification port-pair-Delete { + uses port-pair; + } + + notification port-pair-Update { + uses port-pair; + } +} diff --git a/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/test.yang b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/test.yang new file mode 100644 index 0000000000..4e7275c8c1 --- /dev/null +++ b/utils/yangutils/plugin/src/test/resources/interJarFileLinking/yangFiles/test.yang @@ -0,0 +1,29 @@ +module Test { + yang-version 1; + namespace http://huawei.com; + prefix Ant; + container valid { + leaf invalid-interval { + type "uint16"; + units "seconds"; + status current; + reference "RFC 6020"; + } + } + container invalid { + leaf invalid-interval { + type "uint16"; + units "seconds"; + status current; + reference "RFC 6020"; + } + } + container valid2 { + leaf invalid-interval { + type "uint16"; + units "seconds"; + status current; + reference "RFC 6020"; + } + } +}