| /* |
| * Copyright 2016 Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.onosproject.teyang.utils.tunnel; |
| |
| import com.google.common.collect.Lists; |
| import org.onosproject.tetopology.management.api.TeTopologyKey; |
| import org.onosproject.tetopology.management.api.node.TeNodeKey; |
| import org.onosproject.tetopology.management.api.node.TtpKey; |
| import org.onosproject.tetunnel.api.tunnel.DefaultTeTunnel; |
| import org.onosproject.tetunnel.api.tunnel.TeTunnel; |
| import org.onosproject.tetunnel.api.tunnel.TeTunnelKey; |
| import org.onosproject.tetunnel.api.tunnel.path.DefaultTePath; |
| import org.onosproject.tetunnel.api.tunnel.path.DefaultTeRouteUnnumberedLink; |
| import org.onosproject.tetunnel.api.tunnel.path.TePath; |
| import org.onosproject.tetunnel.api.tunnel.path.TeRouteSubobject; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.IetfTe; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.IetfTeOpParam; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.DefaultTe; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.Te; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.Type; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type.DefaultDynamic; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type.DefaultExplicit; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type.explicit.DefaultExplicitRouteObjects; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type.explicit.ExplicitRouteObjects; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.Config; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.DefaultPrimaryPaths; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.DefaultState; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.PrimaryPaths; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.State; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.DefaultTunnels; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.Tunnels; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.tunnels.DefaultTunnel; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.tunnels.Tunnel; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProt1Forn; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtBidir1To1; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtReroute; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtRerouteExtra; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtType; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtUnidir1To1; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtUnprotected; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.PathSignalingRsvpte; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.PathSignalingSr; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.RouteIncludeEro; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.StateDown; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.StateUp; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TunnelP2Mp; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TunnelP2p; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TunnelType; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.explicitroutesubobject.type.DefaultUnnumberedLink; |
| import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.explicitroutesubobject.type.UnnumberedLink; |
| import org.slf4j.Logger; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import static org.onosproject.tetunnel.api.tunnel.TeTunnel.LspProtectionType; |
| import static org.onosproject.tetunnel.api.tunnel.path.TeRouteSubobject.Type.UNNUMBERED_LINK; |
| import static org.onosproject.teyang.utils.tunnel.BasicConverter.bytesToLong; |
| import static org.onosproject.teyang.utils.tunnel.BasicConverter.ipToLong; |
| import static org.onosproject.teyang.utils.tunnel.BasicConverter.longToByte; |
| import static org.onosproject.teyang.utils.tunnel.BasicConverter.longToIp; |
| import static org.slf4j.LoggerFactory.getLogger; |
| |
| |
| /** |
| * Tunnel convert utils. |
| */ |
| public final class TunnelConverter { |
| |
| private static final Logger log = getLogger(TunnelConverter.class); |
| private static final String DEFAULT_PATH_NAME = "ietfPath"; |
| private static final String DEFAULT_PATH_CONSTRAINT = "ietfPath"; |
| private static final int DEFAULT_PATH_PREFERENCE = 1; |
| private static final boolean DEFAULT_CSPF_STATE = true; |
| private static final boolean DEFAULT_LOCKDOWN_STATE = true; |
| |
| // no instantiation |
| private TunnelConverter() { |
| } |
| |
| /** |
| * Build a general IETF TE object with a giving tunnel list. for there are |
| * many kind of attributes in IETF TE, now we only care about the tunnel |
| * attributes. |
| * |
| * @param tunnels tunnels in the TE network |
| * @return IETF te info in the TE network |
| */ |
| public static IetfTe buildIetfTeWithTunnels(List<Tunnel> tunnels) { |
| Tunnels teTunnels = new DefaultTunnels |
| .TunnelsBuilder() |
| .tunnel(tunnels) |
| .build(); |
| Te te = new DefaultTe |
| .TeBuilder() |
| .tunnels(teTunnels) |
| .build(); |
| return new IetfTeOpParam |
| .IetfTeBuilder() |
| .te(te) |
| .yangIetfTeOpType(IetfTe.OnosYangOpType.NONE) |
| .build(); |
| } |
| |
| public static IetfTe buildIetfTe(TeTunnel teTunnel) { |
| Tunnel tunnel = te2YangTunnelConverter(teTunnel); |
| return buildIetfTeWithTunnels(Lists.newArrayList(tunnel)); |
| } |
| |
| /** |
| * Converts a specific te tunnel defined in the APP to the general te tunnel |
| * defined in YANG model. |
| * |
| * @param tunnel te tunnel defined in APP |
| * @return tunnel defined in YANG model |
| */ |
| public static Tunnel te2YangTunnelConverter(TeTunnel tunnel) { |
| List<PrimaryPaths> pathsList = new ArrayList<>(); |
| //TODO add path info after yang tool change to guava from google-collect |
| tunnel.primaryPaths() |
| .forEach(tePath -> pathsList.add(te2YangPrimaryPath(tePath))); |
| |
| Tunnel.TunnelBuilder builder = new DefaultTunnel |
| .TunnelBuilder() |
| .type(te2YangTunnelType(tunnel.type())) |
| .name(tunnel.name()) |
| .identifier(tunnel.teTunnelKey().teTunnelId()) |
| .state(te2YangTunnelState(tunnel)) |
| .primaryPaths(pathsList); |
| |
| return builder.build(); |
| } |
| |
| private static State te2YangTunnelState(TeTunnel tunnel) { |
| State.StateBuilder stateBuilder = new DefaultState.StateBuilder(); |
| stateBuilder.name(tunnel.name()) |
| .identifier((int) tunnel.teTunnelKey().teTunnelId()) |
| .source((longToIp(tunnel.srcNode().teNodeId()))) |
| .destination((longToIp(tunnel.dstNode().teNodeId()))) |
| .srcTpId(longToByte(tunnel.srcTp().ttpId())) |
| .dstTpId(longToByte(tunnel.dstTp().ttpId())) |
| .adminStatus(te2YangStateType(tunnel.adminStatus())) |
| .lspProtectionType( |
| te2YangProtectionType(tunnel.lspProtectionType())) |
| .type(te2YangTunnelType(tunnel.type())) |
| .build(); |
| return stateBuilder.build(); |
| } |
| |
| private static PrimaryPaths te2YangPrimaryPath(TePath tePath) { |
| DefaultPrimaryPaths.PrimaryPathsBuilder builder = new DefaultPrimaryPaths |
| .PrimaryPathsBuilder() |
| .name(DEFAULT_PATH_NAME) |
| .preference(DEFAULT_PATH_PREFERENCE) |
| .state(te2YangPrimaryPathState(tePath)) |
| .yangPrimaryPathsOpType(IetfTe.OnosYangOpType.NONE); |
| return builder.build(); |
| } |
| |
| private static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf |
| .te.rev20160705.ietfte.p2pprimarypathparams.State |
| te2YangPrimaryPathState(TePath tePath) { |
| |
| List<TeRouteSubobject> teRouteSubobjects = tePath.explicitRoute(); |
| |
| List<ExplicitRouteObjects> routeObjects = new ArrayList<>(); |
| teRouteSubobjects.forEach(teRouteSubobject -> { |
| routeObjects.add(te2YangRouteSubobject(teRouteSubobject)); |
| }); |
| DefaultExplicit.ExplicitBuilder explicitBuilder = |
| DefaultExplicit.builder().explicitRouteObjects(routeObjects); |
| |
| return new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf. |
| te.rev20160705.ietfte.p2pprimarypathparams.DefaultState |
| .StateBuilder() |
| .type(explicitBuilder.build()) |
| .pathNamedConstraint(DEFAULT_PATH_CONSTRAINT) |
| .noCspf(DEFAULT_CSPF_STATE) |
| .lockdown(DEFAULT_LOCKDOWN_STATE) |
| .build(); |
| } |
| |
| private static ExplicitRouteObjects |
| te2YangRouteSubobject(TeRouteSubobject routeSubobject) { |
| |
| TeRouteSubobject.Type type = routeSubobject.type(); |
| UnnumberedLink yanglink = null; |
| //TODO implement other kind of TeRouteSubobject type |
| if (type == UNNUMBERED_LINK) { |
| DefaultTeRouteUnnumberedLink unnumberedLink = |
| (DefaultTeRouteUnnumberedLink) routeSubobject; |
| TeNodeKey nodeKey = unnumberedLink.node(); |
| TtpKey ttpKey = unnumberedLink.ttp(); |
| |
| yanglink = DefaultUnnumberedLink.builder() |
| .routerId(longToIp(nodeKey.teNodeId())) |
| .interfaceId(ttpKey.ttpId()) |
| .build(); |
| |
| } |
| |
| //TODO implement other kind of explicitRoute usage type |
| return DefaultExplicitRouteObjects.builder() |
| .type(yanglink) |
| .explicitRouteUsage(RouteIncludeEro.class) |
| .build(); |
| } |
| |
| /** |
| * Converts a YANG TE tunnel defined in the YANG model to a specific TE |
| * tunnel defined in the TE tunnel APP. |
| * |
| * @param tunnel yang tunnel object |
| * @return default Te tunnel defined in TE tunnel APP |
| */ |
| public static DefaultTeTunnel yang2TeTunnel(org.onosproject.yang.gen.v1. |
| urn.ietf.params.xml. |
| ns.yang.ietf.te. |
| rev20160705.ietfte. |
| tunnelsgrouping. |
| tunnels.Tunnel |
| tunnel, |
| TeTopologyKey topologyKey) { |
| //get config info |
| Config config = tunnel.config(); |
| |
| //build basic attribute, node and ttp |
| TeNodeKey srcNodeKey = new TeNodeKey(topologyKey, ipToLong(config.source())); |
| TeNodeKey dstNodeKey = new TeNodeKey(topologyKey, ipToLong(config.destination())); |
| |
| TtpKey srcTtpKey = new TtpKey(srcNodeKey, bytesToLong(config.srcTpId())); |
| TtpKey dstTtpKey = new TtpKey(srcNodeKey, bytesToLong(config.dstTpId())); |
| |
| //check if paths have been set |
| List<PrimaryPaths> primaryPaths = tunnel.primaryPaths(); |
| List<TePath> paths = new ArrayList<>(); |
| primaryPaths.forEach(primaryPath -> paths.add( |
| yang2TePrimaryPaths(primaryPath, topologyKey))); |
| |
| //build the te tunnel |
| DefaultTeTunnel.Builder builder = new DefaultTeTunnel.Builder(); |
| |
| return builder.teTunnelKey(new TeTunnelKey(topologyKey, config.identifier())) |
| .name(config.name()) |
| .type(yang2TeTunnelType(config.type())) |
| .lspProtectionType(yang2TeProtectionType(config.lspProtectionType())) |
| .adminState(yang2TeStateType(config.adminStatus())) |
| .srcNode(srcNodeKey) |
| .dstNode(dstNodeKey) |
| .srcTp(srcTtpKey) |
| .dstTp(dstTtpKey) |
| .primaryPaths(paths).build(); |
| } |
| |
| private static TePath yang2TePrimaryPaths(PrimaryPaths primaryPath, |
| TeTopologyKey topologyKey) { |
| org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te. |
| rev20160705.ietfte.p2pprimarypathparams.Config |
| pathConfig = primaryPath.config(); |
| |
| TePath tePath; |
| TePath.Type tePathType = null; |
| Type type = pathConfig.type(); |
| |
| if (type == null) { |
| return new DefaultTePath(TePath.Type.DYNAMIC, |
| Lists.newArrayList(), |
| Lists.newArrayList(), |
| Lists.newArrayList()); |
| } |
| |
| Class<? extends Type> typeClass = type.getClass(); |
| |
| List<TeRouteSubobject> routeSubobjects = new ArrayList<>(); |
| |
| if (typeClass.isAssignableFrom(DefaultExplicit.class)) { |
| DefaultExplicit explicitPath = (DefaultExplicit) type; |
| explicitPath |
| .explicitRouteObjects() |
| .forEach(o -> routeSubobjects.add( |
| yang2TeRouteSubobject(o, topologyKey))); |
| tePathType = TePath.Type.EXPLICIT; |
| |
| } else if (typeClass.isAssignableFrom(DefaultDynamic.class)) { |
| tePathType = TePath.Type.DYNAMIC; |
| } |
| |
| tePath = new DefaultTePath(tePathType, |
| Lists.newArrayList(), |
| routeSubobjects, |
| Lists.newArrayList()); |
| return tePath; |
| } |
| |
| private static TeRouteSubobject |
| yang2TeRouteSubobject(ExplicitRouteObjects routeObject, |
| TeTopologyKey topologyKey) { |
| |
| //TODO implement other types of route type |
| DefaultUnnumberedLink type = (DefaultUnnumberedLink) routeObject.type(); |
| TeNodeKey nodeKey = new TeNodeKey(topologyKey, ipToLong(type.routerId())); |
| TtpKey tpId = new TtpKey(nodeKey, type.interfaceId()); |
| return new DefaultTeRouteUnnumberedLink(nodeKey, tpId); |
| } |
| |
| private static TeTunnel.Type yang2TeTunnelType(Class type) { |
| TeTunnel.Type tunnelType = null; |
| if (type.isAssignableFrom(TunnelP2Mp.class)) { |
| tunnelType = TeTunnel.Type.P2MP; |
| } else if (type.isAssignableFrom(TunnelP2p.class)) { |
| tunnelType = TeTunnel.Type.P2P; |
| } else if (type.isAssignableFrom(PathSignalingRsvpte.class)) { |
| tunnelType = TeTunnel.Type.PATH_SIGNALING_RSVPTE; |
| } else if (type.isAssignableFrom(PathSignalingSr.class)) { |
| tunnelType = TeTunnel.Type.PATH_SIGNALING_SR; |
| } |
| return tunnelType; |
| } |
| |
| |
| private static Class<? extends TunnelType> te2YangTunnelType(TeTunnel.Type type) { |
| Class<? extends TunnelType> tunnelType = null; |
| switch (type) { |
| |
| case P2P: |
| tunnelType = TunnelP2p.class; |
| break; |
| case P2MP: |
| tunnelType = TunnelP2Mp.class; |
| break; |
| case PATH_SIGNALING_RSVPTE: |
| tunnelType = PathSignalingRsvpte.class; |
| |
| break; |
| case PATH_SIGNALING_SR: |
| tunnelType = PathSignalingSr.class; |
| break; |
| default: |
| log.error("Unknown te tunnel type {}", type.toString()); |
| } |
| return tunnelType; |
| } |
| |
| private static LspProtectionType |
| yang2TeProtectionType(Class<? extends LspProtType> protType) { |
| LspProtectionType type = null; |
| if (protType.isAssignableFrom(LspProt1Forn.class)) { |
| type = LspProtectionType.LSP_PROT_1_FOR_N; |
| } else if (protType.isAssignableFrom(LspProtBidir1To1.class)) { |
| type = LspProtectionType.LSP_PROT_BIDIR_1_TO_1; |
| } else if (protType.isAssignableFrom(LspProtReroute.class)) { |
| type = LspProtectionType.LSP_PROT_REROUTE; |
| } else if (protType.isAssignableFrom(LspProtRerouteExtra.class)) { |
| type = LspProtectionType.LSP_PROT_REROUTE_EXTRA; |
| } else if (protType.isAssignableFrom(LspProtUnidir1To1.class)) { |
| type = LspProtectionType.LSP_PROT_UNIDIR_1_TO_1; |
| } else if (protType.isAssignableFrom(LspProtUnprotected.class)) { |
| type = LspProtectionType.LSP_PROT_UNPROTECTED; |
| } |
| return type; |
| } |
| |
| private static Class<? extends LspProtType> |
| te2YangProtectionType(LspProtectionType protType) { |
| Class<? extends LspProtType> type = null; |
| switch (protType) { |
| |
| case LSP_PROT_UNPROTECTED: |
| type = LspProtUnprotected.class; |
| break; |
| case LSP_PROT_REROUTE: |
| type = LspProtReroute.class; |
| break; |
| case LSP_PROT_REROUTE_EXTRA: |
| type = LspProtRerouteExtra.class; |
| break; |
| case LSP_PROT_UNIDIR_1_TO_1: |
| type = LspProtUnidir1To1.class; |
| break; |
| case LSP_PROT_BIDIR_1_TO_1: |
| type = LspProtBidir1To1.class; |
| break; |
| case LSP_PROT_1_FOR_N: |
| type = LspProt1Forn.class; |
| break; |
| default: |
| log.error("Unknown te tunnel type {}", protType.toString()); |
| } |
| return type; |
| } |
| |
| private static TeTunnel.State |
| yang2TeStateType(Class<? extends org.onosproject.yang.gen.v1.urn.ietf. |
| params.xml.ns.yang.ietf.te.types. |
| rev20160705.ietftetypes.StateType> stateType) { |
| TeTunnel.State teStateType = null; |
| if (stateType.isAssignableFrom(StateUp.class)) { |
| teStateType = TeTunnel.State.UP; |
| } else if (stateType.isAssignableFrom(StateDown.class)) { |
| teStateType = TeTunnel.State.DOWN; |
| } |
| return teStateType; |
| } |
| |
| private static Class<? extends org.onosproject.yang.gen.v1.urn.ietf.params. |
| xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.StateType> |
| te2YangStateType(TeTunnel.State stateType) { |
| Class<? extends org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang. |
| ietf.te.types.rev20160705.ietftetypes.StateType> state = null; |
| |
| switch (stateType) { |
| |
| case DOWN: |
| state = StateDown.class; |
| break; |
| case UP: |
| state = StateUp.class; |
| break; |
| default: |
| log.error("Unknown te tunnel type {}", stateType.toString()); |
| |
| } |
| return state; |
| } |
| } |