Yuta HIGUCHI

implemented GossipDeviceStore with multi-provider, annotation support

Change-Id: I1953bdc37b28af79703ebcfc9201a71a2af49ab2
...@@ -2,7 +2,15 @@ package org.onlab.onos.store; ...@@ -2,7 +2,15 @@ package org.onlab.onos.store;
2 2
3 /** 3 /**
4 * Opaque version structure. 4 * Opaque version structure.
5 + * <p>
6 + * Classes implementing this interface must also implement
7 + * {@link #hashCode()} and {@link #equals(Object)}.
5 */ 8 */
6 public interface Timestamp extends Comparable<Timestamp> { 9 public interface Timestamp extends Comparable<Timestamp> {
7 10
11 + @Override
12 + public abstract int hashCode();
13 +
14 + @Override
15 + public abstract boolean equals(Object obj);
8 } 16 }
......
1 +package org.onlab.onos.store.common.impl;
2 +
3 +import static com.google.common.base.Preconditions.checkNotNull;
4 +
5 +import java.util.Objects;
6 +
7 +import org.onlab.onos.store.Timestamp;
8 +
9 +/**
10 + * Wrapper class to store Timestamped value.
11 + * @param <T>
12 + */
13 +public final class Timestamped<T> {
14 +
15 + private final Timestamp timestamp;
16 + private final T value;
17 +
18 + /**
19 + * Creates a time stamped value.
20 + *
21 + * @param value to be timestamp
22 + * @param timestamp the timestamp
23 + */
24 + public Timestamped(T value, Timestamp timestamp) {
25 + this.value = checkNotNull(value);
26 + this.timestamp = checkNotNull(timestamp);
27 + }
28 +
29 + /**
30 + * Returns the value.
31 + * @return value
32 + */
33 + public T value() {
34 + return value;
35 + }
36 +
37 + /**
38 + * Returns the time stamp.
39 + * @return time stamp
40 + */
41 + public Timestamp timestamp() {
42 + return timestamp;
43 + }
44 +
45 + /**
46 + * Tests if this timestamped value is newer than the other.
47 + *
48 + * @param other timestamped value
49 + * @return true if this instance is newer.
50 + */
51 + public boolean isNewer(Timestamped<T> other) {
52 + return this.timestamp.compareTo(checkNotNull(other).timestamp()) > 0;
53 + }
54 +
55 + @Override
56 + public int hashCode() {
57 + return timestamp.hashCode();
58 + }
59 +
60 + @Override
61 + public boolean equals(Object obj) {
62 + if (this == obj) {
63 + return true;
64 + }
65 + if (!(obj instanceof Timestamped)) {
66 + return false;
67 + }
68 + @SuppressWarnings("unchecked")
69 + Timestamped<T> that = (Timestamped<T>) obj;
70 + return Objects.equals(this.timestamp, that.timestamp);
71 + }
72 +
73 + // Default constructor for serialization
74 + @Deprecated
75 + protected Timestamped() {
76 + this.value = null;
77 + this.timestamp = null;
78 + }
79 +}
1 +/**
2 + * Common abstractions and facilities for implementing distributed store
3 + * using gossip protocol.
4 + */
5 +package org.onlab.onos.store.common.impl;
...@@ -17,9 +17,12 @@ import org.onlab.onos.store.Timestamp; ...@@ -17,9 +17,12 @@ import org.onlab.onos.store.Timestamp;
17 import org.onlab.onos.store.impl.OnosTimestamp; 17 import org.onlab.onos.store.impl.OnosTimestamp;
18 import org.slf4j.Logger; 18 import org.slf4j.Logger;
19 19
20 +/**
21 + * Clock service to issue Timestamp based on Device Mastership.
22 + */
20 @Component(immediate = true) 23 @Component(immediate = true)
21 @Service 24 @Service
22 -public class OnosClockService implements ClockService { 25 +public class DeviceClockManager implements ClockService {
23 26
24 private final Logger log = getLogger(getClass()); 27 private final Logger log = getLogger(getClass());
25 28
......
...@@ -84,4 +84,11 @@ public final class OnosTimestamp implements Timestamp { ...@@ -84,4 +84,11 @@ public final class OnosTimestamp implements Timestamp {
84 public int sequenceNumber() { 84 public int sequenceNumber() {
85 return sequenceNumber; 85 return sequenceNumber;
86 } 86 }
87 +
88 + // Default constructor for serialization
89 + @Deprecated
90 + protected OnosTimestamp() {
91 + this.termNumber = -1;
92 + this.sequenceNumber = -1;
93 + }
87 } 94 }
......
1 +package org.onlab.onos.store.common.impl;
2 +
3 +import static org.junit.Assert.*;
4 +
5 +import java.nio.ByteBuffer;
6 +
7 +import org.junit.After;
8 +import org.junit.AfterClass;
9 +import org.junit.Before;
10 +import org.junit.BeforeClass;
11 +import org.junit.Test;
12 +import org.onlab.onos.store.Timestamp;
13 +import org.onlab.onos.store.impl.OnosTimestamp;
14 +import org.onlab.util.KryoPool;
15 +
16 +import com.google.common.testing.EqualsTester;
17 +
18 +public class TimestampedTest {
19 +
20 + private static final Timestamp TS_1_1 = new OnosTimestamp(1, 1);
21 + private static final Timestamp TS_1_2 = new OnosTimestamp(1, 2);
22 + private static final Timestamp TS_2_1 = new OnosTimestamp(2, 1);
23 +
24 + @BeforeClass
25 + public static void setUpBeforeClass() throws Exception {
26 + }
27 +
28 + @AfterClass
29 + public static void tearDownAfterClass() throws Exception {
30 + }
31 +
32 + @Before
33 + public void setUp() throws Exception {
34 + }
35 +
36 + @After
37 + public void tearDown() throws Exception {
38 + }
39 +
40 + @Test
41 + public final void testHashCode() {
42 + Timestamped<String> a = new Timestamped<>("a", TS_1_1);
43 + Timestamped<String> b = new Timestamped<>("b", TS_1_1);
44 + assertTrue("value does not impact hashCode",
45 + a.hashCode() == b.hashCode());
46 + }
47 +
48 + @Test
49 + public final void testEquals() {
50 + Timestamped<String> a = new Timestamped<>("a", TS_1_1);
51 + Timestamped<String> b = new Timestamped<>("b", TS_1_1);
52 + assertTrue("value does not impact equality",
53 + a.equals(b));
54 +
55 + new EqualsTester()
56 + .addEqualityGroup(new Timestamped<>("a", TS_1_1),
57 + new Timestamped<>("b", TS_1_1),
58 + new Timestamped<>("c", TS_1_1))
59 + .addEqualityGroup(new Timestamped<>("a", TS_1_2),
60 + new Timestamped<>("b", TS_1_2),
61 + new Timestamped<>("c", TS_1_2))
62 + .addEqualityGroup(new Timestamped<>("a", TS_2_1),
63 + new Timestamped<>("b", TS_2_1),
64 + new Timestamped<>("c", TS_2_1))
65 + .testEquals();
66 +
67 + }
68 +
69 + @Test
70 + public final void testValue() {
71 + final Integer n = Integer.valueOf(42);
72 + Timestamped<Integer> tsv = new Timestamped<>(n, TS_1_1);
73 + assertSame(n, tsv.value());
74 +
75 + }
76 +
77 + @Test(expected = NullPointerException.class)
78 + public final void testValueNonNull() {
79 + new Timestamped<>(null, TS_1_1);
80 + }
81 +
82 + @Test(expected = NullPointerException.class)
83 + public final void testTimestampNonNull() {
84 + new Timestamped<>("Foo", null);
85 + }
86 +
87 + @Test
88 + public final void testIsNewer() {
89 + Timestamped<String> a = new Timestamped<>("a", TS_1_2);
90 + Timestamped<String> b = new Timestamped<>("b", TS_1_1);
91 + assertTrue(a.isNewer(b));
92 + assertFalse(b.isNewer(a));
93 + }
94 +
95 + @Test
96 + public final void testKryoSerializable() {
97 + final ByteBuffer buffer = ByteBuffer.allocate(1 * 1024 * 1024);
98 + final KryoPool kryos = KryoPool.newBuilder()
99 + .register(Timestamped.class,
100 + OnosTimestamp.class)
101 + .build();
102 +
103 + Timestamped<String> original = new Timestamped<>("foobar", TS_1_1);
104 + kryos.serialize(original, buffer);
105 + buffer.flip();
106 + Timestamped<String> copy = kryos.deserialize(buffer);
107 +
108 + new EqualsTester()
109 + .addEqualityGroup(original, copy)
110 + .testEquals();
111 + }
112 +}