X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=itm%2Fitm-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fvpnservice%2Fitm%2Frpc%2FItmManagerRpcService.java;h=26b007a9db7f421fcc3402c3875415697b5ffce5;hb=refs%2Fchanges%2F56%2F38256%2F1;hp=dad264df619811925ef286d19b625bab85669e51;hpb=50bb8cd056ca25114a412398c4df672eac891b28;p=vpnservice.git diff --git a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/rpc/ItmManagerRpcService.java b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/rpc/ItmManagerRpcService.java index dad264df..26b007a9 100644 --- a/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/rpc/ItmManagerRpcService.java +++ b/itm/itm-impl/src/main/java/org/opendaylight/vpnservice/itm/rpc/ItmManagerRpcService.java @@ -8,104 +8,564 @@ package org.opendaylight.vpnservice.itm.rpc; import java.math.BigInteger; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.Future; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.vpnservice.mdsalutil.*; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeMplsOverGre; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.TransportZones; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZone; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.TransportZoneKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.Subnets; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.SubnetsKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.DeviceVteps; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.DeviceVtepsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rev150701.transport.zones.transport.zone.subnets.DeviceVtepsKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; import org.opendaylight.vpnservice.itm.confighelpers.ItmExternalTunnelAddWorker; +import org.opendaylight.vpnservice.itm.confighelpers.ItmExternalTunnelDeleteWorker; +import org.opendaylight.vpnservice.itm.globals.ITMConstants; +import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager; import org.opendaylight.vpnservice.itm.impl.ItmUtils; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfo; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.BuildTunnelFromDpnToDcgatewayInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.BuildTunnelToDcgatewayInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.GetTunnelInterfaceIdInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.GetTunnelInterfaceIdOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.GetTunnelInterfaceIdOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.ItmRpcService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.ExternalTunnelList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.TunnelList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.dpn.endpoints.DPNTEPsInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.dpn.endpoints.dpn.teps.info.TunnelEndPoints; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.external.tunnel.list.ExternalTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.external.tunnel.list.ExternalTunnelKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.InternalTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.InternalTunnelKey; import org.opendaylight.yangtools.yang.common.RpcResult; -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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.SettableFuture; import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import com.google.common.base.Optional; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; public class ItmManagerRpcService implements ItmRpcService { - private static final Logger LOG = LoggerFactory.getLogger(ItmRpcService.class); - DataBroker dataBroker; - public ItmManagerRpcService(DataBroker dataBroker) { + private static final Logger LOG = LoggerFactory.getLogger(ItmManagerRpcService.class); + DataBroker dataBroker; + private IMdsalApiManager mdsalManager; + + + public void setMdsalManager(IMdsalApiManager mdsalManager) { + this.mdsalManager = mdsalManager; + } + + IdManagerService idManagerService; + + public ItmManagerRpcService(DataBroker dataBroker, IdManagerService idManagerService) { this.dataBroker = dataBroker; + this.idManagerService = idManagerService; + } + + @Override + public Future> getTunnelInterfaceName(GetTunnelInterfaceNameInput input) { + RpcResultBuilder resultBld = null; + BigInteger sourceDpn = input.getSourceDpid() ; + BigInteger destinationDpn = input.getDestinationDpid() ; + InstanceIdentifier path = InstanceIdentifier.create( + TunnelList.class) + .child(InternalTunnel.class, new InternalTunnelKey(destinationDpn, sourceDpn, input.getTunnelType())); + + Optional tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker); + + if( tnl != null && tnl.isPresent()) + { + InternalTunnel tunnel = tnl.get(); + GetTunnelInterfaceNameOutputBuilder output = new GetTunnelInterfaceNameOutputBuilder() ; + output.setInterfaceName(tunnel.getTunnelInterfaceName()) ; + resultBld = RpcResultBuilder.success(); + resultBld.withResult(output.build()) ; + }else { + resultBld = RpcResultBuilder.failed(); + } + + return Futures.immediateFuture(resultBld.build()); + } + + + @Override + public Future> removeExternalTunnelEndpoint( + RemoveExternalTunnelEndpointInput input) { + //Ignore the Futures for now + final SettableFuture> result = SettableFuture.create(); + List meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ; + ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, idManagerService,meshedDpnList , input.getDestinationIp(), input.getTunnelType()); + result.set(RpcResultBuilder.success().build()); + return result; } - @Override - public Future> buildTunnelFromDpnToDcgateway(BuildTunnelFromDpnToDcgatewayInput input) { + @Override + public Future> removeExternalTunnelFromDpns( + RemoveExternalTunnelFromDpnsInput input) { //Ignore the Futures for now - final SettableFuture> result = SettableFuture.create(); - ItmExternalTunnelAddWorker.buildTunnelsFromDpnToExternalEndPoint(dataBroker, input.getDpid(), null, input.getDcgwyid()); - result.set(RpcResultBuilder.success().build()); - return result ; - } - - @Override - public Future> getTunnelInterfaceId(GetTunnelInterfaceIdInput input) { - final SettableFuture> result = SettableFuture.create() ; - RpcResultBuilder resultBld = null; - BigInteger sourceDpn = input.getSourceDpid() ; - BigInteger destinationDpn = input.getDestinationDpid() ; - String parentName = null; - IpAddress srcIp = null ; - IpAddress destIp = null ; - List meshDpnList = ItmUtils.getTunnelMeshInfo(dataBroker); - for ( DPNTEPsInfo dpn : meshDpnList) { - if( (dpn.getDPNID()).equals(sourceDpn) ){ - parentName = dpn.getTunnelEndPoints().get(0).getInterfaceName(); - srcIp = dpn.getTunnelEndPoints().get(0).getIpAddress() ; - }else if( (dpn.getDPNID()).equals(destinationDpn)) { - destIp = dpn.getTunnelEndPoints().get(0).getIpAddress() ; + final SettableFuture> result = SettableFuture.create(); + List cfgDpnList = ItmUtils.getDPNTEPListFromDPNId(dataBroker, input.getDpnId()) ; + ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, idManagerService, cfgDpnList, input.getDestinationIp(), input.getTunnelType()); + result.set(RpcResultBuilder.success().build()); + return result; + } + + @Override + public Future> buildExternalTunnelFromDpns( + BuildExternalTunnelFromDpnsInput input) { + //Ignore the Futures for now + final SettableFuture> result = SettableFuture.create(); + List> extTunnelResultList = ItmExternalTunnelAddWorker.buildTunnelsFromDpnToExternalEndPoint(dataBroker, idManagerService,input.getDpnId(), input.getDestinationIp(), input.getTunnelType()); + for (ListenableFuture extTunnelResult : extTunnelResultList) { + Futures.addCallback(extTunnelResult, new FutureCallback(){ + + @Override + public void onSuccess(Void aVoid) { + result.set(RpcResultBuilder.success().build()); + } + + @Override + public void onFailure(Throwable error) { + String msg = String.format("Unable to create ext tunnel"); + LOG.error("create ext tunnel failed. {}. {}", msg, error); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build()); + } + }); + } + result.set(RpcResultBuilder.success().build()); + return result; + } + + @Override + public Future> addExternalTunnelEndpoint( + AddExternalTunnelEndpointInput input) { + // TODO Auto-generated method stub + + //Ignore the Futures for now + final SettableFuture> result = SettableFuture.create(); + List meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ; + ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker, idManagerService,meshedDpnList, input.getDestinationIp(), input.getTunnelType()) ; + result.set(RpcResultBuilder.success().build()); + return result; + } + + @Override + public Future> getExternalTunnelInterfaceName( + GetExternalTunnelInterfaceNameInput input) { + final SettableFuture> result = SettableFuture.create() ; + RpcResultBuilder resultBld; + String sourceNode = input.getSourceNode(); + String dstNode = input.getDestinationNode(); + InstanceIdentifier path = InstanceIdentifier.create( + ExternalTunnelList.class) + .child(ExternalTunnel.class, new ExternalTunnelKey(dstNode, sourceNode, input.getTunnelType())); + + Optional ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker); + + if( ext != null && ext.isPresent()) + { + ExternalTunnel exTunnel = ext.get(); + GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder() ; + output.setInterfaceName(exTunnel.getTunnelInterfaceName()) ; + resultBld = RpcResultBuilder.success(); + resultBld.withResult(output.build()) ; + }else { + resultBld = RpcResultBuilder.failed(); + } + + return Futures.immediateFuture(resultBld.build()); + } + + @Override + public Future> createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) { + LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}", input.getDpnId() , input.getServiceId(), input.getInstruction()); + final SettableFuture> result = SettableFuture.create(); + int serviceId = input.getServiceId() ; + List mkMatches = getTunnelMatchesForServiceId(serviceId); + byte[] vxLANHeader = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + // Flags Byte + byte Flags = (byte) 0x08; + vxLANHeader[0] = Flags; + + // Extract the serviceId details and imprint on the VxLAN Header + vxLANHeader[4] = (byte) (serviceId >> 16); + vxLANHeader[5] = (byte) (serviceId >> 8); + vxLANHeader[6] = (byte) (serviceId >> 0); + + // Matching metadata +// mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] { +// new BigInteger(1, vxLANHeader), +// MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID })); + + Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE, + getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,serviceId), 5, String.format("%s:%d","ITM Flow Entry ",serviceId), + 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)),mkMatches, input.getInstruction()); + + ListenableFuture installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow); + Futures.addCallback(installFlowResult, new FutureCallback(){ + + @Override + public void onSuccess(Void aVoid) { + result.set(RpcResultBuilder.success().build()); } - } - if( srcIp != null && destIp != null ) - { - String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(parentName, srcIp.getIpv4Address().getValue(), destIp.getIpv4Address().getValue()) ; - InstanceIdentifierBuilder idBuilder = InstanceIdentifier.builder(InterfacesState.class) - .child(Interface.class, new InterfaceKey(trunkInterfaceName)); - InstanceIdentifier id = idBuilder.build(); - Optional stateIf = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, id, dataBroker); - if(stateIf.isPresent()){ - GetTunnelInterfaceIdOutputBuilder output = new GetTunnelInterfaceIdOutputBuilder() ; - output.setInterfaceid(stateIf.get().getIfIndex()) ; - resultBld.withResult(output.build()) ; - result.set(resultBld.build()) ; - }else { - result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, "Interface Not found ").build()) ; - } - }else { - result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, "Source or Destination Dpn Id not found ").build()) ; - } - return result ; - } - - @Override - public Future> buildTunnelToDcgateway(BuildTunnelToDcgatewayInput input) { - //Ignore the Futures for now - final SettableFuture> result = SettableFuture.create(); - ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker, null, input.getDcgwyid()) ; - result.set(RpcResultBuilder.success().build()); - return result ; - } + + @Override + public void onFailure(Throwable error) { + String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId()); + LOG.error("create terminating service actions failed. {}. {}", msg, error); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build()); + } + }); + // result.set(RpcResultBuilder.success().build()); + return result; + } + + @Override + public Future> removeTerminatingServiceActions(final RemoveTerminatingServiceActionsInput input) { + LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}", input.getDpnId(), input.getServiceId()); + final SettableFuture> result = SettableFuture.create(); + Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE, + getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,input.getServiceId()), 5, String.format("%s:%d","ITM Flow Entry ",input.getServiceId()), + 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(input.getServiceId())),getTunnelMatchesForServiceId(input.getServiceId()), null ); + + ListenableFuture installFlowResult = mdsalManager.removeFlow(input.getDpnId(), terminatingServiceTableFlow); + Futures.addCallback(installFlowResult, new FutureCallback(){ + + @Override + public void onSuccess(Void aVoid) { + result.set(RpcResultBuilder.success().build()); + } + + @Override + public void onFailure(Throwable error) { + String msg = String.format("Unable to remove terminating service flow for %s", input.getDpnId()); + LOG.error("remove terminating service actions failed. {}. {}", msg, error); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build()); + } + }); + //result.set(RpcResultBuilder.success().build()); + + return result ; + } + + + public List getTunnelMatchesForServiceId(int serviceId) { + List mkMatches = new ArrayList(); + byte[] vxLANHeader = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + // Flags Byte + byte Flags = (byte) 0x08; + vxLANHeader[0] = Flags; + + // Extract the serviceId details and imprint on the VxLAN Header + vxLANHeader[4] = (byte) (serviceId >> 16); + vxLANHeader[5] = (byte) (serviceId >> 8); + vxLANHeader[6] = (byte) (serviceId >> 0); + + // Matching metadata + mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[]{ + BigInteger.valueOf(serviceId)})); + + return mkMatches; + } + + private String getFlowRef(long termSvcTable, int svcId) { + return new StringBuffer().append(termSvcTable).append(svcId).toString(); + } + + @Override + public Future> getInternalOrExternalInterfaceName( + GetInternalOrExternalInterfaceNameInput input) { + RpcResultBuilder resultBld = RpcResultBuilder.failed(); + BigInteger srcDpn = input.getSourceDpid() ; + String srcNode = srcDpn.toString(); + IpAddress dstIp = input.getDestinationIp() ; + InstanceIdentifier path1 = InstanceIdentifier.create( + ExternalTunnelList.class) + .child(ExternalTunnel.class, new ExternalTunnelKey(String.valueOf(dstIp), srcDpn.toString(), TunnelTypeMplsOverGre.class)); + + Optional ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path1, dataBroker); + + if( ext != null && ext.isPresent()) + { + ExternalTunnel extTunnel = ext.get(); + GetInternalOrExternalInterfaceNameOutputBuilder output = new GetInternalOrExternalInterfaceNameOutputBuilder().setInterfaceName(extTunnel.getTunnelInterfaceName() ); + resultBld = RpcResultBuilder.success(); + resultBld.withResult(output.build()) ; + } else { + List meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker); + // Look for external tunnels if not look for internal tunnel + for (DPNTEPsInfo teps : meshedDpnList) { + TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0); + if (dstIp.equals(firstEndPt.getIpAddress())) { + InstanceIdentifier path = InstanceIdentifier.create( + TunnelList.class) + .child(InternalTunnel.class, new InternalTunnelKey(teps.getDPNID(), srcDpn, input.getTunnelType())); + + Optional + tnl = + ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker); + if (tnl != null && tnl.isPresent()) { + InternalTunnel tunnel = tnl.get(); + GetInternalOrExternalInterfaceNameOutputBuilder + output = + new GetInternalOrExternalInterfaceNameOutputBuilder() + .setInterfaceName(tunnel.getTunnelInterfaceName()); + resultBld = RpcResultBuilder.success(); + resultBld.withResult(output.build()); + break; + } + } + } + } + return Futures.immediateFuture(resultBld.build()); + } + + @Override + public Future> deleteL2GwDevice(DeleteL2GwDeviceInput input) { + final SettableFuture> result = SettableFuture.create(); + try { + final IpAddress hwIp = input.getIpAddress(); + final String node_id = input.getNodeId(); + InstanceIdentifier containerPath = InstanceIdentifier.create(TransportZones.class); + Optional tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker); + if (tZonesOptional.isPresent()) { + TransportZones tZones = tZonesOptional.get(); + if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) { + LOG.error("No teps configured"); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build()); + return result; + } + String transportZone = tZones.getTransportZone().get(0).getZoneName(); + if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) { + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build()); + return result; + } + SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey(); + DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id); + InstanceIdentifier path = + InstanceIdentifier.builder(TransportZones.class) + .child(TransportZone.class, new TransportZoneKey(transportZone)) + .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey).build(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + //TO DO: add retry if it fails + t.delete(LogicalDatastoreType.CONFIGURATION, path); + + ListenableFuture futureCheck = t.submit(); + Futures.addCallback(futureCheck, new FutureCallback() { + + @Override + public void onSuccess(Void aVoid) { + result.set(RpcResultBuilder.success().build()); + } + + @Override + public void onFailure(Throwable error) { + String msg = String.format("Unable to write HwVtep {} to datastore", node_id); + LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build()); + } + }); + } + return result; + } catch (Exception e) { + RpcResultBuilder resultBuilder = RpcResultBuilder.failed(). + withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e); + return Futures.immediateFuture(resultBuilder.build()); + } + } + + @Override + public Future> addL2GwDevice(AddL2GwDeviceInput input) { + + final SettableFuture> result = SettableFuture.create(); + try { + final IpAddress hwIp = input.getIpAddress(); + final String node_id = input.getNodeId(); + InstanceIdentifier containerPath = InstanceIdentifier.create(TransportZones.class); + Optional tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker); + if (tZonesOptional.isPresent()) { + TransportZones tZones = tZonesOptional.get(); + if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) { + LOG.error("No teps configured"); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build()); + return result; + } + String transportZone = tZones.getTransportZone().get(0).getZoneName(); + if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) { + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build()); + return result; + } + SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey(); + DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id); + InstanceIdentifier path = + InstanceIdentifier.builder(TransportZones.class) + .child(TransportZone.class, new TransportZoneKey(transportZone)) + .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey).build(); + DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp).setNodeId( + node_id).setTopologyId(input.getTopologyId()).build(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + //TO DO: add retry if it fails + t.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true); + + ListenableFuture futureCheck = t.submit(); + Futures.addCallback(futureCheck, new FutureCallback() { + + @Override + public void onSuccess(Void aVoid) { + result.set(RpcResultBuilder.success().build()); + } + + @Override + public void onFailure(Throwable error) { + String msg = String.format("Unable to write HwVtep {} to datastore", node_id); + LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build()); + } + }); + } + else { + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build()); + return result; + } + return result; + } catch (Exception e) { + RpcResultBuilder resultBuilder = RpcResultBuilder.failed(). + withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e); + return Futures.immediateFuture(resultBuilder.build()); + } + } + + @Override + public Future> addL2GwMlagDevice(AddL2GwMlagDeviceInput input) + { + final SettableFuture> result = SettableFuture.create(); + try { + final IpAddress hwIp = input.getIpAddress(); + final List node_id = input.getNodeId(); + InstanceIdentifier containerPath = InstanceIdentifier.create(TransportZones.class); + Optional tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker); + if (tZonesOptional.isPresent()) { + TransportZones tZones = tZonesOptional.get(); + if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) { + LOG.error("No teps configured"); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build()); + return result; + } + String transportZone = tZones.getTransportZone().get(0).getZoneName(); + if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) { + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build()); + return result; + } + SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey(); + DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id.get(0)); + InstanceIdentifier path = + InstanceIdentifier.builder(TransportZones.class) + .child(TransportZone.class, new TransportZoneKey(transportZone)) + .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey).build(); + DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp).setNodeId(node_id.get(0)).setTopologyId(input.getTopologyId()).build(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + LOG.trace("writing hWvtep{}",deviceVtep); + t.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true); + if(node_id.size() == 2) { + LOG.trace("second node-id {}",node_id.get(1)); + DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, node_id.get(1)); + InstanceIdentifier path2 = InstanceIdentifier.builder(TransportZones.class) + .child(TransportZone.class, new TransportZoneKey(transportZone)) + .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey2).build(); + DeviceVteps deviceVtep2 = new DeviceVtepsBuilder().setKey(deviceVtepKey2).setIpAddress(hwIp).setNodeId(node_id.get(1)) + .setTopologyId(input.getTopologyId()).build(); + LOG.trace("writing {}",deviceVtep2); + t.put(LogicalDatastoreType.CONFIGURATION, path2, deviceVtep2, true); + }ListenableFuture futureCheck = t.submit(); + Futures.addCallback(futureCheck, new FutureCallback() { + @Override + public void onSuccess(Void aVoid) { + result.set(RpcResultBuilder.success().build()); + } + @Override + public void onFailure(Throwable error) { + String msg = String.format("Unable to write HwVtep {} to datastore", node_id); + LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build()); + } + }); + } + return result; + } catch (Exception e) { + RpcResultBuilder resultBuilder = RpcResultBuilder.failed(). + withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e); + return Futures.immediateFuture(resultBuilder.build()); + } + } + @Override + public Future> deleteL2GwMlagDevice(DeleteL2GwMlagDeviceInput input) { + final SettableFuture> result = SettableFuture.create(); + try { + final IpAddress hwIp = input.getIpAddress(); + final List node_id = input.getNodeId(); + InstanceIdentifier containerPath = InstanceIdentifier.create(TransportZones.class); + Optional tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker); + if (tZonesOptional.isPresent()) { + TransportZones tZones = tZonesOptional.get(); + if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) { + LOG.error("No teps configured"); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build()); + return result; + } + String transportZone = tZones.getTransportZone().get(0).getZoneName(); + if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) { + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build()); + return result; + } + SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey(); + DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id.get(0)); + InstanceIdentifier path = + InstanceIdentifier.builder(TransportZones.class) + .child(TransportZone.class, new TransportZoneKey(transportZone)) + .child(Subnets.class, subnetsKey).child(DeviceVteps.class, + deviceVtepKey).build(); + WriteTransaction t = dataBroker.newWriteOnlyTransaction(); + t.delete(LogicalDatastoreType.CONFIGURATION, path); + DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, node_id.get(1)); + InstanceIdentifier path2 = + InstanceIdentifier.builder(TransportZones.class) + .child(TransportZone.class, new TransportZoneKey(transportZone)) + .child(Subnets.class, subnetsKey).child(DeviceVteps.class, + deviceVtepKey2).build(); + t.delete(LogicalDatastoreType.CONFIGURATION, path2); + ListenableFuture futureCheck = t.submit(); + Futures.addCallback(futureCheck, new FutureCallback() { + @Override + public void onSuccess(Void aVoid) { + result.set(RpcResultBuilder.success().build()); + } + @Override + public void onFailure(Throwable error) { + String msg = String.format("Unable to write HwVtep {} to datastore", node_id); + LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp); + result.set(RpcResultBuilder.failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build()); + } + }); + } + return result; + } catch (Exception e) { + RpcResultBuilder resultBuilder = RpcResultBuilder.failed(). + withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e); + return Futures.immediateFuture(resultBuilder.build()); + } + } }