package org.opendaylight.protocol.pcep.spi;
import com.google.common.base.Preconditions;
-
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
-
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Tlv;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger LOG = LoggerFactory.getLogger(AbstractObjectWithTlvsParser.class);
- private static final int TLV_TYPE_F_LENGTH = 2;
- private static final int TLV_LENGTH_F_LENGTH = 2;
- private static final int TLV_HEADER_LENGTH = TLV_LENGTH_F_LENGTH + TLV_TYPE_F_LENGTH;
-
- protected static final int PADDED_TO = 4;
-
private final TlvRegistry tlvReg;
protected AbstractObjectWithTlvsParser(final TlvRegistry tlvReg) {
int length = bytes.readUnsignedShort();
if (length > bytes.readableBytes()) {
throw new PCEPDeserializerException("Wrong length specified. Passed: " + length + "; Expected: <= " + bytes.readableBytes()
- + ".");
+ + ".");
}
final ByteBuf tlvBytes = bytes.slice(bytes.readerIndex(), length);
- LOG.trace("Attempt to parse tlv from bytes: {}", ByteBufUtil.hexDump(tlvBytes));
+ LOG.trace("Parsing PCEP TLV : {}", ByteBufUtil.hexDump(tlvBytes));
final Tlv tlv = this.tlvReg.parseTlv(type, tlvBytes);
- LOG.trace("Tlv was parsed. {}", tlv);
+ LOG.trace("Parsed PCEP TLV {}.", tlv);
addTlv(builder, tlv);
- bytes.readerIndex(bytes.readerIndex() + length + getPadding(TLV_HEADER_LENGTH + length, PADDED_TO));
+ bytes.skipBytes(length + TlvUtil.getPadding(TlvUtil.HEADER_SIZE + length, TlvUtil.PADDED_TO));
}
}
Preconditions.checkNotNull(tlv, "PCEP TLV is mandatory.");
LOG.trace("Serializing PCEP TLV {}", tlv);
this.tlvReg.serializeTlv(tlv, buffer);
- LOG.trace("Serialized PCEP TLV {}.", ByteBufUtil.hexDump(buffer));
+ LOG.trace("Serialized PCEP TLV : {}.", ByteBufUtil.hexDump(buffer));
}
protected void addTlv(final T builder, final Tlv tlv) {
// FIXME: No TLVs by default, fallback to augments
}
-
- public static int getPadding(final int length, final int padding) {
- return (padding - (length % padding)) % padding;
- }
}
private static final int HEADER_SIZE = 2;
+ private static final int LOOSE_BIT = 7;
+
private EROSubobjectUtil() {
}
- public static void formatSubobject(final int type, final boolean loose, final ByteBuf body, final ByteBuf buffer) {
- buffer.writeByte(type | (loose ? 1 << 7 : 0));
+ public static void formatSubobject(final int type, final Boolean loose, final ByteBuf body, final ByteBuf buffer) {
+ if (loose == null) {
+ buffer.writeByte(type);
+ } else {
+ buffer.writeByte(type | (loose ? 1 << LOOSE_BIT : 0));
+ }
buffer.writeByte(body.writerIndex() + HEADER_SIZE);
buffer.writeBytes(body);
}
package org.opendaylight.protocol.pcep.spi;
import io.netty.buffer.ByteBuf;
-
import java.util.BitSet;
-
import org.opendaylight.protocol.util.ByteArray;
public final class LabelUtil {
private static final int G_FLAG_OFFSET = 7;
private LabelUtil() {
- throw new UnsupportedOperationException("Utility class should not be instantiated");
}
- public static void formatLabel(final int type, final boolean unidirectional, final boolean global, final ByteBuf body, final ByteBuf buffer) {
+ public static void formatLabel(final int type, final Boolean unidirectional, final Boolean global, final ByteBuf body, final ByteBuf buffer) {
final BitSet reserved = new BitSet(RES_F_LENGTH * Byte.SIZE);
- reserved.set(U_FLAG_OFFSET, unidirectional);
- reserved.set(G_FLAG_OFFSET, global);
+ if (unidirectional != null) {
+ reserved.set(U_FLAG_OFFSET, unidirectional);
+ }
+ if (global != null) {
+ reserved.set(G_FLAG_OFFSET, global);
+ }
buffer.writeBytes(ByteArray.bitSetToBytes(reserved, RES_F_LENGTH));
buffer.writeByte(type);
buffer.writeBytes(body);
package org.opendaylight.protocol.pcep.spi;
import com.google.common.base.Preconditions;
-
import io.netty.buffer.ByteBuf;
public final class MessageUtil {
private static final int VERSION_SF_LENGTH = 3;
private MessageUtil() {
- throw new UnsupportedOperationException("Utility class should not be instantiated");
}
public static void formatMessage(final int messageType, final ByteBuf body, final ByteBuf out) {
*/
public class ObjectHeaderImpl implements ObjectHeader {
- private final boolean processed;
- private final boolean ignored;
+ private final Boolean processed;
+ private final Boolean ignored;
- public ObjectHeaderImpl(final boolean processed, final boolean ignore) {
+ public ObjectHeaderImpl(final Boolean processed, final Boolean ignore) {
this.processed = processed;
this.ignored = ignore;
}
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + (this.ignored ? 1231 : 1237);
- result = prime * result + (this.processed ? 1231 : 1237);
+ result = prime * result + ((this.ignored == null) ? 0 : this.ignored.hashCode());
+ result = prime * result + ((this.processed == null) ? 0 : this.processed.hashCode());
return result;
}
@Override
- public boolean equals(final Object obj) {
+ public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
- if (this.getClass() != obj.getClass()) {
+ if (getClass() != obj.getClass()) {
return false;
}
- final ObjectHeaderImpl other = (ObjectHeaderImpl) obj;
- if (this.ignored != other.ignored) {
+ ObjectHeaderImpl other = (ObjectHeaderImpl) obj;
+ if (this.ignored == null) {
+ if (other.ignored != null) {
+ return false;
+ }
+ } else if (!this.ignored.equals(other.ignored)) {
return false;
}
- if (this.processed != other.processed) {
+ if (this.processed == null) {
+ if (other.processed != null) {
+ return false;
+ }
+ } else if (!this.processed.equals(other.processed)) {
return false;
}
return true;
package org.opendaylight.protocol.pcep.spi;
import io.netty.buffer.ByteBuf;
-
import java.util.BitSet;
-
import org.opendaylight.protocol.util.ByteArray;
public final class ObjectUtil {
}
public static void formatSubobject(final int objectType, final int objectClass, final Boolean processingRule, final Boolean ignore,
- final ByteBuf body, final ByteBuf out) {
+ final ByteBuf body, final ByteBuf out) {
out.writeByte(objectClass);
BitSet flags = new BitSet(Byte.SIZE);
- if (ignore != null && ignore) {
- flags.set(I_FLAG_OFFSET);
+ if (ignore != null) {
+ flags.set(I_FLAG_OFFSET, ignore);
}
- if (processingRule != null && processingRule) {
- flags.set(P_FLAG_OFFSET);
+ if (processingRule != null) {
+ flags.set(P_FLAG_OFFSET, processingRule);
}
byte[] flagB = ByteArray.bitSetToBytes(flags, 1);
int typeByte = objectType << OT_SF_LENGTH | flagB[0];
*/
package org.opendaylight.protocol.pcep.spi;
+import com.google.common.annotations.VisibleForTesting;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
private final short type;
private final short value;
- private PCEPErrorIdentifier(final short type, final short value) {
+ @VisibleForTesting
+ PCEPErrorIdentifier(final short type, final short value) {
this.type = type;
this.value = value;
}
public short getType() {
- return type;
+ return this.type;
}
public short getValue() {
- return value;
+ return this.value;
}
@Override
public final class TlvUtil {
- private static final int HEADER_SIZE = 4;
+ protected static final int HEADER_SIZE = 4;
protected static final int PADDED_TO = 4;
private TlvUtil() {
- throw new UnsupportedOperationException("Utility class should not be instantiated");
}
public static void formatTlv(final int type,final ByteBuf body, final ByteBuf out) {
out.writeShort(type);
out.writeShort(body.writerIndex());
out.writeBytes(body);
- out.writeZero(AbstractObjectWithTlvsParser.getPadding(HEADER_SIZE + body.writerIndex(), PADDED_TO));
+ out.writeZero(getPadding(HEADER_SIZE + body.writerIndex(), PADDED_TO));
+ }
+
+ public static int getPadding(final int length, final int padding) {
+ return (padding - (length % padding)) % padding;
}
}
private static final int HEADER_SIZE = 2;
+ private static final int MANDATORY_BIT = 7;
+
private XROSubobjectUtil() {
}
- public static void formatSubobject(final int type, final boolean mandatory, final ByteBuf body, final ByteBuf buffer) {
- buffer.writeByte(type | (mandatory ? 1 << 7 : 0));
+ public static void formatSubobject(final int type, final Boolean mandatory, final ByteBuf body, final ByteBuf buffer) {
+ if (mandatory == null) {
+ buffer.writeByte(type);
+ } else {
+ buffer.writeByte(type | (mandatory ? 1 << MANDATORY_BIT : 0));
+ }
buffer.writeByte(body.writerIndex() + HEADER_SIZE);
buffer.writeBytes(body);
}
package org.opendaylight.protocol.pcep.spi;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
+import org.opendaylight.protocol.pcep.spi.PCEPErrorMapping.PCEPErrorIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.close.object.CCloseBuilder;
public class APITest {
assertEquals("Some error message.", e1.getMessage());
assertTrue(e1.getCause() instanceof IllegalArgumentException);
}
+
+ @Test
+ public void testObjectHeader() {
+ ObjectHeaderImpl header = new ObjectHeaderImpl(null, true);
+ assertEquals("ObjectHeader [objClass=, processed=null, ignored=true]", header.toString());
+ assertTrue(header.isIgnore());
+ assertNull(header.isProcessingRule());
+
+ assertEquals(new ObjectHeaderImpl(null, true).hashCode(), header.hashCode());
+ assertTrue(new ObjectHeaderImpl(null, true).equals(header));
+ }
+
+ @Test
+ public void testUnknownObject() {
+ UnknownObject un = new UnknownObject(PCEPErrors.CT_AND_SETUP_PRIORITY_DO_NOT_FORM_TE_CLASS);
+ assertFalse(un.isIgnore());
+ assertFalse(un.isProcessingRule());
+ assertEquals(PCEPErrors.CT_AND_SETUP_PRIORITY_DO_NOT_FORM_TE_CLASS, un.getError());
+ final PCEPErrorMapping mapping = PCEPErrorMapping.getInstance();
+ final PCEPErrorIdentifier id = mapping.getFromErrorsEnum(PCEPErrors.CT_AND_SETUP_PRIORITY_DO_NOT_FORM_TE_CLASS);
+ assertEquals(id.getType(), un.getErrors().get(0).getErrorObject().getType().shortValue());
+
+ final Object o = new CCloseBuilder().build();
+ UnknownObject unknown = new UnknownObject(PCEPErrors.LSP_RSVP_ERROR, o);
+ assertEquals(Object.class, unknown.getImplementedInterface());
+ assertEquals(o, unknown.getInvalidObject());
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.pcep.spi;
+
+import static org.junit.Assert.assertEquals;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.protocol.pcep.spi.PCEPErrorMapping.PCEPErrorIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcerr;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcep.error.object.ErrorObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcep.error.object.ErrorObjectBuilder;
+
+public class AbstractMessageParserTest {
+
+ private Object object;
+
+ @Mock
+ private ObjectRegistry registry;
+
+ private class Abs extends AbstractMessageParser {
+
+ protected Abs(ObjectRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public void serializeMessage(Message message, ByteBuf buffer) {
+ }
+
+ @Override
+ protected Message validate(List<Object> objects, List<Message> errors) throws PCEPDeserializerException {
+ short type = ((ErrorObject)objects.get(0)).getType();
+ short value = ((ErrorObject)objects.get(0)).getValue();
+ final PCEPErrorMapping map = PCEPErrorMapping.getInstance();
+ return createErrorMsg(map.getFromErrorIdentifier(new PCEPErrorIdentifier(type, value)));
+ }
+ };
+
+ @Before
+ public void setUp() throws PCEPDeserializerException {
+ MockitoAnnotations.initMocks(this);
+ this.object = new ErrorObjectBuilder().setType((short) 1).setValue((short) 1).build();
+ Mockito.doNothing().when(this.registry).serializeObject(Mockito.any(Object.class), Mockito.any(ByteBuf.class));
+ Mockito.doReturn(this.object).when(this.registry).parseObject(13, 1, new ObjectHeaderImpl(true, true), Unpooled.wrappedBuffer(new byte[] { 0, 0, 1, 1 }));
+ }
+
+ @Test
+ public void testParseObjects() throws PCEPDeserializerException {
+ Abs a = new Abs(this.registry);
+ ByteBuf buffer = Unpooled.buffer();
+ a.serializeObject(this.object, buffer);
+
+ Mockito.verify(this.registry, Mockito.only()).serializeObject(Mockito.any(Object.class), Mockito.any(ByteBuf.class));;
+
+ Message b = a.parseMessage(Unpooled.wrappedBuffer(new byte[] {0x0D, 0x13, 0, 0x08, 0, 0, 1, 1 }), Collections.<Message> emptyList());
+
+ assertEquals(this.object, ((Pcerr) b).getPcerrMessage().getErrors().get(0).getErrorObject());
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.pcep.spi;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.Lists;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.ObjectHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.OfId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Tlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.of.list.tlv.OfList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.of.list.tlv.OfListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.TlvsBuilder;
+
+public class AbstractObjectWithTlvsTest {
+
+ private Tlv tlv;
+
+ @Mock
+ private TlvRegistry tlvRegistry;
+
+ private class Abs extends AbstractObjectWithTlvsParser<TlvsBuilder> {
+
+ protected Abs(TlvRegistry tlvReg) {
+ super(tlvReg);
+ }
+
+ @Override
+ public Object parseObject(ObjectHeader header, ByteBuf buffer) throws PCEPDeserializerException {
+ return null;
+ }
+
+ @Override
+ public void serializeObject(Object object, ByteBuf buffer) {
+ }
+
+ @Override
+ public void addTlv(final TlvsBuilder builder, final Tlv tlv) {
+ builder.setOfList((OfList) tlv);
+ }
+ };
+
+ @Before
+ public void setUp() throws PCEPDeserializerException {
+ MockitoAnnotations.initMocks(this);
+ this.tlv = new OfListBuilder().setCodes(Lists.newArrayList(new OfId(10))).build();
+ Mockito.doNothing().when(this.tlvRegistry).serializeTlv(Mockito.any(Tlv.class), Mockito.any(ByteBuf.class));
+ Mockito.doReturn(this.tlv).when(this.tlvRegistry).parseTlv(4, Unpooled.wrappedBuffer(new byte[] { 5, 6 }));
+ }
+
+ @Test
+ public void testParseTlvs() throws PCEPDeserializerException {
+ Abs a = new Abs(this.tlvRegistry);
+ ByteBuf buffer = Unpooled.buffer();
+ a.serializeTlv(this.tlv, buffer);
+
+ Mockito.verify(this.tlvRegistry, Mockito.only()).serializeTlv(Mockito.any(Tlv.class), Mockito.any(ByteBuf.class));;
+
+ TlvsBuilder b = new TlvsBuilder();
+ a.parseTlvs(b, Unpooled.wrappedBuffer(new byte[] { 0, 4, 0, 2, 5, 6, 0, 0 }));
+
+ assertEquals(this.tlv, b.getOfList());
+ }
+}
package org.opendaylight.protocol.pcep.spi;
import static org.junit.Assert.assertArrayEquals;
+
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
-
import org.junit.Test;
import org.opendaylight.protocol.util.ByteArray;
ObjectUtil.formatSubobject(1, 8, false, false, body, out);
assertArrayEquals(expected, ByteArray.getAllBytes(out));
}
+
+ @Test
+ public void testXROSubobjectUtil() {
+ byte[] expected = { (byte) 0x82, 6, 0, 1, 2, 3 };
+ ByteBuf out = Unpooled.buffer();
+ ByteBuf body = Unpooled.copiedBuffer(new byte[] { 0, 1, 2, 3 });
+ body.markReaderIndex();
+ XROSubobjectUtil.formatSubobject(2, true, body, out);
+ assertArrayEquals(expected, ByteArray.getAllBytes(out));
+
+ expected = new byte[]{ 2, 6, 0, 1, 2, 3 };
+ out.clear();
+ body.resetReaderIndex();
+ XROSubobjectUtil.formatSubobject(2, false, body, out);
+ assertArrayEquals(expected, ByteArray.getAllBytes(out));
+ }
+
+ @Test
+ public void testTlvUtil() {
+ byte[] expected = { 0, 4, 0, 4, 1, 2, 3, 4 };
+ ByteBuf out = Unpooled.buffer();
+ ByteBuf body = Unpooled.copiedBuffer(new byte[] { 1, 2, 3, 4 });
+ TlvUtil.formatTlv(4, body, out);
+ assertArrayEquals(expected, ByteArray.getAllBytes(out));
+
+ expected = new byte[]{ 0, 4, 0, 5, 1, 2, 3, 4, 5, 0, 0, 0 };
+ out.clear();
+ body = Unpooled.copiedBuffer(new byte[] { 1, 2, 3, 4, 5 });
+ TlvUtil.formatTlv(4, body, out);
+ assertArrayEquals(expected, ByteArray.getAllBytes(out));
+ }
+
+ @Test
+ public void testRROSubobjectUtil() {
+ byte[] expected = { 4, 6, 1, 2, 3, 4 };
+ ByteBuf out = Unpooled.buffer();
+ ByteBuf body = Unpooled.copiedBuffer(new byte[] { 1, 2, 3, 4 });
+ RROSubobjectUtil.formatSubobject(4, body, out);
+ assertArrayEquals(expected, ByteArray.getAllBytes(out));
+ }
+
+ @Test
+ public void testEROSubobjectUtil() {
+ byte[] expected = { (byte) 0x82, 6, 0, 1, 2, 3 };
+ ByteBuf out = Unpooled.buffer();
+ ByteBuf body = Unpooled.copiedBuffer(new byte[] { 0, 1, 2, 3 });
+ body.markReaderIndex();
+ EROSubobjectUtil.formatSubobject(2, true, body, out);
+ assertArrayEquals(expected, ByteArray.getAllBytes(out));
+
+ expected = new byte[]{ 2, 6, 0, 1, 2, 3 };
+ out.clear();
+ body.resetReaderIndex();
+ EROSubobjectUtil.formatSubobject(2, false, body, out);
+ assertArrayEquals(expected, ByteArray.getAllBytes(out));
+ }
}