<ietf.interfaces.version>2014.05.08.9-SNAPSHOT</ietf.interfaces.version>
<iana.if.type.version>2014.05.08.9-SNAPSHOT</iana.if.type.version>
<yang.ext.version>2013.09.07.9-SNAPSHOT</yang.ext.version>
- <yangtools.version>0.9.0-SNAPSHOT</yangtools.version>
+ <yangtools.version>1.0.0-SNAPSHOT</yangtools.version>
<mdsal.version>2.1.0-SNAPSHOT</mdsal.version>
<controller.mdsal.version>1.4.0-SNAPSHOT</controller.mdsal.version>
<vpns.mdsalutil.version>0.3.0-SNAPSHOT</vpns.mdsalutil.version>
<properties>
<!-- ODL -->
<vpnservices.version>0.3.0-SNAPSHOT</vpnservices.version>
- <yangtools.version>0.9.0-SNAPSHOT</yangtools.version>
+ <yangtools.version>1.0.0-SNAPSHOT</yangtools.version>
+ <mdsal.model.version>0.9.0-SNAPSHOT</mdsal.model.version>
<controller.mdsal.version>1.4.0-SNAPSHOT</controller.mdsal.version>
<vpns.mdsalutil.version>0.3.0-SNAPSHOT</vpns.mdsalutil.version>
<model.bgp.version>2013.07.15.9-SNAPSHOT</model.bgp.version>
<dependency>
<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>mdsal-model-artifacts</artifactId>
- <version>0.9.0-SNAPSHOT</version>
+ <version>${mdsal.model.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<maven>3.1.1</maven>
</prerequisites>
<properties>
- <karaf.localFeature>odl-vpnservice-core</karaf.localFeature>
+ <!-- <karaf.localFeature>odl-vpnservice-core</karaf.localFeature> -->
</properties>
<dependencyManagement>
<dependencies>
<mdsal.version>1.4.0-SNAPSHOT</mdsal.version>
<openflowplugin.version>0.3.0-SNAPSHOT</openflowplugin.version>
<restconf.version>1.4.0-SNAPSHOT</restconf.version>
- <yangtools.version>0.9.0-SNAPSHOT</yangtools.version>
+ <yangtools.version>1.0.0-SNAPSHOT</yangtools.version>
<mdsal.model.version>0.9.0-SNAPSHOT</mdsal.model.version>
<vpnservices.version>0.3.0-SNAPSHOT</vpnservices.version>
<ovsdb.version>1.3.0-SNAPSHOT</ovsdb.version>
<liblldp.version>0.11.0-SNAPSHOT</liblldp.version>
<neutron.version>0.7.0-SNAPSHOT</neutron.version>
+ <nic.version>1.2.0-SNAPSHOT</nic.version>
<arputil.version>${vpnservices.version}</arputil.version>
<mdsalutil.version>${vpnservices.version}</mdsalutil.version>
<vpnmanager.version>${vpnservices.version}</vpnmanager.version>
<type>xml</type>
<scope>runtime</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.nic</groupId>
+ <artifactId>features-nic</artifactId>
+ <classifier>features</classifier>
+ <version>${nic.version}</version>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
<groupId>org.opendaylight.ovsdb</groupId>
<artifactId>features-ovsdb</artifactId>
<artifactId>commons-net</artifactId>
<version>${commons.net.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>vpnintent-api</artifactId>
+ <version>${vpnservices.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>vpnintent-impl</artifactId>
+ <version>${vpnservices.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>vpnintent-impl</artifactId>
+ <version>${vpnservices.version}</version>
+ <classifier>config</classifier>
+ <type>xml</type>
+ </dependency>
</dependencies>
</project>
<repository>mvn:org.opendaylight.netconf/features-restconf/${restconf.version}/xml/features</repository>
<repository>mvn:org.opendaylight.ovsdb/features-ovsdb/${ovsdb.version}/xml/features</repository>
<repository>mvn:org.opendaylight.neutron/features-neutron/${neutron.version}/xml/features</repository>
+ <repository>mvn:org.opendaylight.nic/features-nic/{{VERSION}}/xml/features</repository>
<feature name='odl-vpnservice-api' version='${project.version}' description='OpenDaylight :: vpnservice :: api '>
<feature version='${mdsal.version}'>odl-mdsal-broker</feature>
<feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
<bundle>mvn:org.opendaylight.vpnservice/elanmanager-impl/${elanmgr.version}</bundle>
<!--<bundle>mvn:org.opendaylight.vpnservice.third-party/org.apache.thriftlib/1.1.0-SNAPSHOT</bundle>-->
+ <!--<bundle>mvn:org.opendaylight.vpnservice.third-party/org.apache.thriftlib/1.0.1-SNAPSHOT</bundle>-->
<bundle>wrap:mvn:org.apache.thrift/libthrift/0.9.1$overwrite=merge&Bundle-Version=0.9.1&Export-Package=*;-noimport:=true;version="0.9.1"</bundle>
<!--<bundle>wrap:mvn:javax.servlet/servlet-api/2.5</bundle>-->
<configfile finalname="lockmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/lockmanager-impl/${lockmanager.version}/xml/config</configfile>
<feature name='odl-vpnservice-openstack' version='${project.version}' description='OpenDaylight :: vpnservice :: impl :: REST '>
<feature version="${project.version}">odl-vpnservice-impl</feature>
</feature>
+ <feature name='odl-vpnservice-intent' version='${project.version}' description='OpenDaylight :: vpnservice :: intent'>
+ <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
+ <feature version='${nic.version}'>odl-nic-core-service-mdsal</feature>
+ <feature version='${nic.version}'>odl-nic-core</feature>
+ <feature version='${nic.version}'>odl-nic-listeners</feature>
+ <bundle>mvn:org.opendaylight.vpnservice/vpnintent-api/{{VERSION}}</bundle>
+ <bundle>mvn:org.opendaylight.vpnservice/vpnintent-impl/{{VERSION}}</bundle>
+ <configfile finalname="vpnintent-impl-default-config.xml">mvn:org.opendaylight.vpnservice/vpnintent-impl/{{VERSION}}/xml/config</configfile>
+ </feature>
</features>
localDpnId, remoteDpnId, vpnId, prefixIp, nextHopIp);
LOG.trace("getRemoteNextHopPointer: Calling ITM with localDpnId {} ", localDpnId);
- try{
- // here use the config for tunnel type param
- tunnelIfName = getTunnelInterfaceName(remoteDpnId, IpAddressBuilder.getDefaultInstance(nextHopIp));
- }catch(Exception ex){
- LOG.error("Error while retrieving nexthop pointer for DC Gateway : ", ex.getMessage());
+ if (nextHopIp != null && !nextHopIp.isEmpty()) {
+ try{
+ // here use the config for tunnel type param
+ tunnelIfName = getTunnelInterfaceName(remoteDpnId, IpAddressBuilder.getDefaultInstance(nextHopIp));
+ }catch(Exception ex){
+ LOG.error("Error while retrieving nexthop pointer for nexthop {} : ", nextHopIp, ex.getMessage());
+ }
}
return tunnelIfName;
}
<dependency>
<groupId>org.opendaylight.mdsal</groupId>
<artifactId>yang-binding</artifactId>
- <version>${yangtools.version}</version>
+ <version>${mdsal.model.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
return;
}
String portname = NeutronvpnUtils.uuidToTapPortName(port.getUuid());
- String name = new StringBuilder(portname).append(":0").toString();
List<Adjacency> adjList = new ArrayList<Adjacency>();
InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
- child(VpnInterface.class, new VpnInterfaceKey(name)).build();
+ child(VpnInterface.class, new VpnInterfaceKey(portname)).build();
// find router associated to vpn
Uuid routerId = NeutronvpnUtils.getRouterforVpn(broker, vpnId);
Router rtr = null;
// create extra route adjacency
if (rtr != null && rtr.getRoutes() != null) {
List<String> routeList = rtr.getRoutes();
- List<Adjacency> erAdjList = addAdjacencyforExtraRoute(routeList, false, name);
+ List<Adjacency> erAdjList = addAdjacencyforExtraRoute(routeList, false, portname);
if (erAdjList != null) {
adjList.addAll(erAdjList);
}
}
// create vpn-interface on this neutron port
Adjacencies adjs = new AdjacenciesBuilder().setAdjacency(adjList).build();
- VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(name)).
- setName(name).setVpnInstanceName(vpnId.getValue()).addAugmentation(Adjacencies.class, adjs);
+ VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(portname)).
+ setName(portname).setVpnInstanceName(vpnId.getValue()).addAugmentation(Adjacencies.class, adjs);
VpnInterface vpnIf = vpnb.build();
- NeutronvpnUtils.lockVpnInterface(lockManager, name);
+ NeutronvpnUtils.lockVpnInterface(lockManager, portname);
try {
logger.debug("Creating vpn interface {}", vpnIf);
MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
} catch (Exception ex) {
- logger.error("Creation of vpninterface {} failed due to {}", name, ex);
+ logger.error("Creation of vpninterface {} failed due to {}", portname, ex);
} finally {
- NeutronvpnUtils.unlockVpnInterface(lockManager, name);
+ NeutronvpnUtils.unlockVpnInterface(lockManager, portname);
}
}
if (port != null) {
String pname = NeutronvpnUtils.uuidToTapPortName(port.getUuid());
- String name = new StringBuilder(pname).append(":0").toString();
InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
- child(VpnInterface.class, new VpnInterfaceKey(name)).build();
+ child(VpnInterface.class, new VpnInterfaceKey(pname)).build();
- NeutronvpnUtils.lockVpnInterface(lockManager, name);
+ NeutronvpnUtils.lockVpnInterface(lockManager, pname);
try {
- logger.debug("Deleting vpn interface {}", name);
+ logger.debug("Deleting vpn interface {}", pname);
MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
} catch (Exception ex) {
- logger.error("Deletion of vpninterface {} failed due to {}", name, ex);
+ logger.error("Deletion of vpninterface {} failed due to {}", pname, ex);
} finally {
- NeutronvpnUtils.unlockVpnInterface(lockManager, name);
+ NeutronvpnUtils.unlockVpnInterface(lockManager, pname);
}
}
}
String destination = parts[1];
String tapPortName = NeutronvpnUtils.getNeutronPortNamefromPortFixedIp(broker, nextHop);
- String ifname = new StringBuilder(tapPortName).append(":0").toString();
logger.trace("Adding extra route with nexthop {}, destination {}, ifName {}", nextHop,
- destination, ifname);
+ destination, tapPortName);
Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIp(nextHop).setKey
(new AdjacencyKey(destination)).build();
if (rtrUp == false) {
- if (ifname.equals(vpnifname)) {
+ if (tapPortName.equals(vpnifname)) {
adjList.add(erAdj);
}
continue;
}
InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
- child(VpnInterface.class, new VpnInterfaceKey(ifname)).build();
+ child(VpnInterface.class, new VpnInterfaceKey(tapPortName)).build();
Optional<VpnInterface> optionalVpnInterface = NeutronvpnUtils.read(broker, LogicalDatastoreType
.CONFIGURATION, vpnIfIdentifier);
if (optionalVpnInterface.isPresent()) {
Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(erAdj)).build();
- VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(ifname))
+ VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(tapPortName))
.addAugmentation(Adjacencies.class, erAdjs).build();
MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
logger.trace("extra route {} added successfully", route);
} else {
logger.error("VM adjacency for interface {} not present ; cannot add extra route adjacency",
- ifname);
+ tapPortName);
}
} else {
logger.error("Incorrect input received for extra route. {}", parts);
String destination = parts[1];
String tapPortName = NeutronvpnUtils.getNeutronPortNamefromPortFixedIp(broker, nextHop);
- String ifname = new StringBuilder(tapPortName).append(":0").toString();
logger.trace("Removing extra route with nexthop {}, destination {}, ifName {}", nextHop,
- destination, ifname);
+ destination, tapPortName);
InstanceIdentifier<Adjacency> adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
- child(VpnInterface.class, new VpnInterfaceKey(ifname)).augmentation(Adjacencies.class)
+ child(VpnInterface.class, new VpnInterfaceKey(tapPortName)).augmentation(Adjacencies.class)
.child(Adjacency.class, new AdjacencyKey(destination)).build();
MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
logger.trace("extra route {} deleted successfully", route);
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 INTERNAL
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>org.opendaylight.vpnservice</groupId>
<artifactId>vpnservice</artifactId>
<version>0.3.0-SNAPSHOT</version>
<module>distribution/karaf</module>
<module>features</module>
<module>vpnservice-artifacts</module>
+ <module>vpnintent</module>
</modules>
<!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
<url>https://wiki.opendaylight.org/view/VPNService:Main</url>
<tag>HEAD</tag>
</scm>
-</project>
+</project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2016 Inocybe Technologies 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.opendaylight.vpnservice</groupId>
+ <artifactId>binding-parent</artifactId>
+ <version>0.3.0-SNAPSHOT</version>
+ <relativePath>../../commons/binding-parent</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.opendaylight.vpnservice</groupId>
+ <artifactId>vpnintent-api</artifactId>
+ <version>${vpnservices.version}</version>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-inet-types</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-yang-types</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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 INTERNAL
+ */
+module vpnintent {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:vpnintent";
+ prefix "vpnintent";
+
+ import ietf-inet-types { prefix inet; revision-date 2010-09-24;}
+
+ revision "2015-01-05" {
+ description "Initial revision of VPN intent model.
+ Create VPN via Intent, keep VPN state and manage MPLS labels";
+ }
+
+ container vpns{
+ list vpn-intents {
+ key "vpn-name";
+ uses vpn-intent;
+ }
+ }
+
+ typedef failover-type {
+ type enumeration {
+ enum fast-reroute {
+ value 1;
+ }
+ enum slow-reroute {
+ value 2;
+ }
+ }
+ }
+
+ grouping vpn-intent {
+ leaf vpn-name {
+ type string;
+ description "VPN name";
+ mandatory true;
+ }
+ leaf path-protection {
+ type boolean;
+ }
+ leaf failover-type {
+ type failover-type;
+ }
+ list endpoint {
+ key "site-name";
+ uses endpoint-fields;
+ description "List to keep track site name and endpoint.";
+ }
+ }
+
+ grouping endpoint-fields {
+ leaf site-name{
+ type string;
+ description "VPN member site name.";
+ }
+
+ leaf ip-prefix {
+ type inet:ip-prefix;
+ description "VPN member IP prefix.";
+ }
+
+ leaf switch-port-id {
+ type string;
+ description "Switch and port ID that VPN member is connected to.";
+ }
+ }
+
+ grouping labels {
+ list label {
+ key "label-id";
+ leaf "label-id"{
+ type uint32 {
+ range "0 .. 524288";
+ }
+ description "20 bit MPLS label ID";
+ mandatory true;
+ }
+ uses endpoint-fields;
+ description "Keep track of MPLS/other label endpoint relation.";
+ }
+ }
+
+ container mpls-labels {
+ uses labels;
+ }
+
+ rpc add-vpn-endpoint{
+ description
+ "Add VPN endpoint.";
+ input {
+ leaf vpn-name {
+ type string;
+ description "VPN name";
+ mandatory true;
+ }
+ uses endpoint-fields;
+ }
+ }
+
+ rpc remove-vpn-endpoint{
+ description
+ "Remove VPN endpoint.";
+ input {
+ leaf vpn-name {
+ type string;
+ description "VPN name";
+ mandatory true;
+ }
+ leaf site-name{
+ type string;
+ description "VPN member site name.";
+ }
+ }
+ }
+
+ rpc remove-vpn{
+ description
+ "Remove VPN and its endpoints.";
+ input {
+ leaf vpn-name {
+ type string;
+ description "VPN name";
+ mandatory true;
+ }
+ }
+ }
+ }
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2016 Inocybe Technologies 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 INTERNAL
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.opendaylight.vpnservice</groupId>
+ <artifactId>config-parent</artifactId>
+ <version>0.3.0-SNAPSHOT</version>
+ <relativePath>../../commons/config-parent</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>vpnintent-impl</artifactId>
+ <version>${vpnservices.version}</version>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <nic.version>1.2.0-SNAPSHOT</nic.version>
+ <powermock.version>1.5.2</powermock.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>vpnintent-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- NIC dependency -->
+ <dependency>
+ <groupId>org.opendaylight.nic</groupId>
+ <artifactId>intent-api</artifactId>
+ <version>${nic.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.nic</groupId>
+ <artifactId>utils</artifactId>
+ <version>${nic.version}</version>
+ </dependency>
+
+ <!-- Testing Dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito</artifactId>
+ <version>${powermock.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ <version>${powermock.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.nic</groupId>
+ <artifactId>intent-mapping-interface</artifactId>
+ <version>${nic.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+Copyright (c) 2016 Inocybe Technologies 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
+-->
+<snapshot>
+ <required-capabilities>
+ <capability>urn:opendaylight:params:xml:ns:yang:vpnintent:impl?module=vpnintent-impl&revision=2014-12-10</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28</capability>
+ </required-capabilities>
+ <configuration>
+
+ <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:vpnintent:impl">prefix:vpnintent-impl</type>
+ <name>vpnintent-impl-default</name>
+ <broker>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+ <name>binding-osgi-broker</name>
+ </broker>
+ <rpc-registry>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+ <name>binding-rpc-broker</name>
+ </rpc-registry>
+ </module>
+ </modules>
+ </data>
+ </configuration>
+</snapshot>
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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.vpnservice.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.nic.utils.MdsalUtils;
+import org.opendaylight.vpnservice.utils.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.constraints.rev150122.FailoverType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.Intents;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.IntentsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.Actions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.ActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.Constraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.ConstraintsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.Subjects;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.SubjectsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.actions.action.allow.AllowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.actions.action.block.BlockBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.constraints.constraints.failover.constraint.FailoverConstraintBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.constraints.constraints.protection.constraint.ProtectionConstraintBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.end.point.group.EndPointGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.end.point.group.EndPointGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intents.Intent;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intents.IntentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intents.IntentKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.types.rev150122.Uuid;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+
+public class IntentServiceManager {
+
+ /**
+ * This class is used to build Intents object and
+ * write it to Network Intent Composition md-sal tree
+ * in order to create/delete intents between two endpoint groups.
+ */
+
+ private static final Logger LOG = LoggerFactory.getLogger(IntentServiceManager.class);
+ private static final short FIRST_SUBJECT = 1;
+ private static final short SECOND_SUBJECT = 2;
+ public static final String ACTION_ALLOW = "ALLOW";
+ public static final String ACTION_BLOCK = "BLOCK";
+ public static final String FAST_REROUTE = "fast-reroute";
+ public static final String SLOW_REROUTE = "slow-reroute";
+ private final DataBroker dataBroker;
+ private static final InstanceIdentifier<Intents> INTENTS_IID = IidFactory.getIntentsIid();
+ private MdsalUtils mdsal;
+
+ public IntentServiceManager(DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
+ this.mdsal = new MdsalUtils(dataBroker);
+ }
+
+ /**
+ * Create Intents object and write to to config tree to trigger intents
+ * @param src :Source Site Name
+ * @param dst :Destination Site Name
+ * @param intentAction :Intent verb: ALLOW or BLOCK
+ * @param failOverType
+ */
+ public void addIntent(String src, String dst, String intentAction, String failOverType) {
+ Preconditions.checkNotNull(src);
+ Preconditions.checkNotNull(dst);
+ Preconditions.checkNotNull(intentAction);
+
+ List<Intent> intentList = null;
+ List<Subjects> subjects = createSubjects(dst, src);
+ List<Actions> intentActions = createActions(intentAction);
+ List<Constraints> intentConstraints = createConstraints(failOverType);
+
+ Intent intent = new IntentBuilder().setId(new Uuid(UUID.randomUUID().toString()))
+ .setSubjects(subjects).setActions(intentActions)
+ .setConstraints(intentConstraints)
+ .build();
+
+ Intents currentIntents = mdsal.read(LogicalDatastoreType.CONFIGURATION, INTENTS_IID);
+ if (currentIntents == null) {
+ intentList = new ArrayList<>();
+ } else {
+ intentList = currentIntents.getIntent();
+ }
+ intentList.add(intent);
+ Intents intents = new IntentsBuilder().setIntent(intentList).build();
+ mdsal.put(LogicalDatastoreType.CONFIGURATION, INTENTS_IID, intents);
+ LOG.info("AddIntent: config populated: {}", intents);
+ }
+
+ /**
+ * Delete an Intent
+ * @param id :Uuid of the Intent to be deleted
+ */
+ public void removeIntent(Uuid id) {
+ Preconditions.checkNotNull(id);
+ InstanceIdentifier<Intent> iid = InstanceIdentifier.create(Intents.class).child(Intent.class, new IntentKey(id));
+ mdsal.delete(LogicalDatastoreType.CONFIGURATION, iid);
+ LOG.info("RemoveIntent succeeded");
+ }
+
+ /**
+ * Remove all associated intents by endpointGroupName
+ * @param endpointGroupName
+ */
+ public void removeIntentsByEndpoint(String endpointGroupName) {
+ Preconditions.checkNotNull(endpointGroupName);
+
+ Intents intents = mdsal.read(LogicalDatastoreType.CONFIGURATION, INTENTS_IID);
+
+ if (intents != null && intents.getIntent() != null) {
+ for (Intent intent : intents.getIntent()) {
+ if (intent.getSubjects() != null && intent.getSubjects().size() > 0) {
+ String endpointValue = "";
+ for (Subjects subject : intent.getSubjects()) {
+ if (subject
+ .getSubject() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroup) {
+ org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroup epg = (org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroup) subject
+ .getSubject();
+ endpointValue = epg.getEndPointGroup().getName();
+ } else if (subject
+ .getSubject() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointSelector) {
+ org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointSelector epg = (org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointSelector) subject
+ .getSubject();
+ endpointValue = epg.getEndPointSelector().getEndPointSelector();
+ } else if (subject
+ .getSubject() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroupSelector) {
+ org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroupSelector epg = (org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroupSelector) subject
+ .getSubject();
+ endpointValue = epg.getEndPointGroupSelector().getEndPointGroupSelector();
+ }
+ if (endpointValue.equalsIgnoreCase(endpointGroupName)) {
+ removeIntent(intent.getId());
+ LOG.info("Deleted Intent ID : {} for endpoint: {}", intent.getId(), endpointGroupName);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Create a list of Intent actions
+ * @param intentAction
+ * @return :a list of Actions
+ */
+ private List<Actions> createActions(String intentAction) {
+ List<Actions> actionsList = new ArrayList<Actions>();
+ short order = 1;
+ org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.actions.Action action = null;
+ if (intentAction.equalsIgnoreCase(ACTION_ALLOW)) {
+ action = new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.actions.action
+ .AllowBuilder().setAllow(new AllowBuilder().build()).build();
+ } else if (intentAction.equalsIgnoreCase(ACTION_BLOCK)) {
+ action = new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.actions.action
+ .BlockBuilder().setBlock(new BlockBuilder().build()).build();
+ }
+
+ Actions intentActions = new ActionsBuilder().setOrder(order).setAction(action).build();
+ actionsList.add(intentActions);
+ return actionsList;
+ }
+
+ /**
+ * Create a list of Intent subjects
+ * @param src :Source Site Name
+ * @param dst :Destination Site Name
+ * @return :a list of Subjects
+ */
+ private List<Subjects> createSubjects(String src, String dst) {
+ List<Subjects> subjectList = new ArrayList<Subjects>();
+
+ EndPointGroup endpointGroupFrom = new EndPointGroupBuilder().setName(src).build();
+ org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroup fromEPG =
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject
+ .EndPointGroupBuilder().setEndPointGroup(endpointGroupFrom).build();
+ Subjects subjects1 = new SubjectsBuilder().setOrder(FIRST_SUBJECT).setSubject(fromEPG).build();
+
+ EndPointGroup endpointGroupTo = new EndPointGroupBuilder().setName(dst).build();
+ org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroup toEPG =
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject
+ .EndPointGroupBuilder().setEndPointGroup(endpointGroupTo).build();
+ Subjects subjects2 = new SubjectsBuilder().setOrder(SECOND_SUBJECT).setSubject(toEPG).build();
+
+ subjectList.add(subjects1);
+ subjectList.add(subjects2);
+ return subjectList;
+ }
+
+ /**
+ * Create a list of Intent constraints
+ * @param failOverType :Type of failover, fast-reroute or slow-reroute
+ * @return
+ */
+ private List<Constraints> createConstraints(String failOverType) {
+ List<Constraints> intentConstraints = new ArrayList<Constraints>();
+ if (failOverType==null) {
+ return intentConstraints;
+ }
+ short order = 1;
+ org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.constraints.Constraints
+ protectionConstraint = null;
+ org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.constraints.Constraints
+ failoverConstraint = null;
+ if (failOverType.equals(FAST_REROUTE)) {
+ protectionConstraint = new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent
+ .constraints.constraints.ProtectionConstraintBuilder()
+ .setProtectionConstraint(new ProtectionConstraintBuilder().setIsProtected(true).build()).build();
+ failoverConstraint = new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.constraints
+ .constraints.FailoverConstraintBuilder()
+ .setFailoverConstraint(new FailoverConstraintBuilder().setFailoverSelector(FailoverType.FastReroute).build())
+ .build();
+ } else if (failOverType.equals(SLOW_REROUTE)) {
+ protectionConstraint = new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent
+ .constraints.constraints.ProtectionConstraintBuilder()
+ .setProtectionConstraint(new ProtectionConstraintBuilder().setIsProtected(true).build()).build();
+ failoverConstraint = new org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.constraints
+ .constraints.FailoverConstraintBuilder()
+ .setFailoverConstraint(new FailoverConstraintBuilder().setFailoverSelector(FailoverType.SlowReroute).build())
+ .build();
+ }
+ Constraints constraint1 = new ConstraintsBuilder().setOrder(order).setConstraints(protectionConstraint).build();
+ Constraints constraint2 = new ConstraintsBuilder().setOrder(++order).setConstraints(failoverConstraint).build();
+ intentConstraints.add(constraint1);
+ intentConstraints.add(constraint2);
+ return intentConstraints;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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.vpnservice.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.opendaylight.nic.mapping.api.IntentMappingService;
+
+import com.google.common.base.Preconditions;
+
+public class MappingServiceManager {
+
+ private IntentMappingService intentMappingService;
+ private String IP_PREFIX_PROPERTY = "ip_prefix";
+ private String SWITCH_PORT_ID_PROPERTY = "switch_port";
+ private String MPLS_LABEL_PROPERTY = "mpls_label";
+ private String NEXT_HOP_PROPERTY = "next_hop";
+
+ public MappingServiceManager(IntentMappingService intentMappingService) {
+ Preconditions.checkNotNull(intentMappingService);
+ this.intentMappingService = intentMappingService;
+ }
+
+ /**
+ * @param siteName
+ * Name of the member
+ * @param ipPrefix
+ * Ip prefix of the member
+ * @param switchPortId
+ * Switch ID and port ID (i.e. openflow:1:2)
+ * @param mplsLabel
+ * MPLS label, if needed
+ * @param nextHop
+ * Next hop in the route
+ */
+ public void add(final String siteName, final String ipPrefix, final String switchPortId, final Long mplsLabel,
+ final String nextHop) {
+ Preconditions.checkNotNull(siteName);
+ Preconditions.checkNotNull(ipPrefix);
+ Preconditions.checkNotNull(switchPortId);
+
+ Map<String, String> objs = new HashMap<>();
+ objs.put(IP_PREFIX_PROPERTY, ipPrefix);
+ objs.put(SWITCH_PORT_ID_PROPERTY, switchPortId);
+
+ if (mplsLabel != null)
+ objs.put(MPLS_LABEL_PROPERTY, String.valueOf(mplsLabel));
+ if (nextHop != null)
+ objs.put(NEXT_HOP_PROPERTY, nextHop);
+
+ intentMappingService.add(siteName, objs);
+ }
+
+ /**
+ * @param siteName
+ * Name of the member
+ * @return Map of parameters related to the member
+ */
+ public Map<String, String> get(String siteName) {
+ return intentMappingService.get(siteName);
+ }
+
+ /**
+ * @param siteName
+ * Name of the member
+ * @return Return true if transaction succeed, otherwise false
+ */
+ public boolean delete(String siteName) {
+ try {
+ // TODO: Implement delete() in mapping service
+ // By now, it's going to overwrite data for this key
+ intentMappingService.add(siteName, null);
+ return true;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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.vpnservice.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.nic.utils.MdsalUtils;
+import org.opendaylight.vpnservice.utils.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.MplsLabels;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.labels.Label;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.labels.LabelBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.labels.LabelKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.vpn.intent.Endpoint;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MplsLabelManagerService {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MplsLabelManagerService.class);
+ private static final Integer MAX_MPLS_LABEL = 524288;
+ private static InstanceIdentifier<Label> LABEL_IID = null;
+ public static final InstanceIdentifier<MplsLabels> MPLS_LABELS_IID = IidFactory.getMplsLabelsIid();
+ private final DataBroker dataBroker;
+ private final Random random = new Random();
+ private MdsalUtils mdsal;
+
+ public MplsLabelManagerService(DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
+ this.mdsal = new MdsalUtils(this.dataBroker);
+ }
+
+ /**
+ * Generate a unique Mpls Label
+ * Mpls label is of length 20 bits maximum
+ * @return :next unique Mpls label value
+ */
+ public Long getUniqueLabel(Endpoint endpoint) {
+ Long nextUniqueLabel = (long) random.nextInt(MAX_MPLS_LABEL);
+ while(checkIsLabelUsed(nextUniqueLabel)) {
+ nextUniqueLabel = (long) random.nextInt(MAX_MPLS_LABEL);
+ }
+ updateToLabelStore(nextUniqueLabel, endpoint, true);
+ return nextUniqueLabel;
+ }
+
+ /**
+ * Delete label from datastore
+ * @param endpoint :endpoint whose label needs to be deleted
+ */
+ public void deleteLabel(Endpoint endpoint) {
+ Map<Long, String> labelMap = getAllLabels();
+ for (Map.Entry<Long, String> labelEntry : labelMap.entrySet()) {
+ if(labelEntry.getValue().equalsIgnoreCase(endpoint.getSiteName())) {
+ updateToLabelStore(labelEntry.getKey(), endpoint, false);
+ }
+ }
+ }
+
+ /**
+ * Update the model for Labels with used Mpls label values
+ * @param label :mpls label allocated to an endpoint
+ * @param endpoint :endpoint to which mpls label is allocated to
+ * @param add :true if add label to datastore, false to delete label from datastore
+ */
+ private void updateToLabelStore(Long label, Endpoint endpoint, boolean add) {
+ LABEL_IID = IidFactory.getLabelIid(label);
+ Label mplsLabel = new LabelBuilder().
+ setKey(new LabelKey(label)).
+ setLabelId(label).
+ setSiteName(endpoint.getSiteName()).
+ setIpPrefix(endpoint.getIpPrefix()).
+ setSwitchPortId(endpoint.getSwitchPortId()).build();
+
+ if(add) {
+ mdsal.put(LogicalDatastoreType.OPERATIONAL, LABEL_IID, mplsLabel);
+ LOG.info("Add mpls label to operational datastore: {} for endpoint: {}", label, endpoint.getSiteName());
+ } else {
+ mdsal.delete(LogicalDatastoreType.OPERATIONAL, LABEL_IID);
+ LOG.info("Delete mpls label from operational datastore: {} for endpoint: {}", label, endpoint.getSiteName());
+ }
+ }
+
+ /**
+ * Check if label is already allocated to any endpoint
+ * @param nextUniqueLabel :value of mpls label
+ * @return :true is label is already used else false
+ */
+ private boolean checkIsLabelUsed(Long nextUniqueLabel) {
+ Map<Long, String> labelMap = getAllLabels();
+ if(labelMap.containsKey(nextUniqueLabel)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Get a map of all the labels allocated to the endpoints
+ * @return :hashmap of labels as key, site names as value
+ */
+ private Map<Long, String> getAllLabels() {
+ Map<Long, String> labelMap = new HashMap<>();
+ MplsLabels mplsLabels = mdsal.read(LogicalDatastoreType.OPERATIONAL, MPLS_LABELS_IID);
+ if(mplsLabels != null) {
+ for (Label label : mplsLabels.getLabel()) {
+ labelMap.put(label.getLabelId(), label.getSiteName());
+ }
+ }
+ return labelMap;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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.vpnservice.impl;
+
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.nic.mapping.api.IntentMappingService;
+import org.opendaylight.nic.utils.MdsalUtils;
+import org.opendaylight.vpnservice.utils.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.AddVpnEndpointInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.FailoverType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.MplsLabels;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.MplsLabelsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.RemoveVpnEndpointInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.RemoveVpnInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.VpnintentService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.Vpns;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.VpnsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.vpn.intent.Endpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.vpn.intent.EndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.vpn.intent.EndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.vpns.VpnIntents;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.vpns.VpnIntentsKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+
+public class VpnintentProvider implements VpnintentService, BindingAwareProvider, AutoCloseable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(VpnintentProvider.class);
+ public static final InstanceIdentifier<MplsLabels> LABELS_IID = IidFactory.getMplsLabelsIid();
+ public static final InstanceIdentifier<Vpns> VPN_IID = IidFactory.getVpnsIid();
+ public static final InstanceIdentifier<VpnIntents> VPN_INTENT_IID = IidFactory.getVpnIntentIid();
+ public static final InstanceIdentifier<Endpoint> ENDPOINT_IID = IidFactory.getEndpointIid();
+
+ private DataBroker dataBroker;
+ private IntentMappingService intentMappingService;
+ private BindingAwareBroker.RpcRegistration<VpnintentService> rpcRegistration = null;
+ private MdsalUtils mdsal;
+
+ @Override
+ public void onSessionInitiated(ProviderContext session) {
+ LOG.info("VpnintentProvider Session Initiated");
+ dataBroker = session.getSALService(DataBroker.class);
+ rpcRegistration = session.addRpcImplementation(VpnintentService.class, this);
+ this.mdsal = new MdsalUtils(this.dataBroker);
+
+ // Load IntentMappingService Reference
+ loadIntentMappingServiceReference();
+
+ Vpns vpns = new VpnsBuilder().build();
+ MplsLabels labels = new MplsLabelsBuilder().build();
+
+ // Initialize MD-SAL data store for vpn-intents and mpls-labels
+ initDatastore(LogicalDatastoreType.CONFIGURATION, VPN_IID, vpns);
+ initDatastore(LogicalDatastoreType.OPERATIONAL, LABELS_IID, labels);
+ }
+
+ @Override
+ public void close() throws Exception {
+ LOG.info("VpnintentProvider Closed");
+ }
+
+ private <T extends DataObject> void initDatastore(LogicalDatastoreType store, InstanceIdentifier<T> iid, T object) {
+ // Put data to MD-SAL data store
+ WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
+ transaction.put(store, iid, object);
+
+ // Perform the tx.submit asynchronously
+ Futures.addCallback(transaction.submit(), new FutureCallback<Void>() {
+ @Override
+ public void onSuccess(final Void result) {
+ LOG.info("initDatastore for VPN-Intents: transaction succeeded");
+ }
+
+ @Override
+ public void onFailure(final Throwable throwable) {
+ LOG.error("initDatastore for VPN-Intents: transaction failed");
+ }
+ });
+ LOG.info("initDatastore: data populated: {}, {}, {}", store, iid, object);
+ }
+
+ @Override
+ public Future<RpcResult<Void>> removeVpn(RemoveVpnInput input) {
+ InstanceIdentifier<VpnIntents> vpnIdentifier = InstanceIdentifier.builder(Vpns.class)
+ .child(VpnIntents.class, new VpnIntentsKey(input.getVpnName())).build();
+ MappingServiceManager msManager = new MappingServiceManager(intentMappingService);
+ MplsLabelManagerService mplsManager = new MplsLabelManagerService(dataBroker);
+
+ VpnIntents vpn = getVpn(input.getVpnName());
+
+ if (vpn.getEndpoint() != null && vpn.getEndpoint().size() > 0) {
+ for (Endpoint endpoint : vpn.getEndpoint()) {
+ // Release MPLS label
+ mplsManager.deleteLabel(endpoint);
+
+ // Remove all intents related to this endpoint
+ IntentServiceManager intentManager = new IntentServiceManager(dataBroker);
+ intentManager.removeIntentsByEndpoint(endpoint.getSiteName());
+
+ // Remove info from Mapping Service
+ msManager.delete(endpoint.getSiteName());
+ }
+ }
+
+ mdsal.delete(LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
+ LOG.info("Deleted VPN {}", input.getVpnName());
+ return Futures.immediateFuture(RpcResultBuilder.<Void> success().build());
+ }
+
+ @Override
+ public Future<RpcResult<Void>> addVpnEndpoint(AddVpnEndpointInput input) {
+ Endpoint currentEndpoint = new EndpointBuilder().setIpPrefix(input.getIpPrefix())
+ .setSiteName(input.getSiteName()).setSwitchPortId(input.getSwitchPortId())
+ .setKey(new EndpointKey(input.getSiteName())).build();
+ VpnIntents vpn = getVpn(input.getVpnName());
+ String failOverType = null;
+ if (vpn.isPathProtection() && vpn.getFailoverType()!= null) {
+ if (vpn.getFailoverType().equals(FailoverType.FastReroute)) {
+ failOverType = IntentServiceManager.FAST_REROUTE;
+ } else if(vpn.getFailoverType().equals(FailoverType.SlowReroute)) {
+ failOverType = IntentServiceManager.SLOW_REROUTE;
+ }
+ }
+
+ MplsLabelManagerService mplsManager = new MplsLabelManagerService(dataBroker);
+
+ // Get unique MPLS label
+ Long mplsLabel = mplsManager.getUniqueLabel(currentEndpoint);
+
+ // Add info into Mapping Service
+ MappingServiceManager msManager = new MappingServiceManager(intentMappingService);
+ msManager.add(currentEndpoint.getSiteName(), extractIP(currentEndpoint.getIpPrefix()),
+ currentEndpoint.getSwitchPortId(), mplsLabel, null);
+
+ if (vpn.getEndpoint() != null && vpn.getEndpoint().size() > 0) {
+ IntentServiceManager intentManager = new IntentServiceManager(dataBroker);
+
+ for (Endpoint member : vpn.getEndpoint()) {
+ // Create mesh of Intents
+ intentManager.addIntent(member.getSiteName(), currentEndpoint.getSiteName(),
+ IntentServiceManager.ACTION_ALLOW, failOverType);
+ intentManager.addIntent(currentEndpoint.getSiteName(), member.getSiteName(),
+ IntentServiceManager.ACTION_ALLOW, failOverType);
+ }
+ }
+ // Associate endpoint with VPN
+ addEndpointToVpn(vpn, currentEndpoint);
+
+ return Futures.immediateFuture(RpcResultBuilder.<Void> success().build());
+ }
+
+ /**
+ * @param IpPrefix
+ * object
+ * @return String representation of IP prefix
+ */
+ private String extractIP(IpPrefix ipPrefix) {
+ String ip = null;
+ if (ipPrefix.getIpv4Prefix() != null) {
+ ip = ipPrefix.getIpv4Prefix().getValue();
+ } else if (ipPrefix.getIpv6Prefix() != null) {
+ ip = ipPrefix.getIpv6Prefix().getValue();
+ }
+ return ip;
+ }
+
+ /**
+ * @param vpnName
+ * VPN name
+ * @return VPN instance
+ */
+ private VpnIntents getVpn(String vpnName) {
+ InstanceIdentifier<VpnIntents> identifier = InstanceIdentifier.builder(Vpns.class)
+ .child(VpnIntents.class, new VpnIntentsKey(vpnName)).build();
+
+ VpnIntents vpnIntents = mdsal.read(LogicalDatastoreType.CONFIGURATION, identifier);
+ Preconditions.checkNotNull(vpnIntents);
+ return vpnIntents;
+ }
+
+ @Override
+ public Future<RpcResult<Void>> removeVpnEndpoint(RemoveVpnEndpointInput input) {
+ Endpoint endpoint = getEndpoint(input.getVpnName(), input.getSiteName());
+
+ // Release MPLS label
+ MplsLabelManagerService mplsManager = new MplsLabelManagerService(dataBroker);
+ mplsManager.deleteLabel(endpoint);
+
+ // Remove all intents related to this endpoint
+ IntentServiceManager intentManager = new IntentServiceManager(dataBroker);
+ intentManager.removeIntentsByEndpoint(input.getSiteName());
+
+ // Remove endpoint from VPN
+ removeEndpointFromVpn(input.getVpnName(), input.getSiteName());
+
+ return Futures.immediateFuture(RpcResultBuilder.<Void> success().build());
+ }
+
+ /**
+ * @param siteName
+ * Site name of the VPN member
+ * @return VPN member (Endpoint)
+ */
+ private Endpoint getEndpoint(String vpnName, String siteName) {
+ InstanceIdentifier<Endpoint> endpointID = InstanceIdentifier.builder(Vpns.class)
+ .child(VpnIntents.class, new VpnIntentsKey(vpnName)).child(Endpoint.class, new EndpointKey(siteName))
+ .build();
+
+ return mdsal.read(LogicalDatastoreType.CONFIGURATION, endpointID);
+ }
+
+ /**
+ * @param vpnName
+ * VPN name
+ * @param siteName
+ * Site name
+ */
+ private void removeEndpointFromVpn(String vpnName, String siteName) {
+ InstanceIdentifier<Endpoint> identifier = InstanceIdentifier.builder(Vpns.class)
+ .child(VpnIntents.class, new VpnIntentsKey(vpnName)).child(Endpoint.class, new EndpointKey(siteName))
+ .build();
+
+ mdsal.delete(LogicalDatastoreType.CONFIGURATION, identifier);
+ LOG.info("Deleted VPN member : {} from VPN: {}", siteName, vpnName);
+ }
+
+ /**
+ * @param vpn
+ * VPN
+ * @param vpnMember
+ * VPN member (endpoint)
+ */
+ private void addEndpointToVpn(VpnIntents vpn, Endpoint vpnMember) {
+ InstanceIdentifier<Endpoint> identifier = InstanceIdentifier.builder(Vpns.class)
+ .child(VpnIntents.class, vpn.getKey())
+ .child(Endpoint.class, vpnMember.getKey()).build();
+
+ mdsal.put(LogicalDatastoreType.CONFIGURATION, identifier, vpnMember);
+ LOG.info("Added VPN member : {} to VPN: {}", vpnMember.getSiteName(), vpn.getVpnName());
+ }
+
+ /**
+ * Load IntentMappingService reference
+ */
+ private void loadIntentMappingServiceReference() {
+ ServiceReference<?> serviceReference = getBundleCtx().getServiceReference(IntentMappingService.class);
+ intentMappingService = (IntentMappingService) getBundleCtx().getService(serviceReference);
+ }
+
+ private BundleContext getBundleCtx() {
+ return FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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.vpnservice.utils;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.Intents;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.MplsLabels;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.Vpns;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.labels.Label;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.labels.LabelKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.vpn.intent.Endpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.rev150105.vpns.VpnIntents;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class IidFactory {
+
+ public static InstanceIdentifier<MplsLabels> getMplsLabelsIid() {
+ return InstanceIdentifier.builder(MplsLabels.class).build();
+ }
+
+ public static InstanceIdentifier<Label> getLabelIid(Long label) {
+ return InstanceIdentifier.create(MplsLabels.class).child(Label.class, new LabelKey(label));
+ }
+
+ public static InstanceIdentifier<Intents> getIntentsIid() {
+ return InstanceIdentifier.builder(Intents.class).build();
+ }
+
+ public static InstanceIdentifier<Vpns> getVpnsIid() {
+ return InstanceIdentifier.builder(Vpns.class).build();
+ }
+
+ public static InstanceIdentifier<VpnIntents> getVpnIntentIid() {
+ return InstanceIdentifier.builder(Vpns.class).child(VpnIntents.class).build();
+ }
+
+ public static InstanceIdentifier<Endpoint> getEndpointIid() {
+ return InstanceIdentifier.builder(Vpns.class).child(VpnIntents.class).child(Endpoint.class).build();
+ }
+}
--- /dev/null
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.impl.rev141210;
+
+import org.opendaylight.vpnservice.impl.VpnintentProvider;
+
+public class VpnintentImplModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.impl.rev141210.AbstractVpnintentImplModule {
+ public VpnintentImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public VpnintentImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.impl.rev141210.VpnintentImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void customValidation() {
+ // add custom validation form module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ VpnintentProvider provider = new VpnintentProvider();
+ getBrokerDependency().registerProvider(provider);
+ return provider;
+ }
+
+}
--- /dev/null
+/*
+* Generated file
+*
+* Generated from: yang module name: vpnintent-impl yang module local name: vpnintent-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Dec 16 22:44:32 EST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.impl.rev141210;
+public class VpnintentImplModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpnintent.impl.rev141210.AbstractVpnintentImplModuleFactory {
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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 INTERNAL
+ */
+module vpnintent-impl {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:vpnintent:impl";
+ prefix "vpnintent-impl";
+
+ import config { prefix config; revision-date 2013-04-05; }
+ import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
+
+ description
+ "Service definition for vpnintent project";
+
+ revision "2014-12-10" {
+ description
+ "Initial revision";
+ }
+
+ identity vpnintent-impl {
+ base config:module-type;
+ config:java-name-prefix VpnintentImpl;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case vpnintent-impl {
+ when "/config:modules/config:module/config:type = 'vpnintent-impl'";
+ container broker {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity md-sal-binding:binding-broker-osgi-registry;
+ }
+ }
+ }
+ container rpc-registry {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity md-sal-binding:binding-rpc-registry;
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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.vpnservice.impl;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.nic.utils.MdsalUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.Intents;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.IntentsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intents.Intent;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intents.IntentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.types.rev150122.Uuid;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.api.support.membermodification.MemberModifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@PrepareForTest({IntentServiceManager.class})
+@RunWith(PowerMockRunner.class)
+public class IntentServiceManagerTest {
+
+ private static final String SRC_SITE_NAME = "site a";
+ private static final String DST_SITE_NAME = "site b";
+ private static final String INTENT_ALLOW_ACTION = "ALLOW";
+ private IntentServiceManager intentServiceManager;
+ @Mock private MdsalUtils mdsal;
+
+ @Before
+ public void setUp() throws Exception {
+ intentServiceManager = mock(IntentServiceManager.class, Mockito.CALLS_REAL_METHODS);
+ MemberModifier.field(IntentServiceManager.class, "mdsal").set(intentServiceManager, mdsal);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testAddIntent() throws Exception {
+ IntentBuilder intentBldr = mock(IntentBuilder.class);
+ PowerMockito.whenNew(IntentBuilder.class).withNoArguments().thenReturn(intentBldr);
+ when(intentBldr.setId(any(Uuid.class))).thenReturn(intentBldr);
+ when(intentBldr.setSubjects(any(List.class))).thenReturn(intentBldr);
+ when(intentBldr.setActions(any(List.class))).thenReturn(intentBldr);
+ when(intentBldr.setConstraints(any(List.class))).thenReturn(intentBldr);
+ when(intentBldr.build()).thenReturn(mock(Intent.class));
+
+ Intents currentIntents = mock(Intents.class);
+ PowerMockito.when(mdsal.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(currentIntents);
+ IntentsBuilder intentsBldr = mock(IntentsBuilder.class);
+ PowerMockito.whenNew(IntentsBuilder.class).withNoArguments().thenReturn(intentsBldr);
+ when(intentsBldr.setIntent(any(List.class))).thenReturn(intentsBldr);
+ PowerMockito.when(mdsal.put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Intents.class))).thenReturn(true);
+
+ intentServiceManager.addIntent(SRC_SITE_NAME, DST_SITE_NAME, INTENT_ALLOW_ACTION, "fast-reroute");
+ verify(intentBldr).setId(any(Uuid.class));
+ verify(mdsal).read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+ verify(mdsal).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Intents.class));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testRemoveIntents() {
+ Uuid id = mock(Uuid.class);
+ when(mdsal.delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(true);
+
+ intentServiceManager.removeIntent(id);
+ verify(mdsal).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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.vpnservice.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.opendaylight.nic.mapping.api.IntentMappingService;
+
+public class MappingServiceManagerTests {
+
+ @Test
+ public void addInfo() {
+ // Arrange
+ String siteName = "UoR";
+ String ipPrefix = "16.101.233.2/8";
+ String switchPortId = "openflow:1:3";
+ long mplsLabel = 10L;
+ String nextHop = "16.101.233.1/8";
+
+ Map<String, String> map = new HashMap<>();
+ map.put("ip_prefix", ipPrefix);
+ map.put("switch_port", switchPortId);
+ map.put("mpls_label", String.valueOf(mplsLabel));
+ map.put("next_hop", nextHop);
+
+ IntentMappingService mapSvc = mock(IntentMappingService.class);
+ when(mapSvc.get(any(String.class))).thenReturn(map);
+
+ MappingServiceManager manager = new MappingServiceManager(mapSvc);
+
+ // Act
+ manager.add(siteName, ipPrefix, switchPortId, mplsLabel, nextHop);
+
+ Map<String, String> returnedObjs = manager.get(siteName);
+
+ // Assert
+ assertEquals(ipPrefix, returnedObjs.get("ip_prefix"));
+ assertEquals(switchPortId, returnedObjs.get("switch_port"));
+ assertEquals(mplsLabel, Long.parseLong(returnedObjs.get("mpls_label")));
+ assertEquals(nextHop, returnedObjs.get("next_hop"));
+ }
+
+ @Test
+ public void removeInfo() {
+ // Arrange
+ String siteName = "UoR";
+ String ipPrefix = "16.101.233.2/8";
+ String switchPortId = "openflow:1:3";
+
+ Map<String, String> map = new HashMap<>();
+ map.put("ip_prefix", ipPrefix);
+ map.put("switch_port", switchPortId);
+
+ IntentMappingService mapSvc = mock(IntentMappingService.class);
+
+ MappingServiceManager manager = new MappingServiceManager(mapSvc);
+
+ // Add first to delete next
+ manager.add(siteName, ipPrefix, switchPortId, null, null);
+
+ // Act
+ boolean result = manager.delete(siteName);
+
+ // Assert
+ assertTrue(result);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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.vpnservice.impl;
+
+import static org.mockito.Mockito.mock;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+
+public class VpnintentProviderTest {
+ @Ignore
+ @Test
+ public void testOnSessionInitiated() {
+ VpnintentProvider provider = new VpnintentProvider();
+
+ // ensure no exceptions
+ // currently this method is empty
+ provider.onSessionInitiated(mock(BindingAwareBroker.ProviderContext.class));
+ }
+
+ @Ignore
+ @Test
+ public void testClose() throws Exception {
+ VpnintentProvider provider = new VpnintentProvider();
+
+ // ensure no exceptions
+ // currently this method is empty
+ provider.close();
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2016 Inocybe Technologies 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 INTERNAL
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>odlparent-lite</artifactId>
+ <version>1.7.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.opendaylight.vpnservice</groupId>
+ <artifactId>vpnintent-aggregator</artifactId>
+ <version>0.3.0-SNAPSHOT</version>
+ <name>vpnintent</name>
+ <packaging>pom</packaging>
+ <modelVersion>4.0.0</modelVersion>
+ <prerequisites>
+ <maven>3.1.1</maven>
+ </prerequisites>
+ <modules>
+ <module>api</module>
+ <module>impl</module>
+ </modules>
+ <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
+
--- /dev/null
+{
+ "id": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "name": "VPN Intents",
+ "description": "Apply protection and failover-type constraints to VpnService and NIC. When protections is set to true, and failover type is either soft-reroute or hard-reroute then the end-to-end connectivity is self-healing in case of link/node failure. VpnService shall create Intent object with constraints embedded in it (constraints are set by users) and NIC renders flows according based on the constraints.\n\nDisjoint Path Calculation using Suurballe Algorithm when soft-reroute constraint is applied to NIC, two disjoint paths are calculated. When one of the paths is non-usable due to a link/node failure the other disjoint path is automatically invoked to push required flows for all the intents that get affection by the failed path.\n\nDelete flows from the switch when an intent is removed: NIC did not support deleting flows from the nodes when an intent was removed, this was also fixed.",
+ "order": [],
+ "folders": [
+ {
+ "id": "d424223b-11b7-b00d-3875-70b5fb4e6e85",
+ "name": "Add Members to VPN",
+ "description": "",
+ "order": [
+ "bfcc70b5-208a-d64e-7277-f4174b5f9ff9",
+ "45328601-ed77-b7ff-0ae6-c5734c69c170",
+ "84f7e114-532c-02d4-45fa-6e335f2a7e5d",
+ "6421391f-20de-e31b-00a4-5cf36297c074"
+ ],
+ "owner": "255113",
+ "collectionId": "6f9c9d85-2bda-9f02-eaec-a5269af5c0b5"
+ },
+ {
+ "id": "2049f3c6-ebf5-a456-61de-ee9abd1811f4",
+ "name": "Create VPN",
+ "description": "",
+ "order": [
+ "e5f75d2a-c350-e601-5029-e6e5ea736eef",
+ "91d91020-d5e0-2aaf-6c09-ed9cdec077de",
+ "72ac6ee2-90a8-36b1-0dda-9eb886df197c"
+ ],
+ "owner": "255113",
+ "collectionId": "6f9c9d85-2bda-9f02-eaec-a5269af5c0b5"
+ },
+ {
+ "id": "a2deb454-a0e6-3870-0c64-ba7fdffaccba",
+ "name": "MPLS Label Management",
+ "description": "Includes a set of GET operations to access the labels assigned to each member",
+ "order": [
+ "e7ba99ee-7804-d411-e652-9d932687a35c"
+ ],
+ "owner": "255113",
+ "collectionId": "efd3dae9-0818-468a-0d86-86fcec008d22"
+ },
+ {
+ "id": "118a7d9f-7925-4e75-d59a-f9c151b1c4c4",
+ "name": "Network Intent Composition Operations",
+ "description": "GET operations to check the state of Intents",
+ "order": [
+ "109d1ae7-bdd4-907e-be5d-61b6f493640b"
+ ],
+ "owner": "255113",
+ "collectionId": "748af960-874f-028d-cbd0-74134a3c6db7"
+ },
+ {
+ "id": "3ab1d430-5cc5-f506-0619-b827cc6f645b",
+ "name": "Remove Member from VPN",
+ "description": "",
+ "order": [
+ "d3250d1d-ca8d-9a31-dec7-4ded8720e530",
+ "42034ad0-1789-a773-6be3-9b9b5c4881bf",
+ "13757df8-f5ea-c933-a991-b9a8e4d60b07",
+ "0063438d-94b1-5ca3-88f2-1d789f3d2251"
+ ],
+ "owner": "255113",
+ "collectionId": "6f9c9d85-2bda-9f02-eaec-a5269af5c0b5"
+ },
+ {
+ "id": "3958cf6c-b82e-f0d4-a5c3-ce0bb85464c7",
+ "name": "Remove VPN",
+ "description": "",
+ "order": [
+ "63050e81-9cac-5de5-2180-7ed5c6bd361a",
+ "b0ac20bf-7cad-e958-761c-a83a456afdd4"
+ ],
+ "owner": "255113"
+ }
+ ],
+ "timestamp": 1450878947771,
+ "owner": "255113",
+ "remoteLink": "",
+ "public": false,
+ "requests": [
+ {
+ "id": "0063438d-94b1-5ca3-88f2-1d789f3d2251",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/operations/vpnintent:remove-vpn-endpoint",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1452741595237,
+ "name": "Remove Member 4 (site 4) from unprotected VPN",
+ "description": "Remove a Member from a VPN\n\nParameters description\nsite-name: Name of the member\nvpn-name: The VPN from which the member should be deleted",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "responses": [],
+ "rawModeData": "{\n \"input\": {\n \"vpn-name\": \"VPN unprotected\",\n \"site-name\": \"site 4\"\n }\n}"
+ },
+ {
+ "id": "109d1ae7-bdd4-907e-be5d-61b6f493640b",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/config/intent:intents/",
+ "pathVariables": {},
+ "preRequestScript": "",
+ "method": "GET",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "data": [],
+ "dataMode": "params",
+ "name": "GET intents",
+ "description": "Gets a list of intents added",
+ "descriptionFormat": "html",
+ "time": 1450721033712,
+ "version": 2,
+ "responses": [],
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "folder": "118a7d9f-7925-4e75-d59a-f9c151b1c4c4"
+ },
+ {
+ "id": "13757df8-f5ea-c933-a991-b9a8e4d60b07",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/operations/vpnintent:remove-vpn-endpoint",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1452741569695,
+ "name": "Remove Member 3 (site 3) from unprotected VPN",
+ "description": "Remove a Member from a VPN\n\nParameters description\nsite-name: Name of the member\nvpn-name: The VPN from which the member should be deleted",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "responses": [],
+ "rawModeData": "{\n \"input\": {\n \"vpn-name\": \"VPN unprotected\",\n \"site-name\": \"site 3\"\n }\n}"
+ },
+ {
+ "id": "42034ad0-1789-a773-6be3-9b9b5c4881bf",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/operations/vpnintent:remove-vpn-endpoint",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1452741544712,
+ "name": "Remove Member 2 (site 2) from protected VPN",
+ "description": "Remove a Member from a VPN\n\nParameters description\nsite-name: Name of the member\nvpn-name: The VPN from which the member should be deleted",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "responses": [],
+ "rawModeData": "{\n \"input\": {\n \"vpn-name\": \"VPN protected\",\n \"site-name\": \"site 2\"\n }\n}"
+ },
+ {
+ "id": "45328601-ed77-b7ff-0ae6-c5734c69c170",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/operations/vpnintent:add-vpn-endpoint",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1452741386479,
+ "name": "Add Member 2 (site 2) to protected VPN",
+ "description": "Add a Member to a protected VPN\n\nParameters description\nsite-name: Name of the member\nip-prefix: The IP Prefix associated with the Site-Name\nswitch-port-id: The PE switch id:port to which the site is connected to\nvpn-name: The VPN to which the member should belong to",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "responses": [],
+ "rawModeData": "{\n \"input\": {\n \"vpn-name\": \"VPN protected\",\n \"site-name\": \"site 2\",\n \"ip-prefix\": \"10.0.0.2/32\",\n \"switch-port-id\": \"openflow:2:1\"\n }\n}"
+ },
+ {
+ "id": "63050e81-9cac-5de5-2180-7ed5c6bd361a",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/operations/vpnintent:remove-vpn",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1452741509183,
+ "name": "Remove protected VPN",
+ "description": "Delete a VPN\n\nParameters description\nvpn-name: The VPN that needs to be deleted",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "responses": [],
+ "rawModeData": "{\n \"input\": {\n \"vpn-name\": \"VPN protected\"\n }\n}"
+ },
+ {
+ "id": "6421391f-20de-e31b-00a4-5cf36297c074",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/operations/vpnintent:add-vpn-endpoint",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1452741358417,
+ "name": "Add Member 4 (site 4) to unprotected VPN",
+ "description": "Add a Member to an unprotected VPN\n\nParameters description\nsite-name: Name of the member\nip-prefix: The IP Prefix associated with the Site-Name\nswitch-port-id: The PE switch id:port to which the site is connected to\nvpn-name: The VPN to which the member should belong to",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "responses": [],
+ "rawModeData": "{\n \"input\": {\n \"vpn-name\": \"VPN unprotected\",\n \"site-name\": \"site 4\",\n \"ip-prefix\": \"10.0.0.4/32\",\n \"switch-port-id\": \"openflow:4:1\"\n }\n}"
+ },
+ {
+ "id": "72ac6ee2-90a8-36b1-0dda-9eb886df197c",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/config/vpnintent:vpns/",
+ "pathVariables": {},
+ "preRequestScript": "",
+ "method": "GET",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "data": [],
+ "dataMode": "params",
+ "name": "GET VPNs",
+ "description": "Gets a list of all the VPNs along with the list of members that belong to these VPNs",
+ "descriptionFormat": "html",
+ "time": 1450716801343,
+ "version": 2,
+ "responses": [],
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "folder": "2049f3c6-ebf5-a456-61de-ee9abd1811f4"
+ },
+ {
+ "id": "84f7e114-532c-02d4-45fa-6e335f2a7e5d",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/operations/vpnintent:add-vpn-endpoint",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1452741323406,
+ "name": "Add Member 3 (site 3) to unprotected VPN",
+ "description": "Add a Member to an unprotected VPN\n\nParameters description\nsite-name: Name of the member\nip-prefix: The IP Prefix associated with the Site-Name\nswitch-port-id: The PE switch id:port to which the site is connected to\nvpn-name: The VPN to which the member should belong to",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "responses": [],
+ "rawModeData": "{\n \"input\": {\n \"vpn-name\": \"VPN unprotected\",\n \"site-name\": \"site 3\",\n \"ip-prefix\": \"10.0.0.1/32\",\n \"switch-port-id\": \"openflow:3:1\"\n }\n}"
+ },
+ {
+ "id": "91d91020-d5e0-2aaf-6c09-ed9cdec077de",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/config/vpnintent:vpns/",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1452741250149,
+ "name": "Create an unprotected VPN",
+ "description": "Create a protected VPN by pushing to config data tree to the Vpn-intents Yang model\n\nParameters description\nvpn-name: The name of the VPN that you intend to create\nprotection: True if path protection is needed\nfailover-type: Type of failover mechanism\n - slow-reroute\n - fast-reroute",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "responses": [],
+ "rawModeData": "{\n \"vpn-intents\": [\n {\n \"vpn-name\": \"VPN unprotected\",\n \"path-protection\": \"false\",\n \"failover-type\": \"slow-reroute\"\n }\n ]\n}"
+ },
+ {
+ "id": "b0ac20bf-7cad-e958-761c-a83a456afdd4",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/operations/vpnintent:remove-vpn",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1452741501187,
+ "name": "Remove unprotected VPN",
+ "description": "Delete a VPN\n\nParameters description\nvpn-name: The VPN that needs to be deleted",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "responses": [],
+ "rawModeData": "{\n \"input\": {\n \"vpn-name\": \"VPN unprotected\"\n }\n}"
+ },
+ {
+ "id": "bfcc70b5-208a-d64e-7277-f4174b5f9ff9",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/operations/vpnintent:add-vpn-endpoint",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1452741369995,
+ "name": "Add Member 1 (site 1) to protected VPN",
+ "description": "Add a Member to a protected VPN\n\nParameters description\nsite-name: Name of the member\nip-prefix: The IP Prefix associated with the Site-Name\nswitch-port-id: The PE switch id:port to which the site is connected to\nvpn-name: The VPN to which the member should belong to",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "responses": [],
+ "rawModeData": "{\n \"input\": {\n \"vpn-name\": \"VPN protected\",\n \"site-name\": \"site 1\",\n \"ip-prefix\": \"10.0.0.1/32\",\n \"switch-port-id\": \"openflow:1:1\"\n }\n}"
+ },
+ {
+ "id": "d3250d1d-ca8d-9a31-dec7-4ded8720e530",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/operations/vpnintent:remove-vpn-endpoint",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1452741522615,
+ "name": "Remove Member 1 (site 1) from protected VPN",
+ "description": "Remove a Member from a VPN\n\nParameters description\nsite-name: Name of the member\nvpn-name: The VPN from which the member should be deleted",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "responses": [],
+ "rawModeData": "{\n \"input\": {\n \"vpn-name\": \"VPN protected\",\n \"site-name\": \"site 1\"\n }\n}"
+ },
+ {
+ "id": "e5f75d2a-c350-e601-5029-e6e5ea736eef",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/config/vpnintent:vpns/",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1452741238916,
+ "name": "Create a protected VPN",
+ "description": "Create a protected VPN by pushing to config data tree to the Vpn-intents Yang model\n\nParameters description\nvpn-name: The name of the VPN that you intend to create\nprotection: True if path protection is needed\nfailover-type: Type of failover mechanism\n - slow-reroute\n - fast-reroute",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "responses": [],
+ "rawModeData": "{\n \"vpn-intents\": [\n {\n \"vpn-name\": \"VPN protected\",\n \"path-protection\": \"true\",\n \"failover-type\": \"slow-reroute\"\n }\n ]\n}"
+ },
+ {
+ "id": "e7ba99ee-7804-d411-e652-9d932687a35c",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/xml\nContent-Type: application/json\n",
+ "url": "http://localhost:8181/restconf/operational/vpnintent:mpls-labels",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "GET",
+ "data": [],
+ "dataMode": "params",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1452282516268,
+ "name": "GET all unique MPLS Labels",
+ "description": "Gets a list of unique labels assigned to every Member in the VPN",
+ "collectionId": "6250512e-90d0-2fb5-259d-2496c6cd8426",
+ "responses": [],
+ "folder": "a2deb454-a0e6-3870-0c64-ba7fdffaccba"
+ }
+ ]
+}
\ No newline at end of file
LOG.info("Received port UP event for interface {} ", interfaceName);
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
configInterface = InterfaceUtils.getInterface(broker, interfaceName);
+ BigInteger dpnId = InterfaceUtils.getDpIdFromInterface(intrf);
if (configInterface != null && configInterface.getType().equals(Tunnel.class)) {
- BigInteger dpnId = InterfaceUtils.getDpnForInterface(interfaceManager, interfaceName);
if(intrf.getOperStatus().equals(Interface.OperStatus.Up)) {
//advertise all prefixes in all vpns for this dpn to bgp
vpnInterfaceManager.updatePrefixesForDPN(dpnId, VpnInterfaceManager.UpdateRouteAction.ADVERTISE_ROUTE);
}
} else {
- vpnInterfaceManager.processVpnInterfaceUp(interfaceName, intrf.getIfIndex());
+ vpnInterfaceManager.processVpnInterfaceUp(dpnId, interfaceName, intrf.getIfIndex());
}
} catch (Exception e) {
LOG.error("Exception caught in Interface Operational State Up event", e);
LOG.info("Received port DOWN event for interface {} ", interfaceName);
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
intf = InterfaceUtils.getInterface(broker, interfaceName);
+ BigInteger dpId = InterfaceUtils.getDpIdFromInterface(intrf);
if (intf != null && intf.getType().equals(Tunnel.class)) {
- // Get the dpId from del reference itself. Because interfaceManager.getDpnForInterface returns
- // NPE because entry is already deleted in operational data store
- BigInteger dpId = getDpIdFromInterface(intrf);
- if (dpId == null) {
- return;
- }
if(intrf.getOperStatus().equals(Interface.OperStatus.Down)) {
//withdraw all prefixes in all vpns for this dpn from bgp
vpnInterfaceManager.updatePrefixesForDPN(dpId, VpnInterfaceManager.UpdateRouteAction.WITHDRAW_ROUTE);
}
} else {
if (VpnUtil.isVpnInterfaceConfigured(broker, interfaceName)) {
- vpnInterfaceManager.processVpnInterfaceDown(interfaceName, intrf.getIfIndex(), true);
+ vpnInterfaceManager.processVpnInterfaceDown(dpId, interfaceName, intrf.getIfIndex(), true);
}
}
} catch (Exception e) {
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
intf = InterfaceUtils.getInterface(broker, interfaceName);
if (intf != null && intf.getType().equals(Tunnel.class)) {
- BigInteger dpnId = InterfaceUtils.getDpnForInterface(interfaceManager, interfaceName);
+ BigInteger dpnId = InterfaceUtils.getDpIdFromInterface(update);
if(update.getOperStatus().equals(Interface.OperStatus.Up)) {
//advertise all prefixes in all vpns for this dpn to bgp
vpnInterfaceManager.updatePrefixesForDPN(dpnId, VpnInterfaceManager.UpdateRouteAction.ADVERTISE_ROUTE);
}
- public BigInteger getDpIdFromInterface(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface infState) {
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
- InterfaceUtils.getInterfaceStateFromOperDS(broker, infState.getName());
- String lowerLayerIf = ifState.getLowerLayerIf().get(0);
- NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
- return new BigInteger(InterfaceUtils.getDpnFromNodeConnectorId(nodeConnectorId));
- }
-
}
InterfaceUtils.getInterfaceStateFromOperDS(broker, interfaceName);
if (interfaceState != null) {
// Interface state is up
- processVpnInterfaceUp(interfaceName, interfaceState.getIfIndex());
+ processVpnInterfaceUp(InterfaceUtils.getDpIdFromInterface(interfaceState), interfaceName, interfaceState.getIfIndex());
} else {
LOG.trace("VPN interfaces are not yet operational.");
}
}
- protected void processVpnInterfaceUp(String interfaceName, int lPortTag) {
+ protected void processVpnInterfaceUp(BigInteger dpId, String interfaceName, int lPortTag) {
VpnInterface vpnInterface = VpnUtil.getConfiguredVpnInterface(broker, interfaceName);
if(vpnInterface == null) {
}
synchronized (interfaceName.intern()) {
- bindService(vpnName, interfaceName, lPortTag);
+ bindService(dpId, vpnName, interfaceName, lPortTag);
updateDpnDbs(vpnName, interfaceName, true);
processVpnInterfaceAdjacencies(VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName()), vpnInterface);
}
}
- private void bindService(String vpnInstanceName, String vpnInterfaceName, int lPortTag) {
+ private void bindService(BigInteger dpId, String vpnInstanceName, String vpnInterfaceName, int lPortTag) {
int priority = VpnConstants.DEFAULT_FLOW_PRIORITY;
long vpnId = VpnUtil.getVpnId(broker, vpnInstanceName);
VpnConstants.COOKIE_VM_INGRESS_TABLE, instructions);
VpnUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
InterfaceUtils.buildServiceId(vpnInterfaceName, VpnConstants.L3VPN_SERVICE_IDENTIFIER), serviceInfo);
- makeArpFlow(VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName, vpnId, ArpReplyOrRequest.REQUEST, NwConstants.ADD_FLOW);
+ makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
+ vpnId, ArpReplyOrRequest.REQUEST, NwConstants.ADD_FLOW);
}
}
}
- private void makeArpFlow(short sIndex, int lPortTag, String vpnInterfaceName, long vpnId, ArpReplyOrRequest replyOrRequest, int addOrRemoveFlow){
+ private void makeArpFlow(BigInteger dpId,short sIndex, int lPortTag, String vpnInterfaceName,
+ long vpnId, ArpReplyOrRequest replyOrRequest, int addOrRemoveFlow){
List<MatchInfo> matches = new ArrayList<MatchInfo>();
BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(lPortTag, ++sIndex, BigInteger.valueOf(vpnId));
BigInteger metadataMask = MetaDataUtil.getMetaDataMaskForLPortDispatcher(MetaDataUtil.METADATA_MASK_SERVICE_INDEX,
instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
// Install the flow entry in L3_INTERFACE_TABLE
- BigInteger dpId = InterfaceUtils.getDpnForInterface(interfaceManager, vpnInterfaceName);
String flowRef = VpnUtil.getFlowRef(dpId, NwConstants.L3_INTERFACE_TABLE,
NwConstants.ETHTYPE_ARP, lPortTag, replyOrRequest.getArpOperation());
FlowEntity flowEntity;
InterfaceUtils.getInterfaceStateFromOperDS(broker, interfaceName);
if (existingVpnInterface.isPresent() && interfaceState != null) {
- processVpnInterfaceDown(interfaceName, interfaceState.getIfIndex(), false);
+ processVpnInterfaceDown(InterfaceUtils.getDpIdFromInterface(interfaceState), interfaceName, interfaceState.getIfIndex(), false);
} else {
LOG.warn("VPN interface {} was unavailable in operational data store to handle remove event", interfaceName);
}
}
- protected void processVpnInterfaceDown(String interfaceName, int lPortTag, boolean isInterfaceStateDown) {
+ protected void processVpnInterfaceDown(BigInteger dpId, String interfaceName, int lPortTag, boolean isInterfaceStateDown) {
VpnInterface vpnInterface = VpnUtil.getOperationalVpnInterface(broker, interfaceName);
if(vpnInterface == null) {
LOG.info("Unable to process delete/down for interface {} as it is not available in operational data store", interfaceName);
synchronized (interfaceName.intern()) {
removeAdjacenciesFromVpn(identifier, vpnInterface);
LOG.info("Unbinding vpn service from interface {} ", interfaceName);
- unbindService(vpnName, interfaceName, lPortTag, isInterfaceStateDown);
+ unbindService(dpId, vpnName, interfaceName, lPortTag, isInterfaceStateDown);
//wait till DCN for removal of vpn interface in operational DS arrives
Runnable notifyTask = new VpnNotifyTask();
}
- private void unbindService(String vpnInstanceName, String vpnInterfaceName, int lPortTag, boolean isInterfaceStateDown) {
+ private void unbindService(BigInteger dpId, String vpnInstanceName, String vpnInterfaceName,
+ int lPortTag, boolean isInterfaceStateDown) {
if (!isInterfaceStateDown) {
VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION,
InterfaceUtils.buildServiceId(vpnInterfaceName,
VpnUtil.DEFAULT_CALLBACK);
}
long vpnId = VpnUtil.getVpnId(broker, vpnInstanceName);
- makeArpFlow(VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
+ makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
vpnId, ArpReplyOrRequest.REQUEST, NwConstants.DEL_FLOW);
}
String[] split = portId.getValue().split(OF_URI_SEPARATOR);
return split[1];
}
+
+ public static BigInteger getDpIdFromInterface(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
+ String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+ NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+ return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
+ }
+
}