[ONOS-5946] Implement LISP signature type
Change-Id: Ifea098d3b2fd1c0b5e24185b537056b9864b935b
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispSignature.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispSignature.java
index 979e987..12dbc5d 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispSignature.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispSignature.java
@@ -15,8 +15,269 @@
*/
package org.onosproject.lisp.msg.protocols;
+import com.google.common.base.Objects;
+import io.netty.buffer.ByteBuf;
+import org.onlab.packet.DeserializationException;
+import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
/**
* Default LISP signature class.
*/
-public class DefaultLispSignature implements LispSignature {
+public final class DefaultLispSignature implements LispSignature {
+
+ private final int recordTtl;
+ private final int sigExpiration;
+ private final int sigInception;
+ private final short keyTag;
+ private final short sigLength;
+ private final byte sigAlgorithm;
+ private final int signature;
+
+ /**
+ * A private constructor that protects object instantiation from external.
+ *
+ * @param recordTtl record time-to-live value
+ * @param sigExpiration signature expiration
+ * @param sigInception signature inception
+ * @param keyTag key tag
+ * @param sigLength signature length
+ * @param sigAlgorithm signature algorithm
+ * @param signature signature
+ */
+ private DefaultLispSignature(int recordTtl, int sigExpiration, int sigInception,
+ short keyTag, short sigLength, byte sigAlgorithm,
+ int signature) {
+ this.recordTtl = recordTtl;
+ this.sigExpiration = sigExpiration;
+ this.sigInception = sigInception;
+ this.keyTag = keyTag;
+ this.sigLength = sigLength;
+ this.sigAlgorithm = sigAlgorithm;
+ this.signature = signature;
+ }
+
+ @Override
+ public int getRecordTtl() {
+ return recordTtl;
+ }
+
+ @Override
+ public int getSigExpiration() {
+ return sigExpiration;
+ }
+
+ @Override
+ public int getSigInception() {
+ return sigInception;
+ }
+
+ @Override
+ public short getKeyTag() {
+ return keyTag;
+ }
+
+ @Override
+ public short getSigLength() {
+ return sigLength;
+ }
+
+ @Override
+ public byte getSigAlgorithm() {
+ return sigAlgorithm;
+ }
+
+ @Override
+ public int getSignature() {
+ return signature;
+ }
+
+ @Override
+ public void writeTo(ByteBuf byteBuf) throws LispWriterException {
+
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("record TTL", recordTtl)
+ .add("signature expiration", sigExpiration)
+ .add("signature inception", sigInception)
+ .add("key tag", keyTag)
+ .add("signature length", sigLength)
+ .add("signature algorithm", sigAlgorithm)
+ .add("signature", signature)
+ .toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ DefaultLispSignature that = (DefaultLispSignature) o;
+ return Objects.equal(recordTtl, that.recordTtl) &&
+ Objects.equal(sigExpiration, that.sigExpiration) &&
+ Objects.equal(sigInception, that.sigInception) &&
+ Objects.equal(keyTag, that.keyTag) &&
+ Objects.equal(sigLength, that.sigLength) &&
+ Objects.equal(sigAlgorithm, that.sigAlgorithm) &&
+ Objects.equal(signature, that.signature);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(recordTtl, sigExpiration, sigInception,
+ keyTag, sigLength, sigAlgorithm, signature);
+ }
+
+ public static final class DefaultSignatureBuilder implements LispSignature.SignatureBuilder {
+
+ private int recordTtl;
+ private int sigExpiration;
+ private int sigInception;
+ private short keyTag;
+ private short sigLength;
+ private byte sigAlgorithm;
+ private int signature;
+
+ @Override
+ public SignatureBuilder withRecordTtl(int recordTtl) {
+ this.recordTtl = recordTtl;
+ return this;
+ }
+
+ @Override
+ public SignatureBuilder withSigExpiration(int sigExpiration) {
+ this.sigExpiration = sigExpiration;
+ return this;
+ }
+
+ @Override
+ public SignatureBuilder withSigInception(int sigInception) {
+ this.sigInception = sigInception;
+ return this;
+ }
+
+ @Override
+ public SignatureBuilder withKeyTag(short keyTag) {
+ this.keyTag = keyTag;
+ return this;
+ }
+
+ @Override
+ public SignatureBuilder withSigLength(short sigLength) {
+ this.sigLength = sigLength;
+ return this;
+ }
+
+ @Override
+ public SignatureBuilder withSigAlgorithm(byte sigAlgorithm) {
+ this.sigAlgorithm = sigAlgorithm;
+ return this;
+ }
+
+ @Override
+ public SignatureBuilder withSignature(int signature) {
+ this.signature = signature;
+ return this;
+ }
+
+ @Override
+ public LispSignature build() {
+
+ return new DefaultLispSignature(recordTtl, sigExpiration, sigInception,
+ keyTag, sigLength, sigAlgorithm, signature);
+ }
+ }
+
+ /**
+ * A LISP reader for Signature section.
+ */
+ public static final class SignatureReader
+ implements LispMessageReader<LispSignature> {
+
+ private static final int RESERVED_SKIP_LENGTH = 3;
+
+ @Override
+ public LispSignature readFrom(ByteBuf byteBuf) throws LispParseError,
+ LispReaderException, DeserializationException {
+
+ // record TTL -> 32 bits
+ int recordTtl = byteBuf.readInt();
+
+ // signature expiration -> 32 bits
+ int sigExpiration = byteBuf.readInt();
+
+ // signature inception -> 32 bits
+ int sigInception = byteBuf.readInt();
+
+ // key tag -> 16 bits
+ short keyTag = byteBuf.readShort();
+
+ // signature length -> 16 bits
+ short sigLength = byteBuf.readShort();
+
+ // signature algorithm -> 8 bits
+ byte sigAlgorithm = byteBuf.readByte();
+
+ byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
+
+ // TODO: the size of signature should be determined by sigAlgorithm
+ int signature = byteBuf.readInt();
+
+ return new DefaultSignatureBuilder()
+ .withRecordTtl(recordTtl)
+ .withSigExpiration(sigExpiration)
+ .withSigInception(sigInception)
+ .withKeyTag(keyTag)
+ .withSigLength(sigLength)
+ .withSigAlgorithm(sigAlgorithm)
+ .withSignature(signature)
+ .build();
+ }
+ }
+
+ /**
+ * A LISP writer for Signature section.
+ */
+ public static final class SignatureWriter implements LispMessageWriter<LispSignature> {
+
+ private static final int UNUSED_ZERO = 0;
+
+ @Override
+ public void writeTo(ByteBuf byteBuf, LispSignature message) throws LispWriterException {
+
+ // record TTL
+ byteBuf.writeInt(message.getRecordTtl());
+
+ // signature expiration
+ byteBuf.writeInt(message.getSigExpiration());
+
+ // signature inception
+ byteBuf.writeInt(message.getSigInception());
+
+ // key tag
+ byteBuf.writeShort(message.getKeyTag());
+
+ // signature length
+ byteBuf.writeShort(message.getSigLength());
+
+ // signature algorithm
+ byteBuf.writeByte(message.getSigAlgorithm());
+
+ byteBuf.writeByte(UNUSED_ZERO);
+ byteBuf.writeShort(UNUSED_ZERO);
+
+ // signature
+ // TODO: the size of signature should be determined by sigAlgorithm
+ byteBuf.writeInt(message.getSignature());
+ }
+ }
}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispSignature.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispSignature.java
index 291d9d7..d3bda09 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispSignature.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispSignature.java
@@ -15,6 +15,9 @@
*/
package org.onosproject.lisp.msg.protocols;
+import io.netty.buffer.ByteBuf;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+
/**
* LISP signature interface.
*
@@ -43,5 +46,129 @@
*/
public interface LispSignature {
- // TODO: need to implement LispSignature
+ /**
+ * Obtains record TTL value.
+ *
+ * @return record TTL value
+ */
+ int getRecordTtl();
+
+ /**
+ * Obtains signature expiration.
+ *
+ * @return signature expiration
+ */
+ int getSigExpiration();
+
+ /**
+ * Obtains signature inception.
+ *
+ * @return signature inception
+ */
+ int getSigInception();
+
+ /**
+ * Obtains key tag.
+ *
+ * @return key tag
+ */
+ short getKeyTag();
+
+ /**
+ * Obtains signature length.
+ *
+ * @return signature length.
+ */
+ short getSigLength();
+
+ /**
+ * Obtains signature algorithm.
+ *
+ * @return signature algorithm
+ */
+ byte getSigAlgorithm();
+
+ /**
+ * Obtains signature.
+ *
+ * @return signature
+ */
+ int getSignature();
+
+ /**
+ * Writes LISP object into communication channel.
+ *
+ * @param byteBuf byte buffer
+ * @throws LispWriterException on error
+ */
+ void writeTo(ByteBuf byteBuf) throws LispWriterException;
+
+ /**
+ * A builder for LISP signature.
+ */
+ interface SignatureBuilder {
+
+ /**
+ * Sets record TTL value.
+ *
+ * @param recordTtl record TTL
+ * @return SignatureBuilder object
+ */
+ SignatureBuilder withRecordTtl(int recordTtl);
+
+ /**
+ * Sets signature expiration.
+ *
+ * @param sigExpiration signature expiration
+ * @return SignatureBuilder object
+ */
+ SignatureBuilder withSigExpiration(int sigExpiration);
+
+ /**
+ * Sets signature inception.
+ *
+ * @param sigInception signature inception
+ * @return SignatureBuilder object
+ */
+ SignatureBuilder withSigInception(int sigInception);
+
+ /**
+ * Sets key tag.
+ *
+ * @param keyTag key tag
+ * @return SignatureBuilder object
+ */
+ SignatureBuilder withKeyTag(short keyTag);
+
+ /**
+ * Sets signature length.
+ *
+ * @param sigLength signature length
+ * @return SignatureBuilder object
+ */
+ SignatureBuilder withSigLength(short sigLength);
+
+ /**
+ * Sets signature algorithm.
+ *
+ * @param sigAlgorithm signature algorithm
+ * @return SignatureBuilder object
+ */
+ SignatureBuilder withSigAlgorithm(byte sigAlgorithm);
+
+ /**
+ * Sets signature.
+ *
+ * @param signature signature
+ * @return SignatureBuilder object
+ */
+ SignatureBuilder withSignature(int signature);
+
+ /**
+ * Builds LISP signature object.
+ *
+ * @return LISP signature object
+ */
+ LispSignature build();
+ }
}
diff --git a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispSignatureTest.java b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispSignatureTest.java
new file mode 100644
index 0000000..567804f
--- /dev/null
+++ b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispSignatureTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2017-present 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.lisp.msg.protocols;
+
+import com.google.common.testing.EqualsTester;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.DeserializationException;
+import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+import org.onosproject.lisp.msg.protocols.DefaultLispSignature.DefaultSignatureBuilder;
+import org.onosproject.lisp.msg.protocols.DefaultLispSignature.SignatureReader;
+import org.onosproject.lisp.msg.protocols.DefaultLispSignature.SignatureWriter;
+import org.onosproject.lisp.msg.protocols.LispSignature.SignatureBuilder;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+/**
+ * Unit tests for DefaultLispSignature class.
+ */
+public final class DefaultLispSignatureTest {
+
+ private static final int SIG_UNIQUE_VALUE_1 = 100;
+ private static final int SIG_UNIQUE_VALUE_2 = 200;
+
+ private LispSignature signature1;
+ private LispSignature sameAsSignature1;
+ private LispSignature signature2;
+
+ @Before
+ public void setup() {
+
+ SignatureBuilder builder1 = new DefaultSignatureBuilder();
+
+ signature1 = builder1
+ .withRecordTtl(SIG_UNIQUE_VALUE_1)
+ .withSigExpiration(SIG_UNIQUE_VALUE_1)
+ .withSigInception(SIG_UNIQUE_VALUE_1)
+ .withKeyTag((short) SIG_UNIQUE_VALUE_1)
+ .withSigLength((short) SIG_UNIQUE_VALUE_1)
+ .withSigAlgorithm((byte) 1)
+ .withSignature(SIG_UNIQUE_VALUE_1)
+ .build();
+
+ SignatureBuilder builder2 = new DefaultSignatureBuilder();
+
+ sameAsSignature1 = builder2
+ .withRecordTtl(SIG_UNIQUE_VALUE_1)
+ .withSigExpiration(SIG_UNIQUE_VALUE_1)
+ .withSigInception(SIG_UNIQUE_VALUE_1)
+ .withKeyTag((short) SIG_UNIQUE_VALUE_1)
+ .withSigLength((short) SIG_UNIQUE_VALUE_1)
+ .withSigAlgorithm((byte) 1)
+ .withSignature(SIG_UNIQUE_VALUE_1)
+ .build();
+
+ SignatureBuilder builder3 = new DefaultSignatureBuilder();
+
+ signature2 = builder3
+ .withRecordTtl(SIG_UNIQUE_VALUE_2)
+ .withSigExpiration(SIG_UNIQUE_VALUE_2)
+ .withSigInception(SIG_UNIQUE_VALUE_2)
+ .withKeyTag((short) SIG_UNIQUE_VALUE_2)
+ .withSigLength((short) SIG_UNIQUE_VALUE_2)
+ .withSigAlgorithm((byte) 2)
+ .withSignature(SIG_UNIQUE_VALUE_2)
+ .build();
+ }
+
+ @Test
+ public void testEquality() {
+ new EqualsTester()
+ .addEqualityGroup(signature1, sameAsSignature1)
+ .addEqualityGroup(signature2).testEquals();
+ }
+
+ @Test
+ public void testConstruction() {
+ LispSignature signature = signature1;
+
+ assertThat(signature.getRecordTtl(), is(SIG_UNIQUE_VALUE_1));
+ assertThat(signature.getSigExpiration(), is(SIG_UNIQUE_VALUE_1));
+ assertThat(signature.getSigInception(), is(SIG_UNIQUE_VALUE_1));
+ assertThat(signature.getKeyTag(), is((short) SIG_UNIQUE_VALUE_1));
+ assertThat(signature.getSigLength(), is((short) SIG_UNIQUE_VALUE_1));
+ assertThat(signature.getSigAlgorithm(), is((byte) 1));
+ assertThat(signature.getSignature(), is(SIG_UNIQUE_VALUE_1));
+ }
+
+ @Test
+ public void testSerialization() throws LispReaderException, DeserializationException,
+ LispWriterException, LispParseError {
+ ByteBuf byteBuf = Unpooled.buffer();
+
+ SignatureWriter writer = new SignatureWriter();
+ writer.writeTo(byteBuf, signature1);
+
+ SignatureReader reader = new SignatureReader();
+ LispSignature deserialized = reader.readFrom(byteBuf);
+
+ new EqualsTester()
+ .addEqualityGroup(signature1, deserialized).testEquals();
+ }
+}
\ No newline at end of file