X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=vpnintent%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fvpnservice%2Fimpl%2FVpnintentProvider.java;h=1618bb1ef066e148004cc066727e4d704e494c4e;hb=refs%2Fchanges%2F34%2F32234%2F5;hp=715c1735163fe4ee40428da0ddcf8c58065a13d4;hpb=4640d73e6e16aa7ddc6ed7293e3cc0bffd9993e4;p=vpnservice.git diff --git a/vpnintent/impl/src/main/java/org/opendaylight/vpnservice/impl/VpnintentProvider.java b/vpnintent/impl/src/main/java/org/opendaylight/vpnservice/impl/VpnintentProvider.java index 715c1735..1618bb1e 100644 --- a/vpnintent/impl/src/main/java/org/opendaylight/vpnservice/impl/VpnintentProvider.java +++ b/vpnintent/impl/src/main/java/org/opendaylight/vpnservice/impl/VpnintentProvider.java @@ -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 VPN_INTENT_IID = InstanceIdentifier.builder(Vpns.class).build(); - public static final InstanceIdentifier LABELS_IID = InstanceIdentifier.builder(MplsLabels.class).build(); + public static final InstanceIdentifier LABELS_IID = IidFactory.getMplsLabelsIid(); + public static final InstanceIdentifier VPN_IID = IidFactory.getVpnsIid(); + public static final InstanceIdentifier VPN_INTENT_IID = IidFactory.getVpnIntentIid(); + public static final InstanceIdentifier ENDPOINT_IID = IidFactory.getEndpointIid(); private DataBroker dataBroker; + private IntentMappingService intentMappingService; + private BindingAwareBroker.RpcRegistration 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> removeVpn(RemoveVpnInput input) { + InstanceIdentifier 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. success().build()); + } + + @Override + public Future> 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. 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 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> 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. success().build()); + } + + /** + * @param siteName + * Site name of the VPN member + * @return VPN member (Endpoint) + */ + private Endpoint getEndpoint(String vpnName, String siteName) { + InstanceIdentifier 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 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 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(); + } }