BUG-113: Start rework of ParameterRegistry 29/1829/7
authorRobert Varga <rovarga@cisco.com>
Fri, 11 Oct 2013 07:08:02 +0000 (09:08 +0200)
committerRobert Varga <rovarga@cisco.com>
Sun, 13 Oct 2013 06:01:09 +0000 (08:01 +0200)
Change-Id: I4d04707fdb7a8dfbfbc3f92e6290f4883b1bbfb5
Signed-off-by: Robert Varga <rovarga@cisco.com>
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPOpenMessageParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/open/BGPParameterParser.java [deleted file]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/open/CapabilityParameterParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/open/SimpleParameterRegistry.java [moved from bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/open/ParameterRegistryImpl.java with 50% similarity]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/PathAttributeParser.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/ParameterParser.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/ParameterRegistry.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/ParameterUtil.java [new file with mode: 0644]

index 03d0e1ee1678e7102b1cdc8077a70f6e9b75ba6a..80dcce9554c80ec1fc87a619ddb3865e47b19732 100644 (file)
@@ -15,10 +15,11 @@ import java.util.Map.Entry;
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
-import org.opendaylight.protocol.bgp.parser.impl.message.open.BGPParameterParser;
+import org.opendaylight.protocol.bgp.parser.impl.message.open.SimpleParameterRegistry;
 import org.opendaylight.protocol.bgp.parser.spi.MessageParser;
 import org.opendaylight.protocol.bgp.parser.spi.MessageSerializer;
 import org.opendaylight.protocol.bgp.parser.spi.MessageUtil;
+import org.opendaylight.protocol.bgp.parser.spi.ParameterRegistry;
 import org.opendaylight.protocol.concepts.Ipv4Util;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
@@ -59,6 +60,9 @@ public final class BGPOpenMessageParser implements MessageParser, MessageSeriali
 
        private static final int BGP_VERSION = 4;
 
+       @Deprecated
+       private static final ParameterRegistry reg = SimpleParameterRegistry.INSTANCE;
+
        private BGPOpenMessageParser() {
 
        }
@@ -83,9 +87,11 @@ public final class BGPOpenMessageParser implements MessageParser, MessageSeriali
 
                if (open.getBgpParameters() != null) {
                        for (final BgpParameters param : open.getBgpParameters()) {
-                               final byte[] p = BGPParameterParser.put(param);
-                               optParams.put(p, p.length);
-                               optParamsLength += p.length;
+                               final byte[] p = reg.serializeParameter(param);
+                               if (p != null) {
+                                       optParams.put(p, p.length);
+                                       optParamsLength += p.length;
+                               }
                        }
                }
 
