<dependency>
<groupId>org.opendaylight.vpnservice</groupId>
<artifactId>vpnmanager-impl</artifactId>
- <version>1.0-SNAPSHOT</version>
+ <version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.vpnservice</groupId>
public class IfmConstants {
public static final String IFM_IDPOOL_NAME = "interfaces";
+ public static final long IFM_IDPOOL_START = 1L;
+ public static final String IFM_IDPOOL_SIZE = "65535";
public static final String OF_URI_PREFIX = "openflow:";
- public static final String OF_URI_SEPARATOR = "openflow:";
- public static final int DEFAULT_IFINDEX = 65535;
+ public static final String OF_URI_SEPARATOR = ":";
+ public static final int DEFAULT_IFINDEX = 65536;
}
package org.opendaylight.vpnservice.interfacemgr;
+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.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.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.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
-public class IfmUtil {
+public class IfmUtil {
- static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
+ public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
/*
* NodeConnectorId is of form 'openflow:dpnid:portnum'
*/
}
- static NodeId buildDpnNodeId(long dpnId) {
+ public static NodeId buildDpnNodeId(long dpnId) {
return new NodeId(IfmConstants.OF_URI_PREFIX + dpnId);
}
+
+ public static InstanceIdentifier<Interface> buildId(String interfaceName) {
+ //TODO Make this generic and move to AbstractDataChangeListener or Utils.
+ InstanceIdentifierBuilder<Interface> idBuilder =
+ InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
+ InstanceIdentifier<Interface> id = idBuilder.build();
+ return id;
+ }
+
+ public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
+ InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> 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));
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder.build();
+ return id;
+ }
+
+ public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey getStateInterfaceKeyFromName(
+ String name) {
+ return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(name);
+ }
+
+ public static InstanceIdentifier<IdPool> getPoolId(String poolName){
+ InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idBuilder =
+ InstanceIdentifier.builder(Pools.class).child(IdPool.class, new IdPoolKey(poolName));
+ InstanceIdentifier<IdPool> id = idBuilder.build();
+ return id;
+ }
}
*/
package org.opendaylight.vpnservice.interfacemgr;
-
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;
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.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.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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
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.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.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;
return id;
}
- private InstanceIdentifier
- <org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface>
- buildStateInterfaceId(String interfaceName) {
- //TODO Make this generic and move to AbstractDataChangeListener or Utils.
- InstanceIdentifierBuilder
- <org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface>
- 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));
- InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder.build();
- return id;
- }
private void addInterface(final InstanceIdentifier<Interface> identifier,
final Interface interf) {
ncId = nodeConn.getId();
}
mapNcToInterfaceName.put(ncId, interf.getName());
- if(interf.getType().getClass().isInstance(L3tunnel.class)) {
+ if(interf.getType().isAssignableFrom(L3tunnel.class)) {
NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
* if-index = interface-id
*/
InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id =
- buildStateInterfaceId(interf.getName());
+ IfmUtil.buildStateInterfaceId(interf.getName());
Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
read(LogicalDatastoreType.OPERATIONAL, id);
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface;
ifaceBuilder.setOperStatus(getOperStatus(nodeConn));
ifaceBuilder.setIfIndex(getIfIndex(ifName)).setName(ifName).setType(interf.getType());
- ifaceBuilder.setKey(getStateInterfaceKeyFromName(ifName));
+ ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName));
stateIface = ifaceBuilder.build();
LOG.trace("Adding stateIface {} and id {} to OPERATIONAL DS", stateIface, id);
asyncWrite(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK);
* TODO: Start-delete-me
*/
- InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idBuilder =
- InstanceIdentifier.builder(Pools.class).child(IdPool.class, new IdPoolKey("interfaces"));
- InstanceIdentifier<IdPool> id = idBuilder.build();
- Optional<IdPool> globalPool = read(LogicalDatastoreType.OPERATIONAL, id);
+ InstanceIdentifier<IdPool> id = IfmUtil.getPoolId(IfmConstants.IFM_IDPOOL_NAME);
+ Optional<IdPool> globalPool = read(LogicalDatastoreType.OPERATIONAL, id );
Long newIdValue = null;
if (globalPool.isPresent()) {
IdPool pool = globalPool.get();
}
}
- private org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey getStateInterfaceKeyFromName(
- String name) {
- return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(name);
- }
-
private NodeConnector getNodeConnectorFromDataStore(Interface interf) {
NodeConnectorId ncId = interf.getAugmentation(BaseIds.class).getOfPortId();
//TODO: Replace with MDSAL Util method
private void delInterface(final InstanceIdentifier<Interface> identifier,
final Interface delInterface) {
InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id =
- buildStateInterfaceId(delInterface.getName());
+ IfmUtil.buildStateInterfaceId(delInterface.getName());
Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
read(LogicalDatastoreType.OPERATIONAL, id);
if(stateIf.isPresent()) {
NodeConnectorId ncId = getNodeConnectorIdFromInterface(delInterface);
if(ncId != null) {
mapNcToInterfaceName.remove(ncId);
- if(delInterface.getType().getClass().isInstance(L3tunnel.class)) {
+ if(delInterface.getType().isAssignableFrom(L3tunnel.class)) {
Node node = getNodeFromDataStore(delInterface);
if((node != null) &&(node.getNodeConnector().isEmpty())) {
dbDpnEndpoints.remove(node.getId());
if(nc != null) {
// Name doesn't change. Is it present in update?
mapNcToInterfaceName.put(nc.getId(), original.getName());
- if(interf.getType().getClass().isInstance(L3tunnel.class)) {
+ if(interf.getType().isAssignableFrom(L3tunnel.class)) {
NodeId nodeId = getNodeIdFromNodeConnectorId(nc.getId());
IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
updateInterface(identifier, original, update);
}
- private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
+ protected <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- tx.put(datastoreType, path, data, true);
- Futures.addCallback(tx.submit(), callback);
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.put(datastoreType, path, data, true);
+ Futures.addCallback(tx.submit(), callback);
}
- private <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
+ protected <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- tx.merge(datastoreType, path, data, true);
- Futures.addCallback(tx.submit(), callback);
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.merge(datastoreType, path, data, true);
+ Futures.addCallback(tx.submit(), callback);
}
- private <T extends DataObject> void asyncRemove(LogicalDatastoreType datastoreType,
+ protected <T extends DataObject> void asyncRemove(LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path, FutureCallback<Void> callback) {
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- tx.delete(datastoreType, path);
- Futures.addCallback(tx.submit(), callback);
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.delete(datastoreType, path);
+ Futures.addCallback(tx.submit(), callback);
}
void processPortAdd(NodeConnector port) {
NodeConnectorId portId = port.getId();
FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class);
- LOG.debug("PortAdd: PortId { "+portId.getValue()+"} PortName {"+ofPort.getName()+"}");
+ LOG.debug("PortAdd: PortId { " + portId.getValue() + "} PortName {" + ofPort.getName() + "}");
String ifName = this.mapNcToInterfaceName.get(portId);
setInterfaceOperStatus(ifName, OperStatus.Up);
}
private void setInterfaceOperStatus(String ifName, OperStatus opStatus) {
if (ifName != null) {
InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id =
- buildStateInterfaceId(ifName);
+ IfmUtil.buildStateInterfaceId(ifName);
Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
read(LogicalDatastoreType.OPERATIONAL, id);
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface;
long dpn = this.getDpnForInterface(ifName);
long portNo = this.getPortNumForInterface(iface).longValue();
matches.add(new MatchInfo(MatchFieldType.in_port, new long[] {dpn, portNo}));
+
if (ifType.isInstance(L2vlan.class)) {
IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
long vlanVid = vlanIface.getVlanId().longValue();
if (vlanVid != 0) {
- matches.add(new MatchInfo(MatchFieldType.vlan_vid,
+ matches.add(new MatchInfo(MatchFieldType.vlan_vid,
new long[] {vlanVid}));
LOG.trace("L2Vlan: {}",vlanIface);
}
IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class);
Class<? extends TunnelTypeBase> tunnType = ifL3Tunnel.getTunnelType();
LOG.trace("L3Tunnel: {}",ifL3Tunnel);
- } else if (ifType.getClass().isInstance(StackedVlan.class)) {
+ } else if (ifType.isAssignableFrom(StackedVlan.class)) {
IfStackedVlan ifStackedVlan = iface.getAugmentation(IfStackedVlan.class);
LOG.trace("StackedVlan: {}",ifStackedVlan);
- } else if (ifType.getClass().isInstance(Mpls.class)) {
+ } else if (ifType.isAssignableFrom(Mpls.class)) {
IfMpls ifMpls = iface.getAugmentation(IfMpls.class);
LOG.trace("Mpls: {}",ifMpls);
}
if (iface.isEnabled()) {
- if(ifType.isInstance(L2vlan.class)) {
+ if(ifType.isAssignableFrom(L2vlan.class)) {
IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
long vlanVid = vlanIface.getVlanId();
LOG.trace("L2Vlan: {}",vlanIface);
new String[] { Long.toString(vlanVid) }));
}
listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)}));
-
- } else if (ifType.isInstance(L3tunnel.class)) {
+
+ } else if (ifType.isAssignableFrom(L3tunnel.class)) {
//TODO: Handle different tunnel types
IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class);
Class<? extends TunnelTypeBase> tunnType = ifL3Tunnel.getTunnelType();
LOG.trace("L3Tunnel: {}",ifL3Tunnel);
//TODO: check switch_type and configure accordingly
listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)}));
-
- } else if (ifType.isInstance(StackedVlan.class)) {
+
+ } else if (ifType.isAssignableFrom(StackedVlan.class)) {
IfStackedVlan ifStackedVlan = iface.getAugmentation(IfStackedVlan.class);
LOG.trace("StackedVlan: {}",ifStackedVlan);
- // TBD
- } else if (ifType.isInstance(Mpls.class)) {
+ // TODO: TBD
+ } else if (ifType.isAssignableFrom(Mpls.class)) {
IfMpls ifMpls = iface.getAugmentation(IfMpls.class);
LOG.trace("Mpls: {}",ifMpls);
- // TBD
+ // TODO: TBD
}
}
return listActionInfo;
*/
package org.opendaylight.vpnservice.interfacemgr;
-import java.util.concurrent.ExecutionException;
import java.math.BigInteger;
import java.util.List;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
-import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
-import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
import org.opendaylight.idmanager.IdManager;
import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
-import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInputBuilder;
private void createIdPool() {
CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
- .setPoolName("interfaces")
- .setIdStart(1L)
- .setPoolSize(new BigInteger("65535"))
- .build();
+ .setPoolName(IfmConstants.IFM_IDPOOL_NAME)
+ .setIdStart(IfmConstants.IFM_IDPOOL_START)
+ .setPoolSize(new BigInteger(IfmConstants.IFM_IDPOOL_SIZE))
+ .build();
//TODO: Error handling
Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
try {
- if((result != null) && (result.get().isSuccessful())) {
+ if ((result != null) && (result.get().isSuccessful())) {
LOG.debug("Created IdPool for InterfaceMgr");
}
} catch (InterruptedException | ExecutionException e) {
--- /dev/null
+package org.opendaylight.vpnservice.interfacemgr.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+
+public class IfmUtilTest {
+
+ @Mock NodeConnectorId ncId;
+ MockDataChangedEvent event;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testDpnConversions() {
+ String NodeId = IfmUtil.buildDpnNodeId(101L).getValue();
+ assertEquals("openflow:101", NodeId);
+ when(ncId.getValue()).thenReturn("openflow:101:11");
+ assertEquals("101",IfmUtil.getDpnFromNodeConnectorId(ncId));
+ }
+
+}
--- /dev/null
+package org.opendaylight.vpnservice.interfacemgr.test;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+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;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+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.InterfaceManager;
+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.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.InterfaceBuilder;
+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.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.NodeConnectorBuilder;
+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.pools.IdPool;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIdsBuilder;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+@RunWith(MockitoJUnitRunner.class)
+public class InterfaceManagerTest {
+
+ private String ifName = "dpn1-if0";
+ Map<InstanceIdentifier<?>,DataObject> written = new HashMap<>();
+ Map<InstanceIdentifier<?>,DataObject> updated = new HashMap<>();
+ Set<InstanceIdentifier<?>> removed = new HashSet<>();
+
+ @Mock DataBroker dataBroker;
+ @Mock IdManager idManager;
+ @Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
+ @Mock ReadOnlyTransaction mockReadTx;
+ @Mock WriteTransaction mockWriteTx;
+
+ MockDataChangedEvent dataChangeEvent;
+ InterfaceManager imgr;
+
+ NodeConnectorId ncId;
+ NodeConnector nc;
+ Interface interf;
+ InstanceIdentifier<Interface> ifIdent;
+ InstanceIdentifier<NodeConnector> ncIdent;
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifsIdent;
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface;
+ InstanceIdentifier<IdPool> poolIdent;
+
+ @Before
+ public void setUp() throws Exception {
+ when(dataBroker.registerDataChangeListener(
+ any(LogicalDatastoreType.class),
+ any(InstanceIdentifier.class),
+ any(DataChangeListener.class),
+ any(DataChangeScope.class)))
+ .thenReturn(dataChangeListenerRegistration);
+ dataChangeEvent = new MockDataChangedEvent();
+ imgr = new InterfaceManager(dataBroker, idManager) {
+ protected <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+ /*
+ * Do nothing for now. Ideally we should capture this information
+ * and use it to verify results.
+ */
+ written.put(path, data);
+ }
+ protected <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+ updated.put(path, data);
+ }
+
+ protected <T extends DataObject> void asyncRemove(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, FutureCallback<Void> callback) {
+ removed.add(path);
+ }
+
+ };
+ setupMocks();
+ }
+
+ private void setupMocks() {
+ ncId = new NodeConnectorId("openflow:10:111");
+ nc = buildNodeConnector(ncId);
+ interf = buildInterface(ifName, "Test Interface1", true, L2vlan.class, ncId);
+ ifIdent = IfmUtil.buildId(ifName);
+ ncIdent = getNcIdent("openflow:10",ncId);
+ ifsIdent = IfmUtil.buildStateInterfaceId(interf.getName());
+ stateIface = buildStateInterface(ifName);
+ poolIdent = IfmUtil.getPoolId("interfaces");
+
+ // Setup mocks
+ when(dataBroker.newReadOnlyTransaction()).thenReturn(mockReadTx);
+ when(dataBroker.newWriteOnlyTransaction()).thenReturn(mockWriteTx);
+ }
+
+ @Test
+ public void testAdd() {
+ Optional<Interface> expected = Optional.of(interf);
+ Optional<NodeConnector> expectedNc = Optional.of(nc);
+ doReturn(Futures.immediateCheckedFuture(expected)).when(mockReadTx).read(
+ LogicalDatastoreType.CONFIGURATION, ifIdent);
+ doReturn(Futures.immediateCheckedFuture(expectedNc)).when(mockReadTx).read(
+ LogicalDatastoreType.OPERATIONAL, ncIdent);
+ doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read(
+ LogicalDatastoreType.OPERATIONAL, ifsIdent);
+ doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read(
+ LogicalDatastoreType.OPERATIONAL, poolIdent);
+
+ dataChangeEvent.created.put(IfmUtil.buildId(ifName), interf);
+ imgr.onDataChanged(dataChangeEvent);
+ //Add some verifications
+ assertEquals(1,written.size());
+ assertEquals(0,updated.size());
+ assertEquals(0, removed.size());
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface writtenIface =
+ (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface)written.get(ifsIdent);
+ assertEquals(stateIface.getKey(), writtenIface.getKey());
+ assertEquals(65536, writtenIface.getIfIndex().intValue());
+ assertEquals(OperStatus.Up, writtenIface.getOperStatus());
+ }
+
+ @Test
+ public void testUpdate() {
+ Optional<Interface> expected = Optional.of(interf);
+ Optional<NodeConnector> expectedNc = Optional.of(nc);
+ Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> expectedStateIf = Optional.of(stateIface);
+ doReturn(Futures.immediateCheckedFuture(expected)).when(mockReadTx).read(
+ LogicalDatastoreType.CONFIGURATION, ifIdent);
+ doReturn(Futures.immediateCheckedFuture(expectedNc)).when(mockReadTx).read(
+ LogicalDatastoreType.OPERATIONAL, ncIdent);
+ doReturn(Futures.immediateCheckedFuture(expectedStateIf)).when(mockReadTx).read(
+ LogicalDatastoreType.OPERATIONAL, ifsIdent);
+ doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read(
+ LogicalDatastoreType.OPERATIONAL, poolIdent);
+ dataChangeEvent.original.put(IfmUtil.buildId(ifName), interf);
+ dataChangeEvent.updated.put(IfmUtil.buildId(ifName), interf);
+ imgr.onDataChanged(dataChangeEvent);
+ //Add some verifications
+
+ assertEquals(0,written.size());
+ assertEquals(1,updated.size());
+ assertEquals(0, removed.size());
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface updatedIface =
+ (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface)updated.get(ifsIdent);
+ assertNotEquals(stateIface.getKey(),updatedIface.getKey());
+ assertNull(updatedIface.getIfIndex());
+ assertEquals(OperStatus.Up, updatedIface.getOperStatus());
+ }
+
+ private org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface buildStateInterface(
+ String ifName) {
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder =
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder();
+ ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName));
+ return ifaceBuilder.build();
+ }
+
+ private InstanceIdentifier<NodeConnector> getNcIdent(String nodeKey, NodeConnectorId ncId) {
+ return InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, new NodeKey(new NodeId(nodeKey)))
+ .child(NodeConnector.class, new NodeConnectorKey(ncId))
+ .build();
+ }
+
+ private Interface buildInterface(String ifName, String desc, boolean enabled, Class<? extends InterfaceType> ifType, NodeConnectorId ncId) {
+ InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
+ .setDescription(desc).setEnabled(enabled).setType(ifType);
+
+ BaseIds baseId = new BaseIdsBuilder().setOfPortId(ncId).build();
+ builder.addAugmentation(BaseIds.class, baseId);
+ return builder.build();
+ }
+
+ private NodeConnector buildNodeConnector(NodeConnectorId ncId) {
+ NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder()
+ .setId(ncId)
+ .setKey(new NodeConnectorKey(ncId));
+ return ncBuilder.build();
+ }
+
+}
--- /dev/null
+/*
+ * 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.test;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+class MockDataChangedEvent implements AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> {
+ Map<InstanceIdentifier<?>,DataObject> created = new HashMap<>();
+ Map<InstanceIdentifier<?>,DataObject> updated = new HashMap<>();
+ Map<InstanceIdentifier<?>,DataObject> original = new HashMap<>();
+ Set<InstanceIdentifier<?>> removed = new HashSet<>();
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getCreatedData() {
+ return created;
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getUpdatedData() {
+ return updated;
+ }
+
+ @Override
+ public Set<InstanceIdentifier<?>> getRemovedPaths() {
+ return removed;
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getOriginalData() {
+ return original;
+ }
+
+ @Override
+ public DataObject getOriginalSubtree() {
+ throw new UnsupportedOperationException("Not implemented by mock");
+ }
+
+ @Override
+ public DataObject getUpdatedSubtree() {
+ throw new UnsupportedOperationException("Not implemented by mock");
+ }
+}