From b4b1b760287d5aa668c493b0a8f35e2ebae5ecd8 Mon Sep 17 00:00:00 2001 From: Faseela K Date: Fri, 20 Nov 2015 16:05:08 +0530 Subject: [PATCH] Working with OVS - Config and Topology listeners and helpers - Yang updations - Datastore job co-ordinator prototype - Incorporating previous review comments Change-Id: I81be9516578172497d3a45fbfcda0c01bffe9613 Signed-off-by: Faseela K --- features/src/main/features/features.xml | 3 +- .../interfaces/IInterfaceManager.java | 15 +- .../src/main/yang/odl-interface-meta.yang | 20 +- .../src/main/yang/odl-interface-rpc.yang | 57 +--- .../yang/odl-interface-service-bindings.yang | 4 - .../src/main/yang/odl-interface.yang | 46 ++- .../src/main/config/default-config.xml | 4 + .../vpnservice/interfacemgr/IfmConstants.java | 2 + .../vpnservice/interfacemgr/IfmUtil.java | 82 ++++- .../interfacemgr/InterfaceManager.java | 61 ++-- .../interfacemgr/InterfacemgrProvider.java | 135 +++++++- .../commons/InterfaceManagerCommonUtils.java | 159 +++++++++ .../commons/InterfaceMetaUtils.java | 166 +++++++++ .../listeners/InterfaceConfigListener.java | 215 ++++++++++++ .../InterfaceInventoryStateListener.java | 196 +++++++++++ .../InterfaceTopologyStateListener.java | 118 +++++++ .../listeners/VlanMemberConfigListener.java | 208 ++++++++++++ .../OvsInterfaceConfigAddHelper.java | 198 +++++++++++ .../OvsInterfaceConfigRemoveHelper.java | 177 ++++++++++ .../OvsInterfaceConfigUpdateHelper.java | 161 +++++++++ .../OvsVlanMemberConfigAddHelper.java | 149 +++++++++ .../OvsVlanMemberConfigRemoveHelper.java | 91 +++++ .../OvsVlanMemberConfigUpdateHelper.java | 95 ++++++ .../OvsInterfaceStateAddHelper.java | 156 +++++++++ .../OvsInterfaceStateRemoveHelper.java | 94 ++++++ .../OvsInterfaceStateUpdateHelper.java | 140 ++++++++ .../OvsInterfaceTopologyStateAddHelper.java | 106 ++++++ ...OvsInterfaceTopologyStateRemoveHelper.java | 50 +++ .../ovs/utilities/SouthboundUtils.java | 161 +++++++++ .../utilities/VlanTrunkSouthboundUtils.java | 164 +++++++++ .../InterfaceManagerRpcService.java | 316 ++++++++++++++++++ .../FlowBasedServicesConfigBindHelper.java | 143 ++++++++ .../FlowBasedServicesConfigUnbindHelper.java | 117 +++++++ .../FlowBasedServicesConfigListener.java | 109 ++++++ ...owBasedServicesInterfaceStateListener.java | 103 ++++++ .../FlowBasedServicesStateBindHelper.java | 92 +++++ .../FlowBasedServicesStateUnbindHelper.java | 74 ++++ .../utilities/FlowBasedServicesUtils.java | 282 ++++++++++++++++ .../rev150325/InterfacemgrImplModule.java | 2 + .../src/main/yang/interfacemgr-impl.yang | 10 +- .../AsyncDataChangeListenerBase.java | 184 ++++++++++ .../AsyncDataTreeChangeListenerBase.java | 133 ++++++++ .../DataStoreJobCoordinator.java | 299 +++++++++++++++++ .../vpnservice/datastoreutils/JobEntry.java | 85 +++++ .../vpnservice/datastoreutils/JobQueue.java | 36 ++ .../datastoreutils/RollbackCallable.java | 30 ++ .../datastoreutils/TaskRetryLooper.java | 59 ++++ .../vpnservice/mdsalutil/MDSALUtil.java | 53 +++ .../vpnservice/mdsalutil/MetaDataUtil.java | 54 +++ .../interfaces/IMdsalApiManager.java | 8 + .../mdsalutil/internal/MDSALManager.java | 26 +- .../mdsalutil/internal/MDSALUtilProvider.java | 14 + .../vpnservice/nexthopmgr/NexthopManager.java | 6 +- .../OdlInterfaceChangeListener.java | 71 ++-- .../vpnservice/InterfaceChangeListener.java | 10 +- .../vpnservice/VpnInterfaceManager.java | 8 +- 56 files changed, 5397 insertions(+), 160 deletions(-) create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceManagerCommonUtils.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceMetaUtils.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceConfigListener.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceInventoryStateListener.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceTopologyStateListener.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/VlanMemberConfigListener.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigAddHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigRemoveHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigUpdateHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigAddHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigRemoveHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigUpdateHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateAddHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateRemoveHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateUpdateHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateAddHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateRemoveHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/SouthboundUtils.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/VlanTrunkSouthboundUtils.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/rpcservice/InterfaceManagerRpcService.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigBindHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigUnbindHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesConfigListener.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesInterfaceStateListener.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateBindHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateUnbindHelper.java create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/utilities/FlowBasedServicesUtils.java create mode 100644 mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataChangeListenerBase.java create mode 100644 mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataTreeChangeListenerBase.java create mode 100644 mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/DataStoreJobCoordinator.java create mode 100644 mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobEntry.java create mode 100644 mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobQueue.java create mode 100644 mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/RollbackCallable.java create mode 100644 mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/TaskRetryLooper.java diff --git a/features/src/main/features/features.xml b/features/src/main/features/features.xml index 4a4b1cac..e03ef333 100644 --- a/features/src/main/features/features.xml +++ b/features/src/main/features/features.xml @@ -20,7 +20,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html odl-mdsal-broker odl-mdsal-models odl-openflowplugin-nsf-model - odl-ovsdb-southbound-api mvn:org.opendaylight.vpnservice/model-bgp/{{VERSION}} mvn:org.opendaylight.vpnservice/idmanager-api/${idmanager.version} mvn:org.opendaylight.vpnservice/vpnmanager-api/${vpnmanager.version} @@ -30,7 +29,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html odl-mdsal-broker - odl-ovsdb-southbound-api + odl-ovsdb-southbound-impl-rest odl-vpnservice-api odl-openflowplugin-southbound odl-openflowplugin-flow-services diff --git a/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/interfaces/IInterfaceManager.java b/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/interfaces/IInterfaceManager.java index 8ef4efdb..64c98b9f 100644 --- a/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/interfaces/IInterfaceManager.java +++ b/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/interfaces/IInterfaceManager.java @@ -15,14 +15,27 @@ import java.util.List; import org.opendaylight.vpnservice.mdsalutil.ActionInfo; import org.opendaylight.vpnservice.mdsalutil.MatchInfo; +@Deprecated public interface IInterfaceManager { - + @Deprecated public Long getPortForInterface(String ifName); + + @Deprecated public BigInteger getDpnForInterface(String ifName); + + @Deprecated public BigInteger getDpnForInterface(Interface intrf); + + @Deprecated public String getEndpointIpForDpn(BigInteger dpnId); + + @Deprecated public List getInterfaceIngressRule(String ifName); + + @Deprecated public List getInterfaceEgressActions(String ifName); + + @Deprecated public Long getPortForInterface(Interface intf); } \ No newline at end of file diff --git a/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-meta.yang b/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-meta.yang index c2a99dac..66b4a850 100644 --- a/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-meta.yang +++ b/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-meta.yang @@ -24,9 +24,6 @@ module odl-interface-meta { leaf interface-name { type string; } - leaf tp-id-ref { - type southbound:ovsdb-termination-point-ref; - } } } } @@ -47,4 +44,21 @@ module odl-interface-meta { } } } + + container interface-child-info { + description "The container of all Child-Interfaces for a given interface."; + list interface-parent-entry { + key parent-interface; + leaf parent-interface { + type string; + } + + list interface-child-entry { + key child-interface; + leaf child-interface { + type string; + } + } + } + } } \ No newline at end of file diff --git a/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-rpc.yang b/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-rpc.yang index f95d52c2..0e4efca0 100644 --- a/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-rpc.yang +++ b/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-rpc.yang @@ -17,62 +17,7 @@ module odl-interface-rpc { description "ODL Specific Interface Manager Rpcs Module"; } -/* RPCs */ - rpc get-interface-from-lporttag { - description "Used to retrieve the interface-name using lporttag"; - input { - leaf lportag { - type uint32; - } - } - output { - leaf intf-name { - type string; - } - } - } - - rpc get-lporttag-from-interface { - description "Used to retrieve the lporttag from interface-name"; - input { - leaf intf-name { - type string; - } - } - output { - leaf lportag { - type uint32; - } - } - } - - rpc get-interface-from-groupid { - description "Used to retrieve the interface-name using groupid"; - input { - leaf groupid { - type uint32; - } - } - output { - leaf intf-name { - type string; - } - } - } - - rpc get-groupid-from-interface { - description "Used to retrieve the interface-name using groupid"; - input { - leaf intf-name { - type string; - } - } - output { - leaf groupid { - type uint32; - } - } - } + /* RPCs */ rpc get-dpid-from-interface { description "used to retrieve dpid from interface name"; diff --git a/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-service-bindings.yang b/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-service-bindings.yang index cebf3bdd..14af19ff 100644 --- a/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-service-bindings.yang +++ b/interfacemgr/interfacemgr-api/src/main/yang/odl-interface-service-bindings.yang @@ -42,10 +42,6 @@ module interface-service-bindings { } } - leaf interface-name { - type string; - } - leaf service-name { type string; } diff --git a/interfacemgr/interfacemgr-api/src/main/yang/odl-interface.yang b/interfacemgr/interfacemgr-api/src/main/yang/odl-interface.yang index 609c1147..38405be0 100644 --- a/interfacemgr/interfacemgr-api/src/main/yang/odl-interface.yang +++ b/interfacemgr/interfacemgr-api/src/main/yang/odl-interface.yang @@ -23,6 +23,8 @@ module odl-interface { prefix inv; revision-date 2013-08-19; } + import opendaylight-l2-types { prefix ethertype; revision-date "2013-08-27";} + import config { prefix config; revision-date 2013-04-05; } @@ -47,14 +49,13 @@ module odl-interface { reference "MPLS interface"; } + /* Tunnel (GRE, VxLAN) logical port */ identity l3tunnel { status deprecated; base if:interface-type; - reference - "l3 tunnel interface"; + reference "l3 tunnel interface"; } - /* Tunnel (GRE, VxLAN) logical port */ identity tunnel-type-base { description "Base identity for all tunnel-types"; } @@ -99,8 +100,42 @@ module odl-interface { ext:augment-identifier "if-l2vlan"; when "if:type = 'ianaift:l2vlan'"; leaf vlan-id { - type uint16 { - range "1..4094"; + type ethertype:vlan-id; + } + + leaf l2vlan-mode { + description "The VLAN mode of the L2Vlan Interface."; + type enumeration { + enum "access" { + value 1; + description + "The VLAN mode access."; + } + enum "native-tagged" { + value 2; + description + "The VLAN mode native-tagged."; + } + enum "native-untagged" { + value 3; + description + "The VLAN mode native-untagged."; + } + enum "trunk" { + value 4; + description + "The VLAN mode trunk."; + } + enum "trunk-member" { + value 5; + description + "The VLAN mode trunk-member."; + } + enum "transparent" { + value 6; + description + "The VLAN mode transparent."; + } } } } @@ -152,6 +187,7 @@ module odl-interface { base tunnel-type-base; } } + leaf local-ip { type inet:ip-address; description "Local Endpoint IP address"; diff --git a/interfacemgr/interfacemgr-impl/src/main/config/default-config.xml b/interfacemgr/interfacemgr-impl/src/main/config/default-config.xml index e4fb6f45..a0e92ffb 100644 --- a/interfacemgr/interfacemgr-impl/src/main/config/default-config.xml +++ b/interfacemgr/interfacemgr-impl/src/main/config/default-config.xml @@ -24,6 +24,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html binding:binding-broker-osgi-registry binding-osgi-broker + + binding:binding-rpc-registry + binding-rpc-broker + diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java index da85fe55..bcaf8ef2 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java @@ -15,5 +15,7 @@ public class IfmConstants { public static final String OF_URI_PREFIX = "openflow:"; public static final String OF_URI_SEPARATOR = ":"; public static final int DEFAULT_IFINDEX = 65536; + public static final String IFM_LPORT_TAG_IDPOOL_NAME = "vlaninterfaces.lporttag"; + public static final short VLAN_INTERFACE_INGRESS_TABLE = 0; } diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmUtil.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmUtil.java index 2b298475..400ebd24 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmUtil.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmUtil.java @@ -8,16 +8,29 @@ package org.opendaylight.vpnservice.interfacemgr; import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import com.google.common.base.Optional; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadata; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.Pools; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPoolKey; +import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; @@ -55,7 +68,7 @@ public class IfmUtil { InstanceIdentifierBuilder idBuilder = InstanceIdentifier.builder(InterfacesState.class) .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class, - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName)); + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName)); InstanceIdentifier id = idBuilder.build(); return id; } @@ -71,4 +84,71 @@ public class IfmUtil { InstanceIdentifier id = idBuilder.build(); return id; } + + public static List getPortNameAndSuffixFromInterfaceName(String intfName) { + List strList = new ArrayList<>(2); + int index = intfName.indexOf(":"); + if (index != -1) { + strList.add(0, intfName.substring(0, index)); + strList.add(1, intfName.substring(index)); + } + return strList; + } + + public static List getDpIdPortNameAndSuffixFromInterfaceName(String intfName) { + List strList = new ArrayList<>(3); + int index1 = intfName.indexOf(":"); + if (index1 != -1) { + int index2 = intfName.indexOf(":", index1 + 1 ); + strList.add(0, intfName.substring(0, index1)); + if (index2 != -1) { + strList.add(1, intfName.substring(index1, index2)); + strList.add(2, intfName.substring(index2)); + } else { + strList.add(1, intfName.substring(index1)); + strList.add(2, ""); + } + } + return strList; + } + + public static Optional read(LogicalDatastoreType datastoreType, + InstanceIdentifier path, DataBroker broker) { + + ReadOnlyTransaction tx = broker.newReadOnlyTransaction(); + + Optional result = Optional.absent(); + try { + result = tx.read(datastoreType, path).get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + return result; + } + + public static NodeId getNodeIdFromNodeConnectorId(NodeConnectorId ncId) { + return new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":"))); + } + + public static BigInteger[] mergeOpenflowMetadataWriteInstructions(List instructions) { + BigInteger metadata = new BigInteger("0", 16); + BigInteger metadataMask = new BigInteger("0", 16); + if (instructions != null && !instructions.isEmpty()) { + // check if metadata write instruction is present + for (Instruction instruction : instructions) { + org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction actualInstruction = instruction.getInstruction(); + if (actualInstruction instanceof WriteMetadataCase) { + WriteMetadataCase writeMetaDataInstruction = (WriteMetadataCase) actualInstruction ; + WriteMetadata availableMetaData = writeMetaDataInstruction.getWriteMetadata(); + metadata = metadata.or(availableMetaData.getMetadata()); + metadataMask = metadataMask.or(availableMetaData.getMetadataMask()); + } + } + } + return new BigInteger[] { metadata, metadataMask }; + } + + + } diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java index d03fd5f6..bd643ba2 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java @@ -7,17 +7,9 @@ */ package org.opendaylight.vpnservice.interfacemgr; -import java.math.BigInteger; - import com.google.common.base.Optional; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; @@ -31,6 +23,7 @@ import org.opendaylight.vpnservice.mdsalutil.ActionType; import org.opendaylight.vpnservice.mdsalutil.MatchFieldType; import org.opendaylight.vpnservice.mdsalutil.MatchInfo; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; @@ -49,15 +42,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.id.pool.GeneratedIds; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfMpls; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfStackedVlan; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.Mpls; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.StackedVlan; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.*; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -66,6 +51,14 @@ import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + public class InterfaceManager extends AbstractDataChangeListener implements AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(InterfaceManager.class); private ListenerRegistration listenerRegistration; @@ -148,10 +141,10 @@ public class InterfaceManager extends AbstractDataChangeListener impl ncId = nodeConn.getId(); } mapNcToInterfaceName.put(ncId, interf.getName()); - if(interf.getType().isAssignableFrom(L3tunnel.class)) { + if(interf.getType().isAssignableFrom(Tunnel.class)) { NodeId nodeId = getNodeIdFromNodeConnectorId(ncId); - IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class); - dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue()); + IfTunnel tunnel = interf.getAugmentation(IfTunnel.class); + dbDpnEndpoints.put(nodeId, tunnel.getTunnelSource().getIpv4Address().getValue()); LOG.trace("dbDpnEndpoints: {}",dbDpnEndpoints); } } @@ -280,7 +273,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl NodeConnectorId ncId = getNodeConnectorIdFromInterface(delInterface); if(ncId != null) { mapNcToInterfaceName.remove(ncId); - if(delInterface.getType().isAssignableFrom(L3tunnel.class)) { + if(delInterface.getType().isAssignableFrom(Tunnel.class)) { NodeId nodeId = getNodeIdFromNodeConnectorId(ncId); dbDpnEndpoints.remove(nodeId); LOG.trace("dbDpnEndpoints: {}",dbDpnEndpoints); @@ -319,10 +312,10 @@ public class InterfaceManager extends AbstractDataChangeListener impl if(nc != null) { // Name doesn't change. Is it present in update? mapNcToInterfaceName.put(nc.getId(), original.getName()); - if(interf.getType().isAssignableFrom(L3tunnel.class)) { + if(interf.getType().isAssignableFrom(Tunnel.class)) { NodeId nodeId = getNodeIdFromNodeConnectorId(nc.getId()); - IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class); - dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue()); + IfTunnel tunnel = interf.getAugmentation(IfTunnel.class); + dbDpnEndpoints.put(nodeId, tunnel.getTunnelSource().getIpv4Address().getValue()); LOG.trace("dbEndpoints: {}",dbDpnEndpoints); } } @@ -491,17 +484,17 @@ public class InterfaceManager extends AbstractDataChangeListener impl if (ifType.isInstance(L2vlan.class)) { IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class); - long vlanVid = vlanIface.getVlanId().longValue(); + long vlanVid = vlanIface.getVlanId().getValue().longValue(); if (vlanVid != 0) { matches.add(new MatchInfo(MatchFieldType.vlan_vid, new long[] {vlanVid})); LOG.trace("L2Vlan: {}",vlanIface); } - } else if (ifType.isInstance(L3tunnel.class)) { + } else if (ifType.isInstance(Tunnel.class)) { //TODO: Handle different tunnel types - IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class); - Class tunnType = ifL3Tunnel.getTunnelType(); - LOG.trace("L3Tunnel: {}",ifL3Tunnel); + IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class); + Class tunnType = ifTunnel.getTunnelInterfaceType(); + LOG.trace("L3Tunnel: {}",ifTunnel); } else if (ifType.isAssignableFrom(StackedVlan.class)) { IfStackedVlan ifStackedVlan = iface.getAugmentation(IfStackedVlan.class); LOG.trace("StackedVlan: {}",ifStackedVlan); @@ -524,7 +517,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl if(ifType.isAssignableFrom(L2vlan.class)) { IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class); LOG.trace("L2Vlan: {}",vlanIface); - long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId(); + long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId().getValue().longValue(); if (vlanVid != 0) { listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {})); listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid, @@ -532,11 +525,11 @@ public class InterfaceManager extends AbstractDataChangeListener impl } listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)})); - } else if (ifType.isAssignableFrom(L3tunnel.class)) { + } else if (ifType.isAssignableFrom(Tunnel.class)) { //TODO: Handle different tunnel types - IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class); - Class tunnType = ifL3Tunnel.getTunnelType(); - LOG.trace("L3Tunnel: {}",ifL3Tunnel); + IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class); + Class tunnType = ifTunnel.getTunnelInterfaceType(); + LOG.trace("L3Tunnel: {}",ifTunnel); //TODO: check switch_type and configure accordingly listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)})); diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java index 74074883..ace54f55 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java @@ -7,42 +7,96 @@ */ package org.opendaylight.vpnservice.interfacemgr; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; - -import java.math.BigInteger; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +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.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.idmanager.IdManager; +import org.opendaylight.vpnservice.interfacemgr.listeners.InterfaceConfigListener; +import org.opendaylight.vpnservice.interfacemgr.listeners.InterfaceInventoryStateListener; +import org.opendaylight.vpnservice.interfacemgr.listeners.InterfaceTopologyStateListener; import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager; +import org.opendaylight.vpnservice.interfacemgr.rpcservice.InterfaceManagerRpcService; +import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.listeners.FlowBasedServicesConfigListener; +import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.listeners.FlowBasedServicesInterfaceStateListener; +import org.opendaylight.vpnservice.interfacemgr.listeners.VlanMemberConfigListener; import org.opendaylight.vpnservice.mdsalutil.ActionInfo; import org.opendaylight.vpnservice.mdsalutil.MatchInfo; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.*; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.math.BigInteger; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable, IInterfaceManager { private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class); + private RpcProviderRegistry rpcProviderRegistry; + private InterfaceManager interfaceManager; private IfmNodeConnectorListener ifmNcListener; private IdManager idManager; + private InterfaceConfigListener interfaceConfigListener; + private InterfaceTopologyStateListener topologyStateListener; + private InterfaceInventoryStateListener interfaceInventoryStateListener; + private FlowBasedServicesInterfaceStateListener flowBasedServicesInterfaceStateListener; + private FlowBasedServicesConfigListener flowBasedServicesConfigListener; + private VlanMemberConfigListener vlanMemberConfigListener; + + private InterfaceManagerRpcService interfaceManagerRpcService; + private BindingAwareBroker.RpcRegistration rpcRegistration; + + public void setRpcProviderRegistry(RpcProviderRegistry rpcProviderRegistry) { + this.rpcProviderRegistry = rpcProviderRegistry; + } + @Override public void onSessionInitiated(ProviderContext session) { LOG.info("InterfacemgrProvider Session Initiated"); try { final DataBroker dataBroker = session.getSALService(DataBroker.class); idManager = new IdManager(dataBroker); - interfaceManager = new InterfaceManager(dataBroker, idManager); - ifmNcListener = new IfmNodeConnectorListener(dataBroker, interfaceManager); createIdPool(); + + interfaceManagerRpcService = new InterfaceManagerRpcService(dataBroker); + rpcRegistration = getRpcProviderRegistry().addRpcImplementation( + OdlInterfaceRpcService.class, interfaceManagerRpcService); + + interfaceConfigListener = new InterfaceConfigListener(dataBroker, idManager); + interfaceConfigListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker); + + interfaceInventoryStateListener = new InterfaceInventoryStateListener(dataBroker); + interfaceInventoryStateListener.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker); + + topologyStateListener = new InterfaceTopologyStateListener(dataBroker); + topologyStateListener.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker); + + flowBasedServicesConfigListener = new FlowBasedServicesConfigListener(dataBroker); + flowBasedServicesConfigListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker); + + flowBasedServicesInterfaceStateListener = + new FlowBasedServicesInterfaceStateListener(dataBroker); + flowBasedServicesInterfaceStateListener.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker); + + vlanMemberConfigListener = + new VlanMemberConfigListener(dataBroker, idManager); + vlanMemberConfigListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker); + + + /*interfaceManager = new InterfaceManager(dataBroker, idManager); + ifmNcListener = new IfmNodeConnectorListener(dataBroker, interfaceManager);*/ } catch (Exception e) { LOG.error("Error initializing services", e); } @@ -70,27 +124,75 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable LOG.info("InterfacemgrProvider Closed"); interfaceManager.close(); ifmNcListener.close(); + interfaceConfigListener.close(); + rpcRegistration.close(); + } + + public RpcProviderRegistry getRpcProviderRegistry() { + return rpcProviderRegistry; } @Override public Long getPortForInterface(String ifName) { - return interfaceManager.getPortForInterface(ifName); + GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(ifName).build(); + Future> output = interfaceManagerRpcService.getPortFromInterface(input); + try { + RpcResult port = output.get(); + if(port.isSuccessful()){ + return port.getResult().getPortno(); + } + }catch(NullPointerException | InterruptedException | ExecutionException e){ + LOG.warn("Exception when getting port for interface",e); + } + return null; } @Override public Long getPortForInterface(Interface intf) { - return interfaceManager.getPortForInterface(intf); + GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(intf.getName()).build(); + Future> output = interfaceManagerRpcService.getPortFromInterface(input); + try { + RpcResult port = output.get(); + if(port.isSuccessful()){ + return port.getResult().getPortno(); + } + }catch(NullPointerException | InterruptedException | ExecutionException e){ + LOG.warn("Exception when getting port for interface",e); + } + return null; } - @Override public BigInteger getDpnForInterface(String ifName) { - return interfaceManager.getDpnForInterface(ifName); + GetDpidFromInterfaceInput input = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build(); + Future> output = interfaceManagerRpcService.getDpidFromInterface(input); + try { + RpcResult dpn = output.get(); + if(dpn.isSuccessful()){ + return dpn.getResult().getDpid(); + } + }catch(NullPointerException | InterruptedException | ExecutionException e){ + LOG.warn("Exception when getting port for interface",e); + } + return null; } @Override public String getEndpointIpForDpn(BigInteger dpnId) { - return interfaceManager.getEndpointIpForDpn(dpnId); + GetEndpointIpForDpnInput input = new GetEndpointIpForDpnInputBuilder().setDpid(dpnId).build(); + Future> output = interfaceManagerRpcService.getEndpointIpForDpn(input); + try { + RpcResult ipForDpnOutputRpcResult = output.get(); + if(ipForDpnOutputRpcResult.isSuccessful()){ + List localIps = ipForDpnOutputRpcResult.getResult().getLocalIps(); + if(!localIps.isEmpty()) { + return localIps.get(0).getIpv4Address().getValue(); + } + } + }catch(NullPointerException | InterruptedException | ExecutionException e){ + LOG.warn("Exception when getting port for interface",e); + } + return null; } @Override @@ -100,12 +202,11 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable @Override public List getInterfaceEgressActions(String ifName) { - return interfaceManager.getInterfaceEgressActions(ifName); + return interfaceManagerRpcService.getEgressActionInfosForInterface(ifName); } @Override public BigInteger getDpnForInterface(Interface intrf) { - // TODO Auto-generated method stub - return interfaceManager.getDpnForInterface(intrf); + return getDpnForInterface(intrf.getName()); } -} +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceManagerCommonUtils.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceManagerCommonUtils.java new file mode 100644 index 00000000..6b10cb0c --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceManagerCommonUtils.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.commons; + +import com.google.common.base.Optional; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.idmanager.IdManager; +import org.opendaylight.vpnservice.interfacemgr.IfmConstants; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdOutput; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class InterfaceManagerCommonUtils { + private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerCommonUtils.class); + public static NodeConnector getNodeConnectorFromInventoryOperDS(NodeConnectorId nodeConnectorId, + DataBroker dataBroker) { + NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId); + InstanceIdentifier ncIdentifier = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, new NodeKey(nodeId)) + .child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId)).build(); + + Optional nodeConnectorOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, + ncIdentifier, dataBroker); + if (!nodeConnectorOptional.isPresent()) { + return null; + } + return nodeConnectorOptional.get(); + } + + /*public static void addInterfaceEntryToInventoryOperDS(NodeConnectorId nodeConnectorId, long lporttag, String interfaceName, + DataBroker dataBroker, WriteTransaction t) { + NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId); + TunnelInterfaceInventoryInfoKey tunnelInterfaceInventoryInfoKey = new TunnelInterfaceInventoryInfoKey(lporttag); + InstanceIdentifier inventoryIdentifier = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, new NodeKey(nodeId)) + .augmentation(TunnelInterfaceNames.class) + .child(TunnelInterfaceInventoryInfo.class, tunnelInterfaceInventoryInfoKey).build(); + TunnelInterfaceInventoryInfoBuilder builder = new TunnelInterfaceInventoryInfoBuilder().setKey(tunnelInterfaceInventoryInfoKey) + .setTunIntfName(interfaceName); + t.put(LogicalDatastoreType.OPERATIONAL, inventoryIdentifier, builder.build(), true); + } + + public static void removeInterfaceEntryFromInventoryOperDS(NodeConnectorId nodeConnectorId, long lporttag, + String interfaceName, DataBroker dataBroker, + WriteTransaction t) { + NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId); + TunnelInterfaceInventoryInfoKey tunnelInterfaceInventoryInfoKey = new TunnelInterfaceInventoryInfoKey(lporttag); + InstanceIdentifier inventoryIdentifier = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, new NodeKey(nodeId)) + .augmentation(TunnelInterfaceNames.class) + .child(TunnelInterfaceInventoryInfo.class, tunnelInterfaceInventoryInfoKey).build(); + t.delete(LogicalDatastoreType.OPERATIONAL, inventoryIdentifier); + } + + public static void removeInterfaceEntryFromInventoryOperDS(NodeConnectorId nodeConnectorId, long lporttag, + DataBroker dataBroker) { + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId); + TunnelInterfaceInventoryInfoKey tunnelInterfaceInventoryInfoKey = new TunnelInterfaceInventoryInfoKey(lporttag); + InstanceIdentifier inventoryIdentifier = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, new NodeKey(nodeId)) + .augmentation(TunnelInterfaceNames.class) + .child(TunnelInterfaceInventoryInfo.class, tunnelInterfaceInventoryInfoKey).build(); + t.delete(LogicalDatastoreType.OPERATIONAL, inventoryIdentifier); + t.submit(); // This is a Best-Effort Deletion. If Node is already removed, this may fail. + } */ + + public static InstanceIdentifier getInterfaceIdentifier(InterfaceKey interfaceKey) { + InstanceIdentifier.InstanceIdentifierBuilder interfaceInstanceIdentifierBuilder = + InstanceIdentifier.builder(Interfaces.class).child(Interface.class, interfaceKey); + return interfaceInstanceIdentifierBuilder.build(); + } + + public static Interface getInterfaceFromConfigDS(InterfaceKey interfaceKey, DataBroker dataBroker) { + InstanceIdentifier interfaceId = getInterfaceIdentifier(interfaceKey); + Optional interfaceOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceId, dataBroker); + if (!interfaceOptional.isPresent()) { + return null; + } + + return interfaceOptional.get(); + } + + public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(String interfaceName, DataBroker dataBroker) { + InstanceIdentifier ifStateId = + IfmUtil.buildStateInterfaceId(interfaceName); + Optional ifStateOptional = + IfmUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker); + if (!ifStateOptional.isPresent()) { + return null; + } + + return ifStateOptional.get(); + } + + public static Integer getUniqueId(IdManager idManager, String idKey) { + GetUniqueIdInput getIdInput = new GetUniqueIdInputBuilder() + .setPoolName(IfmConstants.IFM_LPORT_TAG_IDPOOL_NAME) + .setIdKey(idKey).build(); + + try { + Future> result = idManager. + getUniqueId(getIdInput); + RpcResult rpcResult = result.get(); + if(rpcResult.isSuccessful()) { + return rpcResult.getResult().getIdValue().intValue(); + } else { + LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors()); + } + } catch (NullPointerException | InterruptedException | ExecutionException e) { + LOG.warn("Exception when getting Unique Id",e); + } + return 0; + } + + public static String getJobKey(String dpId, String portName) { + String jobKey = ""; + if (dpId != null && !"".equals(dpId)) { + jobKey = dpId.toString() + ":"; + } + jobKey = jobKey + portName; + return jobKey; + } + + public static String getJobKey(BigInteger dpId, String portName) { + String jobKey = ""; + if (dpId != null && dpId.longValue() != 0) { + jobKey = dpId.toString() + ":"; + } + jobKey = jobKey + portName; + return jobKey; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceMetaUtils.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceMetaUtils.java new file mode 100644 index 00000000..8367b8a4 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceMetaUtils.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.commons; + +import com.google.common.base.Optional; +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.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.BridgeInterfaceInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.BridgeRefInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.InterfaceChildInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class InterfaceMetaUtils { + public static InstanceIdentifier getBridgeRefEntryIdentifier(BridgeRefEntryKey bridgeRefEntryKey) { + InstanceIdentifier.InstanceIdentifierBuilder bridgeRefEntryInstanceIdentifierBuilder = + InstanceIdentifier.builder(BridgeRefInfo.class) + .child(BridgeRefEntry.class, bridgeRefEntryKey); + return bridgeRefEntryInstanceIdentifierBuilder.build(); + } + + public static BridgeRefEntry getBridgeRefEntryFromOperDS(InstanceIdentifier dpnBridgeEntryIid, + DataBroker dataBroker) { + Optional bridgeRefEntryOptional = + IfmUtil.read(LogicalDatastoreType.OPERATIONAL, dpnBridgeEntryIid, dataBroker); + if (!bridgeRefEntryOptional.isPresent()) { + return null; + } + return bridgeRefEntryOptional.get(); + } + + public static InstanceIdentifier getBridgeEntryIdentifier(BridgeEntryKey bridgeEntryKey) { + InstanceIdentifier.InstanceIdentifierBuilder bridgeEntryIdBuilder = + InstanceIdentifier.builder(BridgeInterfaceInfo.class).child(BridgeEntry.class, bridgeEntryKey); + return bridgeEntryIdBuilder.build(); + } + + public static BridgeEntry getBridgeEntryFromConfigDS(InstanceIdentifier bridgeEntryInstanceIdentifier, + DataBroker dataBroker) { + Optional bridgeEntryOptional = + IfmUtil.read(LogicalDatastoreType.CONFIGURATION, bridgeEntryInstanceIdentifier, dataBroker); + if (!bridgeEntryOptional.isPresent()) { + return null; + } + return bridgeEntryOptional.get(); + } + + public static InstanceIdentifier getBridgeInterfaceEntryIdentifier(BridgeEntryKey bridgeEntryKey, + BridgeInterfaceEntryKey bridgeInterfaceEntryKey) { + return InstanceIdentifier.builder(BridgeInterfaceInfo.class) + .child(BridgeEntry.class, bridgeEntryKey) + .child(BridgeInterfaceEntry.class, bridgeInterfaceEntryKey).build(); + + } + + public static BridgeInterfaceEntry getBridgeInterfaceEntryFromConfigDS( + InstanceIdentifier bridgeInterfaceEntryInstanceIdentifier, DataBroker dataBroker) { + Optional bridgeInterfaceEntryOptional = + IfmUtil.read(LogicalDatastoreType.CONFIGURATION, bridgeInterfaceEntryInstanceIdentifier, dataBroker); + if (!bridgeInterfaceEntryOptional.isPresent()) { + return null; + } + return bridgeInterfaceEntryOptional.get(); + } + + + public static void createBridgeInterfaceEntryInConfigDS(BridgeEntryKey bridgeEntryKey, + BridgeInterfaceEntryKey bridgeInterfaceEntryKey, + String childInterface, + WriteTransaction t) { + InstanceIdentifier bridgeInterfaceEntryIid = + InterfaceMetaUtils.getBridgeInterfaceEntryIdentifier(bridgeEntryKey, bridgeInterfaceEntryKey); + BridgeInterfaceEntryBuilder entryBuilder = new BridgeInterfaceEntryBuilder().setKey(bridgeInterfaceEntryKey) + .setInterfaceName(childInterface); + t.put(LogicalDatastoreType.CONFIGURATION, bridgeInterfaceEntryIid, entryBuilder.build(), true); + } + + public static void createBridgeInterfaceEntryInConfigDS(BridgeEntryKey bridgeEntryKey, + BridgeInterfaceEntryKey bridgeInterfaceEntryKey, + String childInterface, + InstanceIdentifier tpIid, + WriteTransaction t) { + if (tpIid == null) { + createBridgeInterfaceEntryInConfigDS(bridgeEntryKey, bridgeInterfaceEntryKey, childInterface, t); + return; + } + + InstanceIdentifier bridgeInterfaceEntryIid = + InterfaceMetaUtils.getBridgeInterfaceEntryIdentifier(bridgeEntryKey, bridgeInterfaceEntryKey); + BridgeInterfaceEntryBuilder entryBuilder = new BridgeInterfaceEntryBuilder().setKey(bridgeInterfaceEntryKey) + .setInterfaceName(childInterface); + t.put(LogicalDatastoreType.CONFIGURATION, bridgeInterfaceEntryIid, entryBuilder.build(), true); + } + + public static InstanceIdentifier getInterfaceParentEntryIdentifier( + InterfaceParentEntryKey interfaceParentEntryKey) { + InstanceIdentifier.InstanceIdentifierBuilder intfIdBuilder = + InstanceIdentifier.builder(InterfaceChildInfo.class) + .child(InterfaceParentEntry.class, interfaceParentEntryKey); + return intfIdBuilder.build(); + } + + public static InstanceIdentifier getInterfaceChildEntryIdentifier( + InterfaceParentEntryKey interfaceParentEntryKey, InterfaceChildEntryKey interfaceChildEntryKey) { + InstanceIdentifier.InstanceIdentifierBuilder intfIdBuilder = + InstanceIdentifier.builder(InterfaceChildInfo.class) + .child(InterfaceParentEntry.class, interfaceParentEntryKey) + .child(InterfaceChildEntry.class, interfaceChildEntryKey); + return intfIdBuilder.build(); + } + + public static InterfaceParentEntry getInterfaceParentEntryFromConfigDS( + InterfaceParentEntryKey interfaceParentEntryKey, DataBroker dataBroker) { + InstanceIdentifier intfParentIid = + getInterfaceParentEntryIdentifier(interfaceParentEntryKey); + + return getInterfaceParentEntryFromConfigDS(intfParentIid, dataBroker); + } + + public static InterfaceParentEntry getInterfaceParentEntryFromConfigDS( + InstanceIdentifier intfId, DataBroker dataBroker) { + Optional interfaceParentEntryOptional = + IfmUtil.read(LogicalDatastoreType.CONFIGURATION, intfId, dataBroker); + if (!interfaceParentEntryOptional.isPresent()) { + return null; + } + return interfaceParentEntryOptional.get(); + } + + public static InterfaceChildEntry getInterfaceChildEntryFromConfigDS(InterfaceParentEntryKey interfaceParentEntryKey, + InterfaceChildEntryKey interfaceChildEntryKey, + DataBroker dataBroker) { + InstanceIdentifier intfChildIid = + getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey); + + return getInterfaceChildEntryFromConfigDS(intfChildIid, dataBroker); + } + + public static InterfaceChildEntry getInterfaceChildEntryFromConfigDS( + InstanceIdentifier intfChildIid, DataBroker dataBroker) { + Optional interfaceChildEntryOptional = + IfmUtil.read(LogicalDatastoreType.CONFIGURATION, intfChildIid, dataBroker); + if (!interfaceChildEntryOptional.isPresent()) { + return null; + } + return interfaceChildEntryOptional.get(); + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceConfigListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceConfigListener.java new file mode 100644 index 00000000..a8457c55 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceConfigListener.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.listeners; + +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.idmanager.IdManager; +import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase; +import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsInterfaceConfigAddHelper; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsInterfaceConfigRemoveHelper; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsInterfaceConfigUpdateHelper; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.concurrent.Callable; + +/** + * This class listens for interface creation/removal/update in Configuration DS. + * This is used to handle interfaces for base of-ports. + */ +public class InterfaceConfigListener extends AsyncDataTreeChangeListenerBase { + private static final Logger LOG = LoggerFactory.getLogger(InterfaceConfigListener.class); + private DataBroker dataBroker; + private IdManager idManager; + + public InterfaceConfigListener(final DataBroker dataBroker, final IdManager idManager) { + super(Interface.class, InterfaceConfigListener.class); + this.dataBroker = dataBroker; + this.idManager = idManager; + } + + @Override + protected InstanceIdentifier getWildCardPath() { + return InstanceIdentifier.create(Interfaces.class).child(Interface.class); + } + + @Override + protected InterfaceConfigListener getDataTreeChangeListener() { + return InterfaceConfigListener.this; + } + + @Override + protected void remove(InstanceIdentifier key, Interface interfaceOld) { + LOG.debug("Received Interface Remove Event: {}, {}", key, interfaceOld); + String ifName = interfaceOld.getName(); + String parentInterface = null; + + ParentRefs parentRefs = interfaceOld.getAugmentation(ParentRefs.class); + if (parentRefs != null) { + parentInterface = parentRefs.getParentInterface(); + if (parentInterface != null && !parentInterface.equals(ifName)) { + return; + } + if (parentRefs.getDatapathNodeIdentifier() == null) { + return; + } + } + + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + RendererConfigRemoveWorker configWorker = new RendererConfigRemoveWorker(key, interfaceOld, ifName, parentRefs); + coordinator.enqueueJob(ifName, configWorker); + } + + @Override + protected void update(InstanceIdentifier key, Interface interfaceOld, Interface interfaceNew) { + LOG.debug("Received Interface Update Event: {}, {}, {}", key, interfaceOld, interfaceNew); + String ifNameNew = interfaceNew.getName(); + String parentInterface = null; + + ParentRefs parentRefs = interfaceNew.getAugmentation(ParentRefs.class); + if (parentRefs != null) { + parentInterface = parentRefs.getParentInterface(); + } + + if (parentInterface != null && !parentInterface.equals(ifNameNew)) { + return; + } + + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + RendererConfigUpdateWorker worker = new RendererConfigUpdateWorker(key, interfaceOld, interfaceNew, ifNameNew); + coordinator.enqueueJob(ifNameNew, worker); + } + + @Override + protected void add(InstanceIdentifier key, Interface interfaceNew) { + LOG.debug("Received Interface Add Event: {}, {}", key, interfaceNew); + String ifName = interfaceNew.getName(); + String parentInterface = null; + + ParentRefs parentRefs = interfaceNew.getAugmentation(ParentRefs.class); + if (parentRefs != null) { + parentInterface = parentRefs.getParentInterface(); + } + + if (parentInterface != null && !parentInterface.equals(ifName)) { + return; + } + + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + RendererConfigAddWorker configWorker = new RendererConfigAddWorker(key, interfaceNew, parentRefs, ifName); + coordinator.enqueueJob(ifName, configWorker); + } + + private class RendererConfigAddWorker implements Callable>> { + InstanceIdentifier key; + Interface interfaceNew; + String portName; + ParentRefs parentRefs; + + public RendererConfigAddWorker(InstanceIdentifier key, Interface interfaceNew, + ParentRefs parentRefs, String portName) { + this.key = key; + this.interfaceNew = interfaceNew; + this.portName = portName; + this.parentRefs = parentRefs; + } + + @Override + public List> call() throws Exception { + // If another renderer(for eg : CSS) needs to be supported, check can be performed here + // to call the respective helpers. + return OvsInterfaceConfigAddHelper.addConfiguration(dataBroker, parentRefs, interfaceNew, idManager); + } + + @Override + public String toString() { + return "RendererConfigAddWorker{" + + "key=" + key + + ", interfaceNew=" + interfaceNew + + ", portName='" + portName + '\'' + + '}'; + } + } + + /** + * + */ + private class RendererConfigUpdateWorker implements Callable { + InstanceIdentifier key; + Interface interfaceOld; + Interface interfaceNew; + String portNameNew; + + public RendererConfigUpdateWorker(InstanceIdentifier key, Interface interfaceOld, + Interface interfaceNew, String portNameNew) { + this.key = key; + this.interfaceOld = interfaceOld; + this.interfaceNew = interfaceNew; + this.portNameNew = portNameNew; + } + + @Override + public List> call() throws Exception { + // If another renderer(for eg : CSS) needs to be supported, check can be performed here + // to call the respective helpers. + return OvsInterfaceConfigUpdateHelper.updateConfiguration(dataBroker, idManager, interfaceNew, interfaceOld); + } + + @Override + public String toString() { + return "RendererConfigUpdateWorker{" + + "key=" + key + + ", interfaceOld=" + interfaceOld + + ", interfaceNew=" + interfaceNew + + ", portNameNew='" + portNameNew + '\'' + + '}'; + } + } + + /** + * + */ + private class RendererConfigRemoveWorker implements Callable { + InstanceIdentifier key; + Interface interfaceOld; + String portName; + ParentRefs parentRefs; + + public RendererConfigRemoveWorker(InstanceIdentifier key, Interface interfaceOld, String portName, + ParentRefs parentRefs) { + this.key = key; + this.interfaceOld = interfaceOld; + this.portName = portName; + this.parentRefs = parentRefs; + } + + @Override + public List> call() throws Exception { + // If another renderer(for eg : CSS) needs to be supported, check can be performed here + // to call the respective helpers. + return OvsInterfaceConfigRemoveHelper.removeConfiguration(dataBroker, interfaceOld, idManager, parentRefs); + } + + @Override + public String toString() { + return "RendererConfigRemoveWorker{" + + "key=" + key + + ", interfaceOld=" + interfaceOld + + ", portName='" + portName + '\'' + + '}'; + } + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceInventoryStateListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceInventoryStateListener.java new file mode 100644 index 00000000..8629a75c --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceInventoryStateListener.java @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.listeners; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker; +import org.opendaylight.vpnservice.datastoreutils.AsyncDataChangeListenerBase; +import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceStateAddHelper; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceStateRemoveHelper; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceStateUpdateHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.Callable; + +/** + * + * This Class is a Data Change Listener for FlowCapableNodeConnector updates. + * This creates an entry in the interface-state OperDS for every node-connector used. + * + * NOTE: This class just creates an ifstate entry whose interface-name will be the same as the node-connector portname. + * If PortName is not unique across DPNs, this implementation can have problems. + */ + +public class InterfaceInventoryStateListener extends AsyncDataChangeListenerBase implements AutoCloseable{ + private static final Logger LOG = LoggerFactory.getLogger(InterfaceInventoryStateListener.class); + private DataBroker dataBroker; + + public InterfaceInventoryStateListener(final DataBroker dataBroker) { + super(FlowCapableNodeConnector.class, InterfaceInventoryStateListener.class); + this.dataBroker = dataBroker; + } + + @Override + protected InstanceIdentifier getWildCardPath() { + return InstanceIdentifier.create(Nodes.class).child(Node.class).child(NodeConnector.class) + .augmentation(FlowCapableNodeConnector.class); + } + + @Override + protected DataChangeListener getDataChangeListener() { + return InterfaceInventoryStateListener.this; + } + + @Override + protected AsyncDataBroker.DataChangeScope getDataChangeScope() { + return AsyncDataBroker.DataChangeScope.BASE; + } + + @Override + protected void remove(InstanceIdentifier key, + FlowCapableNodeConnector flowCapableNodeConnectorOld) { + LOG.debug("Received NodeConnector Remove Event: {}, {}", key, flowCapableNodeConnectorOld); + String portName = flowCapableNodeConnectorOld.getName(); + NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId(); + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + + InterfaceStateRemoveWorker interfaceStateRemoveWorker = new InterfaceStateRemoveWorker(key, + flowCapableNodeConnectorOld, portName); + coordinator.enqueueJob(portName, interfaceStateRemoveWorker); + } + + @Override + protected void update(InstanceIdentifier key, FlowCapableNodeConnector fcNodeConnectorOld, + FlowCapableNodeConnector fcNodeConnectorNew) { + LOG.debug("Received NodeConnector Update Event: {}, {}, {}", key, fcNodeConnectorOld, fcNodeConnectorNew); + String portName = fcNodeConnectorNew.getName(); + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + + InterfaceStateUpdateWorker interfaceStateUpdateWorker = new InterfaceStateUpdateWorker(key, fcNodeConnectorOld, + fcNodeConnectorNew, portName); + coordinator.enqueueJob(portName, interfaceStateUpdateWorker); + } + + @Override + protected void add(InstanceIdentifier key, FlowCapableNodeConnector fcNodeConnectorNew) { + LOG.debug("Received NodeConnector Add Event: {}, {}", key, fcNodeConnectorNew); + String portName = fcNodeConnectorNew.getName(); + NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId(); + + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + InterfaceStateAddWorker ifStateAddWorker = new InterfaceStateAddWorker(nodeConnectorId, + fcNodeConnectorNew, portName); + coordinator.enqueueJob(portName, ifStateAddWorker); + } + + private class InterfaceStateAddWorker implements Callable { + private final NodeConnectorId nodeConnectorId; + private final FlowCapableNodeConnector fcNodeConnectorNew; + private final String portName; + + public InterfaceStateAddWorker(NodeConnectorId nodeConnectorId, + FlowCapableNodeConnector fcNodeConnectorNew, + String portName) { + this.nodeConnectorId = nodeConnectorId; + this.fcNodeConnectorNew = fcNodeConnectorNew; + this.portName = portName; + } + + @Override + public Object call() throws Exception { + // If another renderer(for eg : CSS) needs to be supported, check can be performed here + // to call the respective helpers. + return OvsInterfaceStateAddHelper.addState(dataBroker, nodeConnectorId, + portName, fcNodeConnectorNew); + } + + @Override + public String toString() { + return "InterfaceStateAddWorker{" + + "nodeConnectorId=" + nodeConnectorId + + ", fcNodeConnectorNew=" + fcNodeConnectorNew + + ", portName='" + portName + '\'' + + '}'; + } + } + + private class InterfaceStateUpdateWorker implements Callable { + private InstanceIdentifier key; + private final FlowCapableNodeConnector fcNodeConnectorOld; + private final FlowCapableNodeConnector fcNodeConnectorNew; + private String portName; + + + public InterfaceStateUpdateWorker(InstanceIdentifier key, + FlowCapableNodeConnector fcNodeConnectorOld, + FlowCapableNodeConnector fcNodeConnectorNew, + String portName) { + this.key = key; + this.fcNodeConnectorOld = fcNodeConnectorOld; + this.fcNodeConnectorNew = fcNodeConnectorNew; + this.portName = portName; + } + + @Override + public Object call() throws Exception { + // If another renderer(for eg : CSS) needs to be supported, check can be performed here + // to call the respective helpers. + return OvsInterfaceStateUpdateHelper.updateState(key, dataBroker, portName, + fcNodeConnectorNew, fcNodeConnectorOld); + } + + @Override + public String toString() { + return "InterfaceStateUpdateWorker{" + + "key=" + key + + ", fcNodeConnectorOld=" + fcNodeConnectorOld + + ", fcNodeConnectorNew=" + fcNodeConnectorNew + + ", portName='" + portName + '\'' + + '}'; + } + } + + private class InterfaceStateRemoveWorker implements Callable { + InstanceIdentifier key; + FlowCapableNodeConnector fcNodeConnectorOld; + private final String portName; + + public InterfaceStateRemoveWorker(InstanceIdentifier key, + FlowCapableNodeConnector fcNodeConnectorOld, + String portName) { + this.key = key; + this.fcNodeConnectorOld = fcNodeConnectorOld; + this.portName = portName; + } + + @Override + public Object call() throws Exception { + // If another renderer(for eg : CSS) needs to be supported, check can be performed here + // to call the respective helpers. + return OvsInterfaceStateRemoveHelper.removeState(key, dataBroker, portName, fcNodeConnectorOld); + } + + @Override + public String toString() { + return "InterfaceStateRemoveWorker{" + + "key=" + key + + ", fcNodeConnectorOld=" + fcNodeConnectorOld + + ", portName='" + portName + '\'' + + '}'; + } + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceTopologyStateListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceTopologyStateListener.java new file mode 100644 index 00000000..db2ebcd7 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceTopologyStateListener.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.listeners; + +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker; +import org.opendaylight.vpnservice.datastoreutils.AsyncDataChangeListenerBase; +import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceTopologyStateAddHelper; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceTopologyStateRemoveHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.concurrent.Callable; + +public class InterfaceTopologyStateListener extends AsyncDataChangeListenerBase { + private static final Logger LOG = LoggerFactory.getLogger(InterfaceTopologyStateListener.class); + private DataBroker dataBroker; + + public InterfaceTopologyStateListener(DataBroker dataBroker) { + super(OvsdbBridgeAugmentation.class, InterfaceTopologyStateListener.class); + this.dataBroker = dataBroker; + } + + @Override + protected InstanceIdentifier getWildCardPath() { + return InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class) + .child(Node.class).augmentation(OvsdbBridgeAugmentation.class).build(); + } + + @Override + protected DataChangeListener getDataChangeListener() { + return InterfaceTopologyStateListener.this; + } + + @Override + protected AsyncDataBroker.DataChangeScope getDataChangeScope() { + return AsyncDataBroker.DataChangeScope.BASE; + } + + @Override + protected void remove(InstanceIdentifier identifier, OvsdbBridgeAugmentation bridgeOld) { + LOG.debug("Received Remove DataChange Notification for identifier: {}, ovsdbBridgeAugmentation: {}", + identifier, bridgeOld); + DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance(); + RendererStateRemoveWorker rendererStateRemoveWorker = new RendererStateRemoveWorker(identifier, bridgeOld); + jobCoordinator.enqueueJob(bridgeOld.getBridgeName().getValue() + bridgeOld.getDatapathId(), rendererStateRemoveWorker); + } + + @Override + protected void update(InstanceIdentifier identifier, OvsdbBridgeAugmentation bridgeOld, + OvsdbBridgeAugmentation bridgeNew) { + LOG.info("Received Update DataChange Notification for identifier: {}, ovsdbBridgeAugmentation old: {}, new: {}." + + "No Action Performed.", identifier, bridgeOld, bridgeNew); + } + + @Override + protected void add(InstanceIdentifier identifier, OvsdbBridgeAugmentation bridgeNew) { + LOG.debug("Received Add DataChange Notification for identifier: {}, ovsdbBridgeAugmentation: {}", + identifier, bridgeNew); + DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance(); + RendererStateAddWorker rendererStateAddWorker = new RendererStateAddWorker(identifier, bridgeNew); + jobCoordinator.enqueueJob(bridgeNew.getBridgeName().getValue() + bridgeNew.getDatapathId(), rendererStateAddWorker); + } + + private class RendererStateAddWorker implements Callable>> { + InstanceIdentifier instanceIdentifier; + OvsdbBridgeAugmentation bridgeNew; + + + public RendererStateAddWorker(InstanceIdentifier instanceIdentifier, + OvsdbBridgeAugmentation bridgeNew) { + this.instanceIdentifier = instanceIdentifier; + this.bridgeNew = bridgeNew; + } + + @Override + public List> call() throws Exception { + // If another renderer(for eg : CSS) needs to be supported, check can be performed here + // to call the respective helpers. + return OvsInterfaceTopologyStateAddHelper.addPortToBridge(instanceIdentifier, + bridgeNew, dataBroker); + } + } + + private class RendererStateRemoveWorker implements Callable>> { + InstanceIdentifier instanceIdentifier; + OvsdbBridgeAugmentation bridgeNew; + + + public RendererStateRemoveWorker(InstanceIdentifier instanceIdentifier, + OvsdbBridgeAugmentation bridgeNew) { + this.instanceIdentifier = instanceIdentifier; + this.bridgeNew = bridgeNew; + } + + @Override + public List> call() throws Exception { + // If another renderer(for eg : CSS) needs to be supported, check can be performed here + // to call the respective helpers. + return OvsInterfaceTopologyStateRemoveHelper.removePortFromBridge(instanceIdentifier, + bridgeNew, dataBroker); + } + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/VlanMemberConfigListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/VlanMemberConfigListener.java new file mode 100644 index 00000000..2d947162 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/VlanMemberConfigListener.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.listeners; + +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.idmanager.IdManager; +import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase; +import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsVlanMemberConfigAddHelper; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsVlanMemberConfigRemoveHelper; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsVlanMemberConfigUpdateHelper; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.concurrent.Callable; + +public class VlanMemberConfigListener extends AsyncDataTreeChangeListenerBase { + private static final Logger LOG = LoggerFactory.getLogger(VlanMemberConfigListener.class); + private DataBroker dataBroker; + private IdManager idManager; + + public VlanMemberConfigListener(final DataBroker dataBroker, final IdManager idManager) { + super(Interface.class, VlanMemberConfigListener.class); + this.dataBroker = dataBroker; + this.idManager = idManager; + } + + @Override + protected InstanceIdentifier getWildCardPath() { + return InstanceIdentifier.create(Interfaces.class).child(Interface.class); + } + + @Override + protected void remove(InstanceIdentifier key, Interface interfaceOld) { + IfL2vlan ifL2vlan = interfaceOld.getAugmentation(IfL2vlan.class); + if (ifL2vlan == null) { + return; + } + + if (ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.TrunkMember) { + return; + } + + ParentRefs parentRefs = interfaceOld.getAugmentation(ParentRefs.class); + if (parentRefs == null) { + LOG.error("Attempt to remove Vlan Trunk-Member {} without a parent interface", interfaceOld); + return; + } + + String lowerLayerIf = parentRefs.getParentInterface(); + if (lowerLayerIf.equals(interfaceOld.getName())) { + LOG.error("Attempt to remove Vlan Trunk-Member {} with same parent interface name.", interfaceOld); + return; + } + + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + RendererConfigRemoveWorker removeWorker = new RendererConfigRemoveWorker(key, interfaceOld, parentRefs, ifL2vlan); + coordinator.enqueueJob(lowerLayerIf, removeWorker); + } + + @Override + protected void update(InstanceIdentifier key, Interface interfaceOld, Interface interfaceNew) { + IfL2vlan ifL2vlanNew = interfaceNew.getAugmentation(IfL2vlan.class); + if (ifL2vlanNew == null) { + return; + } + if (ifL2vlanNew.getL2vlanMode() != IfL2vlan.L2vlanMode.TrunkMember) { + LOG.error("Configuration Error. Attempt to modify Vlan Mode of interface: {} " + + "to interface: {}", interfaceOld, interfaceNew); + return; + } + + ParentRefs parentRefsNew = interfaceNew.getAugmentation(ParentRefs.class); + if (parentRefsNew == null) { + LOG.error("Configuration Error. Attempt to update Vlan Trunk-Member {} without a " + + "parent interface", interfaceNew); + return; + } + + String lowerLayerIf = parentRefsNew.getParentInterface(); + if (lowerLayerIf.equals(interfaceNew.getName())) { + LOG.error("Configuration Error. Attempt to update Vlan Trunk-Member {} with same parent " + + "interface name.", interfaceNew); + return; + } + + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + RendererConfigUpdateWorker updateWorker = new RendererConfigUpdateWorker(key, interfaceNew, interfaceOld, + parentRefsNew, ifL2vlanNew); + coordinator.enqueueJob(lowerLayerIf, updateWorker); + } + + @Override + protected void add(InstanceIdentifier key, Interface interfaceNew) { + IfL2vlan ifL2vlan = interfaceNew.getAugmentation(IfL2vlan.class); + if (ifL2vlan == null) { + return; + } + + if (ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.TrunkMember) { + return; + } + + ParentRefs parentRefs = interfaceNew.getAugmentation(ParentRefs.class); + if (parentRefs == null) { + LOG.error("Attempt to add Vlan Trunk-Member {} without a parent interface", interfaceNew); + return; + } + + String lowerLayerIf = parentRefs.getParentInterface(); + if (lowerLayerIf.equals(interfaceNew.getName())) { + LOG.error("Attempt to add Vlan Trunk-Member {} with same parent interface name.", interfaceNew); + return; + } + + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + RendererConfigAddWorker configWorker = new RendererConfigAddWorker(key, interfaceNew, parentRefs, ifL2vlan); + coordinator.enqueueJob(lowerLayerIf, configWorker); + } + + @Override + protected VlanMemberConfigListener getDataTreeChangeListener() { + return VlanMemberConfigListener.this; + } + + private class RendererConfigAddWorker implements Callable>> { + InstanceIdentifier key; + Interface interfaceNew; + IfL2vlan ifL2vlan; + ParentRefs parentRefs; + + public RendererConfigAddWorker(InstanceIdentifier key, Interface interfaceNew, + ParentRefs parentRefs, IfL2vlan ifL2vlan) { + this.key = key; + this.interfaceNew = interfaceNew; + this.ifL2vlan = ifL2vlan; + this.parentRefs = parentRefs; + } + + @Override + public List> call() throws Exception { + // If another renderer(for eg : CSS) needs to be supported, check can be performed here + // to call the respective helpers. + return OvsVlanMemberConfigAddHelper.addConfiguration(dataBroker, parentRefs, interfaceNew, + ifL2vlan, idManager); + } + } + + private class RendererConfigUpdateWorker implements Callable>> { + InstanceIdentifier key; + Interface interfaceNew; + Interface interfaceOld; + IfL2vlan ifL2vlanNew; + ParentRefs parentRefsNew; + + public RendererConfigUpdateWorker(InstanceIdentifier key, Interface interfaceNew, + Interface interfaceOld, ParentRefs parentRefsNew, IfL2vlan ifL2vlanNew) { + this.key = key; + this.interfaceNew = interfaceNew; + this.interfaceOld = interfaceOld; + this.ifL2vlanNew = ifL2vlanNew; + this.parentRefsNew = parentRefsNew; + } + + @Override + public List> call() throws Exception { + // If another renderer(for eg : CSS) needs to be supported, check can be performed here + // to call the respective helpers. + return OvsVlanMemberConfigUpdateHelper.updateConfiguration(dataBroker, parentRefsNew, interfaceOld, + ifL2vlanNew, interfaceNew, idManager); + } + } + + private class RendererConfigRemoveWorker implements Callable>> { + InstanceIdentifier key; + Interface interfaceOld; + IfL2vlan ifL2vlan; + ParentRefs parentRefs; + + public RendererConfigRemoveWorker(InstanceIdentifier key, Interface interfaceOld, + ParentRefs parentRefs, IfL2vlan ifL2vlan) { + this.key = key; + this.interfaceOld = interfaceOld; + this.ifL2vlan = ifL2vlan; + this.parentRefs = parentRefs; + } + + @Override + public List> call() throws Exception { + // If another renderer(for eg : CSS) needs to be supported, check can be performed here + // to call the respective helpers. + return OvsVlanMemberConfigRemoveHelper.removeConfiguration(dataBroker, parentRefs, interfaceOld, + ifL2vlan, idManager); + } + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigAddHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigAddHelper.java new file mode 100644 index 00000000..cc261927 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigAddHelper.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.renderer.ovs.confighelpers; + +import com.google.common.base.Optional; +import com.google.common.util.concurrent.ListenableFuture; +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.idmanager.IdManager; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities.SouthboundUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public class OvsInterfaceConfigAddHelper { + private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceConfigAddHelper.class); + + public static List> addConfiguration(DataBroker dataBroker, ParentRefs parentRefs, + Interface interfaceNew, IdManager idManager) { + List> futures = new ArrayList<>(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + + IfTunnel ifTunnel = interfaceNew.getAugmentation(IfTunnel.class); + if (ifTunnel != null) { + addTunnelConfiguration(dataBroker, parentRefs, interfaceNew, idManager, t); + futures.add(t.submit()); + return futures; + } + + addVlanConfiguration(interfaceNew, t, dataBroker); + futures.add(t.submit()); + return futures; + } + + private static void addVlanConfiguration(Interface interfaceNew, WriteTransaction t, DataBroker dataBroker) { + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = + InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceNew.getName(), dataBroker); + if (ifState == null) { + return; + } + updateStateEntry(interfaceNew, t, ifState); + + IfL2vlan ifL2vlan = interfaceNew.getAugmentation(IfL2vlan.class); + if (ifL2vlan == null || ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) { + return; + } + + InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(interfaceNew.getName()); + InterfaceParentEntry interfaceParentEntry = + InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker); + if (interfaceParentEntry == null) { + return; + } + + List interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry(); + if (interfaceChildEntries == null) { + return; + } + + OperStatus operStatus = ifState.getOperStatus(); + PhysAddress physAddress = ifState.getPhysAddress(); + AdminStatus adminStatus = ifState.getAdminStatus(); + NodeConnectorId nodeConnectorId = new NodeConnectorId(ifState.getLowerLayerIf().get(0)); + + //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100. + for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) { + InterfaceKey childIfKey = new InterfaceKey(interfaceChildEntry.getChildInterface()); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface ifaceChild = + InterfaceManagerCommonUtils.getInterfaceFromConfigDS(childIfKey, dataBroker); + + if (!ifaceChild.isEnabled()) { + operStatus = OperStatus.Down; + } + + InstanceIdentifier ifChildStateId = + IfmUtil.buildStateInterfaceId(ifaceChild.getName()); + List childLowerLayerIfList = new ArrayList<>(); + childLowerLayerIfList.add(0, nodeConnectorId.getValue()); + childLowerLayerIfList.add(1, interfaceNew.getName()); + InterfaceBuilder childIfaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus) + .setOperStatus(operStatus).setPhysAddress(physAddress).setLowerLayerIf(childLowerLayerIfList); + childIfaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifaceChild.getName())); + t.put(LogicalDatastoreType.OPERATIONAL, ifChildStateId, childIfaceBuilder.build(), true); + } + } + + private static void addTunnelConfiguration(DataBroker dataBroker, ParentRefs parentRefs, + Interface interfaceNew, IdManager idManager, + WriteTransaction t) { + if (parentRefs == null) { + LOG.warn("ParentRefs for interface: {} Not Found. " + + "Creation of Tunnel OF-Port not supported when dpid not provided.", interfaceNew.getName()); + return; + } + + BigInteger dpId = parentRefs.getDatapathNodeIdentifier(); + if (dpId == null) { + LOG.warn("dpid for interface: {} Not Found. No DPID provided. " + + "Creation of OF-Port not supported.", interfaceNew.getName()); + return; + } + + createBridgeEntryIfNotPresent(dpId, dataBroker, t); + + BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId); + InstanceIdentifier dpnBridgeEntryIid = + InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey); + BridgeRefEntry bridgeRefEntry = + InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker); + BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(dpId); + BridgeInterfaceEntryKey bridgeInterfaceEntryKey = new BridgeInterfaceEntryKey(interfaceNew.getName()); + if (bridgeRefEntry == null) { + InterfaceMetaUtils.createBridgeInterfaceEntryInConfigDS(bridgeEntryKey, bridgeInterfaceEntryKey, + interfaceNew.getName(), t); + return; + } + + InstanceIdentifier bridgeIid = + (InstanceIdentifier)bridgeRefEntry.getBridgeReference().getValue(); + Optional bridgeNodeOptional = + IfmUtil.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker); + if (bridgeNodeOptional.isPresent()) { + OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNodeOptional.get(); + String bridgeName = ovsdbBridgeAugmentation.getBridgeName().getValue(); + SouthboundUtils.addPortToBridge(bridgeIid, interfaceNew, + ovsdbBridgeAugmentation, bridgeName, interfaceNew.getName(), dataBroker, t); + } + + InstanceIdentifier tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier( + InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), interfaceNew.getName()); + InterfaceMetaUtils.createBridgeInterfaceEntryInConfigDS(bridgeEntryKey, bridgeInterfaceEntryKey, + interfaceNew.getName(), tpIid, t); + } + + private static void updateStateEntry(Interface interfaceNew, WriteTransaction t, + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) { + OperStatus operStatus; + if (!interfaceNew.isEnabled() && ifState.getOperStatus() != OperStatus.Down) { + operStatus = OperStatus.Down; + InstanceIdentifier ifStateId = + IfmUtil.buildStateInterfaceId(interfaceNew.getName()); + InterfaceBuilder ifaceBuilder = new InterfaceBuilder(); + ifaceBuilder.setOperStatus(operStatus); + ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceNew.getName())); + t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build()); + } + } + + private static void createBridgeEntryIfNotPresent(BigInteger dpId, + DataBroker dataBroker, WriteTransaction t) { + BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(dpId); + InstanceIdentifier bridgeEntryInstanceIdentifier = + InterfaceMetaUtils.getBridgeEntryIdentifier(bridgeEntryKey); + BridgeEntry bridgeEntry = + InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier, + dataBroker); + if (bridgeEntry == null) { + BridgeEntryBuilder bridgeEntryBuilder = new BridgeEntryBuilder().setKey(bridgeEntryKey) + .setDpid(dpId); + t.put(LogicalDatastoreType.CONFIGURATION, bridgeEntryInstanceIdentifier, bridgeEntryBuilder.build(), true); + } + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigRemoveHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigRemoveHelper.java new file mode 100644 index 00000000..edb6d27e --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigRemoveHelper.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.renderer.ovs.confighelpers; + +import com.google.common.util.concurrent.ListenableFuture; +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.idmanager.IdManager; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities.SouthboundUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public class OvsInterfaceConfigRemoveHelper { + private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceConfigRemoveHelper.class); + + public static List> removeConfiguration(DataBroker dataBroker, Interface interfaceOld, + IdManager idManager, ParentRefs parentRefs) { + List> futures = new ArrayList<>(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + + IfTunnel ifTunnel = interfaceOld.getAugmentation(IfTunnel.class); + if (ifTunnel != null) { + removeTunnelConfiguration(parentRefs, dataBroker, interfaceOld, idManager, t); + futures.add(t.submit()); + return futures; + } + + removeVlanConfiguration(dataBroker, interfaceOld, t); + + /* FIXME: Deallocate ID from Idmanager. */ + + futures.add(t.submit()); + return futures; + } + + private static void removeVlanConfiguration(DataBroker dataBroker, Interface interfaceOld, WriteTransaction t) { + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = + InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceOld.getName(), dataBroker); + if (ifState == null) { + return; + } + + String ncStr = ifState.getLowerLayerIf().get(0); + NodeConnectorId nodeConnectorId = new NodeConnectorId(ncStr); + NodeConnector nodeConnector = + InterfaceManagerCommonUtils.getNodeConnectorFromInventoryOperDS(nodeConnectorId, dataBroker); + FlowCapableNodeConnector flowCapableNodeConnector = + nodeConnector.getAugmentation(FlowCapableNodeConnector.class); + //State state = flowCapableNodeConnector.getState(); + OperStatus operStatus = flowCapableNodeConnector == null ? OperStatus.Down : OperStatus.Up; + + if (ifState.getOperStatus() != operStatus) { + InstanceIdentifier ifStateId = + IfmUtil.buildStateInterfaceId(interfaceOld.getName()); + InterfaceBuilder ifaceBuilder = new InterfaceBuilder(); + ifaceBuilder.setOperStatus(operStatus); + ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceOld.getName())); + t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build()); + } + + IfL2vlan ifL2vlan = interfaceOld.getAugmentation(IfL2vlan.class); + if (ifL2vlan == null || ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) { + return; + } + + // For Vlan-Trunk Interface, remove the trunk-member operstates as well... + InterfaceKey interfaceKey = new InterfaceKey(interfaceOld.getName()); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface = + InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker); + if (iface == null) { + return; + } + + InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(iface.getName()); + InterfaceParentEntry interfaceParentEntry = + InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker); + if (interfaceParentEntry == null) { + return; + } + + List interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry(); + if (interfaceChildEntries == null) { + return; + } + + //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100. + for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) { + InstanceIdentifier ifChildStateId = + IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface()); + t.delete(LogicalDatastoreType.OPERATIONAL, ifChildStateId); + } + } + + private static void removeTunnelConfiguration(ParentRefs parentRefs, DataBroker dataBroker, Interface interfaceOld, + IdManager idManager, WriteTransaction t) { + + BigInteger dpId = null; + if (parentRefs != null) { + dpId = parentRefs.getDatapathNodeIdentifier(); + } + + if (dpId == null) { + return; + } + + BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(dpId); + InstanceIdentifier bridgeRefEntryIid = + InterfaceMetaUtils.getBridgeRefEntryIdentifier(bridgeRefEntryKey); + BridgeRefEntry bridgeRefEntry = + InterfaceMetaUtils.getBridgeRefEntryFromOperDS(bridgeRefEntryIid, dataBroker); + + if (bridgeRefEntry != null) { + InstanceIdentifier bridgeIid = bridgeRefEntry.getBridgeReference().getValue(); + InstanceIdentifier tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier( + InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), interfaceOld.getName()); + t.delete(LogicalDatastoreType.CONFIGURATION, tpIid); + } + + BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(dpId); + InstanceIdentifier bridgeEntryIid = InterfaceMetaUtils.getBridgeEntryIdentifier(bridgeEntryKey); + BridgeEntry bridgeEntry = InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryIid, dataBroker); + if (bridgeEntry == null) { + return; + } + + List bridgeInterfaceEntries = bridgeEntry.getBridgeInterfaceEntry(); + if (bridgeInterfaceEntries == null) { + return; + } + + if (bridgeInterfaceEntries.size() <= 1) { + t.delete(LogicalDatastoreType.CONFIGURATION, bridgeEntryIid); + } else { + BridgeInterfaceEntryKey bridgeInterfaceEntryKey = + new BridgeInterfaceEntryKey(interfaceOld.getName()); + InstanceIdentifier bridgeInterfaceEntryIid = + InterfaceMetaUtils.getBridgeInterfaceEntryIdentifier(bridgeEntryKey, + bridgeInterfaceEntryKey); + t.delete(LogicalDatastoreType.CONFIGURATION, bridgeInterfaceEntryIid); + } + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigUpdateHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigUpdateHelper.java new file mode 100644 index 00000000..b7c2bb09 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigUpdateHelper.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.renderer.ovs.confighelpers; + +import com.google.common.util.concurrent.ListenableFuture; +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.idmanager.IdManager; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class OvsInterfaceConfigUpdateHelper { + private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceConfigUpdateHelper.class); + + public static List> updateConfiguration(DataBroker dataBroker, IdManager idManager, + Interface interfaceNew, Interface interfaceOld) { + List> futures = new ArrayList<>(); + + if(portAttributesModified(interfaceOld, interfaceNew)) { + futures.addAll(OvsInterfaceConfigRemoveHelper.removeConfiguration(dataBroker, interfaceOld, idManager, + interfaceOld.getAugmentation(ParentRefs.class))); + futures.addAll(OvsInterfaceConfigAddHelper.addConfiguration(dataBroker, + interfaceNew.getAugmentation(ParentRefs.class), interfaceNew, idManager)); + return futures; + } + + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = + InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceNew.getName(), dataBroker); + if (ifState == null) { + futures.addAll(OvsInterfaceConfigAddHelper.addConfiguration(dataBroker, + interfaceNew.getAugmentation(ParentRefs.class), interfaceNew, idManager)); + return futures; + } + + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + if (interfaceNew.isEnabled() != interfaceOld.isEnabled()) { + OperStatus operStatus; + if (!interfaceNew.isEnabled()) { + operStatus = OperStatus.Down; + } else { + String ncStr = ifState.getLowerLayerIf().get(0); + NodeConnectorId nodeConnectorId = new NodeConnectorId(ncStr); + NodeConnector nodeConnector = + InterfaceManagerCommonUtils.getNodeConnectorFromInventoryOperDS(nodeConnectorId, dataBroker); + FlowCapableNodeConnector flowCapableNodeConnector = + nodeConnector.getAugmentation(FlowCapableNodeConnector.class); + //State state = flowCapableNodeConnector.getState(); + operStatus = flowCapableNodeConnector == null ? OperStatus.Down : OperStatus.Up; + } + + String ifName = interfaceNew.getName(); + InstanceIdentifier ifStateId = + IfmUtil.buildStateInterfaceId(interfaceNew.getName()); + InterfaceBuilder ifaceBuilder = new InterfaceBuilder(); + ifaceBuilder.setOperStatus(operStatus); + ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName)); + t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build()); + + IfL2vlan ifL2vlan = interfaceNew.getAugmentation(IfL2vlan.class); + if (ifL2vlan == null || ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) { + futures.add(t.submit()); + return futures; + } + + InterfaceKey interfaceKey = new InterfaceKey(ifName); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface = + InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker); + if (iface == null) { + futures.add(t.submit()); + return futures; + } + + InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(iface.getName()); + InterfaceParentEntry interfaceParentEntry = + InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker); + if (interfaceParentEntry == null) { + futures.add(t.submit()); + return futures; + } + + List interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry(); + if (interfaceChildEntries == null) { + futures.add(t.submit()); + return futures; + } + + for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) { + InstanceIdentifier ifChildStateId = + IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface()); + InterfaceBuilder ifaceBuilderChild = new InterfaceBuilder(); + ifaceBuilderChild.setOperStatus(operStatus); + ifaceBuilderChild.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceChildEntry.getChildInterface())); + t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilderChild.build()); + } + } + + futures.add(t.submit()); + return futures; + } + + private static boolean portAttributesModified(Interface interfaceOld, Interface interfaceNew) { + ParentRefs parentRefsOld = interfaceOld.getAugmentation(ParentRefs.class); + ParentRefs parentRefsNew = interfaceNew.getAugmentation(ParentRefs.class); + if (checkAugmentations(parentRefsOld, parentRefsNew)) { + return true; + } + + IfL2vlan ifL2vlanOld = interfaceOld.getAugmentation(IfL2vlan.class); + IfL2vlan ifL2vlanNew = interfaceNew.getAugmentation(IfL2vlan.class); + if (checkAugmentations(ifL2vlanOld, ifL2vlanNew)) { + return true; + } + + IfTunnel ifTunnelOld = interfaceOld.getAugmentation(IfTunnel.class); + IfTunnel ifTunnelNew = interfaceNew.getAugmentation(IfTunnel.class); + if (checkAugmentations(ifTunnelOld, ifTunnelNew)) { + return true; + } + + return false; + } + + private static boolean checkAugmentations(T oldAug, T newAug) { + if ((oldAug != null && newAug == null) || + (oldAug == null && newAug != null)) { + return true; + } + + if (newAug != null && oldAug != null && !newAug.equals(oldAug)) { + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigAddHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigAddHelper.java new file mode 100644 index 00000000..e90a8f95 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigAddHelper.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.renderer.ovs.confighelpers; + +import com.google.common.util.concurrent.ListenableFuture; +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.idmanager.IdManager; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class OvsVlanMemberConfigAddHelper { + private static final Logger LOG = LoggerFactory.getLogger(OvsVlanMemberConfigAddHelper.class); + public static List> addConfiguration(DataBroker dataBroker, ParentRefs parentRefs, + Interface interfaceNew, IfL2vlan ifL2vlan, + IdManager idManager) { + List> futures = new ArrayList<>(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + + InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentRefs.getParentInterface()); + createInterfaceParentEntryIfNotPresent(dataBroker, t, interfaceParentEntryKey, parentRefs.getParentInterface()); + createInterfaceChildEntry(dataBroker, idManager, t, interfaceParentEntryKey, interfaceNew.getName()); + + InterfaceKey interfaceKey = new InterfaceKey(parentRefs.getParentInterface()); + Interface ifaceParent = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker); + if (ifaceParent == null) { + LOG.info("Parent Interface: {} not found when adding child interface: {}", + parentRefs.getParentInterface(), interfaceNew.getName()); + futures.add(t.submit()); + return futures; + } + + IfL2vlan parentIfL2Vlan = ifaceParent.getAugmentation(IfL2vlan.class); + if (parentIfL2Vlan == null || parentIfL2Vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) { + LOG.error("Parent Interface: {} not of trunk Type when adding trunk-member: {}", ifaceParent, interfaceNew); + futures.add(t.submit()); + return futures; + } + + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = + InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(parentRefs.getParentInterface(), dataBroker); + if (ifState != null) { + OperStatus operStatus = ifState.getOperStatus(); + AdminStatus adminStatus = ifState.getAdminStatus(); + PhysAddress physAddress = ifState.getPhysAddress(); + + if (!interfaceNew.isEnabled()) { + operStatus = OperStatus.Down; + } + + InstanceIdentifier ifStateId = + IfmUtil.buildStateInterfaceId(interfaceNew.getName()); + List lowerLayerIfList = new ArrayList<>(); + lowerLayerIfList.add(parentRefs.getParentInterface()); + InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus).setOperStatus(operStatus) + .setPhysAddress(physAddress).setLowerLayerIf(lowerLayerIfList); + ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceNew.getName())); + t.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), true); + + // FIXME: Maybe, add the new interface to the higher-layer if of the parent interface-state. + // That may not serve any purpose though for interface manager.... Unless some external parties are interested in it. + + /* FIXME -- Below code is needed to add vlan-trunks to the of-port. Is this really needed. + String lowerLayerIf = ifState.getLowerLayerIf().get(0); + + NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf); + BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId)); + + BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId); + InstanceIdentifier dpnBridgeEntryIid = + InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey); + BridgeRefEntry bridgeRefEntry = + InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker); + if (bridgeRefEntry != null) { + InstanceIdentifier bridgeIid = + (InstanceIdentifier)bridgeRefEntry.getBridgeReference().getValue(); + Optional bridgeNodeOptional = + IfmUtil.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker); + if (bridgeNodeOptional.isPresent()) { + OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNodeOptional.get(); + String bridgeName = ovsdbBridgeAugmentation.getBridgeName().getValue(); + VlanTrunkSouthboundUtils.addVlanPortToBridge(bridgeIid, ifL2vlan, + ovsdbBridgeAugmentation, bridgeName, parentRefs.getParentInterface(), dataBroker, t); + } + } */ + // FIXME: Need to add the Group here with actions: Push-Vlan, output_port. May not be needed here... + } + + futures.add(t.submit()); + return futures; + } + + private static void createInterfaceParentEntryIfNotPresent(DataBroker dataBroker, WriteTransaction t, + InterfaceParentEntryKey interfaceParentEntryKey, + String parentInterface){ + InstanceIdentifier interfaceParentEntryIdentifier = + InterfaceMetaUtils.getInterfaceParentEntryIdentifier(interfaceParentEntryKey); + InterfaceParentEntry interfaceParentEntry = + InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryIdentifier, dataBroker); + + if(interfaceParentEntry != null){ + LOG.info("Not Found entry for Parent Interface: {} in Vlan Trunk-Member Interface Renderer ConfigDS. " + + "Creating...", parentInterface); + InterfaceParentEntryBuilder interfaceParentEntryBuilder = new InterfaceParentEntryBuilder() + .setKey(interfaceParentEntryKey).setParentInterface(parentInterface); + t.put(LogicalDatastoreType.CONFIGURATION, interfaceParentEntryIdentifier, + interfaceParentEntryBuilder.build(), true); + } + } + + private static long createInterfaceChildEntry(DataBroker dataBroker, IdManager idManager, WriteTransaction t, + InterfaceParentEntryKey interfaceParentEntryKey, String childInterface){ + long lportTag = InterfaceManagerCommonUtils.getUniqueId(idManager, childInterface); + InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface); + InstanceIdentifier intfId = + InterfaceMetaUtils.getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey); + InterfaceChildEntryBuilder entryBuilder = new InterfaceChildEntryBuilder().setKey(interfaceChildEntryKey) + .setChildInterface(childInterface); + t.put(LogicalDatastoreType.CONFIGURATION, intfId, entryBuilder.build(),true); + return lportTag; + } +} diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigRemoveHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigRemoveHelper.java new file mode 100644 index 00000000..a0b404f3 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigRemoveHelper.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.renderer.ovs.confighelpers; + +import com.google.common.util.concurrent.ListenableFuture; +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.idmanager.IdManager; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class OvsVlanMemberConfigRemoveHelper { + private static final Logger LOG = LoggerFactory.getLogger(OvsVlanMemberConfigRemoveHelper.class); + public static List> removeConfiguration(DataBroker dataBroker, ParentRefs parentRefs, + Interface interfaceOld, IfL2vlan ifL2vlan, + IdManager idManager) { + List> futures = new ArrayList<>(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + + InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentRefs.getParentInterface()); + InstanceIdentifier interfaceParentEntryIid = + InterfaceMetaUtils.getInterfaceParentEntryIdentifier(interfaceParentEntryKey); + InterfaceParentEntry interfaceParentEntry = + InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryIid, dataBroker); + + List interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry(); + if (interfaceChildEntries.size() <= 1) { + t.delete(LogicalDatastoreType.CONFIGURATION, interfaceParentEntryIid); + } else { + InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(interfaceOld.getName()); + InstanceIdentifier interfaceChildEntryIid = + InterfaceMetaUtils.getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey); + t.delete(LogicalDatastoreType.CONFIGURATION, interfaceChildEntryIid); + } + + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = + InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(parentRefs.getParentInterface(), dataBroker); + if (ifState != null) { + /* FIXME -- The below code is needed if vlan-trunks should be updated in the of-port + + String lowerLayerIf = ifState.getLowerLayerIf().get(0); + NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf); + BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId)); + + BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId); + InstanceIdentifier dpnBridgeEntryIid = + InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey); + BridgeRefEntry bridgeRefEntry = + InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker); + if (bridgeRefEntry != null) { + InstanceIdentifier bridgeIid = + (InstanceIdentifier)bridgeRefEntry.getBridgeReference().getValue(); + Optional bridgeNodeOptional = + IfmUtil.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker); + if (bridgeNodeOptional.isPresent()) { + OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNodeOptional.get(); + String bridgeName = ovsdbBridgeAugmentation.getBridgeName().getValue(); + VlanTrunkSouthboundUtils.updateVlanMemberInTrunk(bridgeIid, ifL2vlan, + ovsdbBridgeAugmentation, bridgeName, parentRefs.getParentInterface(), dataBroker, t); + } + } */ + + InstanceIdentifier ifStateId = + IfmUtil.buildStateInterfaceId(interfaceOld.getName()); + t.delete(LogicalDatastoreType.OPERATIONAL, ifStateId); + } + + futures.add(t.submit()); + return futures; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigUpdateHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigUpdateHelper.java new file mode 100644 index 00000000..73edde02 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigUpdateHelper.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.renderer.ovs.confighelpers; + +import com.google.common.util.concurrent.ListenableFuture; +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.idmanager.IdManager; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class OvsVlanMemberConfigUpdateHelper { + private static final Logger LOG = LoggerFactory.getLogger(OvsVlanMemberConfigUpdateHelper.class); + public static List> updateConfiguration(DataBroker dataBroker, ParentRefs parentRefsNew, + Interface interfaceOld, IfL2vlan ifL2vlanNew, + Interface interfaceNew, IdManager idManager) { + List> futures = new ArrayList<>(); + ParentRefs parentRefsOld = interfaceOld.getAugmentation(ParentRefs.class); + + InterfaceParentEntryKey interfaceParentEntryKey = + new InterfaceParentEntryKey(parentRefsOld.getParentInterface()); + InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(interfaceOld.getName()); + InterfaceChildEntry interfaceChildEntry = + InterfaceMetaUtils.getInterfaceChildEntryFromConfigDS(interfaceParentEntryKey, interfaceChildEntryKey, + dataBroker); + + if (interfaceChildEntry == null) { + futures.addAll(OvsInterfaceConfigAddHelper.addConfiguration(dataBroker, + interfaceNew.getAugmentation(ParentRefs.class), interfaceNew, idManager)); + return futures; + } + + IfL2vlan ifL2vlanOld = interfaceOld.getAugmentation(IfL2vlan.class); + if (ifL2vlanOld == null || (ifL2vlanNew.getL2vlanMode() != ifL2vlanOld.getL2vlanMode())) { + LOG.error("Configuration Error. Vlan Mode Change of Vlan Trunk Member {} as new trunk member: {} is " + + "not allowed.", interfaceOld, interfaceNew); + return futures; + } + + if (ifL2vlanOld.getVlanId() != ifL2vlanNew.getVlanId() || + !parentRefsOld.getParentInterface().equals(parentRefsNew.getParentInterface())) { + futures.addAll(OvsVlanMemberConfigRemoveHelper.removeConfiguration(dataBroker, parentRefsOld, interfaceOld, + ifL2vlanOld, idManager)); + futures.addAll(OvsVlanMemberConfigAddHelper.addConfiguration(dataBroker, parentRefsNew, interfaceNew, + ifL2vlanNew, idManager)); + return futures; + } + + if (interfaceNew.isEnabled() == interfaceOld.isEnabled()) { + return futures; + } + + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface pifState = + InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(parentRefsNew.getParentInterface(), dataBroker); + if (pifState != null) { + OperStatus operStatus = OperStatus.Down; + if (interfaceNew.isEnabled()) { + operStatus = pifState.getOperStatus(); + } + + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + InstanceIdentifier ifStateId = + IfmUtil.buildStateInterfaceId(interfaceNew.getName()); + InterfaceBuilder ifaceBuilder = new InterfaceBuilder(); + ifaceBuilder.setOperStatus(operStatus); + ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceNew.getName())); + + t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build()); + futures.add(t.submit()); + } + + return futures; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateAddHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateAddHelper.java new file mode 100644 index 00000000..95df1987 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateAddHelper.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.renderer.ovs.statehelpers; + +import com.google.common.util.concurrent.ListenableFuture; +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.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * This worker is responsible for adding the openflow-interfaces/of-port-info container + * in odl-interface-openflow yang. + * Where applicable: + * Create the entries in Interface-State OperDS. + * Create the entries in Inventory OperDS. + */ + +public class OvsInterfaceStateAddHelper { + private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateAddHelper.class); + + public static List> addState(DataBroker dataBroker, NodeConnectorId nodeConnectorId, + String portName, FlowCapableNodeConnector fcNodeConnectorNew) { + LOG.debug("Adding Interface State to Oper DS for port: {}", portName); + List> futures = new ArrayList<>(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + + //Retrieve PbyAddress & OperState from the DataObject + PhysAddress physAddress = new PhysAddress(fcNodeConnectorNew.getHardwareAddress().getValue()); + /*FIXME + State state = fcNodeConnectorNew.getState(); + Interface.OperStatus operStatus = + fcNodeConnectorNew == null ? Interface.OperStatus.Down : Interface.OperStatus.Up; + Interface.AdminStatus adminStatus = state.isBlocked() ? Interface.AdminStatus.Down : Interface.AdminStatus.Up; + */ + Interface.OperStatus operStatus = Interface.OperStatus.Up; + Interface.AdminStatus adminStatus = Interface.AdminStatus.Up; + InterfaceKey interfaceKey = new InterfaceKey(portName); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface = + InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker); + + if (iface != null && !iface.isEnabled()) { + operStatus = Interface.OperStatus.Down; + } + + List lowerLayerIfList = new ArrayList<>(); + lowerLayerIfList.add(nodeConnectorId.getValue()); + + InstanceIdentifier ifStateId = IfmUtil.buildStateInterfaceId(portName); + InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setOperStatus(operStatus) + .setAdminStatus(adminStatus).setPhysAddress(physAddress).setLowerLayerIf(lowerLayerIfList) + .setKey(IfmUtil.getStateInterfaceKeyFromName(portName)); + t.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), true); + + if (iface == null) { + futures.add(t.submit()); + return futures; + } + + // If this interface maps to a Vlan trunk entity, operational states of all the vlan-trunk-members + // should also be created here. + IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class); + if (ifL2vlan == null || ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) { + futures.add(t.submit()); + return futures; + } + + InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(iface.getName()); + InterfaceParentEntry interfaceParentEntry = + InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker); + if (interfaceParentEntry == null) { + futures.add(t.submit()); + return futures; + } + + List interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry(); + if (interfaceChildEntries == null) { + futures.add(t.submit()); + return futures; + } + + //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100. + //List trunks = new ArrayList<>(); + for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) { + InterfaceKey childIfKey = new InterfaceKey(interfaceChildEntry.getChildInterface()); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface ifaceChild = + InterfaceManagerCommonUtils.getInterfaceFromConfigDS(childIfKey, dataBroker); + + // IfL2vlan ifL2vlanChild = iface.getAugmentation(IfL2vlan.class); + // trunks.add(new TrunksBuilder().setTrunk(ifL2vlanChild.getVlanId()).build()); + + if (!ifaceChild.isEnabled()) { + operStatus = Interface.OperStatus.Down; + } + + InstanceIdentifier ifChildStateId = + IfmUtil.buildStateInterfaceId(ifaceChild.getName()); + List childLowerLayerIfList = new ArrayList<>(); + childLowerLayerIfList.add(0, nodeConnectorId.getValue()); + childLowerLayerIfList.add(1, iface.getName()); + InterfaceBuilder childIfaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus).setOperStatus(operStatus) + .setPhysAddress(physAddress).setLowerLayerIf(childLowerLayerIfList); + childIfaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifaceChild.getName())); + t.put(LogicalDatastoreType.OPERATIONAL, ifChildStateId, childIfaceBuilder.build(), true); + } + + /** Below code will be needed if we want to update the vlan-trunks on the of-port + if (trunks.isEmpty()) { + futures.add(t.submit()); + return futures; + } + + BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId)); + + BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId); + InstanceIdentifier dpnBridgeEntryIid = + InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey); + BridgeRefEntry bridgeRefEntry = + InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker); + if (bridgeRefEntry == null) { + futures.add(t.submit()); + return futures; + } + + InstanceIdentifier bridgeIid = + (InstanceIdentifier)bridgeRefEntry.getBridgeReference().getValue(); + VlanTrunkSouthboundUtils.addTerminationPointWithTrunks(bridgeIid, trunks, iface.getName(), t); + */ + + futures.add(t.submit()); + return futures; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateRemoveHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateRemoveHelper.java new file mode 100644 index 00000000..26734cac --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateRemoveHelper.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.renderer.ovs.statehelpers; + +import com.google.common.util.concurrent.ListenableFuture; +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.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class OvsInterfaceStateRemoveHelper { + private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateRemoveHelper.class); + + public static List> removeState(InstanceIdentifier key, + DataBroker dataBroker, String portName, FlowCapableNodeConnector fcNodeConnectorOld) { + LOG.debug("Removing interface-state for port: {}", portName); + List> futures = new ArrayList<>(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + + InstanceIdentifier ifStateId = IfmUtil.buildStateInterfaceId(portName); + t.delete(LogicalDatastoreType.OPERATIONAL, ifStateId); + + // For Vlan-Trunk Interface, remove the trunk-member operstates as well... + InterfaceKey interfaceKey = new InterfaceKey(portName); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface = + InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker); + if (iface == null) { + futures.add(t.submit()); + return futures; + } + + InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(iface.getName()); + InterfaceParentEntry interfaceParentEntry = + InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker); + if (interfaceParentEntry == null) { + futures.add(t.submit()); + return futures; + } + + List interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry(); + if (interfaceChildEntries == null) { + futures.add(t.submit()); + return futures; + } + + //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100. + for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) { + InstanceIdentifier ifChildStateId = + IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface()); + t.delete(LogicalDatastoreType.OPERATIONAL, ifChildStateId); + } + + /* Below code will be needed if we want to update the vlan-trunk in the of-port. + NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId(); + BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId)); + + BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId); + InstanceIdentifier dpnBridgeEntryIid = + InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey); + BridgeRefEntry bridgeRefEntry = + InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker); + if (bridgeRefEntry == null) { + futures.add(t.submit()); + return futures; + } + + InstanceIdentifier bridgeIid = bridgeRefEntry.getBridgeReference().getValue(); + InstanceIdentifier tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier( + InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), interfaceOld.getName()); + t.delete(LogicalDatastoreType.CONFIGURATION, tpIid); */ + + futures.add(t.submit()); + return futures; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateUpdateHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateUpdateHelper.java new file mode 100644 index 00000000..02a3a2ac --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateUpdateHelper.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.renderer.ovs.statehelpers; + +import com.google.common.util.concurrent.ListenableFuture; +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.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class OvsInterfaceStateUpdateHelper { + private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateUpdateHelper.class); + + public static List> updateState(InstanceIdentifier key, + DataBroker dataBroker, String portName, + FlowCapableNodeConnector flowCapableNodeConnectorNew, + FlowCapableNodeConnector flowCapableNodeConnectorOld) { + LOG.debug("Update of Interface State for port: {}", portName); + List> futures = new ArrayList<>(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + + Interface.OperStatus operStatusNew = + flowCapableNodeConnectorNew.getState().isLinkDown() ? Interface.OperStatus.Down : Interface.OperStatus.Up; + Interface.AdminStatus adminStatusNew = + flowCapableNodeConnectorNew.getState().isBlocked() ? Interface.AdminStatus.Down : Interface.AdminStatus.Up; + MacAddress macAddressNew = flowCapableNodeConnectorNew.getHardwareAddress(); + + Interface.OperStatus operStatusOld = + flowCapableNodeConnectorOld.getState().isLinkDown() ? Interface.OperStatus.Down : Interface.OperStatus.Up; + Interface.AdminStatus adminStatusOld = + flowCapableNodeConnectorOld.getState().isBlocked() ? Interface.AdminStatus.Down : Interface.AdminStatus.Up; + MacAddress macAddressOld = flowCapableNodeConnectorOld.getHardwareAddress(); + + boolean opstateModified = false; + boolean adminStateModified = false; + boolean hardwareAddressModified = false; + if (!operStatusNew.equals(operStatusOld)) { + opstateModified = true; + } + if (!adminStatusNew.equals(adminStatusOld)) { + adminStateModified = true; + } + if (!macAddressNew.equals(macAddressOld)) { + hardwareAddressModified = true; + } + + if (!opstateModified && !adminStateModified && !hardwareAddressModified) { + LOG.debug("If State entry for port: {} Not Modified.", portName); + return futures; + } + + InstanceIdentifier ifStateId = IfmUtil.buildStateInterfaceId(portName); + InterfaceBuilder ifaceBuilder = new InterfaceBuilder(); + + boolean modified = false; + if (opstateModified) { + LOG.debug("Opstate Modified for Port: {}", portName); + InterfaceKey interfaceKey = new InterfaceKey(portName); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface = + InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker); + + // If interface config admin state is disabled, set operstate of the Interface State entity to Down. + if (iface != null && !iface.isEnabled()) { + operStatusNew = Interface.OperStatus.Down; + } + + ifaceBuilder.setOperStatus(operStatusNew); + modified = true; + } + + if (adminStateModified) { + LOG.debug("Admin state Modified for Port: {}", portName); + ifaceBuilder.setAdminStatus(adminStatusNew); + modified = true; + } + + if (hardwareAddressModified) { + LOG.debug("Hw-Address Modified for Port: {}", portName); + PhysAddress physAddress = new PhysAddress(macAddressNew.getValue()); + ifaceBuilder.setPhysAddress(physAddress); + modified = true; + } + + /* FIXME: Is there chance that lower layer node-connector info is updated. + Not Considering for now. + */ + + if (modified) { + ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(portName)); + t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build()); + + InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(portName); + InterfaceParentEntry interfaceParentEntry = + InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker); + if (interfaceParentEntry == null) { + futures.add(t.submit()); + return futures; + } + + List interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry(); + if (interfaceChildEntries == null) { + futures.add(t.submit()); + return futures; + } + + LOG.debug("Updating if-state entries for Vlan-Trunk Members for port: {}", portName); + //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100. + for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) { + InstanceIdentifier ifChildStateId = + IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface()); + t.merge(LogicalDatastoreType.OPERATIONAL, ifChildStateId, ifaceBuilder.build()); + } + } + + futures.add(t.submit()); + return futures; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateAddHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateAddHelper.java new file mode 100644 index 00000000..bf37408a --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateAddHelper.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.renderer.ovs.statehelpers; + +import com.google.common.base.Optional; +import com.google.common.util.concurrent.ListenableFuture; +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.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils; +import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities.SouthboundUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public class OvsInterfaceTopologyStateAddHelper { + private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceTopologyStateAddHelper.class); + public static List> addPortToBridge(InstanceIdentifier bridgeIid, + OvsdbBridgeAugmentation bridgeNew, DataBroker dataBroker) { + List> futures = new ArrayList<>(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + + if (bridgeNew.getDatapathId() == null) { + LOG.warn("DataPathId found as null for Bridge Augmentation: {}... retrying...", bridgeNew); + Optional bridgeNodeOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker); + if (bridgeNodeOptional.isPresent()) { + bridgeNew = bridgeNodeOptional.get(); + } + if (bridgeNew.getDatapathId() == null) { + LOG.warn("DataPathId found as null again for Bridge Augmentation: {}. Bailing out.", bridgeNew); + return futures; + } + } + + String dpId = bridgeNew.getDatapathId().getValue(); + String bridgeName = bridgeNew.getBridgeName().getValue(); + + if (dpId == null) { + LOG.error("Optained null dpid for bridge: {}", bridgeNew); + return futures; + } + + dpId = dpId.replaceAll("[^\\d.]", ""); + BigInteger ovsdbDpId = new BigInteger(dpId, 16); + BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(ovsdbDpId); + InstanceIdentifier bridgeEntryId = + InterfaceMetaUtils.getBridgeRefEntryIdentifier(bridgeRefEntryKey); + BridgeRefEntryBuilder tunnelDpnBridgeEntryBuilder = + new BridgeRefEntryBuilder().setKey(bridgeRefEntryKey).setDpid(ovsdbDpId) + .setBridgeReference(new OvsdbBridgeRef(bridgeIid)); + t.put(LogicalDatastoreType.OPERATIONAL, bridgeEntryId, tunnelDpnBridgeEntryBuilder.build(), true); + + BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(ovsdbDpId); + InstanceIdentifier bridgeEntryInstanceIdentifier = + InterfaceMetaUtils.getBridgeEntryIdentifier(bridgeEntryKey); + BridgeEntry bridgeEntry = + InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier, + dataBroker); + if (bridgeEntry == null) { + futures.add(t.submit()); + return futures; + } + + List bridgeInterfaceEntries = bridgeEntry.getBridgeInterfaceEntry(); + for (BridgeInterfaceEntry bridgeInterfaceEntry : bridgeInterfaceEntries) { + String portName = bridgeInterfaceEntry.getInterfaceName(); + InterfaceKey interfaceKey = new InterfaceKey(portName); + Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker); + if (iface.getAugmentation(IfTunnel.class) != null) { + SouthboundUtils.addPortToBridge(bridgeIid, iface, bridgeNew, bridgeName, portName, dataBroker, t); + InstanceIdentifier tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier( + InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), portName); + InterfaceMetaUtils.createBridgeInterfaceEntryInConfigDS(bridgeEntryKey, + new BridgeInterfaceEntryKey(portName), portName, tpIid, t); + } + } + + futures.add(t.submit()); + return futures; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateRemoveHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateRemoveHelper.java new file mode 100644 index 00000000..b38708a0 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateRemoveHelper.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.renderer.ovs.statehelpers; + +import com.google.common.util.concurrent.ListenableFuture; +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.vpnservice.interfacemgr.commons.InterfaceMetaUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public class OvsInterfaceTopologyStateRemoveHelper { + private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceTopologyStateRemoveHelper.class); + + public static List> removePortFromBridge(InstanceIdentifier bridgeIid, + OvsdbBridgeAugmentation bridgeOld, DataBroker dataBroker) { + List> futures = new ArrayList<>(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction();; + + String dpId = bridgeOld.getDatapathId().getValue().replaceAll("[^\\d.]", ""); + if (dpId == null) { + LOG.warn("Got Null DPID for Bridge: {}", bridgeOld); + return futures; + } + + dpId = dpId.replaceAll("[^\\d.]", ""); + BigInteger ovsdbDpId = new BigInteger(dpId,16); + BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(ovsdbDpId); + InstanceIdentifier bridgeEntryId = + InterfaceMetaUtils.getBridgeRefEntryIdentifier(bridgeRefEntryKey); + t.delete(LogicalDatastoreType.OPERATIONAL, bridgeEntryId); + + futures.add(t.submit()); + return futures; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/SouthboundUtils.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/SouthboundUtils.java new file mode 100644 index 00000000..d921ac91 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/SouthboundUtils.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.renderer.ovs.utilities; + +import com.google.common.collect.Maps; +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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.*; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class SouthboundUtils { + private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class); + public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1")); + + public static void addPortToBridge(InstanceIdentifier bridgeIid, Interface iface, + OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName, + String portName, DataBroker dataBroker, WriteTransaction t) { + IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class); + if (ifTunnel != null) { + addTunnelPortToBridge(ifTunnel, bridgeIid, iface, bridgeAugmentation, bridgeName, portName, dataBroker, t); + return; + } + + IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class); + if (ifL2vlan != null) { + addVlanPortToBridge(bridgeIid, ifL2vlan, bridgeAugmentation, bridgeName, portName, dataBroker, t); + } + } + + private static void addVlanPortToBridge(InstanceIdentifier bridgeIid, IfL2vlan ifL2vlan, + OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName, + String portName, DataBroker dataBroker, WriteTransaction t) { + int vlanId = ifL2vlan.getVlanId().getValue(); + addTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, portName, vlanId, null, null, dataBroker, t); + } + + private static void addTunnelPortToBridge(IfTunnel ifTunnel, InstanceIdentifier bridgeIid, Interface iface, + OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName, + String portName, DataBroker dataBroker, WriteTransaction t) { + Class type = null; + if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeGre.class)) { + type = InterfaceTypeGre.class; + } else if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) { + type = InterfaceTypeVxlan.class; + } + + if (type == null) { + LOG.warn("Unknown Tunnel Type obtained while creating interface: {}", iface); + return; + } + + int vlanId = 0; + IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class); + if (ifL2vlan != null) { + vlanId = ifL2vlan.getVlanId().getValue(); + } + + Map options = Maps.newHashMap(); + options.put("key", "flow"); + + IpAddress localIp = ifTunnel.getTunnelSource(); + options.put("local_ip", localIp.getIpv4Address().getValue()); + + IpAddress remoteIp = ifTunnel.getTunnelDestination(); + options.put("remote_ip", remoteIp.getIpv4Address().getValue()); + + addTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, portName, vlanId, type, options, dataBroker, t); + } + + private static void addTerminationPoint(InstanceIdentifier bridgeIid, OvsdbBridgeAugmentation bridgeNode, + String bridgeName, String portName, int vlanId, Class type, + Map options, DataBroker dataBroker, WriteTransaction t) { + InstanceIdentifier tpIid = createTerminationPointInstanceIdentifier( + InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), portName); + OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); + + tpAugmentationBuilder.setName(portName); + + if (type != null) { + tpAugmentationBuilder.setInterfaceType(type); + } + + if (options != null) { + List optionsList = new ArrayList(); + for (Map.Entry entry : options.entrySet()) { + OptionsBuilder optionsBuilder = new OptionsBuilder(); + optionsBuilder.setKey(new OptionsKey(entry.getKey())); + optionsBuilder.setOption(entry.getKey()); + optionsBuilder.setValue(entry.getValue()); + optionsList.add(optionsBuilder.build()); + } + tpAugmentationBuilder.setOptions(optionsList); + } + + if (vlanId != 0) { + tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Access); + tpAugmentationBuilder.setVlanTag(new VlanId(vlanId)); + } + + TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); + tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid)); + tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build()); + + t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true); + } + + private static InstanceIdentifier createTerminationPointInstanceIdentifier(Node node, + String portName){ + InstanceIdentifier terminationPointPath = InstanceIdentifier + .create(NetworkTopology.class) + .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID)) + .child(Node.class,node.getKey()) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName))); + + LOG.debug("Termination point InstanceIdentifier generated : {}", terminationPointPath); + return terminationPointPath; + } + + public static InstanceIdentifier createTerminationPointInstanceIdentifier(NodeKey nodekey, + String portName){ + InstanceIdentifier terminationPointPath = InstanceIdentifier + .create(NetworkTopology.class) + .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID)) + .child(Node.class,nodekey) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName))); + + LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath); + return terminationPointPath; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/VlanTrunkSouthboundUtils.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/VlanTrunkSouthboundUtils.java new file mode 100644 index 00000000..19868da4 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/VlanTrunkSouthboundUtils.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.renderer.ovs.utilities; + +import com.google.common.base.Optional; +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.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class VlanTrunkSouthboundUtils { + private static final Logger LOG = LoggerFactory.getLogger(VlanTrunkSouthboundUtils.class); + public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1")); + + public static void addVlanPortToBridge(InstanceIdentifier bridgeIid, IfL2vlan ifL2vlan, + OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName, + String parentInterface, DataBroker dataBroker, WriteTransaction t) { + LOG.info("Vlan Interface creation not supported yet. please visit later."); + int vlanId = ifL2vlan.getVlanId().getValue(); + addTrunkTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, parentInterface, vlanId, dataBroker, t); + } + + public static void updateVlanMemberInTrunk(InstanceIdentifier bridgeIid, IfL2vlan ifL2vlan, + OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName, + String parentInterface, DataBroker dataBroker, WriteTransaction t) { + LOG.info("Vlan Interface creation not supported yet. please visit later."); + int vlanId = ifL2vlan.getVlanId().getValue(); + updateTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, parentInterface, vlanId, dataBroker, t); + } + + private static void addTrunkTerminationPoint(InstanceIdentifier bridgeIid, OvsdbBridgeAugmentation bridgeNode, + String bridgeName, String parentInterface, int vlanId, + DataBroker dataBroker, WriteTransaction t) { + if (vlanId == 0) { + LOG.error("Found vlanid 0 for bridge: {}, interface: {}", bridgeName, parentInterface); + return; + } + + InstanceIdentifier tpIid = createTerminationPointInstanceIdentifier( + InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), parentInterface); + OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); + tpAugmentationBuilder.setName(parentInterface); + tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Trunk); + OvsdbTerminationPointAugmentation terminationPointAugmentation = null; + Optional terminationPointOptional = + IfmUtil.read(LogicalDatastoreType.OPERATIONAL, tpIid, dataBroker); + if (terminationPointOptional.isPresent()) { + TerminationPoint terminationPoint = terminationPointOptional.get(); + terminationPointAugmentation = terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + if (terminationPointAugmentation != null) { + List trunks = terminationPointAugmentation.getTrunks(); + if (trunks == null) { + trunks = new ArrayList<>(); + } + + trunks.add(new TrunksBuilder().setTrunk(new VlanId(vlanId)).build()); + tpAugmentationBuilder.setTrunks(trunks); + } + } else { + List trunks = new ArrayList<>(); + trunks.add(new TrunksBuilder().setTrunk(new VlanId(vlanId)).build()); + tpAugmentationBuilder.setTrunks(trunks); + } + + TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); + tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid)); + tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build()); + + t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true); + } + + public static void addTerminationPointWithTrunks(InstanceIdentifier bridgeIid, List trunks, + String parentInterface, WriteTransaction t) { + InstanceIdentifier tpIid = createTerminationPointInstanceIdentifier( + InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), parentInterface); + OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); + tpAugmentationBuilder.setName(parentInterface); + tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Trunk); + tpAugmentationBuilder.setTrunks(trunks); + + TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); + tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid)); + tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build()); + + t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true); + } + + private static void updateTerminationPoint(InstanceIdentifier bridgeIid, OvsdbBridgeAugmentation bridgeNode, + String bridgeName, String parentInterface, int vlanId, + DataBroker dataBroker, WriteTransaction t) { + if (vlanId == 0) { + LOG.error("Found vlanid 0 for bridge: {}, interface: {}", bridgeName, parentInterface); + return; + } + + InstanceIdentifier tpIid = createTerminationPointInstanceIdentifier( + InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), parentInterface); + OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); + tpAugmentationBuilder.setName(parentInterface); + tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Trunk); + OvsdbTerminationPointAugmentation terminationPointAugmentation = null; + Optional terminationPointOptional = + IfmUtil.read(LogicalDatastoreType.OPERATIONAL, tpIid, dataBroker); + if (terminationPointOptional.isPresent()) { + TerminationPoint terminationPoint = terminationPointOptional.get(); + terminationPointAugmentation = terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class); + if (terminationPointAugmentation != null) { + List trunks = terminationPointAugmentation.getTrunks(); + if (trunks != null) { + trunks.remove(new TrunksBuilder().setTrunk(new VlanId(vlanId)).build()); + } + + tpAugmentationBuilder.setTrunks(trunks); + TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); + tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid)); + tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build()); + + t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true); + } + } + } + + private static InstanceIdentifier createTerminationPointInstanceIdentifier(NodeKey nodekey, + String portName){ + InstanceIdentifier terminationPointPath = InstanceIdentifier + .create(NetworkTopology.class) + .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID)) + .child(Node.class,nodekey) + .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName))); + + LOG.debug("Termination point InstanceIdentifier generated : {}", terminationPointPath); + return terminationPointPath; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/rpcservice/InterfaceManagerRpcService.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/rpcservice/InterfaceManagerRpcService.java new file mode 100644 index 00000000..fbf86df8 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/rpcservice/InterfaceManagerRpcService.java @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.rpcservice; + +import com.google.common.base.Optional; +import com.google.common.util.concurrent.Futures; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils; +import org.opendaylight.vpnservice.mdsalutil.ActionInfo; +import org.opendaylight.vpnservice.mdsalutil.ActionType; +import org.opendaylight.vpnservice.mdsalutil.InstructionInfo; +import org.opendaylight.vpnservice.mdsalutil.InstructionType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.InterfaceChildInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.*; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.Future; + +public class InterfaceManagerRpcService implements OdlInterfaceRpcService { + private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerRpcService.class); + DataBroker dataBroker; + public InterfaceManagerRpcService(DataBroker dataBroker) { + this.dataBroker = dataBroker; + } + + @Override + public Future> getDpidFromInterface(GetDpidFromInterfaceInput input) { + String interfaceName = input.getIntfName(); + RpcResultBuilder rpcResultBuilder; + try { + BigInteger dpId = null; + InterfaceKey interfaceKey = new InterfaceKey(interfaceName); + Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker); + if (Tunnel.class.equals(interfaceInfo.getType())) { + ParentRefs parentRefs = interfaceInfo.getAugmentation(ParentRefs.class); + dpId = parentRefs.getDatapathNodeIdentifier(); + } else { + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = + InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker); + String lowerLayerIf = ifState.getLowerLayerIf().get(0); + NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf); + dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId)); + } + GetDpidFromInterfaceOutputBuilder output = new GetDpidFromInterfaceOutputBuilder().setDpid( + (dpId)); + rpcResultBuilder = RpcResultBuilder.success(); + rpcResultBuilder.withResult(output.build()); + } catch (Exception e) { + LOG.error("Retrieval of datapath id for the key {} failed due to {}", interfaceName, e); + rpcResultBuilder = RpcResultBuilder.failed(); + } + return Futures.immediateFuture(rpcResultBuilder.build()); + } + + @Override + public Future> getEndpointIpForDpn(GetEndpointIpForDpnInput input) { + RpcResultBuilder rpcResultBuilder; + try { + BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(input.getDpid()); + InstanceIdentifier bridgeEntryInstanceIdentifier = + InterfaceMetaUtils.getBridgeEntryIdentifier(bridgeEntryKey); + BridgeEntry bridgeEntry = + InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier, + dataBroker); + // local ip of any of the bridge interface entry will be the dpn end point ip + BridgeInterfaceEntry bridgeInterfaceEntry = bridgeEntry.getBridgeInterfaceEntry().get(0); + InterfaceKey interfaceKey = new InterfaceKey(bridgeInterfaceEntry.getInterfaceName()); + Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker); + IfTunnel tunnel = interfaceInfo.getAugmentation(IfTunnel.class); + GetEndpointIpForDpnOutputBuilder endpointIpForDpnOutput = new GetEndpointIpForDpnOutputBuilder().setLocalIps(Arrays.asList(tunnel.getTunnelSource())); + rpcResultBuilder = RpcResultBuilder.success(); + rpcResultBuilder.withResult(endpointIpForDpnOutput.build()); + }catch(Exception e){ + LOG.error("Retrieval of endpoint of for dpn {} failed due to {}" ,input.getDpid(), e); + rpcResultBuilder = RpcResultBuilder.failed(); + } + return Futures.immediateFuture(rpcResultBuilder.build()); + } + + @Override + public Future> getEgressInstructionsForInterface(GetEgressInstructionsForInterfaceInput input) { + RpcResultBuilder rpcResultBuilder; + try { + List instructionInfo = new ArrayList(); + List actionInfo = getEgressActionInfosForInterface(input.getIntfName()); + instructionInfo.add(new InstructionInfo(InstructionType.write_actions, actionInfo)); + GetEgressInstructionsForInterfaceOutputBuilder output = new GetEgressInstructionsForInterfaceOutputBuilder(). + setInstruction(buildInstructions(instructionInfo)); + rpcResultBuilder = RpcResultBuilder.success(); + rpcResultBuilder.withResult(output.build()); + }catch(Exception e){ + LOG.error("Retrieval of egress actions for the key {} failed due to {}" ,input.getIntfName(), e); + rpcResultBuilder = RpcResultBuilder.failed(); + } + return Futures.immediateFuture(rpcResultBuilder.build()); + } + + @Override + public Future> getEgressActionsForInterface(GetEgressActionsForInterfaceInput input) { + RpcResultBuilder rpcResultBuilder; + try { + List actionsList = getEgressActionsForInterface(input.getIntfName()); + GetEgressActionsForInterfaceOutputBuilder output = new GetEgressActionsForInterfaceOutputBuilder(). + setAction(actionsList); + rpcResultBuilder = RpcResultBuilder.success(); + rpcResultBuilder.withResult(output.build()); + }catch(Exception e){ + LOG.error("Retrieval of egress actions for the key {} failed due to {}" ,input.getIntfName(), e); + rpcResultBuilder = RpcResultBuilder.failed(); + } + return Futures.immediateFuture(rpcResultBuilder.build()); + } + + public static InstanceIdentifier getInterfaceChildEntryIdentifier(InterfaceParentEntryKey parentEntryKey, InterfaceChildEntryKey interfaceChildEntryKey) { + InstanceIdentifier.InstanceIdentifierBuilder interfaceChildEntryInstanceIdentifierBuilder = + InstanceIdentifier.builder(InterfaceChildInfo.class).child(InterfaceParentEntry.class, parentEntryKey).child(InterfaceChildEntry.class, interfaceChildEntryKey); + return interfaceChildEntryInstanceIdentifierBuilder.build(); + } + + public static InterfaceChildEntry getInterfaceChildEntryFromConfigDS(String interfaceName, + DataBroker dataBroker) { + InterfaceParentEntryKey parentEntryKey = new InterfaceParentEntryKey(interfaceName); + InterfaceChildEntryKey childEntryKey = new InterfaceChildEntryKey(interfaceName); + InstanceIdentifier interfaceChildEntryInstanceIdentifier = getInterfaceChildEntryIdentifier(parentEntryKey, childEntryKey); + Optional interfaceChildEntryOptional = + IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceChildEntryInstanceIdentifier, dataBroker); + if (!interfaceChildEntryOptional.isPresent()) { + return null; + } + return interfaceChildEntryOptional.get(); + } + + @Override + public Future> getPortFromInterface(GetPortFromInterfaceInput input) { + RpcResultBuilder rpcResultBuilder; + String interfaceName = input.getIntfName(); + try { + BigInteger dpId = null; + long portNo = 0; + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = + InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker); + String lowerLayerIf = ifState.getLowerLayerIf().get(0); + NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf); + dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId)); + portNo = Long.valueOf(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId)); + // FIXME Assuming portName and interfaceName are same + GetPortFromInterfaceOutputBuilder output = new GetPortFromInterfaceOutputBuilder().setDpid(dpId). + setPortname(interfaceName).setPortno(Long.valueOf(portNo)); + rpcResultBuilder = RpcResultBuilder.success(); + rpcResultBuilder.withResult(output.build()); + }catch(Exception e){ + LOG.error("Retrieval of lport tag for the key {} failed due to {}" ,input.getIntfName(), e); + rpcResultBuilder = RpcResultBuilder.failed(); + } + return Futures.immediateFuture(rpcResultBuilder.build()); + } + + @Override + public Future> getInterfaceFromPort(GetInterfaceFromPortInput input) { + /*RpcResultBuilder rpcResultBuilder; + try { + Interface interfaceInfo = null; + NodeId nodeId = IfmUtil.buildDpnNodeId(input.getDpid()); + Node node = getNodeFromInventoryOperDS(nodeId, dataBroker); + ChildInterfaceNames childInterfaceNames = node.getAugmentation(ChildInterfaceNames.class); + for(OfInterfaceRefInfo ofInterfaceRefInfo : childInterfaceNames.getOfInterfaceRefInfo()){ + interfaceInfo = getInterfaceFromTunnelKey(ofInterfaceRefInfo.getOfIntfName(), input.getInterfaceId(), + input.getInterfaceType()); + } + GetInterfaceFromPortOutputBuilder output = new GetInterfaceFromPortOutputBuilder(). + setInterfaceName(interfaceInfo == null ? null : interfaceInfo.getName()); + rpcResultBuilder = RpcResultBuilder.success(); + rpcResultBuilder.withResult(output.build()); + }catch(Exception e){ + LOG.error("Retrieval of interface for the key {} failed due to {}" ,input.getPortno(), e); + rpcResultBuilder = RpcResultBuilder.failed(); + } + return Futures.immediateFuture(rpcResultBuilder.build()); + */ + return null; + } + + public List getEgressActionInfosForInterface(String interfaceName) { + Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), + dataBroker); + List listActionInfo = new ArrayList(); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = + InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker); + + String lowerLayerIf = ifState.getLowerLayerIf().get(0); + NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf); + String portNo = IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId); + Class ifType = interfaceInfo.getType(); + if(L2vlan.class.equals(ifType)){ + IfL2vlan vlanIface = interfaceInfo.getAugmentation(IfL2vlan.class); + LOG.trace("L2Vlan: {}",vlanIface); + long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId().getValue(); + if (vlanVid != 0) { + listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {})); + listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid, + new String[] { Long.toString(vlanVid) })); + } + listActionInfo.add(new ActionInfo(ActionType.output, new String[] {portNo})); + }else if(Tunnel.class.equals(ifType)){ + listActionInfo.add(new ActionInfo(ActionType.output, new String[] { portNo})); + } + return listActionInfo; + } + + public List getEgressActionsForInterface(String interfaceName) { + List listActionInfo = getEgressActionInfosForInterface(interfaceName); + List actionsList = new ArrayList<>(); + for (ActionInfo actionInfo : listActionInfo) { + actionsList.add(actionInfo.buildAction()); + } + return actionsList; + } + + protected static List buildInstructions(List listInstructionInfo) { + if (listInstructionInfo != null) { + List instructions = new ArrayList(); + int instructionKey = 0; + + for (InstructionInfo instructionInfo : listInstructionInfo) { + instructions.add(instructionInfo.buildInstruction(instructionKey)); + instructionKey++; + } + return instructions; + } + + return null; + } + + public static Node getNodeFromInventoryOperDS(NodeId nodeId, DataBroker dataBroker) { + InstanceIdentifier nodeIdentifier = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, new NodeKey(nodeId)).build(); + + Optional nodeOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, + nodeIdentifier, dataBroker); + if (!nodeOptional.isPresent()) { + return null; + } + return nodeOptional.get(); + } + + public Interface getInterfaceFromTunnelKey(String interfaceName, BigInteger tunnelKey, + Class ifType){ + + /*Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker); + + if(ifType.isAssignableFrom(IfL2vlan.class)){ + IfL2vlan vlanIface = interfaceInfo.getAugmentation(IfL2vlan.class); + LOG.trace("L2Vlan: {}",vlanIface); + long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId(); + if(tunnelKey.intValue() == vlanVid){ + return interfaceInfo; + } + }else if(ifType.isAssignableFrom(TunnelTypeBase.class)){ + IfTunnel ifTunnel = interfaceInfo.getAugmentation(IfTunnel.class); + TunnelResources tunnelResources = ifTunnel.getTunnelResources(); + if(ifType.isAssignableFrom(TunnelTypeGre.class)) { + IfGre ifGre = tunnelResources.getAugmentation(IfGre.class); + if (ifGre.getGreKey() == tunnelKey) { + return interfaceInfo; + } + }else if(ifType.isAssignableFrom(TunnelTypeVxlan.class)){ + IfVxlan ifVxlan = tunnelResources.getAugmentation(IfVxlan.class); + if(ifVxlan.getVni() == tunnelKey){ + return interfaceInfo; + } + } + } + return null;*/ + return null; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigBindHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigBindHelper.java new file mode 100644 index 00000000..bd1c9945 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigBindHelper.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.servicebindings.flowbased.confighelpers; + +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.vpnservice.interfacemgr.IfmConstants; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils; +import org.opendaylight.vpnservice.mdsalutil.MatchInfo; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class FlowBasedServicesConfigBindHelper { + private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesConfigBindHelper.class); + + public static List> bindService(InstanceIdentifier instanceIdentifier, + BoundServices boundServiceNew, DataBroker dataBroker) { + List> futures = new ArrayList<>(); + WriteTransaction t = null; + String interfaceName = + InstanceIdentifier.keyOf(instanceIdentifier.firstIdentifierOf(ServicesInfo.class)).getInterfaceName(); + + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = + InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker); + if (ifState == null || ifState.getOperStatus() == OperStatus.Down) { + LOG.info("Not Binding Service since for Interface: {}", interfaceName); + return futures; + } + + // Get the Parent ServiceInfo + ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(interfaceName, dataBroker); + if (servicesInfo == null) { + LOG.error("Reached Impossible part 1 in the code during bind service for: {}", boundServiceNew); + return futures; + } + + InterfaceKey interfaceKey = new InterfaceKey(interfaceName); + Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker); + + List allServices = servicesInfo.getBoundServices(); + if (allServices.isEmpty()) { + LOG.error("Reached Impossible part 2 in the code during bind service for: {}", boundServiceNew); + return futures; + } + + NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker); + long portNo = Long.parseLong(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId)); + BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId)); + + Long lportTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker); + if (allServices.size() == 1) { + // If only one service present, install instructions in table 0. + int vlanId = 0; + List matches = null; + if (iface.getType().isAssignableFrom(L2vlan.class)) { + vlanId = iface.getAugmentation(IfL2vlan.class).getVlanId().getValue(); + matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, vlanId); + } else if (iface.getType().isAssignableFrom(Tunnel.class)){ + matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface); + } + + if (matches != null) { + FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, vlanId, boundServiceNew, + dataBroker, t, matches, lportTag.intValue(), IfmConstants.VLAN_INTERFACE_INGRESS_TABLE); + } + + if (t != null) { + futures.add(t.submit()); + } + return futures; + } + + boolean isCurrentServiceHighestPriority = true; + Map tmpServicesMap = new ConcurrentHashMap<>(); + short highestPriority = 0xFF; + for (BoundServices boundService : allServices) { + if (boundService.getServicePriority() < boundServiceNew.getServicePriority()) { + isCurrentServiceHighestPriority = false; + break; + } + if (!boundService.equals(boundServiceNew)) { + tmpServicesMap.put(boundService.getServicePriority(), boundService); + if (boundService.getServicePriority() < highestPriority) { + highestPriority = boundService.getServicePriority(); + } + } + LOG.error("Reached unexpected part 1 of the code when handling bind service for interface: {}, when binding" + + "service: {}", iface, boundServiceNew); + } + + if (!isCurrentServiceHighestPriority) { + FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, boundServiceNew, iface, dataBroker, t, + lportTag.intValue()); + } else { + BoundServices serviceToReplace = tmpServicesMap.get(highestPriority); + FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, serviceToReplace, iface, dataBroker, t, + lportTag.intValue()); + int vlanId = 0; + List matches = null; + if (iface.getType().isAssignableFrom(L2vlan.class)) { + vlanId = iface.getAugmentation(IfL2vlan.class).getVlanId().getValue(); + matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, vlanId); + } else if (iface.getType().isAssignableFrom(Tunnel.class)){ + matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface); + } + + if (matches != null) { + FlowBasedServicesUtils.removeIngressFlow(iface, serviceToReplace, dpId, dataBroker, t); + FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, vlanId, boundServiceNew, dataBroker, t, + matches, lportTag.intValue(), IfmConstants.VLAN_INTERFACE_INGRESS_TABLE); + } + } + + if (t != null) { + futures.add(t.submit()); + } + return futures; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigUnbindHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigUnbindHelper.java new file mode 100644 index 00000000..847b3dbc --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigUnbindHelper.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.servicebindings.flowbased.confighelpers; + +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.vpnservice.interfacemgr.IfmConstants; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils; +import org.opendaylight.vpnservice.mdsalutil.MatchInfo; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class FlowBasedServicesConfigUnbindHelper { + private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesConfigUnbindHelper.class); + + public static List> unbindService(InstanceIdentifier instanceIdentifier, + BoundServices boundServiceOld, DataBroker dataBroker) { + List> futures = new ArrayList<>(); + WriteTransaction t = null; + + String interfaceName = + InstanceIdentifier.keyOf(instanceIdentifier.firstIdentifierOf(ServicesInfo.class)).getInterfaceName(); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = + InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker); + if (ifState == null || ifState.getOperStatus() == OperStatus.Down) { + LOG.info("Not unbinding Service since operstatus is {} for Interface: {}", + ifState.getOperStatus(), interfaceName); + return futures; + } + + // Get the Parent ServiceInfo + ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(interfaceName, dataBroker); + if (servicesInfo == null) { + LOG.error("Reached Impossible part in the code for bound service: {}", boundServiceOld); + return futures; + } + + InterfaceKey interfaceKey = new InterfaceKey(interfaceName); + Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker); + NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker); + long portNo = Long.parseLong(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId)); + BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId)); + Long lportTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker); + int vlanId = 0; + if (iface.getType().isAssignableFrom(L2vlan.class)) { + vlanId = iface.getAugmentation(IfL2vlan.class).getVlanId().getValue(); + } + List boundServices = servicesInfo.getBoundServices(); + if (boundServices.isEmpty()) { + // Remove entry from Ingress Table. + FlowBasedServicesUtils.removeIngressFlow(iface, boundServiceOld, dpId, dataBroker, t); + if (t != null) { + futures.add(t.submit()); + } + return futures; + } + + Map tmpServicesMap = new ConcurrentHashMap<>(); + short highestPriority = 0xFF; + for (BoundServices boundService : boundServices) { + tmpServicesMap.put(boundService.getServicePriority(), boundService); + if (boundService.getServicePriority() < highestPriority) { + highestPriority = boundService.getServicePriority(); + } + } + + if (highestPriority < boundServiceOld.getServicePriority()) { + FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, iface, boundServiceOld, dataBroker, t); + if (t != null) { + futures.add(t.submit()); + } + return futures; + } + + List matches = null; + if (iface.getType().isAssignableFrom(L2vlan.class)) { + matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, vlanId); + } else if (iface.getType().isAssignableFrom(Tunnel.class)){ + matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface); + } + + BoundServices toBeMoved = tmpServicesMap.get(highestPriority); + FlowBasedServicesUtils.removeIngressFlow(iface, boundServiceOld, dpId, dataBroker, t); + FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, vlanId, toBeMoved, dataBroker, t, + matches, lportTag.intValue(), IfmConstants.VLAN_INTERFACE_INGRESS_TABLE); + FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, iface, toBeMoved, dataBroker, t); + + if (t != null) { + futures.add(t.submit()); + } + return futures; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesConfigListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesConfigListener.java new file mode 100644 index 00000000..8b1d955f --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesConfigListener.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.servicebindings.flowbased.listeners; + +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase; +import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator; +import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.confighelpers.FlowBasedServicesConfigBindHelper; +import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.confighelpers.FlowBasedServicesConfigUnbindHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.ServiceBindings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.concurrent.Callable; + +public class FlowBasedServicesConfigListener extends AsyncDataTreeChangeListenerBase { + private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesConfigListener.class); + private DataBroker dataBroker; + + public FlowBasedServicesConfigListener(final DataBroker dataBroker) { + super(BoundServices.class, FlowBasedServicesConfigListener.class); + this.dataBroker = dataBroker; + } + + @Override + protected InstanceIdentifier getWildCardPath() { + return InstanceIdentifier.create(ServiceBindings.class).child(ServicesInfo.class) + .child(BoundServices.class); + } + + @Override + protected void remove(InstanceIdentifier key, BoundServices boundServiceOld) { + String interfaceName = InstanceIdentifier.keyOf(key.firstIdentifierOf(ServicesInfo.class)).getInterfaceName(); + LOG.info("Service Binding Entry removed for Interface: {}, Data: {}", + interfaceName, boundServiceOld); + + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + RendererConfigRemoveWorker configWorker = new RendererConfigRemoveWorker(key, boundServiceOld); + coordinator.enqueueJob(interfaceName, configWorker); + } + + @Override + protected void update(InstanceIdentifier key, BoundServices boundServiceOld, + BoundServices boundServiceNew) { + LOG.error("Service Binding entry update not allowed for: {}, Data: {}", + InstanceIdentifier.keyOf(key.firstIdentifierOf(ServicesInfo.class)).getInterfaceName(), boundServiceNew); + } + + @Override + protected void add(InstanceIdentifier key, BoundServices boundServicesNew) { + String interfaceName = InstanceIdentifier.keyOf(key.firstIdentifierOf(ServicesInfo.class)).getInterfaceName(); + LOG.info("Service Binding Entry created for Interface: {}, Data: {}", + interfaceName, boundServicesNew); + + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + RendererConfigAddWorker configWorker = new RendererConfigAddWorker(key, boundServicesNew); + coordinator.enqueueJob(interfaceName, configWorker); + } + + @Override + protected FlowBasedServicesConfigListener getDataTreeChangeListener() { + return FlowBasedServicesConfigListener.this; + } + + private class RendererConfigAddWorker implements Callable>> { + InstanceIdentifier instanceIdentifier; + BoundServices boundServicesNew; + + public RendererConfigAddWorker(InstanceIdentifier instanceIdentifier, + BoundServices boundServicesNew) { + this.instanceIdentifier = instanceIdentifier; + this.boundServicesNew = boundServicesNew; + } + + @Override + public List> call() throws Exception { + return FlowBasedServicesConfigBindHelper.bindService(instanceIdentifier, + boundServicesNew, dataBroker); + } + } + + private class RendererConfigRemoveWorker implements Callable>> { + InstanceIdentifier instanceIdentifier; + BoundServices boundServicesNew; + + public RendererConfigRemoveWorker(InstanceIdentifier instanceIdentifier, + BoundServices boundServicesNew) { + this.instanceIdentifier = instanceIdentifier; + this.boundServicesNew = boundServicesNew; + } + + @Override + public List> call() throws Exception { + return FlowBasedServicesConfigUnbindHelper.unbindService(instanceIdentifier, + boundServicesNew, dataBroker); + } + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesInterfaceStateListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesInterfaceStateListener.java new file mode 100644 index 00000000..9ec65bc2 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesInterfaceStateListener.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.servicebindings.flowbased.listeners; + +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase; +import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator; +import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.statehelpers.FlowBasedServicesStateBindHelper; +import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.statehelpers.FlowBasedServicesStateUnbindHelper; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.concurrent.Callable; + +public class FlowBasedServicesInterfaceStateListener extends AsyncDataTreeChangeListenerBase { + private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesInterfaceStateListener.class); + private DataBroker dataBroker; + + public FlowBasedServicesInterfaceStateListener(final DataBroker dataBroker) { + super(Interface.class, FlowBasedServicesInterfaceStateListener.class); + this.dataBroker = dataBroker; + } + + @Override + protected InstanceIdentifier getWildCardPath() { + return InstanceIdentifier.create(InterfacesState.class).child(Interface.class); + } + + @Override + protected void remove(InstanceIdentifier key, Interface interfaceStateOld) { + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + RendererStateInterfaceUnbindWorker stateUnbindWorker = + new RendererStateInterfaceUnbindWorker(interfaceStateOld); + coordinator.enqueueJob(interfaceStateOld.getName(), stateUnbindWorker); + } + + @Override + protected void update(InstanceIdentifier key, Interface interfaceStateOld, Interface interfaceStateNew) { + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + if (interfaceStateNew.getOperStatus() == Interface.OperStatus.Down) { + RendererStateInterfaceUnbindWorker stateUnbindWorker = + new RendererStateInterfaceUnbindWorker(interfaceStateNew); + coordinator.enqueueJob(interfaceStateNew.getName(), stateUnbindWorker); + return; + } + + RendererStateInterfaceBindWorker stateBindWorker = new RendererStateInterfaceBindWorker(interfaceStateNew); + coordinator.enqueueJob(interfaceStateNew.getName(), stateBindWorker); + } + + @Override + protected void add(InstanceIdentifier key, Interface interfaceStateNew) { + if (interfaceStateNew.getOperStatus() == Interface.OperStatus.Down) { + LOG.info("Interface: {} operstate is down when adding. Not Binding services", interfaceStateNew.getName()); + return; + } + + DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance(); + RendererStateInterfaceBindWorker stateBindWorker = new RendererStateInterfaceBindWorker(interfaceStateNew); + coordinator.enqueueJob(interfaceStateNew.getName(), stateBindWorker); + } + + @Override + protected FlowBasedServicesInterfaceStateListener getDataTreeChangeListener() { + return FlowBasedServicesInterfaceStateListener.this; + } + + private class RendererStateInterfaceBindWorker implements Callable>> { + Interface iface; + + public RendererStateInterfaceBindWorker(Interface iface) { + this.iface = iface; + } + + @Override + public List> call() throws Exception { + return FlowBasedServicesStateBindHelper.bindServicesOnInterface(iface, dataBroker); + } + } + + private class RendererStateInterfaceUnbindWorker implements Callable>> { + Interface iface; + + public RendererStateInterfaceUnbindWorker(Interface iface) { + this.iface = iface; + } + + @Override + public List> call() throws Exception { + return FlowBasedServicesStateUnbindHelper.unbindServicesFromInterface(iface, dataBroker); + } + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateBindHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateBindHelper.java new file mode 100644 index 00000000..0e067c4e --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateBindHelper.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.servicebindings.flowbased.statehelpers; + +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.vpnservice.interfacemgr.IfmConstants; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils; +import org.opendaylight.vpnservice.mdsalutil.MatchInfo; +import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public class FlowBasedServicesStateBindHelper { + private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesStateBindHelper.class); + + public static List> bindServicesOnInterface(Interface ifaceState, + DataBroker dataBroker) { + List> futures = new ArrayList<>(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(ifaceState.getName(), dataBroker); + if (servicesInfo == null) { + return futures; + } + + List allServices = servicesInfo.getBoundServices(); + if (allServices == null || allServices.isEmpty()) { + return futures; + } + + BoundServices highestPriorityBoundService = null; + short highestPriority = 0xFF; + for (BoundServices boundService : allServices) { + if (boundService.getServicePriority() < highestPriority) { + highestPriorityBoundService = boundService; + highestPriority = boundService.getServicePriority(); + } + } + + InterfaceKey interfaceKey = new InterfaceKey(ifaceState.getName()); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface = + InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker); + + NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker); + long portNo = Long.parseLong(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId)); + BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId)); + Long lportTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker); + int vlanId = 0; + List matches = null; + if (iface.getType().isAssignableFrom(L2vlan.class)) { + vlanId = iface.getAugmentation(IfL2vlan.class).getVlanId().getValue(); + matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, vlanId); + } else if (iface.getType().isAssignableFrom(Tunnel.class)){ + matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface); + } + + if (matches != null) { + FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, vlanId, highestPriorityBoundService, + dataBroker, t, matches, lportTag.intValue(), IfmConstants.VLAN_INTERFACE_INGRESS_TABLE); + } + + for (BoundServices boundService : allServices) { + if (!boundService.equals(highestPriorityBoundService)) { + FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, boundService, iface, + dataBroker, t, lportTag.intValue()); + } + } + + futures.add(t.submit()); + return futures; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateUnbindHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateUnbindHelper.java new file mode 100644 index 00000000..23705809 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateUnbindHelper.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.servicebindings.flowbased.statehelpers; + +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public class FlowBasedServicesStateUnbindHelper { + private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesStateUnbindHelper.class); + + public static List> unbindServicesFromInterface(Interface ifaceState, + DataBroker dataBroker) { + List> futures = new ArrayList<>(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + + ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(ifaceState.getName(), dataBroker); + if (servicesInfo == null) { + return futures; + } + + List allServices = servicesInfo.getBoundServices(); + if (allServices == null || allServices.isEmpty()) { + return futures; + } + + BoundServices highestPriorityBoundService = null; + short highestPriority = 0xFF; + for (BoundServices boundService : allServices) { + if (boundService.getServicePriority() < highestPriority) { + highestPriorityBoundService = boundService; + highestPriority = boundService.getServicePriority(); + } + } + + InterfaceKey interfaceKey = new InterfaceKey(ifaceState.getName()); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface = + InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker); + + NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker); + BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId)); + Long lportTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker); + + FlowBasedServicesUtils.removeIngressFlow(iface, highestPriorityBoundService, dpId, + dataBroker, t); + + for (BoundServices boundService : allServices) { + if (!boundService.equals(highestPriorityBoundService)) { + FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, iface, boundService, dataBroker, t); + } + } + + return futures; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/utilities/FlowBasedServicesUtils.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/utilities/FlowBasedServicesUtils.java new file mode 100644 index 00000000..8df055ba --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/utilities/FlowBasedServicesUtils.java @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.interfacemgr.servicebindings.flowbased.utilities; + +import com.google.common.base.Optional; +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.vpnservice.interfacemgr.IfmConstants; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils; +import org.opendaylight.vpnservice.mdsalutil.MDSALUtil; +import org.opendaylight.vpnservice.mdsalutil.MatchFieldType; +import org.opendaylight.vpnservice.mdsalutil.MatchInfo; +import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.ServiceBindings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.StypeOpenflow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfoKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public class FlowBasedServicesUtils { + private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesUtils.class); + + public static ServicesInfo getServicesInfoForInterface(String interfaceName, DataBroker dataBroker) { + ServicesInfoKey servicesInfoKey = new ServicesInfoKey(interfaceName); + InstanceIdentifier.InstanceIdentifierBuilder servicesInfoIdentifierBuilder = + InstanceIdentifier.builder(ServiceBindings.class).child(ServicesInfo.class, servicesInfoKey); + Optional servicesInfoOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION, + servicesInfoIdentifierBuilder.build(), dataBroker); + + if (servicesInfoOptional.isPresent()) { + return servicesInfoOptional.get(); + } + + return null; + } + + public static NodeConnectorId getNodeConnectorIdFromInterface(Interface iface, DataBroker dataBroker) { + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = + InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(iface.getName(), dataBroker); + List ofportIds = ifState.getLowerLayerIf(); + return new NodeConnectorId(ofportIds.get(0)); + } + + public static List getMatchInfoForVlanPortAtIngressTable(BigInteger dpId, long portNo, long vlanId) { + List matches = new ArrayList<>(); + matches.add(new MatchInfo(MatchFieldType.in_port, new BigInteger[] {dpId, BigInteger.valueOf(portNo)})); + if (vlanId > 0) { + LOG.error("VlanId matching support is not fully available in Be."); + matches.add(new MatchInfo(MatchFieldType.vlan_vid, new long[]{vlanId})); + } + return matches; + } + + public static List getMatchInfoForTunnelPortAtIngressTable(BigInteger dpId, long portNo, Interface iface) { + List matches = new ArrayList(); + matches.add(new MatchInfo(MatchFieldType.in_port, new BigInteger[]{dpId, BigInteger.valueOf(portNo)})); + /*IfTunnel tunnel = iface.getAugmentation(IfTunnel.class); + TunnelResources tunnelResources = tunnel.getTunnelResources(); + if (tunnelResources.getTunnelType().isAssignableFrom(TunnelTypeGre.class)) { + IfGre ifgre = tunnelResources.getAugmentation(IfGre.class); + BigInteger grekey = ifgre.getGreKey(); + // FIXME: Add tunnel-id match information + + } else if (tunnelResources.getTunnelType().isAssignableFrom(TunnelTypeVxlan.class)) { + IfVxlan ifVxlan = tunnelResources.getAugmentation(IfVxlan.class); + BigInteger vni = ifVxlan.getVni(); + // FIXME: Add tunnel-id match information + }*/ + + return matches; + } + + public static List getMatchInfoForDispatcherTable(BigInteger dpId, Interface iface, + int interfaceTag, short servicePriority) { + List matches = new ArrayList(); + matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] { + MetaDataUtil.getMetaDataForLPortDispatcher(interfaceTag, servicePriority), + MetaDataUtil.getMetaDataMaskForLPortDispatcher() })); + /*if (iface.getType().isAssignableFrom(Tunnel.class)) { + IfTunnel tunnel = iface.getAugmentation(IfTunnel.class); + TunnelResources tunnelResources = tunnel.getTunnelResources(); + if (tunnelResources.getTunnelType().isAssignableFrom(TunnelTypeGre.class)) { + IfGre ifgre = tunnelResources.getAugmentation(IfGre.class); + BigInteger grekey = ifgre.getGreKey(); + // FIXME: Add tunnel-id match information + + } else if (tunnelResources.getTunnelType().isAssignableFrom(TunnelTypeVxlan.class)) { + IfVxlan ifVxlan = tunnelResources.getAugmentation(IfVxlan.class); + BigInteger vni = ifVxlan.getVni(); + // FIXME: Add tunnel-id match information + } + }*/ + return matches; + } + + public static Long getLPortTag(Interface iface, DataBroker dataBroker) { + /*ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class); + String portName = parentRefs.getParentInterface(); + BigInteger dpIdFromInterface = parentRefs.getDatapathNodeIdentifier(); + String portKey = FlowBasedServicesUtils.getInterfaceRefInfo(dpIdFromInterface.toString(), portName); + if (iface.getType().isAssignableFrom(L2vlan.class)) { + InterfacesMetaKey interfacesMetaKey = new InterfacesMetaKey(portKey); + InterfacesInfoKey interfacesInfoKey = new InterfacesInfoKey(iface.getName()); + InterfacesInfo interfacesInfo = VlanInterfaceUtilities.getInterfacesInfoFromConfigDS(interfacesMetaKey, + interfacesInfoKey, dataBroker); + return interfacesInfo.getLporttag(); + } else if (iface.getType().isAssignableFrom(Tunnel.class)) { + TunnelInterfaceRefInfoKey tunnelInterfaceRefInfoKey = new TunnelInterfaceRefInfoKey(portKey); + TunnelInterfaceEntries tunnelInterfaceEntries = + TunnelInterfaceUtilities.getTunnelInterfaceRefEntriesFromConfigDs( + tunnelInterfaceRefInfoKey, iface.getName(), dataBroker); + return tunnelInterfaceEntries.getLportTag(); + } */ + return 0L; + } + + public static void installInterfaceIngressFlow(BigInteger dpId, int vlanId, + BoundServices boundServiceNew, + DataBroker dataBroker, WriteTransaction t, + List matches, int lportTag, short tableId) { + List instructions = boundServiceNew.getAugmentation(StypeOpenflow.class).getInstruction(); + + int serviceInstructionsSize = instructions.size(); + List instructionSet = new ArrayList(); + if (vlanId != 0) { + // incrementing instructionSize and using it as actionKey. Because it won't clash with any other instructions + int actionKey = ++serviceInstructionsSize; + instructionSet.add(MDSALUtil.buildAndGetPopVlanActionInstruction(actionKey, ++serviceInstructionsSize)); + } + + if (lportTag != 0L) { + BigInteger[] metadataValues = IfmUtil.mergeOpenflowMetadataWriteInstructions(instructions); + short sIndex = boundServiceNew.getServicePriority(); + BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(lportTag, + ++sIndex, metadataValues[0]); + BigInteger metadataMask = MetaDataUtil.getMetaDataMaskForLPortDispatcher( + MetaDataUtil.METADATA_MASK_SERVICE_INDEX, + MetaDataUtil.METADATA_MASK_LPORT_TAG, metadataValues[1]); + instructionSet.add(MDSALUtil.buildAndGetWriteMetadaInstruction(metadata, metadataMask, + ++serviceInstructionsSize)); + } + + if (instructions != null && !instructions.isEmpty()) { + for (Instruction info : instructions) { + // Skip meta data write as that is handled already + if (info.getInstruction() instanceof WriteMetadataCase) { + continue; + } + instructionSet.add(info); + } + } + + String serviceRef = boundServiceNew.getServiceName(); + StypeOpenflow stypeOpenflow = boundServiceNew.getAugmentation(StypeOpenflow.class); + Flow ingressFlow = MDSALUtil.buildFlowNew(tableId, serviceRef, + stypeOpenflow.getFlowPriority(), serviceRef, 0, 0, + stypeOpenflow.getFlowCookie(), matches, instructionSet); + installFlow(dpId, ingressFlow, dataBroker, t); + } + + private static void installFlow(BigInteger dpId, Flow flow, DataBroker dataBroker, WriteTransaction t) { + FlowKey flowKey = new FlowKey(new FlowId(flow.getId())); + Node nodeDpn = buildInventoryDpnNode(dpId); + InstanceIdentifier flowInstanceId = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(flow.getTableId())).child(Flow.class,flowKey).build(); + + t.put(LogicalDatastoreType.CONFIGURATION, flowInstanceId, flow, true); + } + + private static Node buildInventoryDpnNode(BigInteger dpnId) { + NodeId nodeId = new NodeId("openflow:" + dpnId); + Node nodeDpn = new NodeBuilder().setId(nodeId).setKey(new NodeKey(nodeId)).build(); + + return nodeDpn; + } + + public static void installLPortDispatcherFlow(BigInteger dpId, BoundServices boundService, Interface iface, + DataBroker dataBroker, WriteTransaction t, int interfaceTag) { + LOG.debug("Installing LPort Dispatcher Flows {}, {}", dpId, iface); + short serviceIndex = boundService.getServicePriority(); + String serviceRef = boundService.getServiceName(); + List matches = FlowBasedServicesUtils.getMatchInfoForDispatcherTable(dpId, iface, + interfaceTag, serviceIndex); + + // Get the metadata and mask from the service's write metadata instruction + StypeOpenflow stypeOpenFlow = boundService.getAugmentation(StypeOpenflow.class); + List serviceInstructions = stypeOpenFlow.getInstruction(); + int instructionSize = serviceInstructions.size(); + BigInteger[] metadataValues = IfmUtil.mergeOpenflowMetadataWriteInstructions(serviceInstructions); + BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(interfaceTag, ++serviceIndex, metadataValues[0]); + BigInteger metadataMask = MetaDataUtil.getMetaDataMaskForLPortDispatcher(MetaDataUtil.METADATA_MASK_SERVICE_INDEX, + MetaDataUtil.METADATA_MASK_LPORT_TAG, metadataValues[1]); + + // build the final instruction for LPort Dispatcher table flow entry + List instructions = new ArrayList(); + instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(metadata, metadataMask, ++instructionSize)); + if (serviceInstructions != null && !serviceInstructions.isEmpty()) { + for (Instruction info : serviceInstructions) { + // Skip meta data write as that is handled already + if (info.getInstruction() instanceof WriteMetadataCase) { + continue; + } + instructions.add(info); + } + } + + // build the flow and install it + Flow ingressFlow = MDSALUtil.buildFlowNew(stypeOpenFlow.getDispatcherTableId(), serviceRef, + boundService.getServicePriority(), serviceRef, 0, 0, stypeOpenFlow.getFlowCookie(), matches, instructions); + installFlow(dpId, ingressFlow, dataBroker, t); + } + + public static void removeIngressFlow(Interface iface, BoundServices serviceOld, BigInteger dpId, + DataBroker dataBroker, WriteTransaction t) { + LOG.debug("Removing Ingress Flows"); + String flowKeyStr = iface.getName() + serviceOld.getServicePriority() + + serviceOld.getServiceName() + IfmConstants.VLAN_INTERFACE_INGRESS_TABLE; + FlowKey flowKey = new FlowKey(new FlowId(flowKeyStr)); + Node nodeDpn = buildInventoryDpnNode(dpId); + InstanceIdentifier flowInstanceId = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(IfmConstants.VLAN_INTERFACE_INGRESS_TABLE)).child(Flow.class, flowKey).build(); + + t.delete(LogicalDatastoreType.CONFIGURATION, flowInstanceId); + } + + public static void removeLPortDispatcherFlow(BigInteger dpId, Interface iface, BoundServices boundServicesOld, + DataBroker dataBroker, WriteTransaction t) { + LOG.debug("Removing LPort Dispatcher Flows {}, {}", dpId, iface); + Long interfaceTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker); + + StypeOpenflow stypeOpenFlow = boundServicesOld.getAugmentation(StypeOpenflow.class); + String flowKeyStr = iface.getName() + boundServicesOld.getServicePriority() + + boundServicesOld.getServiceName() + stypeOpenFlow.getDispatcherTableId(); + FlowKey flowKey = new FlowKey(new FlowId(flowKeyStr)); + Node nodeDpn = buildInventoryDpnNode(dpId); + InstanceIdentifier flowInstanceId = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(stypeOpenFlow.getDispatcherTableId())).child(Flow.class, flowKey).build(); + + t.delete(LogicalDatastoreType.CONFIGURATION, flowInstanceId); + } + + public static String getInterfaceRefInfo(String dpId, String portName) { + String portRefInfo = ""; + if (!"".equals(dpId)) { + portRefInfo = dpId.toString() + ":"; + } + portRefInfo = portRefInfo + portName; + return portRefInfo; + } +} \ No newline at end of file diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/interfacemgr/impl/rev150325/InterfacemgrImplModule.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/interfacemgr/impl/rev150325/InterfacemgrImplModule.java index e4435ff3..c5e8e323 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/interfacemgr/impl/rev150325/InterfacemgrImplModule.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/interfacemgr/impl/rev150325/InterfacemgrImplModule.java @@ -27,6 +27,8 @@ public class InterfacemgrImplModule extends org.opendaylight.yang.gen.v1.urn.ope @Override public java.lang.AutoCloseable createInstance() { InterfacemgrProvider provider = new InterfacemgrProvider(); + provider.setRpcProviderRegistry(getRpcRegistryDependency()); + getBrokerDependency().registerProvider(provider); return provider; } diff --git a/interfacemgr/interfacemgr-impl/src/main/yang/interfacemgr-impl.yang b/interfacemgr/interfacemgr-impl/src/main/yang/interfacemgr-impl.yang index d53803fa..1c8851d2 100644 --- a/interfacemgr/interfacemgr-impl/src/main/yang/interfacemgr-impl.yang +++ b/interfacemgr/interfacemgr-impl/src/main/yang/interfacemgr-impl.yang @@ -32,6 +32,14 @@ module interfacemgr-impl { } } } + container rpc-registry { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity md-sal-binding:binding-rpc-registry; + } + } + } } } -} \ No newline at end of file +} diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataChangeListenerBase.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataChangeListenerBase.java new file mode 100644 index 00000000..fac56593 --- /dev/null +++ b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataChangeListenerBase.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.datastoreutils; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import org.opendaylight.controller.md.sal.binding.api.*; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public abstract class AsyncDataChangeListenerBase implements DataChangeListener, AutoCloseable { + private static final Logger LOG = LoggerFactory.getLogger(AsyncDataChangeListenerBase.class); + + private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_CORE_SIZE = 1; + private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_MAX_SIZE = 1; + private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_KEEP_ALIVE_TIME_SECS = 300; + private static final int STARTUP_LOOP_TICK = 500; + private static final int STARTUP_LOOP_MAX_RETRIES = 8; + + private static ThreadPoolExecutor dataChangeHandlerExecutor = new ThreadPoolExecutor( + DATATREE_CHANGE_HANDLER_THREAD_POOL_CORE_SIZE, + DATATREE_CHANGE_HANDLER_THREAD_POOL_MAX_SIZE, + DATATREE_CHANGE_HANDLER_THREAD_POOL_KEEP_ALIVE_TIME_SECS, + TimeUnit.SECONDS, + new LinkedBlockingQueue()); + + private ListenerRegistration listenerRegistration; + protected final Class clazz; + private final Class eventClazz; + + /** + * @param clazz - for which the data change event is received + */ + public AsyncDataChangeListenerBase(Class clazz, Class eventClazz) { + this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!"); + this.eventClazz = Preconditions.checkNotNull(eventClazz, "eventClazz can not be null!"); + } + + public void registerListener(final LogicalDatastoreType dsType, final DataBroker db) { + try { + TaskRetryLooper looper = new TaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES); + listenerRegistration = looper.loopUntilNoException(new Callable>() { + @Override + public ListenerRegistration call() throws Exception { + return db.registerDataChangeListener(dsType, getWildCardPath(), getDataChangeListener(), getDataChangeScope()); + } + }); + } catch (final Exception e) { + LOG.warn("{}: Data Tree Change listener registration failed.", eventClazz.getName()); + LOG.debug("{}: Data Tree Change listener registration failed: {}", eventClazz.getName(), e); + throw new IllegalStateException( eventClazz.getName() + "{}startup failed. System needs restart.", e); + } + } + + @Override + public void onDataChanged(final AsyncDataChangeEvent, DataObject> changeEvent) { + if (changeEvent == null) { + return; + } + + DataChangeHandler dataChangeHandler = new DataChangeHandler(changeEvent); + dataChangeHandlerExecutor.execute(dataChangeHandler); + } + + @SuppressWarnings("unchecked") + private void createData(final Map, DataObject> createdData) { + final Set> keys = createdData.keySet() != null + ? createdData.keySet() : Collections.>emptySet(); + for (InstanceIdentifier key : keys) { + if (clazz.equals(key.getTargetType())) { + InstanceIdentifier createKeyIdent = key.firstIdentifierOf(clazz); + final Optional value = Optional.of(createdData.get(key)); + if (value.isPresent()) { + this.add(createKeyIdent, (T)value.get()); + } + } + } + } + + @SuppressWarnings("unchecked") + private void updateData(final Map, DataObject> updateData, + final Map, DataObject> originalData) { + + final Set> keys = updateData.keySet() != null + ? updateData.keySet() : Collections.>emptySet(); + for (InstanceIdentifier key : keys) { + if (clazz.equals(key.getTargetType())) { + InstanceIdentifier updateKeyIdent = key.firstIdentifierOf(clazz); + final Optional value = Optional.of(updateData.get(key)); + final Optional original = Optional.of(originalData.get(key)); + if (value.isPresent() && original.isPresent()) { + this.update(updateKeyIdent, (T) original.get(), (T) value.get()); + } + } + } + } + + @SuppressWarnings("unchecked") + private void removeData(final Set> removeData, + final Map, DataObject> originalData) { + + for (InstanceIdentifier key : removeData) { + if (clazz.equals(key.getTargetType())) { + final InstanceIdentifier ident = key.firstIdentifierOf(clazz); + final DataObject removeValue = originalData.get(key); + this.remove(ident, (T)removeValue); + } + } + } + + @Override + public void close() throws Exception { + if (listenerRegistration != null) { + try { + listenerRegistration.close(); + } catch (final Exception e) { + LOG.error("Error when cleaning up DataChangeListener.", e); + } + listenerRegistration = null; + } + LOG.info("Interface Manager Closed"); + } + + protected abstract void remove(InstanceIdentifier identifier, T del); + + protected abstract void update(InstanceIdentifier identifier, T original, T update); + + protected abstract void add(InstanceIdentifier identifier, T add); + + protected abstract InstanceIdentifier getWildCardPath(); + + protected abstract DataChangeListener getDataChangeListener(); + + protected abstract AsyncDataBroker.DataChangeScope getDataChangeScope(); + + public class DataChangeHandler implements Runnable { + final AsyncDataChangeEvent, DataObject> changeEvent; + + public DataChangeHandler(final AsyncDataChangeEvent, DataObject> changeEvent) { + this.changeEvent = changeEvent; + } + + @Override + public void run() { + Preconditions.checkNotNull(changeEvent,"Async ChangeEvent can not be null!"); + + /* All DataObjects for create */ + final Map, DataObject> createdData = changeEvent.getCreatedData() != null + ? changeEvent.getCreatedData() : Collections., DataObject>emptyMap(); + /* All DataObjects for remove */ + final Set> removeData = changeEvent.getRemovedPaths() != null + ? changeEvent.getRemovedPaths() : Collections.>emptySet(); + /* All DataObjects for updates */ + final Map, DataObject> updateData = changeEvent.getUpdatedData() != null + ? changeEvent.getUpdatedData() : Collections., DataObject>emptyMap(); + /* All Original DataObjects */ + final Map, DataObject> originalData = changeEvent.getOriginalData() != null + ? changeEvent.getOriginalData() : Collections., DataObject>emptyMap(); + + createData(createdData); + updateData(updateData, originalData); + removeData(removeData, originalData); + } + } +} diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataTreeChangeListenerBase.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataTreeChangeListenerBase.java new file mode 100644 index 00000000..39bbdb95 --- /dev/null +++ b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataTreeChangeListenerBase.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.datastoreutils; + +import com.google.common.base.Preconditions; +import org.opendaylight.controller.md.sal.binding.api.*; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.concurrent.Callable; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public abstract class AsyncDataTreeChangeListenerBase implements DataTreeChangeListener, AutoCloseable { + private static final Logger LOG = LoggerFactory.getLogger(AsyncDataTreeChangeListenerBase.class); + + private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_CORE_SIZE = 1; + private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_MAX_SIZE = 1; + private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_KEEP_ALIVE_TIME_SECS = 300; + private static final int STARTUP_LOOP_TICK = 500; + private static final int STARTUP_LOOP_MAX_RETRIES = 8; + + private ListenerRegistration listenerRegistration; + + private static ThreadPoolExecutor dataTreeChangeHandlerExecutor = new ThreadPoolExecutor( + DATATREE_CHANGE_HANDLER_THREAD_POOL_CORE_SIZE, + DATATREE_CHANGE_HANDLER_THREAD_POOL_MAX_SIZE, + DATATREE_CHANGE_HANDLER_THREAD_POOL_KEEP_ALIVE_TIME_SECS, + TimeUnit.SECONDS, + new LinkedBlockingQueue()); + + protected final Class clazz; + private final Class eventClazz; + + public AsyncDataTreeChangeListenerBase(Class clazz, Class eventClazz) { + this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!"); + this.eventClazz = Preconditions.checkNotNull(eventClazz, "eventClazz can not be null!"); + } + + @Override + public void onDataTreeChanged(Collection> changes) { + if (changes == null || changes.isEmpty()) { + return; + } + + DataTreeChangeHandler dataTreeChangeHandler = new DataTreeChangeHandler(changes); + dataTreeChangeHandlerExecutor.execute(dataTreeChangeHandler); + } + + public void registerListener(LogicalDatastoreType dsType, final DataBroker db) { + final DataTreeIdentifier treeId = new DataTreeIdentifier<>(dsType, getWildCardPath()); + try { + TaskRetryLooper looper = new TaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES); + listenerRegistration = looper.loopUntilNoException(new Callable>() { + @Override + public ListenerRegistration call() throws Exception { + return db.registerDataTreeChangeListener(treeId, getDataTreeChangeListener()); + } + }); + } catch (final Exception e) { + LOG.warn("{}: Data Tree Change listener registration failed.", eventClazz.getName()); + LOG.debug("{}: Data Tree Change listener registration failed: {}", eventClazz.getName(), e); + throw new IllegalStateException( eventClazz.getName() + "{}startup failed. System needs restart.", e); + } + } + + @Override + public void close() throws Exception { + if (listenerRegistration != null) { + try { + listenerRegistration.close(); + } catch (final Exception e) { + LOG.error("Error when cleaning up DataTreeChangeListener.", e); + } + listenerRegistration = null; + } + } + + protected abstract InstanceIdentifier getWildCardPath(); + protected abstract void remove(InstanceIdentifier key, T dataObjectModification); + protected abstract void update(InstanceIdentifier key, T dataObjectModificationBefore, T dataObjectModificationAfter); + protected abstract void add(InstanceIdentifier key, T dataObjectModification); + protected abstract K getDataTreeChangeListener(); + + public class DataTreeChangeHandler implements Runnable { + Collection> changes; + + public DataTreeChangeHandler(Collection> changes) { + this.changes = changes; + } + + + + @Override + public void run() { + for (DataTreeModification change : changes) { + final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); + final DataObjectModification mod = change.getRootNode(); + + switch (mod.getModificationType()) { + case DELETE: + remove(key, mod.getDataBefore()); + break; + case SUBTREE_MODIFIED: + update(key, mod.getDataBefore(), mod.getDataAfter()); + break; + case WRITE: + if (mod.getDataBefore() == null) { + add(key, mod.getDataAfter()); + } else { + update(key, mod.getDataBefore(), mod.getDataAfter()); + } + break; + default: + // FIXME: May be not a good idea to throw. + throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType()); + } + } + } + } +} \ No newline at end of file diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/DataStoreJobCoordinator.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/DataStoreJobCoordinator.java new file mode 100644 index 00000000..8a31ca3d --- /dev/null +++ b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/DataStoreJobCoordinator.java @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.datastoreutils; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.TimeUnit; + +public class DataStoreJobCoordinator { + private static final Logger LOG = LoggerFactory.getLogger(DataStoreJobCoordinator.class); + + private static final int THREADPOOL_SIZE = Runtime.getRuntime().availableProcessors(); + + private ForkJoinPool fjPool; + private Map> jobQueueMap = new ConcurrentHashMap<>(); + + private static DataStoreJobCoordinator instance; + + static { + instance = new DataStoreJobCoordinator(); + } + + public static DataStoreJobCoordinator getInstance() { + return instance; + } + + /** + * + */ + private DataStoreJobCoordinator() { + fjPool = new ForkJoinPool(); + + for (int i = 0; i < THREADPOOL_SIZE; i++) { + Map jobEntriesMap = new ConcurrentHashMap(); + jobQueueMap.put(i, jobEntriesMap); + } + + new Thread(new JobQueueHandler()).start(); + } + + public void enqueueJob(String key, + Callable>> mainWorker) { + enqueueJob(key, mainWorker, null, 0); + } + + public void enqueueJob(String key, + Callable>> mainWorker, + RollbackCallable rollbackWorker) { + enqueueJob(key, mainWorker, rollbackWorker, 0); + } + + public void enqueueJob(String key, + Callable>> mainWorker, + int maxRetries) { + enqueueJob(key, mainWorker, null, maxRetries); + } + + /** + * + * @param key + * @param mainWorker + * @param rollbackWorker + * @param maxRetries + * + * This is used by the external applications to enqueue a Job with an appropriate key. + * A JobEntry is created and queued appropriately. + */ + + public void enqueueJob(String key, + Callable>> mainWorker, + RollbackCallable rollbackWorker, + int maxRetries) { + JobEntry jobEntry = new JobEntry(key, mainWorker, rollbackWorker, maxRetries); + Integer hashKey = getHashKey(key); + LOG.debug("Obtained Hashkey: {}, for jobkey: {}", hashKey, key); + + Map jobEntriesMap = jobQueueMap.get(hashKey); + synchronized (jobEntriesMap) { + JobQueue jobQueue = jobEntriesMap.get(key); + if (jobQueue == null) { + jobQueue = new JobQueue(); + } + jobQueue.addEntry(jobEntry); + jobEntriesMap.put(key, jobQueue); + } + + jobQueueMap.put(hashKey, jobEntriesMap); // Is this really needed ? + } + + /** + * clearJob is used to cleanup the submitted job from the jobqueue. + **/ + private void clearJob(JobEntry jobEntry) { + Map jobEntriesMap = jobQueueMap.get(getHashKey(jobEntry.getKey())); + synchronized (jobEntriesMap) { + JobQueue jobQueue = jobEntriesMap.get(jobEntry.getKey()); + jobQueue.setExecutingEntry(null); + if (jobQueue.getWaitingEntries().isEmpty()) { + jobEntriesMap.remove(jobEntry.getKey()); + } + } + } + + /** + * + * @param key + * @return generated hashkey + * + * Used to generate the hashkey in to the jobQueueMap. + */ + private Integer getHashKey(String key) { + int code = key.hashCode(); + return (code % THREADPOOL_SIZE + THREADPOOL_SIZE) % THREADPOOL_SIZE; + } + + /** + * JobCallback class is used as a future callback for + * main and rollback workers to handle success and failure. + */ + private class JobCallback implements FutureCallback> { + private JobEntry jobEntry; + + public JobCallback(JobEntry jobEntry) { + this.jobEntry = jobEntry; + } + + /** + * @param voids + * This implies that all the future instances have returned success. -- TODO: Confirm this + */ + @Override + public void onSuccess(List voids) { + clearJob(jobEntry); + } + + /** + * + * @param throwable + * This method is used to handle failure callbacks. + * If more retry needed, the retrycount is decremented and mainworker is executed again. + * After retries completed, rollbackworker is executed. + * If rollbackworker fails, this is a double-fault. Double fault is logged and ignored. + */ + + @Override + public void onFailure(Throwable throwable) { + LOG.warn("Job: {} failed with exception: {}", jobEntry, throwable.getStackTrace()); + if (jobEntry.getMainWorker() == null) { + LOG.error("Job: {} failed with Double-Fault. Bailing Out.", jobEntry); + clearJob(jobEntry); + return; + } + + if (jobEntry.decrementRetryCountAndGet() > 0) { + MainTask worker = new MainTask(jobEntry); + fjPool.execute(worker); + return; + } + + if (jobEntry.getRollbackWorker() != null) { + jobEntry.setMainWorker(null); + RollbackTask rollbackTask = new RollbackTask(jobEntry); + fjPool.execute(rollbackTask); + return; + } + + clearJob(jobEntry); + } + } + + /** + * RollbackTask is used to execute the RollbackCallable provided by the application + * in the eventuality of a failure. + */ + + private class RollbackTask implements Runnable { + private JobEntry jobEntry; + + public RollbackTask(JobEntry jobEntry) { + this.jobEntry = jobEntry; + } + + @Override + public void run() { + RollbackCallable callable = jobEntry.getRollbackWorker(); + callable.setFutures(jobEntry.getFutures()); + List> futures = null; + + try { + futures = callable.call(); + } catch (Exception e){ + LOG.error("Exception when executing jobEntry: {}, exception: {}", jobEntry, e.getStackTrace()); + e.printStackTrace(); + } + + if (futures == null || futures.isEmpty()) { + clearJob(jobEntry); + return; + } + + ListenableFuture> listenableFuture = Futures.allAsList(futures); + Futures.addCallback(listenableFuture, new JobCallback(jobEntry)); + jobEntry.setFutures(futures); + } + } + + /** + * MainTask is used to execute the MainWorker callable. + */ + + private class MainTask implements Runnable { + private JobEntry jobEntry; + + public MainTask(JobEntry jobEntry) { + this.jobEntry = jobEntry; + } + + @Override + public void run() { + List> futures = null; + try { + futures = jobEntry.getMainWorker().call(); + } catch (Exception e){ + LOG.error("Exception when executing jobEntry: {}, exception: {}", jobEntry, e.getStackTrace()); + e.printStackTrace(); + } + + if (futures == null || futures.isEmpty()) { + clearJob(jobEntry); + return; + } + + ListenableFuture> listenableFuture = Futures.allAsList(futures); + Futures.addCallback(listenableFuture, new JobCallback(jobEntry)); + jobEntry.setFutures(futures); + } + } + + private class JobQueueHandler implements Runnable { + @Override + public void run() { + LOG.debug("Starting JobQueue Handler Thread."); + while (true) { + try { + boolean jobAddedToPool = false; + for (int i = 0; i < THREADPOOL_SIZE; i++) { + Map jobEntriesMap = jobQueueMap.get(i); + if (jobEntriesMap.isEmpty()) { + continue; + } + + synchronized (jobEntriesMap) { + Iterator it = jobEntriesMap.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry)it.next(); + if (entry.getValue().getExecutingEntry() != null) { + continue; + } + JobEntry jobEntry = entry.getValue().getWaitingEntries().poll(); + if (jobEntry != null) { + entry.getValue().setExecutingEntry(jobEntry); + MainTask worker = new MainTask(jobEntry); + fjPool.execute(worker); + jobAddedToPool = true; + } else { + it.remove(); + } + } + } + } + + if (!jobAddedToPool) { + TimeUnit.SECONDS.sleep(1); + } + } catch (Exception e) { + e.printStackTrace(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + } +} \ No newline at end of file diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobEntry.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobEntry.java new file mode 100644 index 00000000..bb9849a2 --- /dev/null +++ b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobEntry.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.datastoreutils; + +import com.google.common.util.concurrent.ListenableFuture; + +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * JobEntry is the entity built per job submitted by the application and + * enqueued to the book-keeping data structure. + */ +public class JobEntry { + final private String key; + private Callable>> mainWorker; + final private RollbackCallable rollbackWorker; + private AtomicInteger retryCount; + private List> futures; + + public JobEntry(String key, + Callable>> mainWorker, + RollbackCallable rollbackWorker, + int maxRetries) { + this.key = key; + this.mainWorker = mainWorker; + this.rollbackWorker = rollbackWorker; + retryCount = new AtomicInteger(maxRetries); + } + + /** + * + * @return + * + * The key provided by the application that segregates the + * callables that can be run parallely. + * NOTE: Currently, this is a string. Can be converted to Object where + * Object implementation should provide the hashcode and equals methods. + */ + public String getKey() { + return key; + } + + public Callable>> getMainWorker() { + return mainWorker; + } + + public void setMainWorker(Callable>> mainWorker) { + this.mainWorker = mainWorker; + } + + public RollbackCallable getRollbackWorker() { + return rollbackWorker; + } + + public int decrementRetryCountAndGet() { + return retryCount.decrementAndGet(); + } + + public List> getFutures() { + return futures; + } + + public void setFutures(List> futures) { + this.futures = futures; + } + + @Override + public String toString() { + return "JobEntry{" + + "key='" + key + '\'' + + ", mainWorker=" + mainWorker + + ", rollbackWorker=" + rollbackWorker + + ", retryCount=" + retryCount + + ", futures=" + futures + + '}'; + } +} \ No newline at end of file diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobQueue.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobQueue.java new file mode 100644 index 00000000..6447731c --- /dev/null +++ b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobQueue.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.datastoreutils; + +import java.util.concurrent.ConcurrentLinkedQueue; + +public class JobQueue { + private ConcurrentLinkedQueue waitingEntries; + private JobEntry executingEntry; + + public JobQueue() { + waitingEntries = new ConcurrentLinkedQueue(); + } + + public void addEntry(JobEntry entry) { + waitingEntries.add(entry); // FIXME - Try/Catch. + } + + public ConcurrentLinkedQueue getWaitingEntries() { + return waitingEntries; + } + + public JobEntry getExecutingEntry() { + return executingEntry; + } + + public void setExecutingEntry(JobEntry executingEntry) { + this.executingEntry = executingEntry; + } +} diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/RollbackCallable.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/RollbackCallable.java new file mode 100644 index 00000000..6b8fe231 --- /dev/null +++ b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/RollbackCallable.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.datastoreutils; + +import com.google.common.util.concurrent.ListenableFuture; + +import java.util.List; +import java.util.concurrent.Callable; + +public abstract class RollbackCallable implements Callable>> { + + private List> futures; + + public RollbackCallable() { + } + + public List> getFutures() { + return futures; + } + + public void setFutures(List> futures) { + this.futures = futures; + } +} diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/TaskRetryLooper.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/TaskRetryLooper.java new file mode 100644 index 00000000..94b6643e --- /dev/null +++ b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/TaskRetryLooper.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.datastoreutils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.Callable; + +public class TaskRetryLooper { + private static final Logger LOG = LoggerFactory.getLogger(TaskRetryLooper.class); + + private final long tick; + private final int maxRetries; + + /** + * @param tick sleep between steps in miliseconds + * @param maxRetries retries limit + */ + public TaskRetryLooper(long tick, int maxRetries) { + this.tick = tick; + this.maxRetries = maxRetries; + } + + public T loopUntilNoException(Callable task) throws Exception { + T output = null; + + Exception taskException = null; + for (int i = 0; i < maxRetries; i++) { + taskException = null; + try { + output = task.call(); + break; + } catch (Exception exception) { + LOG.debug("looper step failed: {}", exception.getMessage()); + taskException = exception; + } + + try { + Thread.sleep(tick); + } catch (InterruptedException e) { + LOG.debug("interrupted: {}", e.getMessage(), e); + } + } + + if (taskException != null) { + throw taskException; + } + + LOG.debug("looper step succeeded: {}", output); + return output; + } +} \ No newline at end of file diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MDSALUtil.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MDSALUtil.java index 1f09d8bc..23b7b619 100644 --- a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MDSALUtil.java +++ b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MDSALUtil.java @@ -16,6 +16,10 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; @@ -27,7 +31,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.I import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadataBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes; @@ -102,6 +114,23 @@ public class MDSALUtil { .setCookie(new FlowCookie(cookie)).build(); } + public static Flow buildFlowNew(short tableId, String flowId, int priority, String flowName, int idleTimeOut, + int hardTimeOut, BigInteger cookie, List listMatchInfo, List listInstructionInfo) { + return MDSALUtil.buildFlowNew(tableId, flowId, priority, flowName, idleTimeOut, hardTimeOut, cookie, + listMatchInfo, listInstructionInfo, true); + } + + private static Flow buildFlowNew(short tableId, String flowId, int priority, String flowName, int idleTimeOut, + int hardTimeOut, BigInteger cookie, List listMatchInfo, + List listInstructionInfo, boolean isStrict) { + FlowKey key = new FlowKey(new FlowId(flowId)); + return new FlowBuilder().setMatch(buildMatches(listMatchInfo)).setKey(key) + .setPriority(Integer.valueOf(priority)).setInstructions(new InstructionsBuilder().setInstruction(listInstructionInfo).build()) + .setBarrier(false).setInstallHw(true).setHardTimeout(hardTimeOut).setIdleTimeout(idleTimeOut) + .setFlowName(flowName).setTableId(Short.valueOf(tableId)).setStrict(isStrict) + .setCookie(new FlowCookie(cookie)).build(); + } + public static GroupEntity buildGroupEntity(BigInteger dpnId, long groupId, String groupName, GroupTypes groupType, List listBucketInfo) { @@ -283,4 +312,28 @@ public class MDSALUtil { // TODO Auto-generated method stub return null; } + + public static Instruction buildAndGetPopVlanActionInstruction(int actionKey, int instructionKey) { + Action popVlanAction = new ActionBuilder().setAction( + new PopVlanActionCaseBuilder().setPopVlanAction(new PopVlanActionBuilder().build()).build()) + .setKey(new ActionKey(actionKey)).build(); + List listAction = new ArrayList (); + listAction.add(popVlanAction); + ApplyActions applyActions = new ApplyActionsBuilder().setAction(listAction).build(); + ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build(); + InstructionBuilder instructionBuilder = new InstructionBuilder(); + + instructionBuilder.setInstruction(applyActionsCase); + instructionBuilder.setKey(new InstructionKey(instructionKey)); + return instructionBuilder.build(); + } + + public static Instruction buildAndGetWriteMetadaInstruction(BigInteger metadata, + BigInteger mask, int instructionKey) { + return new InstructionBuilder() + .setInstruction( + new WriteMetadataCaseBuilder().setWriteMetadata( + new WriteMetadataBuilder().setMetadata(metadata).setMetadataMask(mask).build()) + .build()).setKey(new InstructionKey(instructionKey)).build(); + } } diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MetaDataUtil.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MetaDataUtil.java index 01d5adea..deb8c757 100644 --- a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MetaDataUtil.java +++ b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MetaDataUtil.java @@ -11,4 +11,58 @@ import java.math.BigInteger; public class MetaDataUtil { public static final BigInteger METADATA_MASK_VRFID = new BigInteger("00000000FFFFFFFF", 16); + public static final BigInteger METADATA_MASK_LPORT_TAG = new BigInteger("1FFFFF0000000000", 16); + public static final BigInteger METADATA_MASK_SERVICE = new BigInteger("000000FFFF000000", 16); + public static final BigInteger METADATA_MASK_SERVICE_INDEX = new BigInteger("E000000000000000", 16); + public static final BigInteger METADATA_MASK_LPORT_WRITE = new BigInteger("00FFFF0000000000", 16); + public static final BigInteger METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID = new BigInteger("08000000FFFFFF00", 16); + public static final BigInteger METADATA_MASK_LABEL_ITM = new BigInteger("40FFFFFF000000FF", 16); + + public static BigInteger getMetaDataForLPortDispatcher(int lportTag, short serviceIndex) { + return getServiceIndexMetaData(serviceIndex).or(getLportTagMetaData(lportTag)); + } + + public static BigInteger getMetaDataForLPortDispatcher(int lportTag, short serviceIndex, + BigInteger serviceMetaData) { + return getServiceIndexMetaData(serviceIndex).or(getLportTagMetaData(lportTag)).or(serviceMetaData); + } + + public static BigInteger getServiceIndexMetaData(int serviceIndex) { + return new BigInteger("7", 16).and(BigInteger.valueOf(serviceIndex)).shiftLeft(61); + } + + public static BigInteger getLportTagMetaData(int lportTag) { + return new BigInteger("1FFFFF", 16).and(BigInteger.valueOf(lportTag)).shiftLeft(40); + } + + public static BigInteger getMetaDataMaskForLPortDispatcher() { + return METADATA_MASK_SERVICE_INDEX.or(METADATA_MASK_LPORT_TAG); + } + + public static BigInteger getMetadataLPort(int lPortTag) { + return (new BigInteger("FFFF", 16).and(BigInteger.valueOf(lPortTag))).shiftLeft(40); + } + + public static BigInteger getLportFromMetadata(BigInteger metadata) { + return (metadata.and(METADATA_MASK_LPORT_TAG)).shiftRight(40); + } + + public static int getElanTagFromMetadata(BigInteger metadata) { + return (((metadata.and(MetaDataUtil.METADATA_MASK_SERVICE)). + shiftRight(24))).intValue(); + } + + public static BigInteger getMetaDataMaskForLPortDispatcher(BigInteger metadataMaskForServiceIndex, + BigInteger metadataMaskForLPortTag, BigInteger metadataMaskForService) { + return metadataMaskForServiceIndex.or(metadataMaskForLPortTag).or(metadataMaskForService); + } + + /** + * For the tunnel id with VNI and valid-vni-flag set, the most significant byte + * should have 08. So, shifting 08 to 7 bytes (56 bits) and the result is OR-ed with + * VNI being shifted to 1 byte. + */ + public static BigInteger getTunnelIdWithValidVniBitAndVniSet(int vni) { + return BigInteger.valueOf(0X08).shiftLeft(56).or(BigInteger.valueOf(vni).shiftLeft(8)); + } } diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/interfaces/IMdsalApiManager.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/interfaces/IMdsalApiManager.java index ec09bbdd..a86ad651 100644 --- a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/interfaces/IMdsalApiManager.java +++ b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/interfaces/IMdsalApiManager.java @@ -9,14 +9,22 @@ package org.opendaylight.vpnservice.mdsalutil.interfaces; import java.math.BigInteger; import java.util.List; + +import com.google.common.util.concurrent.CheckedFuture; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.vpnservice.mdsalutil.ActionInfo; import org.opendaylight.vpnservice.mdsalutil.FlowEntity; import org.opendaylight.vpnservice.mdsalutil.GroupEntity; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; public interface IMdsalApiManager { public void installFlow(FlowEntity flowEntity); + public CheckedFuture installFlow(BigInteger dpId, Flow flowEntity); + + public CheckedFuture removeFlow(BigInteger dpId, FlowEntity flowEntity); + public void removeFlow(FlowEntity flowEntity); public void installGroup(GroupEntity groupEntity); diff --git a/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALManager.java b/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALManager.java index 5ca603ca..05accb36 100644 --- a/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALManager.java +++ b/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALManager.java @@ -128,6 +128,18 @@ public class MDSALManager implements AutoCloseable { } } + public CheckedFuture installFlow(BigInteger dpId, Flow flow) { + FlowKey flowKey = new FlowKey( new FlowId(flow.getId()) ); + Node nodeDpn = buildDpnNode(dpId); + InstanceIdentifier flowInstanceId = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(flow.getTableId())).child(Flow.class,flowKey).build(); + + WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction(); + modification.put(LogicalDatastoreType.CONFIGURATION, flowInstanceId, flow, true); + return modification.submit(); + } + public void installGroup(GroupEntity groupEntity) { try { Group group = groupEntity.getGroupBuilder().build(); @@ -181,7 +193,7 @@ public class MDSALManager implements AutoCloseable { WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction(); - modification.delete(LogicalDatastoreType.CONFIGURATION,flowInstanceId ); + modification.delete(LogicalDatastoreType.CONFIGURATION,flowInstanceId); CheckedFuture submitFuture = modification.submit(); @@ -210,6 +222,18 @@ public class MDSALManager implements AutoCloseable { } } + public CheckedFuture removeFlowNew(FlowEntity flowEntity) { + s_logger.debug("Remove flow {}",flowEntity); + Node nodeDpn = buildDpnNode(flowEntity.getDpnId()); + FlowKey flowKey = new FlowKey(new FlowId(flowEntity.getFlowId())); + InstanceIdentifier flowInstanceId = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(flowEntity.getTableId())).child(Flow.class, flowKey).build(); + WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction(); + modification.delete(LogicalDatastoreType.CONFIGURATION,flowInstanceId ); + return modification.submit(); + } + public void removeGroup(GroupEntity groupEntity) { try { Node nodeDpn = buildDpnNode(groupEntity.getDpnId()); diff --git a/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALUtilProvider.java b/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALUtilProvider.java index 398e16f6..eca7a5cd 100644 --- a/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALUtilProvider.java +++ b/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALUtilProvider.java @@ -10,13 +10,17 @@ package org.opendaylight.vpnservice.mdsalutil.internal; import java.math.BigInteger; import java.util.List; + +import com.google.common.util.concurrent.CheckedFuture; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext; import org.opendaylight.vpnservice.mdsalutil.ActionInfo; import org.opendaylight.vpnservice.mdsalutil.FlowEntity; import org.opendaylight.vpnservice.mdsalutil.GroupEntity; import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,6 +59,16 @@ public class MDSALUtilProvider implements BindingAwareConsumer, IMdsalApiManager mdSalMgr.installFlow(flowEntity); } + @Override + public CheckedFuture installFlow(BigInteger dpId, Flow flowEntity) { + return mdSalMgr.installFlow(dpId, flowEntity); + } + + @Override + public CheckedFuture removeFlow(BigInteger dpId, FlowEntity flowEntity) { + return mdSalMgr.removeFlowNew(flowEntity); + } + @Override public void removeFlow(FlowEntity flowEntity) { mdSalMgr.removeFlow(flowEntity); diff --git a/nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/NexthopManager.java b/nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/NexthopManager.java index 1543a819..c0a99838 100644 --- a/nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/NexthopManager.java +++ b/nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/NexthopManager.java @@ -195,11 +195,11 @@ public class NexthopManager implements L3nexthopService, AutoCloseable { } } - public void createRemoteNextHop(String ifName, String ofPortId, String ipAddress) { + public void createRemoteNextHop(String ifName, String ipAddress) { String nhKey = new String("nexthop." + ifName + ipAddress); int groupId = createNextHopPointer(nhKey); - BigInteger dpnId = getDpnId(ofPortId); + BigInteger dpnId = interfaceManager.getDpnForInterface(ifName); TunnelNexthop nexthop = getTunnelNexthop(dpnId, ipAddress); if (nexthop == null) { List listBucketInfo = new ArrayList(); @@ -434,7 +434,7 @@ public class NexthopManager implements L3nexthopService, AutoCloseable { } - private Optional read(LogicalDatastoreType datastoreType, + Optional read(LogicalDatastoreType datastoreType, InstanceIdentifier path) { ReadOnlyTransaction tx = broker.newReadOnlyTransaction(); diff --git a/nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/OdlInterfaceChangeListener.java b/nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/OdlInterfaceChangeListener.java index 49a7bdbb..d5ddfd21 100644 --- a/nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/OdlInterfaceChangeListener.java +++ b/nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/OdlInterfaceChangeListener.java @@ -9,18 +9,20 @@ package org.opendaylight.vpnservice.nexthopmgr; import java.math.BigInteger; + +import com.google.common.base.Optional; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; @@ -60,7 +62,7 @@ public class OdlInterfaceChangeListener extends AbstractDataChangeListener identifier, Interface intrf) { - LOG.trace("Adding Interface : key: " + identifier + ", value=" + intrf ); - - if (intrf.getType().equals(L3tunnel.class)) { - IfL3tunnel intfData = intrf.getAugmentation(IfL3tunnel.class); - IpAddress gatewayIp = intfData.getGatewayIp(); - IpAddress remoteIp = (gatewayIp == null) ? intfData.getRemoteIp() : gatewayIp; - NodeConnectorId ofPort = intrf.getAugmentation(BaseIds.class).getOfPortId(); - nexthopManager.createRemoteNextHop(intrf.getName(), ofPort.toString(), remoteIp.getIpv4Address().getValue()); + protected void add(InstanceIdentifier identifier, Interface interfaceInfo) { + LOG.trace("Adding Interface : key: " + identifier + ", value=" + interfaceInfo ); + // READ interface config information + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface intrf = + getInterfaceFromConfigDS(nexthopManager, new InterfaceKey(interfaceInfo.getName())); + + if(intrf != null && intrf.getType().equals(Tunnel.class)){ + IfTunnel intfData = intrf.getAugmentation(IfTunnel.class); + IpAddress gatewayIp = intfData.getTunnelGateway(); + IpAddress remoteIp = (gatewayIp == null) ? intfData.getTunnelDestination() : gatewayIp; + nexthopManager.createRemoteNextHop(intrf.getName(), remoteIp.getIpv4Address().getValue()); } } - private InstanceIdentifier getWildCardPath() { - return InstanceIdentifier.create(Interfaces.class).child(Interface.class); + return InstanceIdentifier.create(InterfacesState.class).child(Interface.class); } @Override protected void remove(InstanceIdentifier identifier, - Interface intrf) { - LOG.trace("Removing interface : key: " + identifier + ", value=" + intrf ); - if (intrf.getType().equals(L3tunnel.class)) { + Interface interfaceInfo) { + LOG.trace("Removing interface : key: " + identifier + ", value=" + interfaceInfo ); + // READ interface config information + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface intrf = + getInterfaceFromConfigDS(nexthopManager, new InterfaceKey(interfaceInfo.getName())); + + if (intrf != null && intrf.getType().equals(Tunnel.class)) { BigInteger dpnId = interfaceManager.getDpnForInterface(intrf); - IfL3tunnel intfData = intrf.getAugmentation(IfL3tunnel.class); - IpAddress gatewayIp = intfData.getGatewayIp(); - IpAddress remoteIp = (gatewayIp == null) ? intfData.getRemoteIp() : gatewayIp; + IfTunnel intfData = intrf.getAugmentation(IfTunnel.class); + IpAddress gatewayIp = intfData.getTunnelGateway(); + IpAddress remoteIp = (gatewayIp == null) ? intfData.getTunnelDestination() : gatewayIp; nexthopManager.removeRemoteNextHop(dpnId, intrf.getName(), remoteIp.getIpv4Address().getValue()); } } + public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface getInterfaceFromConfigDS(NexthopManager nexthopManager, InterfaceKey interfaceKey) { + InstanceIdentifier interfaceId = + getInterfaceIdentifier(interfaceKey); + Optional interfaceOptional = + nexthopManager.read(LogicalDatastoreType.CONFIGURATION, interfaceId); + if (!interfaceOptional.isPresent()) { + return null; + } + + return interfaceOptional.get(); + } + + public static InstanceIdentifier getInterfaceIdentifier(InterfaceKey interfaceKey) { + InstanceIdentifier.InstanceIdentifierBuilder interfaceInstanceIdentifierBuilder = + InstanceIdentifier.builder(Interfaces.class).child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface.class, interfaceKey); + return interfaceInstanceIdentifierBuilder.build(); + } + @Override protected void update(InstanceIdentifier identifier, Interface original, Interface update) { diff --git a/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/InterfaceChangeListener.java b/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/InterfaceChangeListener.java index 1aead8be..d6c481ff 100644 --- a/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/InterfaceChangeListener.java +++ b/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/InterfaceChangeListener.java @@ -5,25 +5,25 @@ * 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; -import java.math.BigInteger; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager; import org.opendaylight.vpnservice.mdsalutil.NwConstants; +import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.math.BigInteger; + public class InterfaceChangeListener extends AbstractDataChangeListener implements AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(InterfaceChangeListener.class); @@ -82,7 +82,7 @@ public class InterfaceChangeListener extends AbstractDataChangeListener identifier, Interface intrf) { LOG.trace("Remove interface event - key: {}, value: {}", identifier, intrf ); - if (intrf.getType().equals(L3tunnel.class)) { + if (intrf.getType().equals(Tunnel.class)) { BigInteger dpnId = interfaceManager.getDpnForInterface(intrf); String ifName = intrf.getName(); LOG.debug("Removing tunnel interface associated with Interface {}", intrf.getName()); diff --git a/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java b/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java index 3585a6f1..b56c1d06 100644 --- a/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java +++ b/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java @@ -7,7 +7,7 @@ */ package org.opendaylight.vpnservice; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel; import java.math.BigInteger; import java.util.Collection; @@ -321,7 +321,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener