BUG 4181: Fix PCEP Parsers/Serializers
[bgpcep.git] / pcep / impl / src / main / java / org / opendaylight / protocol / pcep / impl / subobject / RROPathKey32SubobjectParser.java
index 6220ead64b659de71a6c87b0bf40608c2276febe..2ae9a2ba8dcd09c8815d22e009c4b7c2dbbb5bce 100644 (file)
@@ -7,65 +7,68 @@
  */
 package org.opendaylight.protocol.pcep.impl.subobject;
 
-import java.util.Arrays;
+import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeUnsignedShort;
 
-import org.opendaylight.protocol.pcep.impl.object.RROSubobjectUtil;
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
 import org.opendaylight.protocol.pcep.spi.RROSubobjectParser;
 import org.opendaylight.protocol.pcep.spi.RROSubobjectSerializer;
+import org.opendaylight.protocol.pcep.spi.RROSubobjectUtil;
 import org.opendaylight.protocol.util.ByteArray;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PathKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PceId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.Subobjects;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.SubobjectsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.subobjects.subobject.type.PathKeyCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.subobjects.subobject.type.PathKeyCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.subobjects.subobject.type.path.key._case.PathKeyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.Subobject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.rro.SubobjectBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.PathKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.PceId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.PathKeyCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.PathKeyCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects.subobject.type.path.key._case.PathKeyBuilder;
 
 public class RROPathKey32SubobjectParser implements RROSubobjectParser, RROSubobjectSerializer {
 
-       public static final int TYPE = 64;
+    public static final int TYPE = 64;
 
-       private static final int PK_F_LENGTH = 2;
-       private static final int PCE_ID_F_LENGTH = 4;
+    private static final int PK_F_LENGTH = 2;
+    private static final int PCE_ID_F_LENGTH = 4;
 
-       private static final int PK_F_OFFSET = 0;
-       private static final int PCE_ID_F_OFFSET = PK_F_OFFSET + PK_F_LENGTH;
+    private static final int PK_F_OFFSET = 0;
+    private static final int PCE_ID_F_OFFSET = PK_F_OFFSET + PK_F_LENGTH;
 
-       private static final int CONTENT_LENGTH = PCE_ID_F_OFFSET + PCE_ID_F_LENGTH;
+    private static final int CONTENT_LENGTH = PCE_ID_F_OFFSET + PCE_ID_F_LENGTH;
 
-       @Override
-       public Subobjects parseSubobject(final byte[] buffer) throws PCEPDeserializerException {
-               if (buffer == null || buffer.length == 0) {
-                       throw new IllegalArgumentException("Array of bytes is mandatory. Can't be null or empty.");
-               }
-               if (buffer.length != CONTENT_LENGTH) {
-                       throw new PCEPDeserializerException("Wrong length of array of bytes. Passed: " + buffer.length + "; Expected: >"
-                                       + CONTENT_LENGTH + ".");
-               }
-               final byte[] pceId = Arrays.copyOfRange(buffer, PCE_ID_F_OFFSET, CONTENT_LENGTH);
-               final int pathKey = ByteArray.bytesToShort(Arrays.copyOfRange(buffer, PK_F_OFFSET, PCE_ID_F_OFFSET));
-               final SubobjectsBuilder builder = new SubobjectsBuilder();
-               final PathKeyBuilder pBuilder = new PathKeyBuilder();
-               pBuilder.setPceId(new PceId(pceId));
-               pBuilder.setPathKey(new PathKey(pathKey));
-               builder.setSubobjectType(new PathKeyCaseBuilder().setPathKey(pBuilder.build()).build());
-               return builder.build();
-       }
+    @Override
+    public Subobject parseSubobject(final ByteBuf buffer) throws PCEPDeserializerException {
+        Preconditions.checkArgument(buffer != null && buffer.isReadable(), "Array of bytes is mandatory. Can't be null or empty.");
+        if (buffer.readableBytes() != CONTENT_LENGTH) {
+            throw new PCEPDeserializerException("Wrong length of array of bytes. Passed: " + buffer.readableBytes() + "; Expected: >"
+                    + CONTENT_LENGTH + ".");
+        }
+        final int pathKey = buffer.readUnsignedShort();
+        final byte[] pceId = ByteArray.readBytes(buffer, PCE_ID_F_LENGTH);
+        final SubobjectBuilder builder = new SubobjectBuilder();
+        final PathKeyBuilder pBuilder = new PathKeyBuilder();
+        pBuilder.setPceId(new PceId(pceId));
+        pBuilder.setPathKey(new PathKey(pathKey));
+        builder.setSubobjectType(new PathKeyCaseBuilder().setPathKey(pBuilder.build()).build());
+        return builder.build();
+    }
 
-       @Override
-       public byte[] serializeSubobject(final Subobjects subobject) {
-               final PathKeyCase pk = (PathKeyCase) subobject.getSubobjectType();
-               final int pathKey = pk.getPathKey().getPathKey().getValue();
-               final byte[] pceId = pk.getPathKey().getPceId().getBinary();
-               final byte[] retBytes = new byte[PK_F_LENGTH + pceId.length];
-               System.arraycopy(ByteArray.shortToBytes((short) pathKey), 0, retBytes, PK_F_OFFSET, PK_F_LENGTH);
-               System.arraycopy(pceId, 0, retBytes, PCE_ID_F_OFFSET, pceId.length);
-               return RROSubobjectUtil.formatSubobject(TYPE, retBytes);
-       }
-
-       @Override
-       public int getType() {
-               return TYPE;
-       }
+    @Override
+    public void serializeSubobject(final Subobject subobject, final ByteBuf buffer) {
+        Preconditions.checkArgument(subobject.getSubobjectType() instanceof PathKeyCase, "Unknown subobject instance. Passed %s. Needed PathKey.", subobject.getSubobjectType().getClass());
+        final PathKeyCase pkcase = (PathKeyCase) subobject.getSubobjectType();
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.subobjects
+            .subobject.type.path.key._case.PathKey pk = pkcase.getPathKey();
+        final ByteBuf body = Unpooled.buffer();
+        Preconditions.checkArgument(pk.getPceId() != null, "PceId is mandatory.");
+        if(pk.getPceId().getBinary().length == 16) {
+            RROPathKey128SubobjectParser.serializeSubobject(subobject,buffer);
+        }
+        Preconditions.checkArgument(pk.getPathKey() != null, "PathKey is mandatory.");
+        writeUnsignedShort(pk.getPathKey().getValue(), body);
+        Preconditions.checkArgument(pk.getPceId().getBinary().length == 4, "PceId 32 Bit required.");
+        body.writeBytes(pk.getPceId().getBinary());
+        RROSubobjectUtil.formatSubobject(TYPE, body, buffer);
+    }
 }