@@ -172,14 +178,45 @@ public final class BGPOpenMessageParser implements MessageParser, MessageSeriali
 
                List<BgpParameters> optParams = Lists.newArrayList();
                if (optLength > 0) {
+                       fillParams(ByteArray.subByte(body, MIN_MSG_LENGTH, optLength), optParams);
+               }
+               logger.trace("Open message was parsed: AS = {}, holdTimer = {}, bgpId = {}, optParams = {}", as, holdTime, bgpId, optParams);
+               return new OpenBuilder().setMyAsNumber(as.getValue().intValue()).setHoldTimer((int) holdTime).setBgpIdentifier(bgpId).setBgpParameters(
+                               optParams).build();
+       }
+
+       private void fillParams(final byte[] bytes, final List<BgpParameters> params) throws BGPDocumentedException {
+               if (bytes == null || bytes.length == 0) {
+                       throw new IllegalArgumentException("Byte array cannot be null or empty.");
+               }
+
+               logger.trace("Started parsing of BGP parameter: {}", Arrays.toString(bytes));
+               int byteOffset = 0;
+               while (byteOffset < bytes.length) {
+                       if (byteOffset + 2 >= bytes.length) {
+                               // FIXME: throw a BGPDocumentedException here?
+                               throw new IllegalArgumentException("Malformed parameter encountered (" + (bytes.length - byteOffset) + " bytes left)");
+                       }
+
+                       final int paramType = UnsignedBytes.toInt(bytes[byteOffset++]);
+                       final int paramLength = UnsignedBytes.toInt(bytes[byteOffset++]);
+                       final byte[] paramBody = ByteArray.subByte(bytes, byteOffset, paramLength);
+                       byteOffset += paramLength;
+
+                       final BgpParameters param;
                        try {
-                               optParams = BGPParameterParser.parse(ByteArray.subByte(body, MIN_MSG_LENGTH, optLength));
+                               param = reg.parseParameter(paramType, paramBody);
                        } catch (final BGPParsingException e) {
                                throw new BGPDocumentedException("Optional parameter not parsed: ." + e.getMessage(), BGPError.UNSPECIFIC_OPEN_ERROR);
                        }
+
+                       if (param != null) {
+                               params.add(param);
+                       } else {
+                               logger.debug("Ignoring BGP Parameter type: {}", paramType);
+                       }
                }
-               logger.trace("Open message was parsed: AS = {}, holdTimer = {}, bgpId = {}, optParams = {}", as, holdTime, bgpId, optParams);
-               return new OpenBuilder().setMyAsNumber(as.getValue().intValue()).setHoldTimer((int) holdTime).setBgpIdentifier(bgpId).setBgpParameters(
-                               optParams).build();
+
+               logger.trace("Parsed BGP parameters: {}", Arrays.toString(params.toArray()));
        }
 }
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/open/BGPParameterParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/open/BGPParameterParser.java
deleted file mode 100644 (file)
index a26a37b..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.parser.impl.message.open;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
-import org.opendaylight.protocol.bgp.parser.BGPParsingException;
-import org.opendaylight.protocol.util.ByteArray;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.BgpParameters;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.BgpParametersBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.bgp.parameters.CParameters;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Lists;
-import com.google.common.primitives.UnsignedBytes;
-
-/**
- * Parser for parameters in BGP Open message.
- */
-public final class BGPParameterParser {
-
-       private static final Logger logger = LoggerFactory.getLogger(BGPParameterParser.class);
-
-       private static final int TYPE_SIZE = 1; // bytes
-       private static final int LENGTH_SIZE = 1; // bytes
-       private static final int CAPABILITIES_OPT_PARAM_TYPE = 2;
-
-       private BGPParameterParser() {
-
-       }
-
-       /**
-        * Serializes given BGP Parameter to byte array. Currently supported only Capability parameters.
-        * 
-        * @param param BGP Parameter to be serialized
-        * @return BGP Parameter converted to byte array
-        */
-       public static byte[] put(final BgpParameters param) {
-               if (param == null) {
-                       throw new IllegalArgumentException("BGP Parameter cannot be null");
-               }
-               logger.trace("Started serializing BGPParameter: {}", param);
-
-               byte[] value = null;
-
-               value = CapabilityParameterParser.put(param.getCParameters());
-
-               if (value == null) {
-                       logger.debug("BGP Parameter not supported.");
-                       return new byte[] {};
-               }
-
-               final byte[] bytes = new byte[TYPE_SIZE + LENGTH_SIZE + value.length];
-               System.arraycopy(ByteArray.intToBytes(2), 3, bytes, 0, TYPE_SIZE);
-               System.arraycopy(ByteArray.intToBytes(value.length), 3, bytes, TYPE_SIZE, LENGTH_SIZE);
-               System.arraycopy(value, 0, bytes, TYPE_SIZE + LENGTH_SIZE, value.length);
-               logger.trace("BGP Parameter serialized to: {}", Arrays.toString(bytes));
-               return bytes;
-       }
-
-       /**
-        * Parses given byte array to a list of BGP Parameters. Currently supporting only Capability parameters.
-        * 
-        * @param bytes byte array representing BGP Parameters
-        * @return list of BGP Parameters
-        * @throws BGPParsingException if the parsing was unsuccessful
-        * @throws BGPDocumentedException
-        */
-       public static List<BgpParameters> parse(final byte[] bytes) throws BGPParsingException, BGPDocumentedException {
-               if (bytes == null || bytes.length == 0) {
-                       throw new IllegalArgumentException("Byte array cannot be null or empty.");
-               }
-               logger.trace("Started parsing of BGP parameter: {}", Arrays.toString(bytes));
-               int byteOffset = 0;
-               final List<BgpParameters> params = Lists.newArrayList();
-               while (byteOffset < bytes.length) {
-                       final int paramType = UnsignedBytes.toInt(bytes[byteOffset++]);
-                       final int paramLength = UnsignedBytes.toInt(bytes[byteOffset++]);
-                       if (paramType == CAPABILITIES_OPT_PARAM_TYPE) {
-                               final CParameters cparam = CapabilityParameterParser.parse(ByteArray.subByte(bytes, byteOffset, paramLength));
-                               if (cparam == null) {
-                                       byteOffset += paramLength;
-                                       continue;
-                               }
-                               final BgpParameters param = new BgpParametersBuilder().setCParameters(cparam).build();
-                               if (param != null) {
-                                       params.add(param);
-                               }
-                       } else {
-                               logger.debug("BGP Parameter not recognized. Type: {}", paramType);
-                       }
-                       byteOffset += paramLength;
-               }
-               logger.trace("Parsed BGP parameters: {}", Arrays.toString(params.toArray()));
-               return params;
-       }
-}
index 4534626b0ec9c6ac3a5488d96035a0b8e1fe5d32..8c02c0909f88e9d7a89b07e801982c12a0d456d4 100644 (file)
@@ -11,54 +11,35 @@ import java.util.Arrays;
 
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.CapabilityRegistry;
+import org.opendaylight.protocol.bgp.parser.spi.ParameterParser;
+import org.opendaylight.protocol.bgp.parser.spi.ParameterSerializer;
+import org.opendaylight.protocol.bgp.parser.spi.ParameterUtil;
 import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.BgpParameters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.BgpParametersBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.bgp.parameters.CParameters;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Preconditions;
 import com.google.common.primitives.UnsignedBytes;
 
 /**
  * Parser for BGP Capability Parameter.
  */
