From: Giovanni Meo Date: Thu, 19 Sep 2013 08:58:20 +0000 (+0000) Subject: Merge "Simple changes to eliminate pmd warnings" X-Git-Tag: releasepom-0.1.0~59 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=3d81902c3f5176bae52be789f57ee461b9d9e158;hp=0007635e8377230bf3befc836f1e05b6e075251b;p=controller.git Merge "Simple changes to eliminate pmd warnings" --- diff --git a/opendaylight/archetypes/odl-model-project/src/main/resources/archetype-resources/pom.xml b/opendaylight/archetypes/odl-model-project/src/main/resources/archetype-resources/pom.xml index b84346514f..ecc08d011d 100644 --- a/opendaylight/archetypes/odl-model-project/src/main/resources/archetype-resources/pom.xml +++ b/opendaylight/archetypes/odl-model-project/src/main/resources/archetype-resources/pom.xml @@ -9,7 +9,7 @@ UTF-8 http://nexus.opendaylight.org/content - 0.5.7-SNAPSHOT + 0.5.8-SNAPSHOT 2.4.0 @@ -56,7 +56,7 @@ org.opendaylight.yangtools yang-maven-plugin - 0.5.7-SNAPSHOT + ${yang.version} @@ -79,7 +79,7 @@ org.opendaylight.yangtools maven-sal-api-gen-plugin - 0.5.7-SNAPSHOT + ${yang.version} jar @@ -136,9 +136,9 @@ - central2 - central2 - http://repo2.maven.org/maven2 + central + maven repo1 + http://repo1.maven.org/maven2 false @@ -168,17 +168,6 @@ ebr-bundles-external ${nexusproxy}/repositories/ebr-bundles-external/ - - central2 - central2 - http://repo2.maven.org/maven2 - - false - - - true - - central central diff --git a/opendaylight/clustering/integrationtest/pom.xml b/opendaylight/clustering/integrationtest/pom.xml index 0fadb12890..63ef24d3b1 100644 --- a/opendaylight/clustering/integrationtest/pom.xml +++ b/opendaylight/clustering/integrationtest/pom.xml @@ -52,7 +52,7 @@ jacoco ../implementation/target/jacoco.exec - ../implementaiton/target/jacoco-it.exec + ../implementation/target/jacoco-it.exec java @@ -69,7 +69,7 @@ org.jacoco jacoco-maven-plugin - 0.5.3.201107060350 + ${jacoco.version} ../implementation/target/jacoco-it.exec org.opendaylight.controller.* diff --git a/opendaylight/clustering/services_implementation/pom.xml b/opendaylight/clustering/services_implementation/pom.xml index c0a8064493..d6bd287434 100644 --- a/opendaylight/clustering/services_implementation/pom.xml +++ b/opendaylight/clustering/services_implementation/pom.xml @@ -30,7 +30,7 @@ org.jacoco jacoco-maven-plugin - 0.5.3.201107060350 + ${jacoco.version} diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index cb1892ae66..31dd741cfd 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -55,13 +55,14 @@ 1.0-SNAPSHOT 2.3.2 3.1 + 0.5.3.201107060350 - central2 - central2 - http://repo2.maven.org/maven2 + central + maven repo1 + http://repo1.maven.org/maven2 @@ -206,17 +207,6 @@ ebr-bundles-external ${nexusproxy}/repositories/ebr-bundles-external/ - - central2 - central2 - http://repo2.maven.org/maven2 - - false - - - true - - central central @@ -438,9 +428,6 @@ org.apache.maven.plugins maven-surefire-plugin ${surefire.version} - - ${testvm.argLine} - diff --git a/opendaylight/connectionmanager/api/src/main/java/org/opendaylight/controller/connectionmanager/ConnectionLocality.java b/opendaylight/connectionmanager/api/src/main/java/org/opendaylight/controller/connectionmanager/ConnectionLocality.java new file mode 100644 index 0000000000..347ca07ec1 --- /dev/null +++ b/opendaylight/connectionmanager/api/src/main/java/org/opendaylight/controller/connectionmanager/ConnectionLocality.java @@ -0,0 +1,28 @@ +package org.opendaylight.controller.connectionmanager; + +public enum ConnectionLocality { + /** + * This controller is the (or one of the) master for a given node + */ + LOCAL("This controller is the (or one of the) master for a given node"), + + /** + * This controller is not the master for a given node + */ + NOT_LOCAL("This controller is not the master for a given node"), + + /** + * The given node is not connected to any of the controllers in the cluster + */ + NOT_CONNECTED("The given node is not connected to any of the controllers in the cluster"); + + private ConnectionLocality(String description) { + this.description = description; + } + + private String description; + + public String toString() { + return description; + } +} diff --git a/opendaylight/connectionmanager/api/src/main/java/org/opendaylight/controller/connectionmanager/IConnectionManager.java b/opendaylight/connectionmanager/api/src/main/java/org/opendaylight/controller/connectionmanager/IConnectionManager.java index 12b196989e..788af16248 100644 --- a/opendaylight/connectionmanager/api/src/main/java/org/opendaylight/controller/connectionmanager/IConnectionManager.java +++ b/opendaylight/connectionmanager/api/src/main/java/org/opendaylight/controller/connectionmanager/IConnectionManager.java @@ -54,12 +54,27 @@ public interface IConnectionManager { public Set getLocalNodes(); /** + * @deprecated Use getLocalityStatus(Node node) instead. + * * Method to test if a node is local to a controller. * - * @return true if node is local to this controller. false otherwise. + * @param node The node for which the locality is being tested + * @return true if node is local to this controller.
+ * false if either node is not connected to this controller or + * not connected to any other controllers in the cluster. */ public boolean isLocal(Node node); + /** + * getLocalityStatus provides the tri-state connectivity status as opposed to the + * binary status returned by isLocal. + * ConnectionLocality enum that is returned by this method also includes the case of + * a Node not connected to any of the controllers in the cluster. + * @param node The node for which the locality is being verified + * @return ConnectionLocality + */ + public ConnectionLocality getLocalityStatus(Node node); + /** * Disconnect a Node from the controller. * diff --git a/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/internal/ConnectionManager.java b/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/internal/ConnectionManager.java index bd377190f2..df5175083b 100644 --- a/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/internal/ConnectionManager.java +++ b/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/internal/ConnectionManager.java @@ -37,6 +37,7 @@ import org.eclipse.osgi.framework.console.CommandProvider; import org.opendaylight.controller.clustering.services.ICacheUpdateAware; import org.opendaylight.controller.clustering.services.IClusterGlobalServices; import org.opendaylight.controller.clustering.services.ICoordinatorChangeAware; +import org.opendaylight.controller.connectionmanager.ConnectionLocality; import org.opendaylight.controller.connectionmanager.ConnectionMgmtScheme; import org.opendaylight.controller.connectionmanager.IConnectionManager; import org.opendaylight.controller.connectionmanager.scheme.AbstractScheme; @@ -185,6 +186,13 @@ public class ConnectionManager implements IConnectionManager, IConnectionListene return scheme.isLocal(node); } + @Override + public ConnectionLocality getLocalityStatus(Node node) { + AbstractScheme scheme = schemes.get(activeScheme); + if (scheme == null) return ConnectionLocality.NOT_CONNECTED; + return scheme.getLocalityStatus(node); + } + @Override public void updateNode(Node node, UpdateType type, Set props) { logger.debug("updateNode: {} type {} props {}", node, type, props); diff --git a/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/AbstractScheme.java b/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/AbstractScheme.java index 06b72219f7..78f274c717 100644 --- a/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/AbstractScheme.java +++ b/opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/AbstractScheme.java @@ -14,6 +14,7 @@ import org.opendaylight.controller.clustering.services.CacheConfigException; import org.opendaylight.controller.clustering.services.CacheExistException; import org.opendaylight.controller.clustering.services.IClusterGlobalServices; import org.opendaylight.controller.clustering.services.IClusterServices; +import org.opendaylight.controller.connectionmanager.ConnectionLocality; import org.opendaylight.controller.connectionmanager.ConnectionMgmtScheme; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.utils.Status; @@ -146,6 +147,15 @@ public abstract class AbstractScheme { return (controllers != null && controllers.contains(myController)); } + public ConnectionLocality getLocalityStatus(Node node) { + if (nodeConnections == null) return ConnectionLocality.NOT_CONNECTED; + Set controllers = nodeConnections.get(node); + if (controllers == null || controllers.size() == 0) return ConnectionLocality.NOT_CONNECTED; + InetAddress myController = clusterServices.getMyAddress(); + return controllers.contains(myController) ? ConnectionLocality.LOCAL: + ConnectionLocality.NOT_LOCAL; + } + public Status removeNode (Node node) { return removeNodeFromController(node, clusterServices.getMyAddress()); } diff --git a/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerConfig.java b/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerConfig.java index a34746949e..89bf424e67 100644 --- a/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerConfig.java +++ b/opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerConfig.java @@ -386,11 +386,38 @@ public class ContainerConfig implements Serializable { config.getName())); } } + } else { + // Check for conflicting names with existing cFlows + List conflicting = new ArrayList(existingNames); + conflicting.retainAll(proposedNames); + if (!conflicting.isEmpty()) { + return new Status(StatusCode.CONFLICT, + "Invalid Flow Spec configuration: flow spec name(s) conflict with existing flow specs: " + + conflicting.toString()); + } + + /* + * Check for conflicting flow spec match (we only check for strict + * equality). Remove this in case (*) is reintroduced + */ + if (this.containerFlows != null && !this.containerFlows.isEmpty()) { + Set existingMatches = new HashSet(); + for (ContainerFlowConfig existing : this.containerFlows) { + existingMatches.addAll(existing.getMatches()); + } + for (ContainerFlowConfig proposed : cFlowConfigs) { + if (existingMatches.removeAll(proposed.getMatches())) { + return new Status(StatusCode.CONFLICT, String.format( + "Invalid Flow Spec configuration: %s conflicts with existing flow spec", + proposed.getName())); + } + } + } } + /* * Revisit the following flow-spec confict validation later based on more testing. - */ - /* + * (*) if (!delete) { // Check for overlapping container flows in the request int size = cFlowConfigs.size(); diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index 1fb131e4af..3efd97e2aa 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -74,7 +74,7 @@ ../../statisticsmanager/api ../../statisticsmanager/implementation ../../statisticsmanager/integrationtest - ../../topologymanager + ../../topologymanager/implementation ../../usermanager/api ../../usermanager/implementation ../../connectionmanager/api diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini index 970929f794..12f18ff645 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini @@ -94,3 +94,6 @@ controllerKeyStore= controllerKeyStorePassword= controllerTrustStore= controllerTrustStorePassword= + +# User Manager configurations +enableStrongPasswordCheck = false diff --git a/opendaylight/forwardingrulesmanager/implementation/pom.xml b/opendaylight/forwardingrulesmanager/implementation/pom.xml index ea55ac8b08..d146eead6f 100644 --- a/opendaylight/forwardingrulesmanager/implementation/pom.xml +++ b/opendaylight/forwardingrulesmanager/implementation/pom.xml @@ -33,7 +33,7 @@ org.jacoco jacoco-maven-plugin - 0.5.3.201107060350 + ${jacoco.version}
diff --git a/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java b/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java index 58d23655ca..6e3e6b6633 100644 --- a/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java +++ b/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java @@ -39,6 +39,7 @@ import org.opendaylight.controller.clustering.services.ICacheUpdateAware; import org.opendaylight.controller.clustering.services.IClusterContainerServices; import org.opendaylight.controller.clustering.services.IClusterServices; import org.opendaylight.controller.configuration.IConfigurationContainerAware; +import org.opendaylight.controller.connectionmanager.ConnectionLocality; import org.opendaylight.controller.connectionmanager.IConnectionManager; import org.opendaylight.controller.forwardingrulesmanager.FlowConfig; import org.opendaylight.controller.forwardingrulesmanager.FlowEntry; @@ -273,7 +274,7 @@ public class ForwardingRulesManager implements } Node n = e.getNode(); - if (!connectionManager.isLocal(n)) { + if (connectionManager.getLocalityStatus(n) == ConnectionLocality.NOT_LOCAL) { Callable> worker = new DistributeOrderCallable(e, u, t); if (worker != null) { Future> workerRes = this.executor.submit(worker); @@ -291,7 +292,7 @@ public class ForwardingRulesManager implements } } - logsync.trace("LOCAL Node {} so processing Entry:{} UpdateType:{}", n, e, t); + logsync.trace("Node {} could be local. so processing Entry:{} UpdateType:{}", n, e, t); return null; } @@ -1867,9 +1868,13 @@ public class ForwardingRulesManager implements } } if (target != null) { - // Program the network node - Status status = (target.installInHw()) ? this.uninstallFlowEntry(target.getFlowEntry()) : this - .installFlowEntry(target.getFlowEntry()); + Status status = target.validate(container); + if (!status.isSuccess()) { + log.warn(status.getDescription()); + return status; + } + status = (target.installInHw()) ? this.uninstallFlowEntry(target.getFlowEntry()) : this + .installFlowEntry(target.getFlowEntry()); if (status.isSuccess()) { // Update Configuration database target.setStatus(SUCCESS); @@ -3105,7 +3110,7 @@ public class ForwardingRulesManager implements return; } Node n = fei.getNode(); - if (connectionManager.isLocal(n)) { + if (connectionManager.getLocalityStatus(n) == ConnectionLocality.LOCAL) { logsync.trace("workOrder for fe {} processed locally", fe); // I'm the controller in charge for the request, queue it for // processing diff --git a/opendaylight/forwardingrulesmanager/integrationtest/pom.xml b/opendaylight/forwardingrulesmanager/integrationtest/pom.xml index 7779243599..32cae25dba 100644 --- a/opendaylight/forwardingrulesmanager/integrationtest/pom.xml +++ b/opendaylight/forwardingrulesmanager/integrationtest/pom.xml @@ -130,7 +130,7 @@ jacoco ../implementation/target/jacoco.exec - ../implementaiton/target/jacoco-it.exec + ../implementation/target/jacoco-it.exec java @@ -147,7 +147,7 @@ org.jacoco jacoco-maven-plugin - 0.5.3.201107060350 + ${jacoco.version} ../implementation/target/jacoco-it.exec org.opendaylight.controller.* diff --git a/opendaylight/hosttracker/implementation/pom.xml b/opendaylight/hosttracker/implementation/pom.xml index 268dd4f67f..e93559b42c 100644 --- a/opendaylight/hosttracker/implementation/pom.xml +++ b/opendaylight/hosttracker/implementation/pom.xml @@ -33,7 +33,7 @@ org.jacoco jacoco-maven-plugin - 0.5.3.201107060350 + ${jacoco.version} diff --git a/opendaylight/hosttracker/integrationtest/pom.xml b/opendaylight/hosttracker/integrationtest/pom.xml index 81551650c3..f2fefcdabc 100644 --- a/opendaylight/hosttracker/integrationtest/pom.xml +++ b/opendaylight/hosttracker/integrationtest/pom.xml @@ -117,7 +117,7 @@ org.jacoco jacoco-maven-plugin - 0.5.3.201107060350 + ${jacoco.version} ../implementation/target/jacoco-it.exec org.opendaylight.controller.* diff --git a/opendaylight/hosttracker_new/implementation/pom.xml b/opendaylight/hosttracker_new/implementation/pom.xml index af2ea7b347..dfc2955cfd 100644 --- a/opendaylight/hosttracker_new/implementation/pom.xml +++ b/opendaylight/hosttracker_new/implementation/pom.xml @@ -22,7 +22,7 @@ jacoco reuseReports - target/jacoco.exec + target/jacoco.exec target/jacoco-it.exec java @@ -33,7 +33,7 @@ org.jacoco jacoco-maven-plugin - 0.5.3.201107060350 + ${jacoco.version} diff --git a/opendaylight/md-sal/sal-compability/pom.xml b/opendaylight/md-sal/sal-compability/pom.xml new file mode 100644 index 0000000000..e3d8c589f7 --- /dev/null +++ b/opendaylight/md-sal/sal-compability/pom.xml @@ -0,0 +1,45 @@ + + 4.0.0 + + org.opendaylight.controller + sal-parent + 1.0-SNAPSHOT + ../../sal/yang-prototype/sal/pom.xml + + sal-compability + + + + org.opendaylight.controller + sal + 0.5.0-SNAPSHOT + + + org.opendaylight.controller.model + model-flow-service + 1.0-SNAPSHOT + + + org.opendaylight.controller.model + model-flow-statistics + 1.0-SNAPSHOT + + + org.opendaylight.controller + sal-binding-api + 1.0-SNAPSHOT + + + org.opendaylight.controller + sal-common-util + 1.0-SNAPSHOT + + + com.google.guava + guava + bundle + 14.0.1 + + + diff --git a/opendaylight/md-sal/sal-compability/src/main/java/org/opendaylight/controller/sal/compability/ToSalConversionsUtils.java b/opendaylight/md-sal/sal-compability/src/main/java/org/opendaylight/controller/sal/compability/ToSalConversionsUtils.java new file mode 100644 index 0000000000..c113cd8924 --- /dev/null +++ b/opendaylight/md-sal/sal-compability/src/main/java/org/opendaylight/controller/sal/compability/ToSalConversionsUtils.java @@ -0,0 +1,349 @@ +package org.opendaylight.controller.sal.compability; + +import static org.opendaylight.controller.sal.match.MatchType.DL_DST; +import static org.opendaylight.controller.sal.match.MatchType.DL_SRC; +import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE; +import static org.opendaylight.controller.sal.match.MatchType.DL_VLAN; +import static org.opendaylight.controller.sal.match.MatchType.DL_VLAN_PR; +import static org.opendaylight.controller.sal.match.MatchType.NW_DST; +import static org.opendaylight.controller.sal.match.MatchType.NW_PROTO; +import static org.opendaylight.controller.sal.match.MatchType.NW_SRC; +import static org.opendaylight.controller.sal.match.MatchType.NW_TOS; +import static org.opendaylight.controller.sal.match.MatchType.TP_DST; +import static org.opendaylight.controller.sal.match.MatchType.TP_SRC; + +import java.net.InetAddress; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.opendaylight.controller.sal.action.Controller; +import org.opendaylight.controller.sal.action.Output; +import org.opendaylight.controller.sal.core.NodeConnector; +import org.opendaylight.controller.sal.flowprogrammer.Flow; +import org.opendaylight.controller.sal.match.Match; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.action.ControllerAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.action.OutputAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.action.PopMplsAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.action.PushMplsAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.action.PushPbbAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.action.PushVlanAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.action.SetMplsTtlAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.action.SetNwTtlAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.action.SetQueueAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.MacAddressFilter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.ethernet.match.fields.EthernetType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.EthernetMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.IpMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.Layer3Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.Layer4Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.VlanMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._3.match.ArpMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._3.match.Ipv4Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._3.match.Ipv6Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._4.match.SctpMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._4.match.TcpMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._4.match.UdpMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.vlan.match.fields.VlanId; + +import com.google.common.net.InetAddresses; + +public class ToSalConversionsUtils { + + private ToSalConversionsUtils() { + + } + + public static Flow flowFrom(NodeFlow source) { + final Flow target = new Flow(); + + Integer hardTimeout = source.getHardTimeout(); + if (hardTimeout != null) { + target.setHardTimeout(hardTimeout.shortValue()); + } + + Integer idleTimeout = source.getIdleTimeout(); + if (idleTimeout != null) { + target.setIdleTimeout(idleTimeout.shortValue()); + } + + Integer priority = source.getPriority(); + if (priority != null) { + target.setPriority(priority.shortValue()); + } + + target.setMatch(matchFrom(source.getMatch())); + + List actions = source.getAction(); + if (actions != null) { + for (Action sourceAction : actions) { + Set targetActions = actionFrom(sourceAction); + for (org.opendaylight.controller.sal.action.Action targetAction : targetActions) { + target.addAction(targetAction); + } + } + } + + target.setId(source.getCookie().longValue()); + return target; + } + + public static Set actionFrom(Action source) { + org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.Action sourceAction = source + .getAction(); + Set targetAction = new HashSet<>(); + if (sourceAction instanceof ControllerAction) { + targetAction.add(new Controller()); + } else if (sourceAction instanceof OutputAction) { + + List nodeConnectors = ((OutputAction) sourceAction).getOutputNodeConnector(); + for (Uri uri : nodeConnectors) { + targetAction.add(new Output(fromNodeConnectorRef(uri))); + } + } else if (sourceAction instanceof PopMplsAction) { + // TODO: define maping + } else if (sourceAction instanceof PushMplsAction) { + // TODO: define maping + } else if (sourceAction instanceof PushPbbAction) { + // TODO: define maping + } else if (sourceAction instanceof PushVlanAction) { + // TODO: define maping + // PushVlanAction vlanAction = (PushVlanAction) sourceAction; + // targetAction.add(new PushVlan(vlanAction., pcp, cfi, vlanId); + } else if (sourceAction instanceof SetMplsTtlAction) { + // TODO: define maping + // targetAction = //no action to map + } else if (sourceAction instanceof SetNwTtlAction) { + // TODO: define maping + } else if (sourceAction instanceof SetQueueAction) { + // TODO: define maping + // targetAction = //no action to map + } + + return targetAction; + } + + private static NodeConnector fromNodeConnectorRef(Uri uri) { + // TODO: Define mapping + return null; + } + + public static Match matchFrom(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.Match source) { + Match target = new Match(); + if (source != null) { + fillFrom(target, source.getVlanMatch()); + fillFrom(target, source.getEthernetMatch()); + fillFrom(target, source.getLayer3Match()); + fillFrom(target, source.getLayer4Match()); + fillFrom(target, source.getIpMatch()); + } + + return target; + } + + private static void fillFrom(Match target, VlanMatch vlanMatch) { + if (vlanMatch != null) { + VlanId vlanId = vlanMatch.getVlanId(); + if (vlanId != null) { + org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId vlanIdInner = vlanId + .getVlanId(); + if (vlanIdInner != null) { + Integer vlanValue = vlanIdInner.getValue(); + if (vlanValue != null) { + target.setField(DL_VLAN, vlanValue.shortValue()); + } + } + } + VlanPcp vlanPcp = vlanMatch.getVlanPcp(); + if (vlanPcp != null) { + Short vlanPcpValue = vlanPcp.getValue(); + if (vlanPcpValue != null) { + target.setField(DL_VLAN_PR, vlanPcpValue.byteValue()); + } + } + } + } + + private static void fillFrom(Match target, IpMatch ipMatch) { + if (ipMatch != null) { + Short ipProtocol = ipMatch.getIpProtocol(); + if (ipProtocol != null) { + target.setField(NW_PROTO, ipProtocol.byteValue()); + } + Dscp dscp = ipMatch.getIpDscp(); + if (dscp != null) { + Short dscpValue = dscp.getValue(); + if (dscpValue != null) { + target.setField(NW_TOS, dscpValue.byteValue()); + } + } + } + } + + private static void fillFrom(Match target, Layer4Match layer4Match) { + if (layer4Match == null) { + return; + } + if (layer4Match instanceof SctpMatch) { + fillTransportLayer(target, (SctpMatch) layer4Match); + } else if (layer4Match instanceof TcpMatch) { + fillTransportLayer(target, (TcpMatch) layer4Match); + } else if (layer4Match instanceof UdpMatch) { + fillTransportLayer(target, (UdpMatch) layer4Match); + } + } + + private static void fillTransportLayer(Match target, UdpMatch source) { + PortNumber udpSourcePort = source.getUdpSourcePort(); + if (udpSourcePort != null) { + Integer udpSourcePortValue = udpSourcePort.getValue(); + if (udpSourcePortValue != null) { + target.setField(TP_SRC, udpSourcePortValue.shortValue()); + } + } + + PortNumber udpDestPort = source.getUdpDestinationPort(); + if (udpDestPort != null) { + Integer udpDestPortValue = udpDestPort.getValue(); + if (udpDestPortValue != null) { + target.setField(TP_DST, udpDestPortValue.shortValue()); + } + } + } + + private static void fillTransportLayer(Match target, TcpMatch source) { + PortNumber tcpSourcePort = source.getTcpSourcePort(); + if (tcpSourcePort != null) { + Integer tcpSourcePortValue = tcpSourcePort.getValue(); + if (tcpSourcePortValue != null) { + target.setField(TP_SRC, tcpSourcePortValue.shortValue()); + } + } + + PortNumber tcpDestPort = source.getTcpDestinationPort(); + if (tcpDestPort != null) { + Integer tcpDestPortValue = tcpDestPort.getValue(); + if (tcpDestPortValue != null) { + target.setField(TP_DST, tcpDestPortValue.shortValue()); + } + } + } + + private static void fillTransportLayer(Match target, SctpMatch source) { + PortNumber sctpSourcePort = source.getSctpSourcePort(); + if (sctpSourcePort != null) { + Integer sctpSourcePortValue = sctpSourcePort.getValue(); + if (sctpSourcePortValue != null) { + target.setField(TP_SRC, sctpSourcePortValue.shortValue()); + } + } + PortNumber sctpDestPort = source.getSctpDestinationPort(); + if (sctpDestPort != null) { + Integer sctpDestPortValue = sctpDestPort.getValue(); + if (sctpDestPortValue != null) { + target.setField(TP_DST, sctpDestPortValue.shortValue()); + } + } + } + + private static void fillFrom(Match target, Layer3Match source) { + if (source == null) + return; + if (source instanceof Ipv4Match) { + fillFromIpv4(target, (Ipv4Match) source); + } else if (source instanceof Ipv6Match) { + fillFromIpv6(target, (Ipv6Match) source); + } else if (source instanceof ArpMatch) { + fillFromArp(target, (ArpMatch) source); + } + } + + private static void fillFromArp(Match target, ArpMatch source) { + Ipv4Prefix sourceAddress = source.getArpSourceTransportAddress(); + if (sourceAddress != null) { + target.setField(NW_SRC, (InetAddress) inetAddressFrom(sourceAddress), null); + } + Ipv4Prefix destAddress = source.getArpSourceTransportAddress(); + if (destAddress != null) { + target.setField(NW_DST, (InetAddress) inetAddressFrom(destAddress), null); + } + } + + private static void fillFromIpv6(Match target, Ipv6Match source) { + Ipv6Prefix sourceAddress = source.getIpv6Source(); + if (sourceAddress != null) { + target.setField(NW_SRC, (InetAddress) inetAddressFrom(sourceAddress), null); + } + Ipv6Prefix destAddress = source.getIpv6Source(); + if (destAddress != null) { + target.setField(NW_DST, (InetAddress) inetAddressFrom(destAddress), null); + } + } + + private static void fillFromIpv4(Match target, Ipv4Match source) { + Ipv4Prefix sourceAddress = source.getIpv4Source(); + if (sourceAddress != null) { + target.setField(NW_SRC, (InetAddress) inetAddressFrom(sourceAddress), null); + } + Ipv4Prefix destAddress = source.getIpv4Source(); + if (destAddress != null) { + target.setField(NW_DST, (InetAddress) inetAddressFrom(destAddress), null); + } + } + + private static InetAddress inetAddressFrom(Ipv4Prefix source) { + if (source != null) { + String[] parts = source.getValue().split("/"); + return InetAddresses.forString(parts[0]); + } + return null; + } + + private static InetAddress inetAddressFrom(Ipv6Prefix source) { + if (source != null) { + String[] parts = source.getValue().split("/"); + return InetAddresses.forString(parts[0]); + } + return null; + } + + private static void fillFrom(Match target, EthernetMatch source) { + if (source == null) + return; + EthernetType ethType = source.getEthernetType(); + if (ethType != null) { + EtherType ethInnerType = ethType.getType(); + if (ethInnerType != null) { + Long value = ethInnerType.getValue(); + target.setField(DL_TYPE, value.shortValue()); + } + } + + MacAddressFilter ethSource = source.getEthernetSource(); + if (ethSource != null) { + target.setField(DL_SRC, bytesFrom(ethSource.getAddress())); + } + + MacAddressFilter ethDest = source.getEthernetDestination(); + if (ethDest != null) { + target.setField(DL_DST, bytesFrom(ethDest.getAddress())); + } + } + + private static byte[] bytesFrom(MacAddress address) { + if (address != null) { + return address.getValue().getBytes(); + } + return null; + } +} diff --git a/opendaylight/northbound/commons/pom.xml b/opendaylight/northbound/commons/pom.xml index 692b17a9a6..972bece91f 100644 --- a/opendaylight/northbound/commons/pom.xml +++ b/opendaylight/northbound/commons/pom.xml @@ -48,7 +48,9 @@ org.osgi.service.packageadmin, org.osgi.util.tracker, javax.servlet.http, + org.codehaus.jackson, org.codehaus.jackson.jaxrs, + org.codehaus.jackson.map, org.slf4j diff --git a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/JacksonJsonProcessingExceptionMapper.java b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/JacksonJsonProcessingExceptionMapper.java new file mode 100644 index 0000000000..ca0d1b7cae --- /dev/null +++ b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/JacksonJsonProcessingExceptionMapper.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.northbound.commons; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.GenericEntity; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + +import org.codehaus.jackson.JsonProcessingException; + +/** + * A custom exception mapper for handling Jackson JsonProcessingException types + */ +@Provider +@Consumes({MediaType.APPLICATION_JSON, "text/json"}) +public class JacksonJsonProcessingExceptionMapper + implements ExceptionMapper +{ + + @Override + public Response toResponse(JsonProcessingException exception) { + GenericEntity entity = + new GenericEntity(exception.getMessage()) {}; + return Response.status(Response.Status.BAD_REQUEST).entity(entity).build(); + } +} + diff --git a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java index 1d3919f4ea..5b8219126b 100644 --- a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java +++ b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java @@ -20,6 +20,7 @@ import javax.xml.bind.JAXBException; import javax.xml.bind.annotation.XmlRootElement; import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider; +import org.codehaus.jackson.map.DeserializationConfig; import org.opendaylight.controller.northbound.bundlescanner.IBundleScanService; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -54,7 +55,8 @@ public class NorthboundApplication extends Application { } } ); - singletons.add(new JacksonJaxbJsonProvider()); + singletons.add(getJsonProvider()); + singletons.add(new JacksonJsonProcessingExceptionMapper()); return singletons; } @@ -65,6 +67,13 @@ public class NorthboundApplication extends Application { return result; } + private static final JacksonJaxbJsonProvider getJsonProvider() { + JacksonJaxbJsonProvider jsonProvider = new JacksonJaxbJsonProvider(); + jsonProvider.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, + false); + return jsonProvider; + } + private BundleContext getBundleContext() { ClassLoader tlcl = Thread.currentThread().getContextClassLoader(); Bundle bundle = null; diff --git a/opendaylight/northbound/integrationtest/pom.xml b/opendaylight/northbound/integrationtest/pom.xml index 9f4e05dff0..3f2585e0c2 100644 --- a/opendaylight/northbound/integrationtest/pom.xml +++ b/opendaylight/northbound/integrationtest/pom.xml @@ -20,9 +20,9 @@ 0.4.0-SNAPSHOT - central2 - central2 - http://repo2.maven.org/maven2 + central + maven repo1 + http://repo1.maven.org/maven2 false diff --git a/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java b/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java index 4404951135..e7ca7f5782 100644 --- a/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java +++ b/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java @@ -428,6 +428,11 @@ public class NorthboundIT { // Test GET deleted subnet1 result = getJsonResult(baseURL + "default/subnet/" + name1); Assert.assertEquals(404, httpResponseCode.intValue()); + + // TEST PUT bad subnet, expect 400, validate JSON exception mapper + JSONObject joBad = new JSONObject().put("foo", "bar"); + result = getJsonResult(baseURL + "default/subnet/foo", "PUT", joBad.toString()); + Assert.assertEquals(400, httpResponseCode.intValue()); } @Test diff --git a/opendaylight/sal/yang-prototype/pom.xml b/opendaylight/sal/yang-prototype/pom.xml index b1107594f5..3f84ff09a4 100644 --- a/opendaylight/sal/yang-prototype/pom.xml +++ b/opendaylight/sal/yang-prototype/pom.xml @@ -43,9 +43,9 @@ - central2 - central2 - http://repo2.maven.org/maven2 + central + maven repo1 + http://repo1.maven.org/maven2 false @@ -76,17 +76,6 @@ ebr-bundles-external ${nexusproxy}/repositories/ebr-bundles-external/ - - central2 - central2 - http://repo2.maven.org/maven2 - - false - - - true - - central central diff --git a/opendaylight/sal/yang-prototype/sal/model/model-flow-base/src/main/yang/group-types.yang b/opendaylight/sal/yang-prototype/sal/model/model-flow-base/src/main/yang/group-types.yang new file mode 100644 index 0000000000..626eabd16a --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/model/model-flow-base/src/main/yang/group-types.yang @@ -0,0 +1,175 @@ +module opendaylight-group-types { + namespace "urn:opendaylight:group:types"; + prefix group; + + import ietf-inet-types {prefix inet;} + import ietf-yang-types {prefix yang;} + import opendaylight-flow-types {prefix flow-types;} + + revision "2013-09-17" { + description "Initial revision of group service"; + } + + typedef group-ref { + type instance-identifier; + } + + grouping group-types { + leaf group-type { + type enumeration { + enum group-all; + enum group_select; + enum group_indirect; + enum group_ff; + } + } + } + + grouping group { + + uses group-types; + + leaf group-id { + type group-ref; + } + + container buckets { + list bucket { + key "order"; + leaf order { + type int32; + } + + leaf weight { + type uint16; + } + + leaf watch_port { + type uint32; + } + + leaf watch_group { + type uint32; + } + + container actions { + list action { + key "action-order"; + leaf action-order { + type int32; + } + + uses flow-types:action; + } + } + } + } + } + + grouping group-statistics-request { + list group-stats { + key "group-id"; + + leaf group-id { + type int32; + } + } + } + + grouping group-statistics { + + leaf group-id { + type int32; + } + + leaf ref-count { + type yang:counter32; + } + + leaf packet-count { + type yang:counter64; + } + + leaf byte-count { + type yang:counter64; + } + + container duration { + leaf second { + type yang:counter32; + } + leaf nanosecond { + type yang:counter32; + } + } + + container buckets { + list bucket-counter { + key "order"; + leaf order { + type int32; + } + + leaf packet-count { + type yang:counter64; + } + + leaf byte-count { + type yang:counter64; + } + } + } + } + + grouping group-statistics-reply { + list group-stats { + key "group-stats-order"; + leaf group-stats-order { + type int32; + } + + uses group-statistics; + } + } + + grouping group-desc-stats { + list group-desc-stats { + key "order-id"; + + leaf order-id { + type int32; + } + + uses group; + } + } + + grouping group-features { + list group-features { + key "order"; + leaf order { + type int32; + } + + uses group-types; + type capabilities { + enum select-weight; + enum select-liveness; + enum chaining; + enum chaining-checks; + } + + leaf-list max-groups { + type uint32; + description "Maximum number of groups for each type"; + max-elements 4; + } + + leaf-list actions { + type uint32; + description "Bitmap number OFPAT_* that are supported"; + max-elements 4; + } + } + } +} \ No newline at end of file diff --git a/opendaylight/sal/yang-prototype/sal/model/model-flow-base/src/main/yang/match-types.yang b/opendaylight/sal/yang-prototype/sal/model/model-flow-base/src/main/yang/match-types.yang index 54b46d5587..757686c662 100644 --- a/opendaylight/sal/yang-prototype/sal/model/model-flow-base/src/main/yang/match-types.yang +++ b/opendaylight/sal/yang-prototype/sal/model/model-flow-base/src/main/yang/match-types.yang @@ -68,16 +68,16 @@ module opendaylight-match-types { grouping "ip-match-fields" { leaf ip-protocol { description "IP protocol."; - type uint8; // TODO define IP protocol number + type uint8; } leaf ip-dscp { description "IP DSCP (6 bits in ToS field)."; - type inet:dscp; // TODO: Define DSCP type + type inet:dscp; } leaf ip-ecn { description "IP ECN (2 bits in ToS field)."; - type uint8; // TODO define ECN + type uint8; } } @@ -130,7 +130,7 @@ module opendaylight-match-types { description "SCTP source port."; type inet:port-number; } - leaf sctp-destination-dst { + leaf sctp-destination-port { description "SCTP destination port."; type inet:port-number; } diff --git a/opendaylight/sal/yang-prototype/sal/model/model-flow-service/src/main/yang/group-service.yang b/opendaylight/sal/yang-prototype/sal/model/model-flow-service/src/main/yang/group-service.yang new file mode 100644 index 0000000000..1ea2d34a38 --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/model/model-flow-service/src/main/yang/group-service.yang @@ -0,0 +1,49 @@ +module sal-group { + namespace "urn:opendaylight:group:service"; + prefix group; + + import yang-ext {prefix ext;} + import opendaylight-inventory {prefix inv;} + import ietf-inet-types {prefix inet;} + import opendaylight-group-types {prefix group-type;} + + revision "2013-09-17" { + description "Initial revision of group service"; + } + + grouping node-group { + leaf node { + type inv:node-ref; + } + + uses group-type:group; + } + + /** Base configuration structure **/ + grouping group-update { + container original-group { + uses group-type:group; + } + container updated-group { + uses group-type:group; + } + } + + rpc add-group { + input { + uses node-group; + } + } + + rpc remove-group { + input { + uses node-group; + } + } + + rpc update-group { + input { + uses node-group; + } + } +} \ No newline at end of file diff --git a/opendaylight/sal/yang-prototype/sal/pom.xml b/opendaylight/sal/yang-prototype/sal/pom.xml index 0442e8f9b2..d70338e4e0 100644 --- a/opendaylight/sal/yang-prototype/sal/pom.xml +++ b/opendaylight/sal/yang-prototype/sal/pom.xml @@ -25,7 +25,7 @@ UTF-8 1.7.2 http://nexus.opendaylight.org/content - 0.5.7-SNAPSHOT + 0.5.8-SNAPSHOT 2.4.0 2.3.2 14.0.1 @@ -33,9 +33,9 @@ - central2 - central2 - http://repo2.maven.org/maven2 + central + maven repo1 + http://repo1.maven.org/maven2 false @@ -52,17 +52,6 @@ - - central2 - central2 - http://repo2.maven.org/maven2 - - false - - - true - - central central diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/pom.xml b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/pom.xml index 549e427d82..96a16dcd57 100644 --- a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/pom.xml +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/pom.xml @@ -1,113 +1,121 @@ - 4.0.0 - - org.opendaylight.controller - sal-parent - 1.0-SNAPSHOT - - sal-binding-broker-impl - bundle + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.opendaylight.controller + sal-parent + 1.0-SNAPSHOT + + sal-binding-broker-impl + bundle - scm:git:ssh://git.opendaylight.org:29418/controller.git - scm:git:ssh://git.opendaylight.org:29418/controller.git - https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL + scm:git:ssh://git.opendaylight.org:29418/controller.git + scm:git:ssh://git.opendaylight.org:29418/controller.git + https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL - - - - org.apache.felix - maven-bundle-plugin - ${maven.bundle.version} - true - - - ${project.groupId}.${project.artifactId} - org.opendaylight.controller.sal.binding.impl.BrokerActivator - - org.opendaylight.controller.sal.binding.impl, - org.opendaylight.controller.sal.binding.impl.utils, - org.eclipse.xtend2.lib, - org.eclipse.xtext.xbase.* - - - - + + + + org.apache.felix + maven-bundle-plugin + ${maven.bundle.version} + true + + + ${project.groupId}.${project.artifactId} + org.opendaylight.controller.sal.binding.impl.BrokerActivator + + org.opendaylight.controller.sal.binding.impl, + org.opendaylight.controller.sal.binding.impl.*, + org.opendaylight.controller.sal.binding.codegen.*, + org.eclipse.xtend2.lib, + org.eclipse.xtend.lib, + org.eclipse.xtext.xbase.* + + + + - - org.eclipse.xtend - xtend-maven-plugin - 2.4.2 - - - - compile - - - ${basedir}/src/main/xtend-gen - - - - - - maven-clean-plugin - 2.4.1 - - - - ${basedir}/src/main/xtend-gen - - ** - - - - - - - + + org.eclipse.xtend + xtend-maven-plugin + 2.4.2 + + + + compile + + + ${basedir}/src/main/xtend-gen + + + + + + maven-clean-plugin + 2.4.1 + + + + ${basedir}/src/main/xtend-gen + + ** + + + + + + + - - - org.opendaylight.controller - sal-common-util - 1.0-SNAPSHOT - - - org.opendaylight.controller - sal-binding-api - 1.0-SNAPSHOT - - + + + org.opendaylight.controller + sal-common-util + 1.0-SNAPSHOT + + + org.opendaylight.controller + sal-binding-api + 1.0-SNAPSHOT + + - - org.slf4j - slf4j-api - - - org.osgi - org.osgi.core - 5.0.0 - - - com.google.guava - guava - - - org.reflections - reflections - 0.9.9-RC1 - - - org.javassist - javassist - 3.17.1-GA - - - org.eclipse.xtend - org.eclipse.xtend.lib - 2.4.2 - - + + org.slf4j + slf4j-api + + + org.osgi + org.osgi.core + 5.0.0 + + + com.google.guava + guava + + + org.reflections + reflections + 0.9.9-RC1 + + + org.javassist + javassist + 3.17.1-GA + + + org.eclipse.xtend + org.eclipse.xtend.lib + 2.4.2 + + + org.mockito + mockito-all + 1.9.5 + test + + diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeHelper.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeHelper.xtend new file mode 100644 index 0000000000..6bdb3c8fbe --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeHelper.xtend @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.codegen + +import java.util.Map + +import org.opendaylight.yangtools.yang.binding.BaseIdentity +import org.opendaylight.yangtools.yang.binding.RpcService +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier + +import static extension org.opendaylight.controller.sal.binding.codegen.RuntimeCodeSpecification.* + +class RuntimeCodeHelper { + /** + * Helper method to return delegate from ManagedDirectedProxy with use of reflection. + * + * Note: This method uses reflection, but access to delegate field should be + * avoided and called only if neccessary. + * + */ + public static def getDelegate(RpcService proxy) { + val field = proxy.class.getField(DELEGATE_FIELD) + if (field == null) throw new UnsupportedOperationException("Unable to get delegate from proxy"); + return field.get(proxy) as T + } + + /** + * Helper method to set delegate to ManagedDirectedProxy with use of reflection. + * + * Note: This method uses reflection, but setting delegate field should not occur too much + * to introduce any significant performance hits. + * + */ + public static def void setDelegate(RpcService proxy, RpcService delegate) { + val field = proxy.class.getField(DELEGATE_FIELD) + if (field == null) throw new UnsupportedOperationException("Unable to set delegate to proxy"); + if (field.type.isAssignableFrom(delegate.class)) { + field.set(proxy, delegate) + } else + throw new IllegalArgumentException("delegate class is not assignable to proxy"); + } + + public static def Map getRoutingTable(RpcService target, + Class tableClass) { + val field = target.class.getField(tableClass.routingTableField) + if (field == null) throw new UnsupportedOperationException( + "Unable to get routing table. Table field does not exists"); + return field.get(target) as Map; + } + + public static def void setRoutingTable(RpcService target, Class tableClass, + Map routingTable) { + val field = target.class.getField(tableClass.routingTableField) + if (field == null) throw new UnsupportedOperationException( + "Unable to set routing table. Table field does not exists"); + field.set(target,routingTable); + + } + +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeSpecification.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeSpecification.xtend new file mode 100644 index 0000000000..c6e76c2907 --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeSpecification.xtend @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.codegen + +import org.opendaylight.yangtools.yang.binding.RpcService +import org.opendaylight.yangtools.yang.binding.BaseIdentity +import org.opendaylight.yangtools.yang.binding.NotificationListener + +/** + * + * + */ +class RuntimeCodeSpecification { + + public static val PACKAGE_PREFIX = "_gen."; + + public static val DIRECT_PROXY_SUFFIX = "DirectProxy"; + public static val ROUTER_SUFFIX = "Router"; + public static val INVOKER_SUFFIX = "Invoker"; + + public static val DELEGATE_FIELD = "_delegate" + public static val ROUTING_TABLE_FIELD_PREFIX = "_routes_" + + public static def getInvokerName(Class listener) { + getGeneratedName(listener, INVOKER_SUFFIX); + } + + /** + * Returns a name for DirectProxy implementation + * + * + */ + public static def getDirectProxyName(Class base) { + getGeneratedName(base, DIRECT_PROXY_SUFFIX); + } + + /** + * Returns a name for Router implementation + * + */ + public static def getRouterName(Class base) { + getGeneratedName(base, ROUTER_SUFFIX); + } + + /** + * Returns a name for generated interface + * + */ + public static def getGeneratedName(Class cls, String suffix) { + '''«PACKAGE_PREFIX»«cls.package.name».«cls.simpleName»$«suffix»'''.toString() + } + + /** + * Returns a field name for specified routing context + * + */ + public static def getRoutingTableField(Class routingContext) { + return '''_routes_«routingContext.simpleName»'''.toString; + } +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/YangtoolsMappingHelper.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/YangtoolsMappingHelper.xtend new file mode 100644 index 0000000000..18d3e26346 --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/YangtoolsMappingHelper.xtend @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.codegen + +import java.lang.reflect.Method +import org.opendaylight.yangtools.yang.binding.Notification + +public static class YangtoolsMappingHelper { + + public static def boolean isNotificationCallback(Method it) { + return name.startsWith("on") && parameterTypes.size === 1 && + Notification.isAssignableFrom(parameterTypes.get(0)) + } +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/JavassistUtils.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/JavassistUtils.java new file mode 100644 index 0000000000..c6be284f4c --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/JavassistUtils.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.codegen.impl; + +import javassist.CtClass; +import javassist.CtField; +import javassist.CtMethod; + +public class JavassistUtils { + + public static interface ClassGenerator { + void process(CtClass cls); + } + + public static interface MethodGenerator { + void process(CtMethod method); + } + + public static interface FieldGenerator { + void process(CtField field); + } +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RoutingPair.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RoutingPair.xtend new file mode 100644 index 0000000000..4324b4eb9a --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RoutingPair.xtend @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.codegen.impl + +import org.opendaylight.yangtools.yang.binding.BaseIdentity +import javassist.CtMethod +import java.lang.reflect.Method + +@Data +class RoutingPair { + + @Property + val Class context; + @Property + val CtMethod getter; +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RuntimeCodeGenerator.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RuntimeCodeGenerator.xtend new file mode 100644 index 0000000000..3b3f4190cf --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RuntimeCodeGenerator.xtend @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.codegen.impl + +import javassist.ClassPool +import org.opendaylight.yangtools.yang.binding.RpcService + +import javassist.CtClass +import static com.google.common.base.Preconditions.* + +import javassist.CtField +import javassist.Modifier +import javassist.CtMethod +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier +import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext +import org.opendaylight.yangtools.yang.binding.BaseIdentity + +import java.util.Map +import java.util.HashMap +import javassist.NotFoundException +import javassist.LoaderClassPath +import org.opendaylight.controller.sal.binding.codegen.impl.JavassistUtils.MethodGenerator +import org.opendaylight.controller.sal.binding.codegen.impl.JavassistUtils.ClassGenerator +import org.opendaylight.yangtools.yang.binding.NotificationListener +import org.opendaylight.yangtools.yang.binding.Notification +import java.util.Arrays + +import static extension org.opendaylight.controller.sal.binding.codegen.YangtoolsMappingHelper.* +import static extension org.opendaylight.controller.sal.binding.codegen.RuntimeCodeSpecification.* + +class RuntimeCodeGenerator { + + val ClassPool classPool; + + public new(ClassPool pool) { + classPool = pool; + } + + def Class generateDirectProxy(Class iface) { + val supertype = iface.asCtClass + val targetCls = createClass(iface.directProxyName, supertype) [ + field(DELEGATE_FIELD, iface); + implementMethodsFrom(supertype) [ + body = '''return ($r) «DELEGATE_FIELD».«it.name»($$);''' + ] + ] + return targetCls.toClass(iface.classLoader) + } + + def Class generateRouter(Class iface) { + val supertype = iface.asCtClass + val targetCls = createClass(iface.routerName, supertype) [ + //field(ROUTING_TABLE_FIELD,Map) + field(DELEGATE_FIELD, iface) + val contexts = new HashMap>(); + // We search for routing pairs and add fields + supertype.methods.filter[declaringClass == supertype && parameterTypes.size === 1].forEach [ method | + val routingPair = method.routingContextInput; + if (routingPair !== null) + contexts.put(routingPair.context.routingTableField, routingPair.context); + ] + for (ctx : contexts.entrySet) { + field(ctx.key, Map) + } + implementMethodsFrom(supertype) [ + if (parameterTypes.size === 1) { + val routingPair = routingContextInput; + val bodyTmp = ''' + { + final «InstanceIdentifier.name» identifier = $1.«routingPair.getter.name»(); + «supertype.name» instance = («supertype.name») «routingPair.context.routingTableField».get(identifier); + if(instance == null) { + instance = «DELEGATE_FIELD»; + } + return ($r) instance.«it.name»($$); + }''' + body = bodyTmp + } else if (parameterTypes.size === 0) { + body = '''return ($r) «DELEGATE_FIELD».«it.name»($$);''' + } + ] + ] + return targetCls.toClass(iface.classLoader) + } + + def Class generateListenerInvoker(Class iface) { + val targetCls = createClass(iface.invokerName) [ + field(DELEGATE_FIELD, iface) + it.method(Void, "invoke", Notification) [ + val callbacks = iface.methods.filter[notificationCallback] + body = ''' + { + «FOR callback : callbacks SEPARATOR " else "» + if($1 instanceof «val cls = callback.parameterTypes.get(0).name») { + «DELEGATE_FIELD».«callback.name»((«cls») $1); + return; + } + «ENDFOR» + } + ''' + ] + ] + return targetCls.toClass(iface.classLoader); + } + + def void method(CtClass it, Class returnType, String name, Class parameter, MethodGenerator function1) { + val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter.asCtClass), it); + function1.process(method); + it.addMethod(method); + } + + private def routingContextInput(CtMethod method) { + val inputClass = method.parameterTypes.get(0); + return inputClass.contextInstance; + } + + private def RoutingPair getContextInstance(CtClass dataClass) { + for (method : dataClass.methods) { + if (method.parameterTypes.size === 0 && method.name.startsWith("get")) { + for (annotation : method.availableAnnotations) { + if (annotation instanceof RoutingContext) { + return new RoutingPair((annotation as RoutingContext).value, method) + } + } + } + } + for (iface : dataClass.interfaces) { + val ret = getContextInstance(iface); + if (ret != null) return ret; + } + return null; + } + + private def void implementMethodsFrom(CtClass target, CtClass source, MethodGenerator function1) { + for (method : source.methods) { + if (method.declaringClass == source) { + val redeclaredMethod = new CtMethod(method, target, null); + function1.process(redeclaredMethod); + target.addMethod(redeclaredMethod); + } + } + } + + private def CtClass createClass(String fqn, ClassGenerator cls) { + val target = classPool.makeClass(fqn); + cls.process(target); + return target; + } + + private def CtClass createClass(String fqn, CtClass superInterface, ClassGenerator cls) { + val target = classPool.makeClass(fqn); + target.implementsType(superInterface); + cls.process(target); + return target; + } + + private def void implementsType(CtClass it, CtClass supertype) { + checkArgument(supertype.interface, "Supertype must be interface"); + addInterface(supertype); + } + + private def asCtClass(Class class1) { + classPool.get(class1); + } + + private def CtField field(CtClass it, String name, Class returnValue) { + val field = new CtField(returnValue.asCtClass, name, it); + field.modifiers = Modifier.PUBLIC + addField(field); + return field; + } + + def get(ClassPool pool, Class cls) { + try { + return pool.get(cls.name) + } catch (NotFoundException e) { + pool.appendClassPath(new LoaderClassPath(cls.classLoader)); + return pool.get(cls.name) + } + } +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend index 2953466b29..298a74ece5 100644 --- a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend @@ -11,30 +11,29 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer import org.opendaylight.controller.sal.binding.api.BindingAwareProvider import org.opendaylight.yangtools.yang.binding.RpcService import javassist.ClassPool -import javassist.CtMethod -import javassist.CtField import org.osgi.framework.BundleContext import java.util.Map import java.util.HashMap import javassist.LoaderClassPath import org.opendaylight.controller.sal.binding.api.BindingAwareBroker import java.util.Hashtable +import static extension org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper.* -import static extension org.opendaylight.controller.sal.binding.impl.utils.PropertiesUtils.* -import static extension org.opendaylight.controller.sal.binding.impl.utils.GeneratorUtils.* import org.opendaylight.controller.sal.binding.api.NotificationProviderService import org.osgi.framework.ServiceRegistration -import org.opendaylight.controller.sal.binding.impl.utils.PropertiesUtils +import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.* +import static extension org.opendaylight.controller.sal.binding.impl.osgi.PropertiesUtils.* import org.opendaylight.controller.sal.binding.api.NotificationService import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext -import javassist.Modifier + import org.slf4j.LoggerFactory +import org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator class BindingAwareBrokerImpl implements BindingAwareBroker { - private static val DELEGATE_FIELD = "_delegate" private static val log = LoggerFactory.getLogger(BindingAwareBrokerImpl) private val clsPool = ClassPool.getDefault() + private var RuntimeCodeGenerator generator; private Map, RpcProxyContext> managedProxies = new HashMap(); private var NotificationBrokerImpl notifyBroker private var ServiceRegistration notifyBrokerRegistration @@ -47,7 +46,7 @@ class BindingAwareBrokerImpl implements BindingAwareBroker { // Initialization of notificationBroker notifyBroker = new NotificationBrokerImpl(null); - val brokerProperties = PropertiesUtils.newProperties(); + val brokerProperties = newProperties(); notifyBrokerRegistration = brokerBundleContext.registerService(NotificationProviderService, notifyBroker, brokerProperties) brokerBundleContext.registerService(NotificationService, notifyBroker, brokerProperties) @@ -56,7 +55,8 @@ class BindingAwareBrokerImpl implements BindingAwareBroker { def initGenerator() { // YANG Binding Class Loader - clsPool.appendClassPath(new LoaderClassPath(RpcService.classLoader)) + clsPool.appendClassPath(new LoaderClassPath(RpcService.classLoader)); + generator = new RuntimeCodeGenerator(clsPool); } override registerConsumer(BindingAwareConsumer consumer, BundleContext bundleCtx) { @@ -97,35 +97,16 @@ class BindingAwareBrokerImpl implements BindingAwareBroker { if ((existing = managedProxies.get(service)) != null) { return existing.proxy } - val proxyClass = service.generateDirectProxy() + val proxyClass = generator.generateDirectProxy(service) val rpcProxyCtx = new RpcProxyContext(proxyClass) val properties = new Hashtable() rpcProxyCtx.proxy = proxyClass.newInstance as RpcService - properties.salServiceType = Constants.SAL_SERVICE_TYPE_CONSUMER_PROXY + properties.salServiceType = SAL_SERVICE_TYPE_CONSUMER_PROXY rpcProxyCtx.registration = brokerBundleContext.registerService(service, rpcProxyCtx.proxy as T, properties) managedProxies.put(service, rpcProxyCtx) return rpcProxyCtx.proxy } - - protected def generateDirectProxy(Class delegate) { - val targetFqn = delegate.generatedName(Constants.PROXY_DIRECT_SUFFIX) - log.debug("Generating DirectProxy for {} Proxy name: {}",delegate,targetFqn); - val objCls = clsPool.get(Object) - val delegateCls = clsPool.get(delegate) - val proxyCls = clsPool.makeClass(targetFqn) - proxyCls.addInterface(delegateCls) - val delField = new CtField(delegateCls, DELEGATE_FIELD, proxyCls); - delField.modifiers = Modifier.PUBLIC - proxyCls.addField(delField) - delegateCls.methods.filter[it.declaringClass != objCls].forEach [ - val proxyMethod = new CtMethod(it, proxyCls, null); - proxyMethod.body = '''return ($r) «DELEGATE_FIELD».«it.name»($$);''' - proxyCls.addMethod(proxyMethod) - ] - return proxyCls.toClass(delegate.classLoader) - } - /** * Registers RPC Implementation * @@ -140,34 +121,4 @@ class BindingAwareBrokerImpl implements BindingAwareBroker { proxy.delegate = service; return new RpcServiceRegistrationImpl(type, service, osgiReg); } - - /** - * Helper method to return delegate from ManagedDirectedProxy with use of reflection. - * - * Note: This method uses reflection, but access to delegate field should be - * avoided and called only if neccessary. - * - */ - def getDelegate(RpcService proxy) { - val field = proxy.class.getField(DELEGATE_FIELD) - if(field == null) throw new UnsupportedOperationException("Unable to get delegate from proxy"); - return field.get(proxy) as T - } - - /** - * Helper method to set delegate to ManagedDirectedProxy with use of reflection. - * - * Note: This method uses reflection, but setting delegate field should not occur too much - * to introduce any significant performance hits. - * - */ - def void setDelegate(RpcService proxy, RpcService delegate) { - val field = proxy.class.getField(DELEGATE_FIELD) - if(field == null) throw new UnsupportedOperationException("Unable to set delegate to proxy"); - if (field.type.isAssignableFrom(delegate.class)) { - field.set(proxy,delegate) - } else throw new IllegalArgumentException("delegate class is not assignable to proxy"); - } - - } diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/DataProviderContext.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/DataProviderContext.xtend new file mode 100644 index 0000000000..398a2196c6 --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/DataProviderContext.xtend @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.impl + +import org.opendaylight.controller.sal.common.DataStoreIdentifier +import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider + +class DataProviderContext { + + @Property + var DataStoreIdentifier identifier; + @Property + var RuntimeDataProvider provider; +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend index da1ba79997..22db73526e 100644 --- a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend @@ -45,6 +45,7 @@ class NotificationBrokerImpl implements NotificationProviderService { notification.class.interfaces.filter[it != Notification && Notification.isAssignableFrom(it)] } + @SuppressWarnings("unchecked") def notifyAll(Collection> listeners, Notification notification) { listeners.forEach[(it as NotificationListener).onNotification(notification)] } diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend index a87fa0642a..a9031240c7 100644 --- a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ package org.opendaylight.controller.sal.binding.impl; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext; @@ -7,47 +14,45 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.slf4j.LoggerFactory +import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.* class OsgiConsumerContext implements ConsumerContext { - static val log = LoggerFactory.getLogger(OsgiConsumerContext) - protected val BundleContext bundleContext; - protected val BindingAwareBrokerImpl broker; - - new(BundleContext ctx,BindingAwareBrokerImpl broker) { - this.bundleContext = ctx; - this.broker = broker; - } - - - override def getSALService(Class service) { - // SAL Services are global - var ref = bundleContext.getServiceReference(service); - return bundleContext.getService(ref) as T; - } - - - - override def T getRpcService(Class module) { - try { - - val services = bundleContext.getServiceReferences(module, getProxyFilter()); - - // Proxy service found / using first implementation - // FIXME: Add advanced logic to retrieve service with right set of models - if(false == services.empty) { - val ref = services.iterator().next() as ServiceReference; - return bundleContext.getService(ref) as T; - } - } catch (InvalidSyntaxException e) { - log.error("Created filter was invalid:", e.message,e) - } - return null; - - - } - - private def getProxyFilter() { - return '''(«Constants.SAL_SERVICE_TYPE»=«Constants.SAL_SERVICE_TYPE_CONSUMER_PROXY»)''' - } + static val log = LoggerFactory.getLogger(OsgiConsumerContext) + protected val BundleContext bundleContext; + protected val BindingAwareBrokerImpl broker; + + new(BundleContext ctx, BindingAwareBrokerImpl broker) { + this.bundleContext = ctx; + this.broker = broker; + } + + override def getSALService(Class service) { + + // SAL Services are global + var ref = bundleContext.getServiceReference(service); + return bundleContext.getService(ref) as T; + } + + override def T getRpcService(Class module) { + try { + + val services = bundleContext.getServiceReferences(module, getProxyFilter()); + + // Proxy service found / using first implementation + // FIXME: Add advanced logic to retrieve service with right set of models + if (false == services.empty) { + val ref = services.iterator().next() as ServiceReference; + return bundleContext.getService(ref) as T; + } + } catch (InvalidSyntaxException e) { + log.error("Created filter was invalid:", e.message, e) + } + return null; + + } + + private def getProxyFilter() { + return '''(«SAL_SERVICE_TYPE»=«SAL_SERVICE_TYPE_CONSUMER_PROXY»)''' + } } diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend index 195fa8b959..c769ca1ee3 100644 --- a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiProviderContext.xtend @@ -16,7 +16,8 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcService import org.opendaylight.yangtools.yang.binding.RpcService; import org.osgi.framework.BundleContext; -import static extension org.opendaylight.controller.sal.binding.impl.utils.PropertiesUtils.*; +import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.*; +import static extension org.opendaylight.controller.sal.binding.impl.osgi.PropertiesUtils.*; class OsgiProviderContext extends OsgiConsumerContext implements ProviderContext { @@ -32,7 +33,7 @@ class OsgiProviderContext extends OsgiConsumerContext implements ProviderContext // TODO Auto-generated method stub val properties = new Hashtable(); - properties.salServiceType = Constants.SAL_SERVICE_TYPE_PROVIDER + properties.salServiceType = SAL_SERVICE_TYPE_PROVIDER // Fill requirements val salReg = broker.registerRpcImplementation(type, implementation, this, properties) diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/_DataBrokerImpl.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/_DataBrokerImpl.xtend new file mode 100644 index 0000000000..b278df56f8 --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/_DataBrokerImpl.xtend @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.impl + +import org.opendaylight.controller.sal.binding.api.data.DataBrokerService +import org.opendaylight.controller.sal.common.DataStoreIdentifier +import org.opendaylight.yangtools.yang.binding.DataRoot +import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.opendaylight.controller.sal.binding.api.data.DataCommitHandler +import org.opendaylight.controller.sal.binding.api.data.DataRefresher +import org.opendaylight.controller.sal.binding.api.data.DataValidator +import org.opendaylight.yangtools.yang.common.RpcResult +import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider +import java.util.Map + +class _DataBrokerImpl implements DataProviderService { + + Map dataProviders; + var DataProviderContext defaultDataProvider; + + override getData(DataStoreIdentifier store, Class rootType) { + val dataStore = resolveProvider(store, rootType); + return dataStore.provider.getData(store, rootType); + } + + override getData(DataStoreIdentifier store, T filter) { + } + + override T getCandidateData(DataStoreIdentifier store, Class rootType) { + throw new UnsupportedOperationException("TODO: auto-generated method stub"); + } + + override T getCandidateData(DataStoreIdentifier store, T filter) { + throw new UnsupportedOperationException("TODO: auto-generated method stub"); + } + + override commit(DataStoreIdentifier store) { + throw new UnsupportedOperationException("TODO: auto-generated method stub") + } + + override editCandidateData(DataStoreIdentifier store, DataRoot changeSet) { + throw new UnsupportedOperationException("TODO: auto-generated method stub") + } + + override addCommitHandler(DataStoreIdentifier store, DataCommitHandler provider) { + throw new UnsupportedOperationException("TODO: auto-generated method stub") + } + + override addRefresher(DataStoreIdentifier store, DataRefresher refresher) { + throw new UnsupportedOperationException("TODO: auto-generated method stub") + } + + override addValidator(DataStoreIdentifier store, DataValidator validator) { + throw new UnsupportedOperationException("TODO: auto-generated method stub") + } + + override removeRefresher(DataStoreIdentifier store, DataRefresher refresher) { + throw new UnsupportedOperationException("TODO: auto-generated method stub") + } + + override removeCommitHandler(DataStoreIdentifier store, DataCommitHandler provider) { + throw new UnsupportedOperationException("TODO: auto-generated method stub") + + } + + override removeValidator(DataStoreIdentifier store, DataValidator validator) { + throw new UnsupportedOperationException("TODO: auto-generated method stub") + } + + def DataProviderContext resolveProvider(DataStoreIdentifier store, Class root) { + } + +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/Constants.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/Constants.xtend similarity index 84% rename from opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/Constants.xtend rename to opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/Constants.xtend index 668635a39e..9fb2140e83 100644 --- a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/Constants.xtend +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/Constants.xtend @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.controller.sal.binding.impl +package org.opendaylight.controller.sal.binding.impl.osgi class Constants { @@ -16,6 +16,4 @@ class Constants { public static val SAL_SERVICE_TYPE_CONSUMER_PROXY = "consumerProxy" public static val SAL_SERVICE_TYPE_PROVIDER = "provider" public static val SAL_SERVICE_TYPE_CONNECTOR = "connector" - - public static val PROXY_DIRECT_SUFFIX = "DirectProxy"; } diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/PropertiesUtils.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/PropertiesUtils.xtend new file mode 100644 index 0000000000..d04ca7f4ce --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/PropertiesUtils.xtend @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.impl.osgi + +import java.util.Hashtable +import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.* + +class PropertiesUtils { + + private new() { + } + + static def setSalServiceType(Hashtable properties, String value) { + properties.put(SAL_SERVICE_TYPE, value) + return properties + } + + static def getSalServiceType(Hashtable properties) { + return properties.get(SAL_SERVICE_TYPE) + } + + static def newProperties() { + new Hashtable() + } + +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/package-info.java new file mode 100644 index 0000000000..d788ccf3a3 --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/package-info.java @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.impl.osgi; \ No newline at end of file diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/utils/GeneratorUtils.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/utils/GeneratorUtils.xtend deleted file mode 100644 index c888121eb9..0000000000 --- a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/utils/GeneratorUtils.xtend +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.impl.utils - -import javassist.ClassPool -import javassist.NotFoundException -import javassist.LoaderClassPath - -class GeneratorUtils { - - static val PREFIX = "_gen."; - - public static def generatedName(Class cls, String suffix) { - '''«PREFIX»«cls.package.name».«cls.simpleName»$«suffix»'''.toString() - } - - public static def get(ClassPool pool, Class cls) { - try { - return pool.get(cls.name) - } catch (NotFoundException e) { - pool.appendClassPath(new LoaderClassPath(cls.classLoader)); - return pool.get(cls.name) - } - } -} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/utils/PropertiesUtils.xtend b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/utils/PropertiesUtils.xtend deleted file mode 100644 index 7ba62f5ca1..0000000000 --- a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/utils/PropertiesUtils.xtend +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.impl.utils - -import java.util.Hashtable -import org.opendaylight.controller.sal.binding.impl.Constants - -class PropertiesUtils { - - private new() {} - - static def setSalServiceType(Hashtable properties, String value) { - properties.put(Constants.SAL_SERVICE_TYPE,value) - return properties - } - - static def getSalServiceType(Hashtable properties) { - return properties.get(Constants.SAL_SERVICE_TYPE) - } - - static def newProperties() { - new Hashtable() - } - -} \ No newline at end of file diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/utils/package-info.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/utils/package-info.java deleted file mode 100644 index 511023860e..0000000000 --- a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/utils/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.impl.utils; \ No newline at end of file diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/test/org/opendaylight/controller/sal/binding/test/GenerationTest.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/test/org/opendaylight/controller/sal/binding/test/GenerationTest.java new file mode 100644 index 0000000000..9bbb5013c0 --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/test/org/opendaylight/controller/sal/binding/test/GenerationTest.java @@ -0,0 +1,31 @@ +package org.opendaylight.controller.sal.binding.test; +import static org.junit.Assert.*; + +import java.util.concurrent.Future; + +import org.junit.Test; +import org.opendaylight.controller.sal.binding.impl.ProxyFactoryGenerator; +import org.opendaylight.controller.sal.binding.impl.RpcServiceProxy; +import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.yang.common.RpcResult; + + +public class GenerationTest { + + public interface MockService extends RpcService { + + Future> cancelToast(); + + Future> makeToast(String input); + } + + @Test + public void test() { + ProxyFactoryGenerator generator = new ProxyFactoryGenerator(); + Class> ret = generator.generate(MockService.class); + + assertTrue(RpcServiceProxy.class.isAssignableFrom(ret)); + assertTrue(MockService.class.isAssignableFrom(ret)); + } + +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java new file mode 100644 index 0000000000..5dddd1ab9d --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java @@ -0,0 +1,142 @@ +package org.opendaylight.controller.sal.binding.test; +import static org.junit.Assert.*; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import javassist.ClassPool; + +import org.junit.Before; +import org.junit.Test; +import static org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper.*; +import org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator; +import org.opendaylight.controller.sal.binding.test.mock.FooService; +import org.opendaylight.controller.sal.binding.test.mock.ReferencableObject; +import org.opendaylight.controller.sal.binding.test.mock.ReferencableObjectKey; +import org.opendaylight.controller.sal.binding.test.mock.SimpleInput; +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.binding.BaseIdentity; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; + +import static org.mockito.Mockito.*; + + +public class RuntimeCodeGeneratorTest { + + private RuntimeCodeGenerator codeGenerator; + + + @Before + public void initialize() { + this.codeGenerator = new RuntimeCodeGenerator(ClassPool.getDefault()); + } + + @Test + public void testGenerateDirectProxy() { + Class product = codeGenerator.generateDirectProxy(FooService.class); + assertNotNull(product); + } + + @Test + public void testGenerateRouter() throws Exception { + Class product = codeGenerator.generateRouter(FooService.class); + assertNotNull(product); + assertNotNull(product.getSimpleName()); + assertEquals("2 fields should be generated.",2,product.getFields().length); + + verifyRouting(product.newInstance()); + } + + private void verifyRouting(FooService product) { + Map routingTable = new HashMap<>(); + setRoutingTable(product, BaseIdentity.class, routingTable); + + assertSame("Returned routing table should be same instance",routingTable,getRoutingTable(product, BaseIdentity.class)); + + int servicesCount = 2; + int instancesPerService = 3; + + InstanceIdentifier[][] identifiers = identifiers(servicesCount,instancesPerService); + FooService service[] = new FooService[] { + mock(FooService.class, "Instance 0"), + mock(FooService.class,"Instance 1") + }; + + for(int i = 0;i pathArg = new IdentifiableItem<>(ReferencableObject.class,key); + return new InstanceIdentifier(Arrays.asList(pathArg), ReferencableObject.class); + } + + private static class SimpleInputImpl implements SimpleInput { + private final InstanceIdentifier identifier; + + public SimpleInputImpl(InstanceIdentifier _identifier) { + this.identifier = _identifier; + } + + @Override + public > E getAugmentation(Class augmentationType) { + return null; + } + + @Override + public InstanceIdentifier getIdentifier() { + return this.identifier; + } + } +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/BarUpdate.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/BarUpdate.java new file mode 100644 index 0000000000..b64ebdf86b --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/BarUpdate.java @@ -0,0 +1,7 @@ +package org.opendaylight.controller.sal.binding.test.mock; + +import org.opendaylight.yangtools.yang.binding.Notification; + +public interface BarUpdate extends Grouping,Notification { + +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/FooListener.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/FooListener.java new file mode 100644 index 0000000000..3629689cdf --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/FooListener.java @@ -0,0 +1,10 @@ +package org.opendaylight.controller.sal.binding.test.mock; + +import org.opendaylight.yangtools.yang.binding.NotificationListener; + +public interface FooListener extends NotificationListener { + + void onFooUpdate(FooUpdate notification); + void onBarUpdate(BarUpdate notification); + +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/FooService.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/FooService.java new file mode 100644 index 0000000000..3161e936dc --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/FooService.java @@ -0,0 +1,16 @@ +package org.opendaylight.controller.sal.binding.test.mock; + +import java.util.concurrent.Future; + +import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.yang.common.RpcResult; + +public interface FooService extends RpcService { + + Future> foo(); + + Future> simple(SimpleInput obj); + + Future> inheritedContextInput(InheritedContextInput obj); + +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/FooUpdate.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/FooUpdate.java new file mode 100644 index 0000000000..a5a5eb8ecb --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/FooUpdate.java @@ -0,0 +1,7 @@ +package org.opendaylight.controller.sal.binding.test.mock; + +import org.opendaylight.yangtools.yang.binding.Notification; + +public interface FooUpdate extends Notification { + +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/Grouping.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/Grouping.java new file mode 100644 index 0000000000..86624e0732 --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/Grouping.java @@ -0,0 +1,11 @@ +package org.opendaylight.controller.sal.binding.test.mock; + +import org.opendaylight.yangtools.yang.binding.BaseIdentity; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext; + +public interface Grouping { + + @RoutingContext(BaseIdentity.class) + InstanceIdentifier getInheritedIdentifier(); +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/InheritedContextInput.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/InheritedContextInput.java new file mode 100644 index 0000000000..39b20cc1f1 --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/InheritedContextInput.java @@ -0,0 +1,5 @@ +package org.opendaylight.controller.sal.binding.test.mock; + +public interface InheritedContextInput extends Grouping { + +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/ReferencableObject.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/ReferencableObject.java new file mode 100644 index 0000000000..8e0d4579eb --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/ReferencableObject.java @@ -0,0 +1,8 @@ +package org.opendaylight.controller.sal.binding.test.mock; + +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.Identifiable; + +public interface ReferencableObject extends DataObject,Identifiable { + +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/ReferencableObjectKey.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/ReferencableObjectKey.java new file mode 100644 index 0000000000..d2e18175e1 --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/ReferencableObjectKey.java @@ -0,0 +1,44 @@ +package org.opendaylight.controller.sal.binding.test.mock; + +import org.opendaylight.yangtools.yang.binding.Identifier; + +public class ReferencableObjectKey implements Identifier { + + final Integer value; + + public ReferencableObjectKey(Integer _value) { + this.value = _value; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ReferencableObjectKey other = (ReferencableObjectKey) obj; + if (value == null) { + if (other.value != null) + return false; + } else if (!value.equals(other.value)) + return false; + return true; + } + + @Override + public String toString() { + return "ReferencableObjectKey [value=" + value + "]"; + } + + +} diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/SimpleInput.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/SimpleInput.java new file mode 100644 index 0000000000..dedbd9885e --- /dev/null +++ b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/test/java/org/opendaylight/controller/sal/binding/test/mock/SimpleInput.java @@ -0,0 +1,13 @@ +package org.opendaylight.controller.sal.binding.test.mock; + +import org.opendaylight.yangtools.yang.binding.Augmentable; +import org.opendaylight.yangtools.yang.binding.BaseIdentity; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext; + +public interface SimpleInput extends DataObject,Augmentable { + + @RoutingContext(BaseIdentity.class) + InstanceIdentifier getIdentifier(); +} diff --git a/opendaylight/statisticsmanager/implementation/pom.xml b/opendaylight/statisticsmanager/implementation/pom.xml index 8be254e6b5..d7dea84686 100644 --- a/opendaylight/statisticsmanager/implementation/pom.xml +++ b/opendaylight/statisticsmanager/implementation/pom.xml @@ -21,7 +21,7 @@ jacoco reuseReports - target/jacoco.exec + target/jacoco.exec target/jacoco-it.exec java @@ -31,7 +31,7 @@ org.jacoco jacoco-maven-plugin - 0.5.3.201107060350 + ${jacoco.version} diff --git a/opendaylight/statisticsmanager/integrationtest/pom.xml b/opendaylight/statisticsmanager/integrationtest/pom.xml index 527dd0a02b..d620d676f4 100644 --- a/opendaylight/statisticsmanager/integrationtest/pom.xml +++ b/opendaylight/statisticsmanager/integrationtest/pom.xml @@ -104,7 +104,7 @@ jacoco ../implementation/target/jacoco.exec - ../implementaiton/target/jacoco-it.exec + ../implementation/target/jacoco-it.exec java @@ -121,7 +121,7 @@ org.jacoco jacoco-maven-plugin - 0.5.3.201107060350 + ${jacoco.version} ../implementation/target/jacoco-it.exec org.opendaylight.controller.* diff --git a/opendaylight/switchmanager/api/pom.xml b/opendaylight/switchmanager/api/pom.xml index 607c42858e..14a056d5fe 100644 --- a/opendaylight/switchmanager/api/pom.xml +++ b/opendaylight/switchmanager/api/pom.xml @@ -32,7 +32,7 @@ org.jacoco jacoco-maven-plugin - 0.5.3.201107060350 + ${jacoco.version} diff --git a/opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SpanConfig.java b/opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SpanConfig.java index 522f45946d..4bb6438b32 100644 --- a/opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SpanConfig.java +++ b/opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SpanConfig.java @@ -14,10 +14,8 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; -import org.opendaylight.controller.sal.core.ConstructionException; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; -import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType; import org.opendaylight.controller.sal.utils.GUIField; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -116,32 +114,12 @@ public class SpanConfig implements Serializable { } public ArrayList getPortArrayList() { - Node node = Node.fromString(nodeId); ArrayList portList = new ArrayList(); String[] elemArray = spanPort.split(","); for (String elem : elemArray) { - if (elem.contains("-")) { - String[] limits = elem.split("-"); - for (short j = Short.valueOf(limits[0]); j <= Short - .valueOf(limits[1]); j++) { - try { - portList.add(new NodeConnector( - NodeConnectorIDType.OPENFLOW, Short.valueOf(j), - node)); - } catch (ConstructionException e) { - logger.error("",e); - } - } - } else { - try { - portList.add(new NodeConnector( - NodeConnectorIDType.OPENFLOW, Short.valueOf(elem), - node)); - } catch (NumberFormatException e) { - logger.error("",e); - } catch (ConstructionException e) { - logger.error("",e); - } + NodeConnector nodeConnector = NodeConnector.fromString(elem); + if (nodeConnector != null) { + portList.add(nodeConnector); } } return portList; diff --git a/opendaylight/switchmanager/implementation/pom.xml b/opendaylight/switchmanager/implementation/pom.xml index 1b09f3c34d..ee126f3408 100644 --- a/opendaylight/switchmanager/implementation/pom.xml +++ b/opendaylight/switchmanager/implementation/pom.xml @@ -32,7 +32,7 @@ org.jacoco jacoco-maven-plugin - 0.5.3.201107060350 + ${jacoco.version} diff --git a/opendaylight/switchmanager/integrationtest/pom.xml b/opendaylight/switchmanager/integrationtest/pom.xml index d571d9df53..3fc63001d4 100644 --- a/opendaylight/switchmanager/integrationtest/pom.xml +++ b/opendaylight/switchmanager/integrationtest/pom.xml @@ -78,25 +78,16 @@ jacoco ../implementation/target/jacoco.exec - ../implementaiton/target/jacoco-it.exec + ../implementation/target/jacoco-it.exec java - - - - org.jacoco - jacoco-maven-plugin - 0.5.3.201107060350 - - - org.jacoco jacoco-maven-plugin - 0.5.3.201107060350 + ${jacoco.version} ../implementation/target/jacoco-it.exec org.opendaylight.controller.* diff --git a/opendaylight/topologymanager/pom.xml b/opendaylight/topologymanager/implementation/pom.xml similarity index 97% rename from opendaylight/topologymanager/pom.xml rename to opendaylight/topologymanager/implementation/pom.xml index 98bc0e42c8..399f878223 100755 --- a/opendaylight/topologymanager/pom.xml +++ b/opendaylight/topologymanager/implementation/pom.xml @@ -6,7 +6,7 @@ org.opendaylight.controller commons.opendaylight 1.4.0-SNAPSHOT - ../commons/opendaylight + ../../commons/opendaylight scm:git:ssh://git.opendaylight.org:29418/controller.git diff --git a/opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManager.java b/opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManager.java similarity index 100% rename from opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManager.java rename to opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManager.java diff --git a/opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManagerAware.java b/opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManagerAware.java similarity index 100% rename from opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManagerAware.java rename to opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManagerAware.java diff --git a/opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManagerClusterWideAware.java b/opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManagerClusterWideAware.java similarity index 100% rename from opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManagerClusterWideAware.java rename to opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManagerClusterWideAware.java diff --git a/opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/TopologyUserLinkConfig.java b/opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/TopologyUserLinkConfig.java similarity index 100% rename from opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/TopologyUserLinkConfig.java rename to opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/TopologyUserLinkConfig.java diff --git a/opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/internal/Activator.java b/opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/internal/Activator.java similarity index 100% rename from opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/internal/Activator.java rename to opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/internal/Activator.java diff --git a/opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImpl.java b/opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImpl.java similarity index 100% rename from opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImpl.java rename to opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImpl.java diff --git a/opendaylight/topologymanager/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java b/opendaylight/topologymanager/implementation/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java similarity index 100% rename from opendaylight/topologymanager/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java rename to opendaylight/topologymanager/implementation/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java diff --git a/opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/UserConfig.java b/opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/UserConfig.java index cca194e953..07c814adf1 100644 --- a/opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/UserConfig.java +++ b/opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/UserConfig.java @@ -34,9 +34,11 @@ public class UserConfig implements Serializable { protected String user; protected List roles; private String password; + + private static final boolean strongPasswordCheck = Boolean.getBoolean("enableStrongPasswordCheck"); + private static final String BAD_PASSWORD = "Bad Password"; private static final int USERNAME_MAXLENGTH = 32; - private static final int PASSWORD_MINLENGTH = 5; - private static final int PASSWORD_MAXLENGTH = 256; + protected static final String PASSWORD_REGEX = "(?=.*[^\\w])(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,256}$"; private static final Pattern INVALID_USERNAME_CHARACTERS = Pattern.compile("([/\\s\\.\\?#%;\\\\]+)"); private static MessageDigest oneWayFunction = null; static { @@ -63,16 +65,12 @@ public class UserConfig implements Serializable { public UserConfig(String user, String password, List roles) { this.user = user; - this.password = password; - if (this.validatePassword().isSuccess()) { - /* - * Only if the password is a valid one, hash it. So in case it is not - * valid, when UserConfig.validate() is called, the proper - * validation error will be returned to the caller. If we hashed a - * priori instead, the mis-configuration would be masked - */ - this.password = hash(this.password); - } + /* + * Password validation to be done on clear text password. If fails, mark + * the password with a well known label, so that object validation can + * report the proper error. Only if password is a valid one, hash it. + */ + this.password = (validatePassword(password).isSuccess()) ? hash(password) : BAD_PASSWORD; this.roles = (roles == null) ? new ArrayList() : new ArrayList(roles); } @@ -142,12 +140,15 @@ public class UserConfig implements Serializable { } public Status validate() { - Status validCheck = validateRoles(); + Status validCheck = validateUsername(); if (validCheck.isSuccess()) { - validCheck = validateUsername(); + validCheck = (!password.equals(BAD_PASSWORD)) ? new Status(StatusCode.SUCCESS) : new Status( + StatusCode.BADREQUEST, + "Password should be 8 to 256 characters long, contain both upper and lower case letters, " + + "at least one number and at least one non alphanumeric character"); } if (validCheck.isSuccess()) { - validCheck = validatePassword(); + validCheck = validateRoles(); } return validCheck; } @@ -168,15 +169,15 @@ public class UserConfig implements Serializable { return new Status(StatusCode.SUCCESS); } - private Status validatePassword() { + private Status validatePassword(String password) { if (password == null || password.isEmpty()) { return new Status(StatusCode.BADREQUEST, "Password cannot be empty"); } - if (password.length() < UserConfig.PASSWORD_MINLENGTH - || password.length() > UserConfig.PASSWORD_MAXLENGTH) { - return new Status(StatusCode.BADREQUEST, - "Password should have 5-256 characters"); + if (strongPasswordCheck && !password.matches(UserConfig.PASSWORD_REGEX)) { + return new Status(StatusCode.BADREQUEST, "Password should be 8 to 256 characters long, " + + "contain both upper and lower case letters, at least one number " + + "and at least one non alphanumeric character"); } return new Status(StatusCode.SUCCESS); } @@ -247,4 +248,25 @@ public class UserConfig implements Serializable { UserConfig.oneWayFunction.reset(); return HexEncode.bytesToHexString(UserConfig.oneWayFunction.digest(message.getBytes(Charset.defaultCharset()))); } + + /** + * Returns UserConfig instance populated with the passed parameters. It does + * not run any checks on the passed parameters. + * + * @param userName + * the user name + * @param password + * the plain text password + * @param roles + * the list of roles + * @return the UserConfig object populated with the passed parameters. No + * validity check is run on the input parameters. + */ + public static UserConfig getUncheckedUserConfig(String userName, String password, List roles) { + UserConfig config = new UserConfig(); + config.user = userName; + config.password = hash(password); + config.roles = roles; + return config; + } } diff --git a/opendaylight/usermanager/api/src/test/java/org/opendaylight/controller/usermanager/AuthorizationUserConfigTest.java b/opendaylight/usermanager/api/src/test/java/org/opendaylight/controller/usermanager/AuthorizationUserConfigTest.java index 4c2a19e426..8c029a7488 100644 --- a/opendaylight/usermanager/api/src/test/java/org/opendaylight/controller/usermanager/AuthorizationUserConfigTest.java +++ b/opendaylight/usermanager/api/src/test/java/org/opendaylight/controller/usermanager/AuthorizationUserConfigTest.java @@ -117,4 +117,41 @@ public class AuthorizationUserConfigTest { UserConfig userConfig2 = new UserConfig("uname", "ciscocisco", roles); assertEquals(userConfig, userConfig2); } + + @Test + public void userConfigPasswordTest() { + + String regex = UserConfig.PASSWORD_REGEX; + String password = null; + + // Good password + password = "aBc@eF#h9"; + assertTrue(password.matches(regex)); + password = "^aBc@eF#h9$88ad*o&"; + assertTrue(password.matches(regex)); + password = "_^aBc@\":eF#h;9$\\8|8ad*o&-(){}/,.> roles = new ArrayList(1); roles.add(DEFAULT_ADMIN_ROLE); - localUserConfigList.put(DEFAULT_ADMIN, new UserConfig(DEFAULT_ADMIN, DEFAULT_ADMIN_PASSWORD, roles)); + // Need to skip the strong password check for the default admin + UserConfig defaultAdmin = UserConfig.getUncheckedUserConfig(UserManager.DEFAULT_ADMIN, + UserManager.DEFAULT_ADMIN_PASSWORD, roles); + localUserConfigList.put(UserManager.DEFAULT_ADMIN, defaultAdmin); } }