/* * Copyright (c) 2016 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.netvirt.vpnmanager.api; import static java.util.stream.Collectors.toList; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker; import org.opendaylight.genius.infra.Datastore.Configuration; import org.opendaylight.genius.infra.Datastore.Operational; import org.opendaylight.genius.infra.TypedReadTransaction; import org.opendaylight.genius.mdsalutil.MDSALUtil; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelTypeInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelTypeOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.ExtrarouteRdsMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.extraroute.rds.map.ExtrarouteRds; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.extraroute.rds.map.ExtrarouteRdsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.extraroute.rds.map.extraroute.rds.DestPrefixes; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.extraroute.rds.map.extraroute.rds.DestPrefixesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.extraroute.rds.map.extraroute.rds.dest.prefixes.AllocatedRds; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.extraroute.rds.map.extraroute.rds.dest.prefixes.AllocatedRdsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnToExtraroutes; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.Vpn; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.VpnKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.ExtraRoutes; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.ExtraRoutesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.Routes; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.RoutesKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.Uint32; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class VpnExtraRouteHelper { private static final Logger LOG = LoggerFactory.getLogger(VpnExtraRouteHelper.class); private VpnExtraRouteHelper() { } public static Optional getVpnExtraroutes(DataBroker broker, String vpnName, String vpnRd, String destPrefix) { InstanceIdentifier vpnExtraRoutesId = getVpnToExtrarouteVrfIdIdentifier(vpnName, vpnRd, destPrefix); Optional extraRouteOptional = Optional.empty(); try { extraRouteOptional = SingleTransactionDataBroker.syncReadOptional(broker, LogicalDatastoreType.OPERATIONAL, vpnExtraRoutesId); } catch (ExecutionException | InterruptedException e) { LOG.error("getVpnExtraroutes: failed to read VpnToExtraRoutes for vpn {} rd {} destprefix {} due " + "to exception", vpnName, vpnRd, destPrefix, e); } return extraRouteOptional; } public static Optional getVpnExtraroutes(TypedReadTransaction operTx, String vpnName, String vpnRd, String destPrefix) throws ExecutionException, InterruptedException { return operTx.read(getVpnToExtrarouteVrfIdIdentifier(vpnName, vpnRd, destPrefix)).get(); } public static InstanceIdentifier getVpnToExtrarouteVrfIdIdentifier(String vpnName, String vrfId, String ipPrefix) { return InstanceIdentifier.builder(VpnToExtraroutes.class) .child(Vpn.class, new VpnKey(vpnName)).child(ExtraRoutes.class, new ExtraRoutesKey(vrfId)).child(Routes.class, new RoutesKey(ipPrefix)).build(); } public static InstanceIdentifier getVpnToExtrarouteVpnIdentifier(String vpnName) { return InstanceIdentifier.builder(VpnToExtraroutes.class) .child(Vpn.class, new VpnKey(vpnName)).build(); } public static List getAllVpnExtraRoutes(DataBroker dataBroker, String vpnName, List usedRds, String destPrefix) { List routes = new ArrayList<>(); for (String rd : usedRds) { try { Optional extraRouteInfo = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, getVpnToExtrarouteVrfIdIdentifier(vpnName, rd, destPrefix)); extraRouteInfo.ifPresent(routes::add); } catch (ExecutionException | InterruptedException e) { LOG.error("getAllVpnExtraRoutes: failed to read VpnToExtraRouteVrf for vpn {} rd {} destprefix {} due " + "to exception", vpnName, rd, destPrefix, e); } } return routes; } public static List getUsedRds(DataBroker broker, Uint32 vpnId, String destPrefix) { InstanceIdentifier usedRdsId = getUsedRdsIdentifier(vpnId, destPrefix); Optional usedRds = Optional.empty(); try { usedRds = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, usedRdsId); } catch (ExecutionException | InterruptedException e) { LOG.error("getUsedRds: failed to read Used Rds for vpn {} destprefix {} due to exception", vpnId, destPrefix, e); } return usedRds.isPresent() && usedRds.get().getAllocatedRds() != null ? usedRds.get().getAllocatedRds().values().stream() .map(AllocatedRds::getRd).distinct().collect(toList()) : new ArrayList<>(); } public static List getUsedRds(TypedReadTransaction confTx, Uint32 vpnId, String destPrefix) throws ExecutionException, InterruptedException { Optional usedRds = confTx.read(getUsedRdsIdentifier(vpnId, destPrefix)).get(); return usedRds.isPresent() && usedRds.get().getAllocatedRds() != null ? usedRds.get().getAllocatedRds().values().stream() .map(AllocatedRds::getRd).distinct().collect(toList()) : new ArrayList<>(); } public static InstanceIdentifier getUsedRdsIdentifier(Uint32 vpnId) { return InstanceIdentifier.builder(ExtrarouteRdsMap.class) .child(ExtrarouteRds.class, new ExtrarouteRdsKey(vpnId)).build(); } public static InstanceIdentifier getUsedRdsIdentifier(Uint32 vpnId, String destPrefix) { return InstanceIdentifier.builder(ExtrarouteRdsMap.class) .child(ExtrarouteRds.class, new ExtrarouteRdsKey(vpnId)) .child(DestPrefixes.class, new DestPrefixesKey(destPrefix)).build(); } public static InstanceIdentifier getUsedRdsIdentifier(Uint32 vpnId, String destPrefix, String nh) { return InstanceIdentifier.builder(ExtrarouteRdsMap.class) .child(ExtrarouteRds.class, new ExtrarouteRdsKey(vpnId)) .child(DestPrefixes.class, new DestPrefixesKey(destPrefix)) .child(AllocatedRds.class, new AllocatedRdsKey(nh)).build(); } @Nullable public static Class getTunnelType(ItmRpcService itmRpcService, String ifName) { try { Future> result = itmRpcService.getTunnelType(new GetTunnelTypeInputBuilder().setIntfName(ifName).build()); RpcResult rpcResult = result.get(); if (!rpcResult.isSuccessful()) { LOG.warn("RPC Call to getTunnelInterfaceId returned with Errors {}", rpcResult.getErrors()); } else { return rpcResult.getResult().getTunnelType(); } } catch (InterruptedException | ExecutionException e) { LOG.warn("Exception when getting tunnel interface Id for tunnel type", e); } return null; } public static java.util.Optional getRdAllocatedForExtraRoute(DataBroker broker, Uint32 vpnId, String destPrefix, String nextHop) { InstanceIdentifier usedRdsId = getUsedRdsIdentifier(vpnId, destPrefix, nextHop); try { return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, usedRdsId) .map(AllocatedRds::getRd); } catch (ExecutionException | InterruptedException e) { LOG.error("getRdAllocatedForExtraRoute: failed to read Used Rds for vpn {} destprefix {} nexthop {} due " + "to exception", vpnId, destPrefix, nextHop, e); } return Optional.empty(); } public static List getExtraRouteDestPrefixes(DataBroker broker, Uint32 vpnId) { try { Optional optionalExtraRoutes = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, getUsedRdsIdentifier(vpnId)); Map prefixesMap = optionalExtraRoutes.map(ExtrarouteRds::getDestPrefixes).orElse(null); return prefixesMap == null ? Collections.emptyList() : new ArrayList(prefixesMap.values()); } catch (ExecutionException | InterruptedException e) { LOG.error("getExtraRouteDestPrefixes: failed to read ExRoutesRdsMap for vpn {} due to exception", vpnId, e); } return new ArrayList<>(); } }