Java tutorial
/* * Copyright (c) 2013 Cisco Systems, Inc. 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.protocol.bgp.linkstate.nlri; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import org.opendaylight.protocol.bgp.linkstate.spi.TlvUtil; import org.opendaylight.protocol.bgp.parser.BGPParsingException; import org.opendaylight.protocol.bgp.parser.spi.NlriParser; import org.opendaylight.protocol.bgp.parser.spi.NlriSerializer; import org.opendaylight.protocol.util.Ipv4Util; import org.opendaylight.protocol.util.Ipv6Util; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Identifier; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NlriType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.RouteDistinguisher; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.ObjectType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.destination.CLinkstateDestination; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.destination.CLinkstateDestinationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.LinkCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.LinkCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.NodeCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.NodeCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.PrefixCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.PrefixCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.TeLspCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.TeLspCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.link._case.LinkDescriptors; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.link._case.LocalNodeDescriptors; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.link._case.RemoteNodeDescriptors; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.node._case.NodeDescriptors; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.prefix._case.AdvertisingNodeDescriptors; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.prefix._case.PrefixDescriptors; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.AddressFamily; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.address.family.Ipv4CaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.address.family.Ipv6CaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstateCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.linkstate._case.DestinationLinkstateBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Attributes; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutes; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.LspId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.TunnelId; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Parser and serializer for Linkstate NLRI. */ public final class LinkstateNlriParser implements NlriParser, NlriSerializer { private static final Logger LOG = LoggerFactory.getLogger(LinkstateNlriParser.class); private static final int ROUTE_DISTINGUISHER_LENGTH = 8; private static final int PROTOCOL_ID_LENGTH = 1; private static final int IDENTIFIER_LENGTH = 8; private static final int TYPE_LENGTH = 2; private static final int LENGTH_SIZE = 2; private static final int LOCAL_NODE_DESCRIPTORS_TYPE = 256; private static final int REMOTE_NODE_DESCRIPTORS_TYPE = 257; @VisibleForTesting public static final NodeIdentifier OBJECT_TYPE_NID = new NodeIdentifier(ObjectType.QNAME); @VisibleForTesting public static final NodeIdentifier NODE_DESCRIPTORS_NID = new NodeIdentifier(NodeDescriptors.QNAME); @VisibleForTesting public static final NodeIdentifier LOCAL_NODE_DESCRIPTORS_NID = new NodeIdentifier(LocalNodeDescriptors.QNAME); @VisibleForTesting public static final NodeIdentifier REMOTE_NODE_DESCRIPTORS_NID = new NodeIdentifier( RemoteNodeDescriptors.QNAME); @VisibleForTesting public static final NodeIdentifier ADVERTISING_NODE_DESCRIPTORS_NID = new NodeIdentifier( AdvertisingNodeDescriptors.QNAME); @VisibleForTesting public static final NodeIdentifier PREFIX_DESCRIPTORS_NID = new NodeIdentifier(PrefixDescriptors.QNAME); @VisibleForTesting public static final NodeIdentifier LINK_DESCRIPTORS_NID = new NodeIdentifier(LinkDescriptors.QNAME); @VisibleForTesting public static final NodeIdentifier TE_LSP_NID = new NodeIdentifier(TeLspCase.QNAME); @VisibleForTesting public static final NodeIdentifier DISTINGUISHER_NID = new NodeIdentifier( QName.create(CLinkstateDestination.QNAME, "route-distinguisher").intern()); @VisibleForTesting public static final NodeIdentifier PROTOCOL_ID_NID = new NodeIdentifier( QName.create(CLinkstateDestination.QNAME, "protocol-id").intern()); @VisibleForTesting public static final NodeIdentifier IDENTIFIER_NID = new NodeIdentifier( QName.create(CLinkstateDestination.QNAME, "identifier").intern()); private final boolean isVpn; public LinkstateNlriParser(final boolean isVpn) { this.isVpn = isVpn; } private static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NodeIdentifier parseLink( final CLinkstateDestinationBuilder builder, final ByteBuf buffer, final LocalNodeDescriptors localDescriptors) throws BGPParsingException { final int type = buffer.readUnsignedShort(); final int length = buffer.readUnsignedShort(); final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NodeIdentifier remote = null; RemoteNodeDescriptors remoteDescriptors = null; if (type == REMOTE_NODE_DESCRIPTORS_TYPE) { remoteDescriptors = (RemoteNodeDescriptors) NodeNlriParser .parseNodeDescriptors(buffer.readSlice(length), NlriType.Link, false); } builder.setObjectType(new LinkCaseBuilder().setLocalNodeDescriptors(localDescriptors) .setRemoteNodeDescriptors(remoteDescriptors) .setLinkDescriptors(LinkNlriParser.parseLinkDescriptors(buffer.slice())).build()); return remote; } /** * Parses common parts for Link State Nodes, Links and Prefixes, that includes protocol ID and identifier tlv. * * @param nlri as byte array * @param isVpn flag which determines that destination has route distinguisher * @return {@link CLinkstateDestination} * @throws BGPParsingException if parsing was unsuccessful */ public static List<CLinkstateDestination> parseNlri(final ByteBuf nlri, final boolean isVpn) throws BGPParsingException { final List<CLinkstateDestination> dests = new ArrayList<>(); while (nlri.isReadable()) { final CLinkstateDestinationBuilder builder = new CLinkstateDestinationBuilder(); final NlriType type = NlriType.forValue(nlri.readUnsignedShort()); // length means total length of the tlvs including route distinguisher not including the type field final int length = nlri.readUnsignedShort(); RouteDistinguisher distinguisher = null; if (isVpn) { // this parses route distinguisher distinguisher = new RouteDistinguisher(BigInteger.valueOf(nlri.readLong())); builder.setDistinguisher(distinguisher); } // parse source protocol final ProtocolId sp = ProtocolId.forValue(nlri.readByte()); builder.setProtocolId(sp); // parse identifier final Identifier identifier = new Identifier(BigInteger.valueOf(nlri.readLong())); builder.setIdentifier(identifier); // if we are dealing with linkstate nodes/links, parse local node descriptor org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NodeIdentifier localDescriptor = null; ByteBuf rest = null; if (!type.equals(NlriType.Ipv4TeLsp) && !type.equals(NlriType.Ipv6TeLsp)) { final int localtype = nlri.readUnsignedShort(); final int locallength = nlri.readUnsignedShort(); if (localtype == LOCAL_NODE_DESCRIPTORS_TYPE) { localDescriptor = NodeNlriParser.parseNodeDescriptors(nlri.readSlice(locallength), type, true); } final int restLength = length - (isVpn ? ROUTE_DISTINGUISHER_LENGTH : 0) - PROTOCOL_ID_LENGTH - IDENTIFIER_LENGTH - TYPE_LENGTH - LENGTH_SIZE - locallength; LOG.trace("Restlength {}", restLength); rest = nlri.readSlice(restLength); } setObjectType(nlri, builder, type, localDescriptor, rest); dests.add(builder.build()); } return dests; } private static void setObjectType(final ByteBuf nlri, final CLinkstateDestinationBuilder builder, final NlriType type, final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NodeIdentifier localDescriptor, final ByteBuf rest) throws BGPParsingException { switch (type) { case Link: parseLink(builder, rest, (LocalNodeDescriptors) localDescriptor); break; case Ipv4Prefix: builder.setObjectType(new PrefixCaseBuilder() .setAdvertisingNodeDescriptors((AdvertisingNodeDescriptors) localDescriptor) .setPrefixDescriptors(PrefixNlriParser.parsePrefixDescriptors(rest, true)).build()); break; case Ipv6Prefix: builder.setObjectType(new PrefixCaseBuilder() .setAdvertisingNodeDescriptors((AdvertisingNodeDescriptors) localDescriptor) .setPrefixDescriptors(PrefixNlriParser.parsePrefixDescriptors(rest, false)).build()); break; case Node: // node nlri is already parsed as it contains only the common fields for node and link nlri builder.setObjectType( new NodeCaseBuilder().setNodeDescriptors((NodeDescriptors) localDescriptor).build()); break; case Ipv4TeLsp: builder.setObjectType(parseIpv4TeLsp(nlri)); break; case Ipv6TeLsp: builder.setObjectType(parseIpv6TeLsp(nlri)); break; default: break; } } private static TeLspCase parseIpv6TeLsp(final ByteBuf nlri) { final Ipv6CaseBuilder ipv6Builder = new Ipv6CaseBuilder(); ipv6Builder.setIpv6TunnelSenderAddress(Ipv6Util.addressForByteBuf(nlri)); final TunnelId tunnelId6 = new TunnelId(nlri.readUnsignedShort()); final LspId lspId6 = new LspId((long) nlri.readUnsignedShort()); ipv6Builder.setIpv6TunnelEndpointAddress(Ipv6Util.addressForByteBuf(nlri)); return new TeLspCaseBuilder().setAddressFamily(ipv6Builder.build()).setLspId(lspId6).setTunnelId(tunnelId6) .build(); } private static TeLspCase parseIpv4TeLsp(final ByteBuf nlri) { final Ipv4CaseBuilder ipv4Builder = new Ipv4CaseBuilder(); ipv4Builder.setIpv4TunnelSenderAddress(Ipv4Util.addressForByteBuf(nlri)); final TunnelId tunnelId = new TunnelId(nlri.readUnsignedShort()); final LspId lspId = new LspId((long) nlri.readUnsignedShort()); ipv4Builder.setIpv4TunnelEndpointAddress(Ipv4Util.addressForByteBuf(nlri)); return new TeLspCaseBuilder().setAddressFamily(ipv4Builder.build()).setLspId(lspId).setTunnelId(tunnelId) .build(); } @Override public void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder) throws BGPParsingException { if (!nlri.isReadable()) { return; } final List<CLinkstateDestination> dst = parseNlri(nlri, this.isVpn); builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType( new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCaseBuilder() .setDestinationLinkstate( new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.linkstate._case.DestinationLinkstateBuilder() .setCLinkstateDestination(dst).build()) .build()) .build()); } @Override public void parseNlri(final ByteBuf nlri, final MpReachNlriBuilder builder) throws BGPParsingException { if (!nlri.isReadable()) { return; } final List<CLinkstateDestination> dst = parseNlri(nlri, this.isVpn); builder.setAdvertizedRoutes( new AdvertizedRoutesBuilder() .setDestinationType(new DestinationLinkstateCaseBuilder() .setDestinationLinkstate( new DestinationLinkstateBuilder().setCLinkstateDestination(dst).build()) .build()) .build()); } /** * Serializes Linkstate NLRI to byte array. We need this as NLRI serves as a key in upper layers. * * @param destination Linkstate NLRI to be serialized * @param buffer where Linkstate NLRI will be serialized */ public static void serializeNlri(final CLinkstateDestination destination, final ByteBuf buffer) { final ByteBuf nlriByteBuf = Unpooled.buffer(); if (destination.getDistinguisher() != null) { nlriByteBuf.writeBytes(destination.getDistinguisher().getValue().toByteArray()); } nlriByteBuf.writeByte(destination.getProtocolId().getIntValue()); nlriByteBuf.writeLong(destination.getIdentifier().getValue().longValue()); final ByteBuf ldescs = Unpooled.buffer(); final ObjectType ot = destination.getObjectType(); NlriType nlriType = null; if (ot instanceof PrefixCase) { final PrefixCase pCase = (PrefixCase) destination.getObjectType(); NodeNlriParser.serializeNodeIdentifier(pCase.getAdvertisingNodeDescriptors(), ldescs); TlvUtil.writeTLV(LOCAL_NODE_DESCRIPTORS_TYPE, ldescs, nlriByteBuf); if (pCase.getPrefixDescriptors() != null) { PrefixNlriParser.serializePrefixDescriptors(pCase.getPrefixDescriptors(), nlriByteBuf); if (pCase.getPrefixDescriptors().getIpReachabilityInformation().getIpv4Prefix() != null) { nlriType = NlriType.Ipv4Prefix; } else { nlriType = NlriType.Ipv6Prefix; } } } else if (ot instanceof LinkCase) { final LinkCase lCase = (LinkCase) destination.getObjectType(); NodeNlriParser.serializeNodeIdentifier(lCase.getLocalNodeDescriptors(), ldescs); NodeNlriParser.serializeEpeNodeDescriptors(lCase.getLocalNodeDescriptors(), ldescs); TlvUtil.writeTLV(LOCAL_NODE_DESCRIPTORS_TYPE, ldescs, nlriByteBuf); final ByteBuf rdescs = Unpooled.buffer(); NodeNlriParser.serializeNodeIdentifier(lCase.getRemoteNodeDescriptors(), rdescs); NodeNlriParser.serializeEpeNodeDescriptors(lCase.getRemoteNodeDescriptors(), rdescs); TlvUtil.writeTLV(REMOTE_NODE_DESCRIPTORS_TYPE, rdescs, nlriByteBuf); if (lCase.getLinkDescriptors() != null) { LinkNlriParser.serializeLinkDescriptors(lCase.getLinkDescriptors(), nlriByteBuf); } nlriType = NlriType.Link; } else if (ot instanceof NodeCase) { final NodeCase nCase = (NodeCase) destination.getObjectType(); NodeNlriParser.serializeNodeIdentifier(nCase.getNodeDescriptors(), ldescs); TlvUtil.writeTLV(LOCAL_NODE_DESCRIPTORS_TYPE, ldescs, nlriByteBuf); nlriType = NlriType.Node; } else if (ot instanceof TeLspCase) { final TeLspCase teLSP = (TeLspCase) destination.getObjectType(); final AddressFamily afi = teLSP.getAddressFamily(); nlriType = TeLspNlriParser.serializeIpvTSA(afi, ldescs); TeLspNlriParser.serializeTunnelID(teLSP.getTunnelId(), ldescs); TeLspNlriParser.serializeLspID(teLSP.getLspId(), ldescs); TeLspNlriParser.serializeTEA(afi, ldescs); } else { LOG.warn("Unknown NLRI Type."); } TlvUtil.writeTLV(nlriType.getIntValue(), nlriByteBuf, buffer); } @Override public void serializeAttribute(final DataObject attribute, final ByteBuf byteAggregator) { Preconditions.checkArgument(attribute instanceof Attributes, "Attribute parameter is not a PathAttribute object."); final Attributes pathAttributes = (Attributes) attribute; final Attributes1 pathAttributes1 = pathAttributes.getAugmentation(Attributes1.class); final Attributes2 pathAttributes2 = pathAttributes.getAugmentation(Attributes2.class); if (pathAttributes1 != null) { final AdvertizedRoutes routes = (pathAttributes1.getMpReachNlri()).getAdvertizedRoutes(); if (routes != null && routes .getDestinationType() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstateCase) { final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstateCase linkstateCase = (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstateCase) routes .getDestinationType(); for (final CLinkstateDestination cLinkstateDestination : linkstateCase.getDestinationLinkstate() .getCLinkstateDestination()) { serializeNlri(cLinkstateDestination, byteAggregator); } } } else if (pathAttributes2 != null) { final MpUnreachNlri mpUnreachNlri = pathAttributes2.getMpUnreachNlri(); if (mpUnreachNlri.getWithdrawnRoutes() != null && mpUnreachNlri.getWithdrawnRoutes() .getDestinationType() instanceof DestinationLinkstateCase) { final DestinationLinkstateCase linkstateCase = (DestinationLinkstateCase) mpUnreachNlri .getWithdrawnRoutes().getDestinationType(); for (final CLinkstateDestination cLinkstateDestination : linkstateCase.getDestinationLinkstate() .getCLinkstateDestination()) { serializeNlri(cLinkstateDestination, byteAggregator); } } } } // FIXME : use codec private static int domProtocolIdValue(final String protocolId) { switch (protocolId) { case "unknown": return ProtocolId.Unknown.getIntValue(); case "isis-level1": return ProtocolId.IsisLevel1.getIntValue(); case "isis-level2": return ProtocolId.IsisLevel2.getIntValue(); case "ospf": return ProtocolId.Ospf.getIntValue(); case "direct": return ProtocolId.Direct.getIntValue(); case "static": return ProtocolId.Static.getIntValue(); case "rsvpte": return ProtocolId.RsvpTe.getIntValue(); case "bgp-epe": return ProtocolId.BgpEpe.getIntValue(); case "segment-routing": return ProtocolId.SegmentRouting.getIntValue(); default: return 0; } } public static CLinkstateDestination extractLinkstateDestination( final DataContainerNode<? extends PathArgument> linkstate) { final CLinkstateDestinationBuilder builder = new CLinkstateDestinationBuilder(); serializeCommonParts(builder, linkstate); final ChoiceNode objectType = (ChoiceNode) linkstate.getChild(OBJECT_TYPE_NID).get(); if (!builder.getProtocolId().equals(ProtocolId.RsvpTe)) { if (objectType.getChild(ADVERTISING_NODE_DESCRIPTORS_NID).isPresent()) { serializeAdvertisedNodeDescriptor(builder, objectType); } else if (objectType.getChild(LOCAL_NODE_DESCRIPTORS_NID).isPresent()) { serializeLocalNodeDescriptor(builder, objectType); } else if (objectType.getChild(NODE_DESCRIPTORS_NID).isPresent()) { serializeNodeDescriptor(builder, objectType); } else { LOG.warn("Unknown Object Type."); } } else if (objectType.getChild(TE_LSP_NID).isPresent()) { builder.setObjectType( TeLspNlriParser.serializeTeLsp((ContainerNode) objectType.getChild(TE_LSP_NID).get())); } return builder.build(); } private static void serializeNodeDescriptor(final CLinkstateDestinationBuilder builder, final ChoiceNode objectType) { final NodeCaseBuilder nodeBuilder = new NodeCaseBuilder(); // node descriptors nodeBuilder.setNodeDescriptors(NodeNlriParser .serializeNodeDescriptors((ContainerNode) objectType.getChild(NODE_DESCRIPTORS_NID).get())); builder.setObjectType(nodeBuilder.build()); } private static void serializeLocalNodeDescriptor(final CLinkstateDestinationBuilder builder, final ChoiceNode objectType) { // link local node descriptors final LinkCaseBuilder linkBuilder = new LinkCaseBuilder(); linkBuilder.setLocalNodeDescriptors(NodeNlriParser.serializeLocalNodeDescriptors( (ContainerNode) objectType.getChild(LOCAL_NODE_DESCRIPTORS_NID).get())); // link remote node descriptors if (objectType.getChild(REMOTE_NODE_DESCRIPTORS_NID).isPresent()) { linkBuilder.setRemoteNodeDescriptors(NodeNlriParser.serializeRemoteNodeDescriptors( (ContainerNode) objectType.getChild(REMOTE_NODE_DESCRIPTORS_NID).get())); } // link descriptors final Optional<DataContainerChild<? extends PathArgument, ?>> linkDescriptors = objectType .getChild(LINK_DESCRIPTORS_NID); if (linkDescriptors.isPresent()) { linkBuilder.setLinkDescriptors( LinkNlriParser.serializeLinkDescriptors((ContainerNode) linkDescriptors.get())); } builder.setObjectType(linkBuilder.build()); } private static void serializeAdvertisedNodeDescriptor(final CLinkstateDestinationBuilder builder, final ChoiceNode objectType) { // prefix node descriptors final PrefixCaseBuilder prefixBuilder = new PrefixCaseBuilder(); prefixBuilder.setAdvertisingNodeDescriptors(NodeNlriParser.serializeAdvNodeDescriptors( (ContainerNode) objectType.getChild(ADVERTISING_NODE_DESCRIPTORS_NID).get())); // prefix descriptors final Optional<DataContainerChild<? extends PathArgument, ?>> prefixDescriptors = objectType .getChild(PREFIX_DESCRIPTORS_NID); if (prefixDescriptors.isPresent()) { prefixBuilder.setPrefixDescriptors( PrefixNlriParser.serializePrefixDescriptors((ContainerNode) prefixDescriptors.get())); } builder.setObjectType(prefixBuilder.build()); } private static void serializeCommonParts(final CLinkstateDestinationBuilder builder, final DataContainerNode<? extends PathArgument> linkstate) { // serialize common parts final Optional<DataContainerChild<? extends PathArgument, ?>> distinguisher = linkstate .getChild(DISTINGUISHER_NID); if (distinguisher.isPresent()) { builder.setDistinguisher(new RouteDistinguisher((BigInteger) distinguisher.get().getValue())); } final Optional<DataContainerChild<? extends PathArgument, ?>> protocolId = linkstate .getChild(PROTOCOL_ID_NID); // DOM representation contains values as are in the model, not as are in generated enum if (protocolId.isPresent()) { builder.setProtocolId(ProtocolId.forValue(domProtocolIdValue((String) protocolId.get().getValue()))); } final Optional<DataContainerChild<? extends PathArgument, ?>> identifier = linkstate .getChild(IDENTIFIER_NID); if (identifier.isPresent()) { builder.setIdentifier(new Identifier((BigInteger) identifier.get().getValue())); } } }