Integration of vpnintent bundle functionality 34/32234/5
authorRashmi Pujar <rpujar@inocybe.com>
Fri, 22 Jan 2016 19:35:00 +0000 (14:35 -0500)
committerRashmi Pujar <rpujar@inocybe.com>
Fri, 22 Jan 2016 19:35:00 +0000 (14:35 -0500)
Change-Id: I0a55cc2b67635a09a5200ecd2bc7451004f898a0
Signed-off-by: Rashmi Pujar <rpujar@inocybe.com>
distribution/karaf/pom.xml
vpnintent/api/src/main/yang/vpnintent.yang
vpnintent/impl/pom.xml
vpnintent/impl/src/main/java/org/opendaylight/vpnservice/impl/IntentServiceManager.java
vpnintent/impl/src/main/java/org/opendaylight/vpnservice/impl/VpnintentProvider.java
vpnintent/impl/src/main/java/org/opendaylight/vpnservice/utils/IidFactory.java

index 3fdedb91c89add5a09e6368134ee012eaa840a1b..c6f059b9e1abee90346f626960b9fe6d4d8d6459 100644 (file)
@@ -22,7 +22,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <maven>3.1.1</maven>
   </prerequisites>
   <properties>
-    <karaf.localFeature>odl-vpnservice-core</karaf.localFeature>
+    <!-- <karaf.localFeature>odl-vpnservice-core</karaf.localFeature> -->
   </properties>
   <dependencyManagement>
     <dependencies>
index e9a971db1e976e08dd30de6e2778efbc0b514e71..f0884e4d6521d0c838d85308677014e8c5be9875 100644 (file)
@@ -88,5 +88,46 @@ module vpnintent {
 
     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;
+            }
+        }
+    }
   }
index ab00412ea74218230cd6fdef336c07666474f3bf..0be7d94b299bd29ddbb97b37c3cd266a25f4f36e 100644 (file)
@@ -25,11 +25,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
   </properties>
 
   <dependencies>
-    <dependency>
-      <groupId>org.opendaylight.vpnservice</groupId>
-      <artifactId>mdsalutil-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>vpnintent-api</artifactId>
index 99d0edc9c66fe3c659f2aac12486e52b7f48de08..dda5447d224863684e70d5c79a4fd7a734cc0f09 100644 (file)
@@ -15,6 +15,7 @@ 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;
@@ -57,7 +58,7 @@ public class IntentServiceManager {
     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 = InstanceIdentifier.builder(Intents.class).build();
+    private static final InstanceIdentifier<Intents> INTENTS_IID = IidFactory.getIntentsIid();
     private MdsalUtils mdsal;
 
     public IntentServiceManager(DataBroker dataBroker) {
index 715c1735163fe4ee40428da0ddcf8c58065a13d4..1618bb1ef066e148004cc066727e4d704e494c4e 100644 (file)
@@ -7,41 +7,74 @@
  */
 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 BindingAwareProvider, AutoCloseable {
+public class VpnintentProvider implements VpnintentService, BindingAwareProvider, AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(VpnintentProvider.class);
-    public static final InstanceIdentifier<Vpns> VPN_INTENT_IID = InstanceIdentifier.builder(Vpns.class).build();
-    public static final InstanceIdentifier<MplsLabels> LABELS_IID = InstanceIdentifier.builder(MplsLabels.class).build();
+    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_INTENT_IID, vpns);
+        initDatastore(LogicalDatastoreType.CONFIGURATION, VPN_IID, vpns);
         initDatastore(LogicalDatastoreType.OPERATIONAL, LABELS_IID, labels);
     }
 
@@ -69,4 +102,176 @@ public class VpnintentProvider implements BindingAwareProvider, AutoCloseable {
         });
         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();
+    }
 }
index d05b69f27e48dce55968e8067007f74421c13cad..e08cf67f9bcabd06951440e0b2299cea4cfb2ca7 100644 (file)
@@ -8,9 +8,13 @@
 
 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 {
@@ -22,4 +26,20 @@ public class IidFactory {
     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();
+    }
 }