-public final class CapabilityParameterParser {
+public final class CapabilityParameterParser implements ParameterParser, ParameterSerializer {
+       public static final int TYPE = 2;
 
        private static final Logger logger = LoggerFactory.getLogger(CapabilityParameterParser.class);
+       private final CapabilityRegistry reg;
 
-       private CapabilityParameterParser() {
-
-       }
-
-       /**
-        * Serializes given BGP Capability Parameter to byte array.
-        * 
-        * @param param BGP Capability to be serialized
-        * @return BGP Capability converted to byte array
-        */
-       public static byte[] put(final CParameters cap) {
-               if (cap == null) {
-                       throw new IllegalArgumentException("BGP Capability cannot be null");
-               }
-               logger.trace("Started serializing BGP Capability: {}", cap);
-
-               byte[] bytes = SimpleCapabilityRegistry.INSTANCE.serializeCapability(cap);
-               if (bytes == null) {
-                       throw new IllegalArgumentException("Unhandled capability " + cap);
-               }
-
-               logger.trace("BGP Parameter serialized to: {}", Arrays.toString(bytes));
-               return bytes;
+       public CapabilityParameterParser(final CapabilityRegistry reg) {
+               this.reg = Preconditions.checkNotNull(reg);
        }
 
-       /**
-        * Parses given byte array to Capability Parameter. Only Multiprotocol capability is supported.
-        * 
-        * @param bytes byte array representing BGP Parameters
-        * @return list of BGP Parameters
-        * @throws BGPParsingException if the parsing was unsuccessful
-        * @throws BGPDocumentedException
-        */
-       public static CParameters parse(final byte[] bytes) throws BGPParsingException, BGPDocumentedException {
+       @Override
+       public BgpParameters parseParameter(final byte[] bytes) throws BGPParsingException, BGPDocumentedException {
                if (bytes == null || bytes.length == 0) {
                        throw new IllegalArgumentException("Byte array cannot be null or empty.");
                }
@@ -68,10 +49,28 @@ public final class CapabilityParameterParser {
                final int capLength = UnsignedBytes.toInt(bytes[byteOffset++]);
                final byte[] paramBody = ByteArray.subByte(bytes, byteOffset, capLength);
 
-               final CParameters ret = SimpleCapabilityRegistry.INSTANCE.parseCapability(capCode, paramBody);
+               final CParameters ret = reg.parseCapability(capCode, paramBody);
                if (ret == null) {
                        logger.debug("Ignoring unsupported capability {}", capCode);
+                       return null;
                }
-               return ret;
+
+               return new BgpParametersBuilder().setCParameters(ret).build();
+       }
+
+       @Override
+       public byte[] serializeParameter(final BgpParameters parameter) {
+               final CParameters cap = parameter.getCParameters();
+
+               logger.trace("Started serializing BGP Capability: {}", cap);
+
+               byte[] bytes = reg.serializeCapability(cap);
+               if (bytes == null) {
+                       throw new IllegalArgumentException("Unhandled capability class" + cap.getImplementedInterface());
+               }
+
+               logger.trace("BGP capability serialized to: {}", Arrays.toString(bytes));
+
+               return ParameterUtil.formatParameter(TYPE, bytes);
        }
 }
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.protocol.bgp.parser.impl.message.open;
 
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.spi.ParameterParser;
 import org.opendaylight.protocol.bgp.parser.spi.ParameterRegistry;
 import org.opendaylight.protocol.bgp.parser.spi.ParameterSerializer;
@@ -16,35 +18,49 @@ import org.opendaylight.yangtools.yang.binding.DataContainer;
 
 import com.google.common.base.Preconditions;
 
-public final class ParameterRegistryImpl extends HandlerRegistry<DataContainer, ParameterParser, ParameterSerializer> implements ParameterRegistry {
+public final class SimpleParameterRegistry implements ParameterRegistry {
        public static final ParameterRegistry INSTANCE;
 
        static {
-               final ParameterRegistry reg = new ParameterRegistryImpl();
+               final ParameterRegistry reg = new SimpleParameterRegistry();
 
-               // FIXME: fix registry
+               final CapabilityParameterParser cpp = new CapabilityParameterParser(SimpleCapabilityRegistry.INSTANCE);
+               reg.registerParameterParser(CapabilityParameterParser.TYPE, cpp);
+               reg.registerParameterSerializer(BgpParameters.class, cpp);
 
                INSTANCE = reg;
        }
 
+       private final HandlerRegistry<DataContainer, ParameterParser, ParameterSerializer> handlers = new HandlerRegistry<>();
+
        @Override
        public AutoCloseable registerParameterParser(final int messageType, final ParameterParser parser) {
                Preconditions.checkArgument(messageType >= 0 && messageType <= 255);
-               return super.registerParser(messageType, parser);
+               return handlers.registerParser(messageType, parser);
        }
 
        @Override
-       public ParameterParser getParameterParser(final int messageType) {
-               return super.getParser(messageType);
+       public AutoCloseable registerParameterSerializer(final Class<? extends BgpParameters> paramClass, final ParameterSerializer serializer) {
+               return handlers.registerSerializer(paramClass, serializer);
        }
 
        @Override
-       public AutoCloseable registerParameterSerializer(final Class<? extends BgpParameters> paramClass, final ParameterSerializer serializer) {
-               return super.registerSerializer(paramClass, serializer);
+       public BgpParameters parseParameter(final int parameterType, final byte[] bytes) throws BGPParsingException, BGPDocumentedException {
+               final ParameterParser parser = handlers.getParser(parameterType);
+               if (parser == null) {
+                       return null;
+               }
+
+               return parser.parseParameter(bytes);
        }
 
        @Override
-       public ParameterSerializer getParameterSerializer(final BgpParameters message) {
-               return super.getSerializer(message.getImplementedInterface());
+       public byte[] serializeParameter(final BgpParameters parameter) {
+               final ParameterSerializer serializer = handlers.getSerializer(parameter.getImplementedInterface());
+               if (serializer == null) {
+                       return null;
+               }
+
+               return serializer.serializeParameter(parameter);
        }
 }
index b9509d9213268dbcef9ef0c2d4392231a1cb5f42..3eb0b78d3c21874472e701affcab56f6d6324efe 100644 (file)
@@ -13,6 +13,7 @@ import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.impl.message.update.AsPathSegmentParser.SegmentType;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeRegistry;
 import org.opendaylight.protocol.concepts.IPv4;
 import org.opendaylight.protocol.concepts.Ipv4Util;
 import org.opendaylight.protocol.util.ByteArray;
@@ -61,6 +62,8 @@ public class PathAttributeParser {
 
        private static final int TYPE_LENGTH = 1;
 
+       private static AttributeRegistry reg = SimpleAttributeRegistry.INSTANCE;
+
        private PathAttributeParser() {
 
        }
@@ -87,7 +90,7 @@ public class PathAttributeParser {
 
                        final byte[] attrBody = ByteArray.subByte(bytes, hdrLength, attrLength);
 
-                       boolean found = SimpleAttributeRegistry.INSTANCE.parseAttribute(UnsignedBytes.toInt(bytes[1]), attrBody, builder);
+                       boolean found = reg.parseAttribute(UnsignedBytes.toInt(bytes[1]), attrBody, builder);
                        if (!optional && !found) {
                                throw new BGPDocumentedException("Well known attribute not recognized.", BGPError.WELL_KNOWN_ATTR_NOT_RECOGNIZED);
                        }
index 6b4c836dca13cd81f3c18def22115f3290775be0..51c6edb6478b70f84fe6975aa53dd1a71b34b9d8 100644 (file)
@@ -7,9 +7,10 @@
  */
 package org.opendaylight.protocol.bgp.parser.spi;
 
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.BgpParameters;
 
 public interface ParameterParser {
-       public BgpParameters parseParameter(final byte[] bytes) throws BGPParsingException;
+       public BgpParameters parseParameter(final byte[] bytes) throws BGPParsingException, BGPDocumentedException;
 }
index ca77a1dfd0e8b726ec884ffe2fb8e3c1ac64fad1..7c3c83cb86178b66f2f0324b4b7646d239577105 100644 (file)
@@ -7,12 +7,14 @@
  */
 package org.opendaylight.protocol.bgp.parser.spi;
 
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.open.BgpParameters;
 
 public interface ParameterRegistry {
        public AutoCloseable registerParameterParser(int parameterType, ParameterParser parser);
-       public ParameterParser getParameterParser(int parameterType);
-
        public AutoCloseable registerParameterSerializer(Class<? extends BgpParameters> paramClass, ParameterSerializer serializer);
-       public ParameterSerializer getParameterSerializer(BgpParameters object);
+
+       public BgpParameters parseParameter(int parameterType, final byte[] bytes) throws BGPParsingException, BGPDocumentedException;
+       public byte[] serializeParameter(final BgpParameters parameter);
 }
diff --git a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/ParameterUtil.java b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/ParameterUtil.java
new file mode 100644 (file)
index 0000000..a331666
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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.parser.spi;
+
+import com.google.common.primitives.UnsignedBytes;
+
+public final class ParameterUtil {
+       private ParameterUtil() {
+
+       }
+
+       public static byte[] formatParameter(final int type, final byte[] value) {
+               final byte[] bytes = new byte[2 + value.length];
+               bytes[0] = UnsignedBytes.checkedCast(type);
+               bytes[1] = UnsignedBytes.checkedCast(value.length);
+               System.arraycopy(value, 0, bytes, 2, value.length);
+               return bytes;
+       }
+}