diff options
Diffstat (limited to 'framework/src/onos/tools')
14 files changed, 130 insertions, 34 deletions
diff --git a/framework/src/onos/tools/build/conf/src/main/resources/onos/checkstyle.xml b/framework/src/onos/tools/build/conf/src/main/resources/onos/checkstyle.xml index e04479c5..fc6757a5 100644 --- a/framework/src/onos/tools/build/conf/src/main/resources/onos/checkstyle.xml +++ b/framework/src/onos/tools/build/conf/src/main/resources/onos/checkstyle.xml @@ -160,7 +160,9 @@ <module name="MemberName"/> <module name="MethodName"/> - <module name="PackageName"/> + <module name="PackageName"> + <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/> + </module> <module name="ParameterName"/> <module name="StaticVariableName"/> <module name="TypeName"/> diff --git a/framework/src/onos/tools/build/onos-build-docs b/framework/src/onos/tools/build/onos-build-docs index 93a73c14..f7d0a0b8 100755 --- a/framework/src/onos/tools/build/onos-build-docs +++ b/framework/src/onos/tools/build/onos-build-docs @@ -34,11 +34,11 @@ rm -fr $ONOS_ROOT/docs/target cd $ONOS_ROOT/docs processPom external.xml -mvn -f aux-external.xml javadoc:aggregate +mvn -f aux-external.xml javadoc:aggregate "$@" cd target && mv site/apidocs $apidocs tar zcf $apidocs.tar.gz $apidocs && cp $apidocs.tar.gz /tmp cd $ONOS_ROOT/docs processPom internal.xml -mvn -f aux-internal.xml javadoc:aggregate +mvn -f aux-internal.xml javadoc:aggregate "$@" diff --git a/framework/src/onos/tools/dev/bash_profile b/framework/src/onos/tools/dev/bash_profile index a0f040a5..b8244a77 100644 --- a/framework/src/onos/tools/dev/bash_profile +++ b/framework/src/onos/tools/dev/bash_profile @@ -67,7 +67,6 @@ alias pub='onos-push-update-bundle' # Short-hand for tailing and searching the ONOS (karaf) log alias tl='$ONOS_ROOT/tools/dev/bin/onos-local-log' -alias ll='less $KARAF_LOG' alias gl='grep $KARAF_LOG --colour=auto -E -e ' function filterLocalLog { diff --git a/framework/src/onos/tools/package/maven-plugin/pom.xml b/framework/src/onos/tools/package/maven-plugin/pom.xml index 54839b11..c2b5d8ae 100644 --- a/framework/src/onos/tools/package/maven-plugin/pom.xml +++ b/framework/src/onos/tools/package/maven-plugin/pom.xml @@ -85,6 +85,11 @@ <artifactId>jackson-annotations</artifactId> <version>2.4.2</version> </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.4</version> + </dependency> </dependencies> <build> diff --git a/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosAppMojo.java b/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosAppMojo.java index bfc6127a..09cf4dd9 100644 --- a/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosAppMojo.java +++ b/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosAppMojo.java @@ -62,6 +62,7 @@ public class OnosAppMojo extends AbstractMojo { private static final String ONOS_APP_NAME = "onos.app.name"; private static final String ONOS_APP_ORIGIN = "onos.app.origin"; + private static final String ONOS_APP_REQUIRES = "onos.app.requires"; private static final String JAR = "jar"; private static final String XML = "xml"; @@ -80,6 +81,7 @@ public class OnosAppMojo extends AbstractMojo { private String name; private String origin; + private String requiredApps; private String version = DEFAULT_VERSION; private String featuresRepo = DEFAULT_FEATURES_REPO; private List<String> artifacts; @@ -160,6 +162,9 @@ public class OnosAppMojo extends AbstractMojo { origin = (String) project.getProperties().get(ONOS_APP_ORIGIN); origin = origin != null ? origin : DEFAULT_ORIGIN; + requiredApps = (String) project.getProperties().get(ONOS_APP_REQUIRES); + requiredApps = requiredApps == null ? "" : requiredApps.replaceAll("[\\s]", ""); + if (appFile.exists()) { loadAppFile(appFile); } else { @@ -338,6 +343,7 @@ public class OnosAppMojo extends AbstractMojo { return string == null ? null : string.replaceAll("\\$\\{onos.app.name\\}", name) .replaceAll("\\$\\{onos.app.origin\\}", origin) + .replaceAll("\\$\\{onos.app.requires\\}", requiredApps) .replaceAll("\\$\\{project.groupId\\}", projectGroupId) .replaceAll("\\$\\{project.artifactId\\}", projectArtifactId) .replaceAll("\\$\\{project.version\\}", projectVersion) diff --git a/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosSwaggerMojo.java b/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosSwaggerMojo.java index ea847459..a75127a3 100644 --- a/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosSwaggerMojo.java +++ b/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosSwaggerMojo.java @@ -18,6 +18,7 @@ package org.onosproject.maven; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.base.Charsets; import com.google.common.io.ByteStreams; import com.google.common.io.Files; import com.thoughtworks.qdox.JavaProjectBuilder; @@ -124,11 +125,13 @@ public class OnosSwaggerMojo extends AbstractMojo { ObjectNode root = initializeRoot(); ArrayNode tags = mapper.createArrayNode(); ObjectNode paths = mapper.createObjectNode(); + ObjectNode definitions = mapper.createObjectNode(); root.set("tags", tags); root.set("paths", paths); + root.set("definitions", definitions); - builder.getClasses().forEach(jc -> processClass(jc, paths, tags)); + builder.getClasses().forEach(jc -> processClass(jc, paths, tags, definitions)); if (paths.size() > 0) { getLog().info("Generating ONOS REST API documentation..."); @@ -172,7 +175,7 @@ public class OnosSwaggerMojo extends AbstractMojo { // Checks whether javaClass has a path tag associated with it and if it does // processes its methods and creates a tag for the class on the root - void processClass(JavaClass javaClass, ObjectNode paths, ArrayNode tags) { + void processClass(JavaClass javaClass, ObjectNode paths, ArrayNode tags, ObjectNode definitions) { // If the class does not have a Path tag then ignore it JavaAnnotation annotation = getPathAnnotation(javaClass); if (annotation == null) { @@ -199,7 +202,7 @@ public class OnosSwaggerMojo extends AbstractMojo { ArrayNode tagArray = mapper.createArrayNode(); tagArray.add(tagPath); - processAllMethods(javaClass, resourcePath, paths, tagArray); + processAllMethods(javaClass, resourcePath, paths, tagArray, definitions); } private JavaAnnotation getPathAnnotation(JavaClass javaClass) { @@ -211,7 +214,7 @@ public class OnosSwaggerMojo extends AbstractMojo { // Checks whether a class's methods are REST methods and then places all the // methods under a specific path into the paths node private void processAllMethods(JavaClass javaClass, String resourcePath, - ObjectNode paths, ArrayNode tagArray) { + ObjectNode paths, ArrayNode tagArray, ObjectNode definitions) { // map of the path to its methods represented by an ObjectNode Map<String, ObjectNode> pathMap = new HashMap<>(); @@ -221,7 +224,7 @@ public class OnosSwaggerMojo extends AbstractMojo { if (name.equals(POST) || name.equals(GET) || name.equals(DELETE) || name.equals(PUT)) { // substring(12) removes "javax.ws.rs." String method = annotation.getType().toString().substring(12).toLowerCase(); - processRestMethod(javaMethod, method, pathMap, resourcePath, tagArray); + processRestMethod(javaMethod, method, pathMap, resourcePath, tagArray, definitions); } }); }); @@ -236,9 +239,10 @@ public class OnosSwaggerMojo extends AbstractMojo { private void processRestMethod(JavaMethod javaMethod, String method, Map<String, ObjectNode> pathMap, - String resourcePath, ArrayNode tagArray) { + String resourcePath, ArrayNode tagArray, ObjectNode definitions) { String fullPath = resourcePath, consumes = "", produces = "", comment = javaMethod.getComment(); + DocletTag tag = javaMethod.getTagByName("rsModel"); for (JavaAnnotation annotation : javaMethod.getAnnotations()) { String name = annotation.getType().getName(); if (name.equals(PATH)) { @@ -256,12 +260,19 @@ public class OnosSwaggerMojo extends AbstractMojo { methodNode.set("tags", tagArray); addSummaryDescriptions(methodNode, comment); - processParameters(javaMethod, methodNode); + addJsonSchemaDefinition(definitions, tag); + addJsonSchemaDefinition(definitions, tag); + + processParameters(javaMethod, methodNode, method, tag); processConsumesProduces(methodNode, "consumes", consumes); processConsumesProduces(methodNode, "produces", produces); - - addResponses(methodNode); + if (tag == null || ((method.toLowerCase().equals("post") || method.toLowerCase().equals("put")) + && !(tag.getParameters().size() > 1))) { + addResponses(methodNode, tag, false); + } else { + addResponses(methodNode, tag, true); + } ObjectNode operations = pathMap.get(fullPath); if (operations == null) { @@ -273,6 +284,24 @@ public class OnosSwaggerMojo extends AbstractMojo { } } + private void addJsonSchemaDefinition(ObjectNode definitions, DocletTag tag) { + File definitionsDirectory = new File(srcDirectory + "/src/main/resources/definitions"); + if (tag != null) { + tag.getParameters().stream().forEach(param -> { + try { + File config = new File(definitionsDirectory.getAbsolutePath() + "/" + + param + ".json"); + String lines = Files.readLines(config, Charsets.UTF_8).stream().reduce((t, u) -> t + u). + get(); + definitions.putPOJO(param, lines); + } catch (IOException e) { + e.printStackTrace(); + } + }); + + } + } + private void processConsumesProduces(ObjectNode methodNode, String type, String io) { if (!io.equals("")) { ArrayNode array = mapper.createArrayNode(); @@ -299,13 +328,19 @@ public class OnosSwaggerMojo extends AbstractMojo { // Temporary solution to add responses to a method // TODO Provide annotations in the web resources for responses and parse them - private void addResponses(ObjectNode methodNode) { + private void addResponses(ObjectNode methodNode, DocletTag tag, boolean responseJson) { ObjectNode responses = mapper.createObjectNode(); methodNode.set("responses", responses); ObjectNode success = mapper.createObjectNode(); success.put("description", "successful operation"); responses.set("200", success); + if (tag != null && responseJson) { + ObjectNode schema = mapper.createObjectNode(); + tag.getParameters().stream().forEach( + param -> schema.put("$ref", "#/definitions/" + param)); + success.set("schema", schema); + } ObjectNode defaultObj = mapper.createObjectNode(); defaultObj.put("description", "Unexpected error"); @@ -329,7 +364,7 @@ public class OnosSwaggerMojo extends AbstractMojo { } // Processes parameters of javaMethod and enters the proper key-values into the methodNode - private void processParameters(JavaMethod javaMethod, ObjectNode methodNode) { + private void processParameters(JavaMethod javaMethod, ObjectNode methodNode, String method, DocletTag tag) { ArrayNode parameters = mapper.createArrayNode(); methodNode.set("parameters", parameters); boolean required = true; @@ -346,7 +381,8 @@ public class OnosSwaggerMojo extends AbstractMojo { if (pathType != null) { //the parameter is a path or query parameter individualParameterNode.put("name", - pathType.getNamedParameter("value").toString().replace("\"", "")); + pathType.getNamedParameter("value") + .toString().replace("\"", "")); if (pathType.getType().getName().equals(PATH_PARAM)) { individualParameterNode.put("in", "path"); } else if (pathType.getType().getName().equals(QUERY_PARAM)) { @@ -357,10 +393,16 @@ public class OnosSwaggerMojo extends AbstractMojo { individualParameterNode.put("name", annotationName); individualParameterNode.put("in", "body"); - // TODO add actual hardcoded schemas and a type - // body parameters must have a schema associated with them - ArrayNode schema = mapper.createArrayNode(); - individualParameterNode.set("schema", schema); + // Adds the reference to the Json model for the input + // that goes in the post or put operation + if (tag != null && (method.toLowerCase().equals("post") || + method.toLowerCase().equals("put"))) { + ObjectNode schema = mapper.createObjectNode(); + tag.getParameters().stream().forEach(param -> { + schema.put("$ref", "#/definitions/" + param); + }); + individualParameterNode.set("schema", schema); + } } for (DocletTag p : javaMethod.getTagsByName("param")) { if (p.getValue().contains(annotationName)) { diff --git a/framework/src/onos/tools/package/maven-plugin/src/main/resources/org/onosproject/maven/app.xml b/framework/src/onos/tools/package/maven-plugin/src/main/resources/org/onosproject/maven/app.xml index 0f3133d3..84998807 100644 --- a/framework/src/onos/tools/package/maven-plugin/src/main/resources/org/onosproject/maven/app.xml +++ b/framework/src/onos/tools/package/maven-plugin/src/main/resources/org/onosproject/maven/app.xml @@ -16,7 +16,7 @@ --> <app name="${onos.app.name}" origin="${onos.app.origin}" version="${project.version}" featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features" - features="${project.artifactId}"> + features="${project.artifactId}" apps="${onos.app.requires}"> <description>${project.description}</description> <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact> </app> diff --git a/framework/src/onos/tools/test/bin/onos-check-apps b/framework/src/onos/tools/test/bin/onos-check-apps index dfd6b4ef..5d83e416 100755 --- a/framework/src/onos/tools/test/bin/onos-check-apps +++ b/framework/src/onos/tools/test/bin/onos-check-apps @@ -24,7 +24,7 @@ for attempt in {1..3}; do # Check for differences case ${3:-equals} in equals) diff $aux.1 $aux.2;; - includes) [ $(egrep -c -f $aux.2 $aux.1) -eq $(wc -l $aux.2 | sed "s|$aux.2||g") ];; + includes) [ $(egrep -c -f $aux.2 $aux.1) -ge $(wc -l $aux.2 | sed "s|$aux.2||g") ];; excludes) ! egrep -f $aux.2 $aux.1;; esac diff --git a/framework/src/onos/tools/test/bin/onos-netcfg b/framework/src/onos/tools/test/bin/onos-netcfg new file mode 100755 index 00000000..23900ecb --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-netcfg @@ -0,0 +1,15 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# ONOS network configuration uploader. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +node="${1:-$OCI}" +file="${2:-$ONOS_ROOT/tools/test/topos/oe-linear-3.json}" +url="${3}" + +curl -sS --fail -L --user $ONOS_WEB_USER:$ONOS_WEB_PASS \ + -X POST -H 'Content-Type:application/json' \ + http://$node:8181/onos/v1/network/configuration/${url} -d@$file diff --git a/framework/src/onos/tools/test/cells/aaron_local_cell b/framework/src/onos/tools/test/cells/aaron_local_cell new file mode 100644 index 00000000..e3b5f734 --- /dev/null +++ b/framework/src/onos/tools/test/cells/aaron_local_cell @@ -0,0 +1,10 @@ +# Local VirtualBox-based ONOS instances 1,2 & ONOS mininet box + +export ONOS_NIC=192.168.56.* +export OC1="192.168.56.101" +export OC2="192.168.56.102" +export OC3="192.168.56.103" +export OCN="192.168.56.100" + +export ONOS_USE_SSH=true +export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility" diff --git a/framework/src/onos/tools/test/scenarios/fast.xml b/framework/src/onos/tools/test/scenarios/fast.xml index 3cfe2c60..0d38c456 100644 --- a/framework/src/onos/tools/test/scenarios/fast.xml +++ b/framework/src/onos/tools/test/scenarios/fast.xml @@ -26,5 +26,5 @@ <dependency name="Archetypes" requires="Setup"/> <import file="${ONOS_SCENARIOS}/wrapup.xml"/> - <dependency name="Wrapup" requires="~Archetypes,~Setup,~Net-Fast"/> + <dependency name="Wrapup" requires="Prerequisites,~Archetypes,~Setup,~Net-Fast"/> </scenario> diff --git a/framework/src/onos/tools/test/scenarios/net-topo.xml b/framework/src/onos/tools/test/scenarios/net-topo.xml index abcf8642..cd720888 100644 --- a/framework/src/onos/tools/test/scenarios/net-topo.xml +++ b/framework/src/onos/tools/test/scenarios/net-topo.xml @@ -38,7 +38,7 @@ <step name="Net-Topo.Verify-Cluster0-LinkCount" requires="Net-Topo.Query-Cluster0" exec="test ${clusterTopo0LinkCount} == 140"/> <step name="Net-Topo.Verify-Cluster0-Root" requires="Net-Topo.Query-Cluster0" - exec="test '${clusterTopo0Root}' == 'of:000000000000000a'"/> + exec="test '${clusterTopo0Root}' == 'of:000000000000000a' -o '${clusterTopo0Root}' == 'of:000000000000000c'"/> <!-- Verify the list of devices for the cluster --> <step name="Net-Topo.Verify-Cluster0-Devices" diff --git a/framework/src/onos/tools/test/scenarios/setup.xml b/framework/src/onos/tools/test/scenarios/setup.xml index c26c0dea..071db8b9 100644 --- a/framework/src/onos/tools/test/scenarios/setup.xml +++ b/framework/src/onos/tools/test/scenarios/setup.xml @@ -40,7 +40,7 @@ <step name="Check-Components-${#}" exec="onos-check-components ${OC#}" requires="~Wait-for-Start-${#},"/> - <step name="Check-Apps-${#}" exec="onos-check-apps ${OC#}" + <step name="Check-Apps-${#}" exec="onos-check-apps ${OC#} ${ONOS_APPS} includes" requires="~Wait-for-Start-${#}"/> </parallel> </group> diff --git a/framework/src/onos/tools/test/topos/opticalUtils.py b/framework/src/onos/tools/test/topos/opticalUtils.py index 5d955e51..87903cc5 100644 --- a/framework/src/onos/tools/test/topos/opticalUtils.py +++ b/framework/src/onos/tools/test/topos/opticalUtils.py @@ -58,7 +58,7 @@ import os from time import sleep import urllib2 -from mininet.node import Switch, RemoteController +from mininet.node import Switch, OVSSwitch, RemoteController from mininet.topo import Topo from mininet.util import quietRun from mininet.net import Mininet @@ -356,8 +356,18 @@ class LINCSwitch(OpticalSwitch): return configDict @staticmethod - def bootOE(net): - "Start the LINC optical emulator within a mininet instance" + def bootOE(net, domain=None): + """ + Start the LINC optical emulator within a mininet instance + + This involves 1. converting the information stored in Linc* to configs + for both LINC and the network config system, 2. starting Linc, 3. connecting + cross-connects, and finally pushing the network configs to ONOS. + + Inevitably, there are times when we have OVS switches that should not be + under the control of the controller in charge of the Linc switches. We + hint at these by passing domain information. + """ LINCSwitch.opticalJSON = {} linkConfig = [] devices = [] @@ -365,9 +375,11 @@ class LINCSwitch(OpticalSwitch): LINCSwitch.controllers = net.controllers for switch in net.switches: + if domain and switch not in domain: + continue if isinstance(switch, OpticalSwitch): devices.append(switch.json()) - else: + elif isinstance(switch, OVSSwitch): devices.append(LINCSwitch.switchJSON(switch)) LINCSwitch.opticalJSON[ 'devices' ] = devices @@ -450,18 +462,21 @@ class LINCSwitch(OpticalSwitch): opener = urllib2.build_opener(handler) opener.open(url) urllib2.install_opener(opener) + # focus on just checking the state of devices we're interested in + devlist = map( lambda x: x['uri'], devices ) while True: response = json.load(urllib2.urlopen(url)) devs = response.get('devices') - # Wait for all devices to be registered - if (len(devices) != len(devs)): + # Wait for all devices to be registered. There is a chance that this is only a subgraph. + if (len(devices) > len(devs)): continue # Wait for all devices to available available = True for d in devs: - available &= d['available'] + if d['id'] in devlist: + available &= d['available'] if available: break @@ -615,9 +630,11 @@ class LINCSwitch(OpticalSwitch): if isinstance(link, LINCLink): if link.annotations[ 'optical.type' ] == 'cross-connect': tapCount += 1 - while True: - if str(tapCount) == quietRun('ip addr | grep tap | wc -l', shell=True).strip('\n'): + # tapCount can be less than the actual number of taps if the optical network + # is a subgraph of a larger multidomain network. + tapNum = int(quietRun('ip addr | grep tap | wc -l', shell=True).strip('\n')) + if tapCount <= tapNum: return True if timeout: if time >= TIMEOUT: |