Committed by
Gerrit Code Review
Kryo related fixes
- KryoNamespace to allow control over registration id Change-Id: Idc2a0e27a09916657c725ee97e4366109144cc66
Showing
38 changed files
with
541 additions
and
355 deletions
... | @@ -18,6 +18,9 @@ package org.onlab.onos.store.cluster.messaging; | ... | @@ -18,6 +18,9 @@ package org.onlab.onos.store.cluster.messaging; |
18 | import java.io.IOException; | 18 | import java.io.IOException; |
19 | 19 | ||
20 | import org.onlab.onos.cluster.NodeId; | 20 | import org.onlab.onos.cluster.NodeId; |
21 | +import org.onlab.util.ByteArraySizeHashPrinter; | ||
22 | + | ||
23 | +import com.google.common.base.MoreObjects; | ||
21 | 24 | ||
22 | // TODO: Should payload type be ByteBuffer? | 25 | // TODO: Should payload type be ByteBuffer? |
23 | /** | 26 | /** |
... | @@ -78,4 +81,13 @@ public class ClusterMessage { | ... | @@ -78,4 +81,13 @@ public class ClusterMessage { |
78 | public void respond(byte[] data) throws IOException { | 81 | public void respond(byte[] data) throws IOException { |
79 | throw new IllegalStateException("One can only repond to message recived from others."); | 82 | throw new IllegalStateException("One can only repond to message recived from others."); |
80 | } | 83 | } |
84 | + | ||
85 | + @Override | ||
86 | + public String toString() { | ||
87 | + return MoreObjects.toStringHelper(getClass()) | ||
88 | + .add("sender", sender) | ||
89 | + .add("subject", subject) | ||
90 | + .add("payload", ByteArraySizeHashPrinter.of(payload)) | ||
91 | + .toString(); | ||
92 | + } | ||
81 | } | 93 | } | ... | ... |
... | @@ -34,7 +34,6 @@ import org.onlab.netty.NettyMessagingService; | ... | @@ -34,7 +34,6 @@ import org.onlab.netty.NettyMessagingService; |
34 | import org.onlab.onos.cluster.ClusterService; | 34 | import org.onlab.onos.cluster.ClusterService; |
35 | import org.onlab.onos.cluster.ControllerNode; | 35 | import org.onlab.onos.cluster.ControllerNode; |
36 | import org.onlab.onos.cluster.NodeId; | 36 | import org.onlab.onos.cluster.NodeId; |
37 | -import org.onlab.onos.store.cluster.impl.ClusterMembershipEvent; | ||
38 | import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; | 37 | import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; |
39 | import org.onlab.onos.store.cluster.messaging.ClusterMessage; | 38 | import org.onlab.onos.store.cluster.messaging.ClusterMessage; |
40 | import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; | 39 | import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; |
... | @@ -67,12 +66,10 @@ public class ClusterCommunicationManager | ... | @@ -67,12 +66,10 @@ public class ClusterCommunicationManager |
67 | protected void setupKryoPool() { | 66 | protected void setupKryoPool() { |
68 | serializerPool = KryoNamespace.newBuilder() | 67 | serializerPool = KryoNamespace.newBuilder() |
69 | .register(KryoNamespaces.API) | 68 | .register(KryoNamespaces.API) |
70 | - .register(ClusterMessage.class, new ClusterMessageSerializer()) | 69 | + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID) |
71 | - .register(ClusterMembershipEvent.class) | 70 | + .register(new ClusterMessageSerializer(), ClusterMessage.class) |
72 | - .register(byte[].class) | 71 | + .register(new MessageSubjectSerializer(), MessageSubject.class) |
73 | - .register(MessageSubject.class, new MessageSubjectSerializer()) | 72 | + .build(); |
74 | - .build() | ||
75 | - .populate(1); | ||
76 | } | 73 | } |
77 | 74 | ||
78 | }; | 75 | }; |
... | @@ -194,11 +191,17 @@ public class ClusterCommunicationManager | ... | @@ -194,11 +191,17 @@ public class ClusterCommunicationManager |
194 | 191 | ||
195 | @Override | 192 | @Override |
196 | public void handle(Message message) { | 193 | public void handle(Message message) { |
194 | + final ClusterMessage clusterMessage; | ||
195 | + try { | ||
196 | + clusterMessage = SERIALIZER.decode(message.payload()); | ||
197 | + } catch (Exception e) { | ||
198 | + log.error("Failed decoding ClusterMessage", e); | ||
199 | + throw e; | ||
200 | + } | ||
197 | try { | 201 | try { |
198 | - ClusterMessage clusterMessage = SERIALIZER.decode(message.payload()); | ||
199 | handler.handle(new InternalClusterMessage(clusterMessage, message)); | 202 | handler.handle(new InternalClusterMessage(clusterMessage, message)); |
200 | } catch (Exception e) { | 203 | } catch (Exception e) { |
201 | - log.error("Exception caught during ClusterMessageHandler", e); | 204 | + log.error("Exception caught handling {}", clusterMessage, e); |
202 | throw e; | 205 | throw e; |
203 | } | 206 | } |
204 | } | 207 | } | ... | ... |
... | @@ -65,8 +65,8 @@ public class DistributedApplicationIdStore | ... | @@ -65,8 +65,8 @@ public class DistributedApplicationIdStore |
65 | protected void setupKryoPool() { | 65 | protected void setupKryoPool() { |
66 | serializerPool = KryoNamespace.newBuilder() | 66 | serializerPool = KryoNamespace.newBuilder() |
67 | .register(KryoNamespaces.API) | 67 | .register(KryoNamespaces.API) |
68 | - .build() | 68 | + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID) |
69 | - .populate(1); | 69 | + .build(); |
70 | } | 70 | } |
71 | }; | 71 | }; |
72 | 72 | ... | ... |
... | @@ -141,18 +141,17 @@ public class GossipDeviceStore | ... | @@ -141,18 +141,17 @@ public class GossipDeviceStore |
141 | @Override | 141 | @Override |
142 | protected void setupKryoPool() { | 142 | protected void setupKryoPool() { |
143 | serializerPool = KryoNamespace.newBuilder() | 143 | serializerPool = KryoNamespace.newBuilder() |
144 | - .register(DistributedStoreSerializers.COMMON) | 144 | + .register(DistributedStoreSerializers.STORE_COMMON) |
145 | - | 145 | + .nextId(DistributedStoreSerializers.STORE_CUSTOM_BEGIN) |
146 | - .register(InternalDeviceEvent.class, new InternalDeviceEventSerializer()) | 146 | + .register(new InternalDeviceEventSerializer(), InternalDeviceEvent.class) |
147 | - .register(InternalDeviceOfflineEvent.class, new InternalDeviceOfflineEventSerializer()) | 147 | + .register(new InternalDeviceOfflineEventSerializer(), InternalDeviceOfflineEvent.class) |
148 | .register(InternalDeviceRemovedEvent.class) | 148 | .register(InternalDeviceRemovedEvent.class) |
149 | - .register(InternalPortEvent.class, new InternalPortEventSerializer()) | 149 | + .register(new InternalPortEventSerializer(), InternalPortEvent.class) |
150 | - .register(InternalPortStatusEvent.class, new InternalPortStatusEventSerializer()) | 150 | + .register(new InternalPortStatusEventSerializer(), InternalPortStatusEvent.class) |
151 | .register(DeviceAntiEntropyAdvertisement.class) | 151 | .register(DeviceAntiEntropyAdvertisement.class) |
152 | .register(DeviceFragmentId.class) | 152 | .register(DeviceFragmentId.class) |
153 | .register(PortFragmentId.class) | 153 | .register(PortFragmentId.class) |
154 | - .build() | 154 | + .build(); |
155 | - .populate(1); | ||
156 | } | 155 | } |
157 | }; | 156 | }; |
158 | 157 | ... | ... |
... | @@ -156,9 +156,9 @@ public class DistributedFlowRuleStore | ... | @@ -156,9 +156,9 @@ public class DistributedFlowRuleStore |
156 | @Override | 156 | @Override |
157 | protected void setupKryoPool() { | 157 | protected void setupKryoPool() { |
158 | serializerPool = KryoNamespace.newBuilder() | 158 | serializerPool = KryoNamespace.newBuilder() |
159 | - .register(DistributedStoreSerializers.COMMON) | 159 | + .register(DistributedStoreSerializers.STORE_COMMON) |
160 | - .build() | 160 | + .nextId(DistributedStoreSerializers.STORE_CUSTOM_BEGIN) |
161 | - .populate(1); | 161 | + .build(); |
162 | } | 162 | } |
163 | }; | 163 | }; |
164 | 164 | ... | ... |
... | @@ -123,13 +123,13 @@ public class GossipHostStore | ... | @@ -123,13 +123,13 @@ public class GossipHostStore |
123 | @Override | 123 | @Override |
124 | protected void setupKryoPool() { | 124 | protected void setupKryoPool() { |
125 | serializerPool = KryoNamespace.newBuilder() | 125 | serializerPool = KryoNamespace.newBuilder() |
126 | - .register(DistributedStoreSerializers.COMMON) | 126 | + .register(DistributedStoreSerializers.STORE_COMMON) |
127 | + .nextId(DistributedStoreSerializers.STORE_CUSTOM_BEGIN) | ||
127 | .register(InternalHostEvent.class) | 128 | .register(InternalHostEvent.class) |
128 | .register(InternalHostRemovedEvent.class) | 129 | .register(InternalHostRemovedEvent.class) |
129 | .register(HostFragmentId.class) | 130 | .register(HostFragmentId.class) |
130 | .register(HostAntiEntropyAdvertisement.class) | 131 | .register(HostAntiEntropyAdvertisement.class) |
131 | - .build() | 132 | + .build(); |
132 | - .populate(1); | ||
133 | } | 133 | } |
134 | }; | 134 | }; |
135 | 135 | ... | ... |
... | @@ -93,8 +93,8 @@ public class DistributedIntentStore | ... | @@ -93,8 +93,8 @@ public class DistributedIntentStore |
93 | serializerPool = KryoNamespace.newBuilder() | 93 | serializerPool = KryoNamespace.newBuilder() |
94 | .setRegistrationRequired(false) | 94 | .setRegistrationRequired(false) |
95 | .register(KryoNamespaces.API) | 95 | .register(KryoNamespaces.API) |
96 | - .build() | 96 | + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID) |
97 | - .populate(1); | 97 | + .build(); |
98 | } | 98 | } |
99 | }; | 99 | }; |
100 | 100 | ... | ... |
... | @@ -86,8 +86,8 @@ public class HazelcastIntentStore | ... | @@ -86,8 +86,8 @@ public class HazelcastIntentStore |
86 | serializerPool = KryoNamespace.newBuilder() | 86 | serializerPool = KryoNamespace.newBuilder() |
87 | .setRegistrationRequired(false) | 87 | .setRegistrationRequired(false) |
88 | .register(KryoNamespaces.API) | 88 | .register(KryoNamespaces.API) |
89 | - .build() | 89 | + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID) |
90 | - .populate(1); | 90 | + .build(); |
91 | } | 91 | } |
92 | 92 | ||
93 | }; | 93 | }; | ... | ... |
... | @@ -129,13 +129,13 @@ public class GossipLinkStore | ... | @@ -129,13 +129,13 @@ public class GossipLinkStore |
129 | @Override | 129 | @Override |
130 | protected void setupKryoPool() { | 130 | protected void setupKryoPool() { |
131 | serializerPool = KryoNamespace.newBuilder() | 131 | serializerPool = KryoNamespace.newBuilder() |
132 | - .register(DistributedStoreSerializers.COMMON) | 132 | + .register(DistributedStoreSerializers.STORE_COMMON) |
133 | + .nextId(DistributedStoreSerializers.STORE_CUSTOM_BEGIN) | ||
133 | .register(InternalLinkEvent.class) | 134 | .register(InternalLinkEvent.class) |
134 | .register(InternalLinkRemovedEvent.class) | 135 | .register(InternalLinkRemovedEvent.class) |
135 | .register(LinkAntiEntropyAdvertisement.class) | 136 | .register(LinkAntiEntropyAdvertisement.class) |
136 | .register(LinkFragmentId.class) | 137 | .register(LinkFragmentId.class) |
137 | - .build() | 138 | + .build(); |
138 | - .populate(1); | ||
139 | } | 139 | } |
140 | }; | 140 | }; |
141 | 141 | ... | ... |
... | @@ -84,10 +84,9 @@ public class DistributedMastershipStore | ... | @@ -84,10 +84,9 @@ public class DistributedMastershipStore |
84 | protected void setupKryoPool() { | 84 | protected void setupKryoPool() { |
85 | serializerPool = KryoNamespace.newBuilder() | 85 | serializerPool = KryoNamespace.newBuilder() |
86 | .register(KryoNamespaces.API) | 86 | .register(KryoNamespaces.API) |
87 | - | 87 | + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID) |
88 | - .register(RoleValue.class, new RoleValueSerializer()) | 88 | + .register(new RoleValueSerializer(), RoleValue.class) |
89 | - .build() | 89 | + .build(); |
90 | - .populate(1); | ||
91 | } | 90 | } |
92 | }; | 91 | }; |
93 | 92 | ... | ... |
... | @@ -72,8 +72,8 @@ public class DistributedPacketStore | ... | @@ -72,8 +72,8 @@ public class DistributedPacketStore |
72 | protected void setupKryoPool() { | 72 | protected void setupKryoPool() { |
73 | serializerPool = KryoNamespace.newBuilder() | 73 | serializerPool = KryoNamespace.newBuilder() |
74 | .register(KryoNamespaces.API) | 74 | .register(KryoNamespaces.API) |
75 | - .build() | 75 | + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID) |
76 | - .populate(1); | 76 | + .build(); |
77 | } | 77 | } |
78 | }; | 78 | }; |
79 | 79 | ... | ... |
core/store/dist/src/main/java/org/onlab/onos/store/serializers/impl/DistributedStoreSerializers.java
... | @@ -23,13 +23,17 @@ import org.onlab.util.KryoNamespace; | ... | @@ -23,13 +23,17 @@ import org.onlab.util.KryoNamespace; |
23 | 23 | ||
24 | public final class DistributedStoreSerializers { | 24 | public final class DistributedStoreSerializers { |
25 | 25 | ||
26 | + | ||
27 | + public static final int STORE_CUSTOM_BEGIN = KryoNamespaces.BEGIN_USER_CUSTOM_ID + 10; | ||
28 | + | ||
26 | /** | 29 | /** |
27 | * KryoNamespace which can serialize ON.lab misc classes. | 30 | * KryoNamespace which can serialize ON.lab misc classes. |
28 | */ | 31 | */ |
29 | - public static final KryoNamespace COMMON = KryoNamespace.newBuilder() | 32 | + public static final KryoNamespace STORE_COMMON = KryoNamespace.newBuilder() |
30 | .register(KryoNamespaces.API) | 33 | .register(KryoNamespaces.API) |
34 | + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID) | ||
31 | .register(Timestamped.class) | 35 | .register(Timestamped.class) |
32 | - .register(MastershipBasedTimestamp.class, new MastershipBasedTimestampSerializer()) | 36 | + .register(new MastershipBasedTimestampSerializer(), MastershipBasedTimestamp.class) |
33 | .register(WallClockTimestamp.class) | 37 | .register(WallClockTimestamp.class) |
34 | .build(); | 38 | .build(); |
35 | 39 | ... | ... |
... | @@ -55,8 +55,8 @@ public class CMap<K, V> { | ... | @@ -55,8 +55,8 @@ public class CMap<K, V> { |
55 | * Creates a CMap instance. | 55 | * Creates a CMap instance. |
56 | * It will create the table if necessary. | 56 | * It will create the table if necessary. |
57 | * | 57 | * |
58 | - * @param dbAdminService | 58 | + * @param dbAdminService DatabaseAdminService to use for this instance |
59 | - * @param dbService | 59 | + * @param dbService DatabaseService to use for this instance |
60 | * @param tableName table which this Map corresponds to | 60 | * @param tableName table which this Map corresponds to |
61 | * @param serializer Value serializer | 61 | * @param serializer Value serializer |
62 | */ | 62 | */ | ... | ... |
... | @@ -2,13 +2,6 @@ package org.onlab.onos.store.service.impl; | ... | @@ -2,13 +2,6 @@ package org.onlab.onos.store.service.impl; |
2 | 2 | ||
3 | import static org.slf4j.LoggerFactory.getLogger; | 3 | import static org.slf4j.LoggerFactory.getLogger; |
4 | 4 | ||
5 | -import java.util.ArrayList; | ||
6 | -import java.util.Arrays; | ||
7 | -import java.util.Collection; | ||
8 | -import java.util.Collections; | ||
9 | -import java.util.HashMap; | ||
10 | -import java.util.HashSet; | ||
11 | -import java.util.LinkedList; | ||
12 | import java.util.Vector; | 5 | import java.util.Vector; |
13 | 6 | ||
14 | import net.kuujo.copycat.cluster.TcpClusterConfig; | 7 | import net.kuujo.copycat.cluster.TcpClusterConfig; |
... | @@ -40,29 +33,14 @@ import org.apache.felix.scr.annotations.Service; | ... | @@ -40,29 +33,14 @@ import org.apache.felix.scr.annotations.Service; |
40 | import org.onlab.onos.cluster.ClusterService; | 33 | import org.onlab.onos.cluster.ClusterService; |
41 | import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; | 34 | import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; |
42 | import org.onlab.onos.store.cluster.messaging.MessageSubject; | 35 | import org.onlab.onos.store.cluster.messaging.MessageSubject; |
43 | -import org.onlab.onos.store.serializers.ImmutableListSerializer; | 36 | +import org.onlab.onos.store.serializers.KryoNamespaces; |
44 | -import org.onlab.onos.store.serializers.ImmutableMapSerializer; | ||
45 | -import org.onlab.onos.store.serializers.ImmutableSetSerializer; | ||
46 | import org.onlab.onos.store.serializers.KryoSerializer; | 37 | import org.onlab.onos.store.serializers.KryoSerializer; |
47 | -import org.onlab.onos.store.service.BatchReadRequest; | 38 | +import org.onlab.onos.store.serializers.StoreSerializer; |
48 | -import org.onlab.onos.store.service.BatchWriteRequest; | 39 | +import org.onlab.onos.store.service.impl.DatabaseStateMachine.State; |
49 | -import org.onlab.onos.store.service.ReadRequest; | 40 | +import org.onlab.onos.store.service.impl.DatabaseStateMachine.TableMetadata; |
50 | -import org.onlab.onos.store.service.ReadResult; | ||
51 | -import org.onlab.onos.store.service.ReadStatus; | ||
52 | -import org.onlab.onos.store.service.VersionedValue; | ||
53 | -import org.onlab.onos.store.service.WriteRequest; | ||
54 | -import org.onlab.onos.store.service.WriteResult; | ||
55 | -import org.onlab.onos.store.service.WriteStatus; | ||
56 | import org.onlab.util.KryoNamespace; | 41 | import org.onlab.util.KryoNamespace; |
57 | import org.slf4j.Logger; | 42 | import org.slf4j.Logger; |
58 | 43 | ||
59 | -import com.esotericsoftware.kryo.Kryo; | ||
60 | -import com.esotericsoftware.kryo.io.Input; | ||
61 | -import com.esotericsoftware.kryo.serializers.CollectionSerializer; | ||
62 | -import com.google.common.collect.ImmutableList; | ||
63 | -import com.google.common.collect.ImmutableMap; | ||
64 | -import com.google.common.collect.ImmutableSet; | ||
65 | - | ||
66 | /** | 44 | /** |
67 | * ONOS Cluster messaging based Copycat protocol. | 45 | * ONOS Cluster messaging based Copycat protocol. |
68 | */ | 46 | */ |
... | @@ -88,7 +66,11 @@ public class ClusterMessagingProtocol | ... | @@ -88,7 +66,11 @@ public class ClusterMessagingProtocol |
88 | public static final MessageSubject COPYCAT_SUBMIT = | 66 | public static final MessageSubject COPYCAT_SUBMIT = |
89 | new MessageSubject("copycat-raft-consensus-submit"); | 67 | new MessageSubject("copycat-raft-consensus-submit"); |
90 | 68 | ||
91 | - private static final KryoNamespace COPYCAT = KryoNamespace.newBuilder() | 69 | + static final int AFTER_COPYCAT = KryoNamespaces.BEGIN_USER_CUSTOM_ID + 50; |
70 | + | ||
71 | + static final KryoNamespace COPYCAT = KryoNamespace.newBuilder() | ||
72 | + .register(KryoNamespaces.API) | ||
73 | + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID) | ||
92 | .register(PingRequest.class) | 74 | .register(PingRequest.class) |
93 | .register(PingResponse.class) | 75 | .register(PingResponse.class) |
94 | .register(PollRequest.class) | 76 | .register(PollRequest.class) |
... | @@ -105,53 +87,23 @@ public class ClusterMessagingProtocol | ... | @@ -105,53 +87,23 @@ public class ClusterMessagingProtocol |
105 | .register(TcpClusterConfig.class) | 87 | .register(TcpClusterConfig.class) |
106 | .register(TcpMember.class) | 88 | .register(TcpMember.class) |
107 | .register(LeaderElectEvent.class) | 89 | .register(LeaderElectEvent.class) |
108 | - .build(); | 90 | + .register(Vector.class) |
109 | - | ||
110 | - private static final KryoNamespace DATABASE = KryoNamespace.newBuilder() | ||
111 | - .register(ReadRequest.class) | ||
112 | - .register(WriteRequest.class) | ||
113 | - .register(WriteRequest.Type.class) | ||
114 | - .register(WriteResult.class) | ||
115 | - .register(ReadResult.class) | ||
116 | - .register(BatchReadRequest.class) | ||
117 | - .register(BatchWriteRequest.class) | ||
118 | - .register(ReadStatus.class) | ||
119 | - .register(WriteStatus.class) | ||
120 | - .register(VersionedValue.class) | ||
121 | - .build(); | ||
122 | - | ||
123 | - public static final KryoNamespace COMMON = KryoNamespace.newBuilder() | ||
124 | - .register(Arrays.asList().getClass(), new CollectionSerializer() { | ||
125 | - @Override | ||
126 | - @SuppressWarnings("rawtypes") | ||
127 | - protected Collection<?> create(Kryo kryo, Input input, Class<Collection> type) { | ||
128 | - return new ArrayList(); | ||
129 | - } | ||
130 | - }) | ||
131 | - .register(ImmutableMap.class, new ImmutableMapSerializer()) | ||
132 | - .register(ImmutableList.class, new ImmutableListSerializer()) | ||
133 | - .register(ImmutableSet.class, new ImmutableSetSerializer()) | ||
134 | - .register( | ||
135 | - Vector.class, | ||
136 | - ArrayList.class, | ||
137 | - Arrays.asList().getClass(), | ||
138 | - HashMap.class, | ||
139 | - HashSet.class, | ||
140 | - LinkedList.class, | ||
141 | - Collections.singletonList("").getClass(), | ||
142 | - byte[].class) | ||
143 | .build(); | 91 | .build(); |
144 | 92 | ||
145 | // serializer used for CopyCat Protocol | 93 | // serializer used for CopyCat Protocol |
146 | - public static final KryoSerializer SERIALIZER = new KryoSerializer() { | 94 | + public static final StoreSerializer DB_SERIALIZER = new KryoSerializer() { |
147 | @Override | 95 | @Override |
148 | protected void setupKryoPool() { | 96 | protected void setupKryoPool() { |
149 | serializerPool = KryoNamespace.newBuilder() | 97 | serializerPool = KryoNamespace.newBuilder() |
150 | .register(COPYCAT) | 98 | .register(COPYCAT) |
151 | - .register(COMMON) | 99 | + .nextId(AFTER_COPYCAT) |
152 | - .register(DATABASE) | 100 | + // for snapshot |
153 | - .build() | 101 | + .register(State.class) |
154 | - .populate(1); | 102 | + .register(TableMetadata.class) |
103 | + // TODO: Move this out ? | ||
104 | + .register(TableModificationEvent.class) | ||
105 | + .register(TableModificationEvent.Type.class) | ||
106 | + .build(); | ||
155 | } | 107 | } |
156 | }; | 108 | }; |
157 | 109 | ... | ... |
1 | package org.onlab.onos.store.service.impl; | 1 | package org.onlab.onos.store.service.impl; |
2 | 2 | ||
3 | import static com.google.common.base.Verify.verifyNotNull; | 3 | import static com.google.common.base.Verify.verifyNotNull; |
4 | -import static org.onlab.onos.store.service.impl.ClusterMessagingProtocol.SERIALIZER; | 4 | +import static org.onlab.onos.store.service.impl.ClusterMessagingProtocol.DB_SERIALIZER; |
5 | import static org.onlab.util.Tools.namedThreads; | 5 | import static org.onlab.util.Tools.namedThreads; |
6 | import static org.slf4j.LoggerFactory.getLogger; | 6 | import static org.slf4j.LoggerFactory.getLogger; |
7 | 7 | ||
... | @@ -139,7 +139,7 @@ public class ClusterMessagingProtocolClient implements ProtocolClient { | ... | @@ -139,7 +139,7 @@ public class ClusterMessagingProtocolClient implements ProtocolClient { |
139 | new ClusterMessage( | 139 | new ClusterMessage( |
140 | localNode.id(), | 140 | localNode.id(), |
141 | messageType(request), | 141 | messageType(request), |
142 | - verifyNotNull(SERIALIZER.encode(request))); | 142 | + verifyNotNull(DB_SERIALIZER.encode(request))); |
143 | this.future = future; | 143 | this.future = future; |
144 | } | 144 | } |
145 | 145 | ||
... | @@ -158,7 +158,8 @@ public class ClusterMessagingProtocolClient implements ProtocolClient { | ... | @@ -158,7 +158,8 @@ public class ClusterMessagingProtocolClient implements ProtocolClient { |
158 | if (!connectionOK.getAndSet(true)) { | 158 | if (!connectionOK.getAndSet(true)) { |
159 | log.info("Connectivity to {} restored", remoteNode); | 159 | log.info("Connectivity to {} restored", remoteNode); |
160 | } | 160 | } |
161 | - future.complete(verifyNotNull(SERIALIZER.decode(response))); | 161 | + future.complete(verifyNotNull(DB_SERIALIZER.decode(response))); |
162 | + | ||
162 | } catch (IOException | TimeoutException e) { | 163 | } catch (IOException | TimeoutException e) { |
163 | if (connectionOK.getAndSet(false)) { | 164 | if (connectionOK.getAndSet(false)) { |
164 | log.warn("Detected connectivity issues with {}. Reason: {}", remoteNode, e.getMessage()); | 165 | log.warn("Detected connectivity issues with {}. Reason: {}", remoteNode, e.getMessage()); | ... | ... |
... | @@ -66,7 +66,7 @@ public class ClusterMessagingProtocolServer implements ProtocolServer { | ... | @@ -66,7 +66,7 @@ public class ClusterMessagingProtocolServer implements ProtocolServer { |
66 | 66 | ||
67 | @Override | 67 | @Override |
68 | public void handle(ClusterMessage message) { | 68 | public void handle(ClusterMessage message) { |
69 | - T request = ClusterMessagingProtocol.SERIALIZER.decode(message.payload()); | 69 | + T request = ClusterMessagingProtocol.DB_SERIALIZER.decode(message.payload()); |
70 | if (handler == null) { | 70 | if (handler == null) { |
71 | // there is a slight window of time during state transition, | 71 | // there is a slight window of time during state transition, |
72 | // where handler becomes null | 72 | // where handler becomes null |
... | @@ -117,7 +117,7 @@ public class ClusterMessagingProtocolServer implements ProtocolServer { | ... | @@ -117,7 +117,7 @@ public class ClusterMessagingProtocolServer implements ProtocolServer { |
117 | } else { | 117 | } else { |
118 | try { | 118 | try { |
119 | log.trace("responding to {}", message.subject()); | 119 | log.trace("responding to {}", message.subject()); |
120 | - message.respond(ClusterMessagingProtocol.SERIALIZER.encode(response)); | 120 | + message.respond(ClusterMessagingProtocol.DB_SERIALIZER.encode(response)); |
121 | } catch (Exception e) { | 121 | } catch (Exception e) { |
122 | log.error("Failed to respond to " + response.getClass().getName(), e); | 122 | log.error("Failed to respond to " + response.getClass().getName(), e); |
123 | } | 123 | } | ... | ... |
... | @@ -54,7 +54,7 @@ public class DatabaseClient implements ClusterMessageHandler { | ... | @@ -54,7 +54,7 @@ public class DatabaseClient implements ClusterMessageHandler { |
54 | @Override | 54 | @Override |
55 | public void handle(ClusterMessage message) { | 55 | public void handle(ClusterMessage message) { |
56 | LeaderElectEvent event = | 56 | LeaderElectEvent event = |
57 | - ClusterMessagingProtocol.SERIALIZER.decode(message.payload()); | 57 | + ClusterMessagingProtocol.DB_SERIALIZER.decode(message.payload()); |
58 | TcpMember newLeader = event.leader(); | 58 | TcpMember newLeader = event.leader(); |
59 | long newLeaderTerm = event.term(); | 59 | long newLeaderTerm = event.term(); |
60 | if (newLeader != null && !newLeader.equals(currentLeader) && newLeaderTerm > currentLeaderTerm) { | 60 | if (newLeader != null && !newLeader.equals(currentLeader) && newLeaderTerm > currentLeaderTerm) { | ... | ... |
... | @@ -101,7 +101,7 @@ public class DatabaseEntryExpirationTracker implements | ... | @@ -101,7 +101,7 @@ public class DatabaseEntryExpirationTracker implements |
101 | log.debug("Broadcasting {} to the entire cluster", event); | 101 | log.debug("Broadcasting {} to the entire cluster", event); |
102 | clusterCommunicator.broadcastIncludeSelf(new ClusterMessage( | 102 | clusterCommunicator.broadcastIncludeSelf(new ClusterMessage( |
103 | localNode.id(), DatabaseStateMachine.DATABASE_UPDATE_EVENTS, | 103 | localNode.id(), DatabaseStateMachine.DATABASE_UPDATE_EVENTS, |
104 | - DatabaseStateMachine.SERIALIZER.encode(event))); | 104 | + ClusterMessagingProtocol.DB_SERIALIZER.encode(event))); |
105 | } catch (IOException e) { | 105 | } catch (IOException e) { |
106 | log.error("Failed to broadcast a database row deleted event.", e); | 106 | log.error("Failed to broadcast a database row deleted event.", e); |
107 | } | 107 | } | ... | ... |
... | @@ -173,7 +173,7 @@ public class DatabaseManager implements DatabaseService, DatabaseAdminService { | ... | @@ -173,7 +173,7 @@ public class DatabaseManager implements DatabaseService, DatabaseAdminService { |
173 | DatabaseStateMachine stateMachine = new DatabaseStateMachine(); | 173 | DatabaseStateMachine stateMachine = new DatabaseStateMachine(); |
174 | stateMachine.addEventListener(expirationTracker); | 174 | stateMachine.addEventListener(expirationTracker); |
175 | Log consensusLog = new MapDBLog(LOG_FILE_PREFIX + localNode.id(), | 175 | Log consensusLog = new MapDBLog(LOG_FILE_PREFIX + localNode.id(), |
176 | - ClusterMessagingProtocol.SERIALIZER); | 176 | + ClusterMessagingProtocol.DB_SERIALIZER); |
177 | 177 | ||
178 | copycat = new Copycat(stateMachine, consensusLog, cluster, copycatMessagingProtocol); | 178 | copycat = new Copycat(stateMachine, consensusLog, cluster, copycatMessagingProtocol); |
179 | copycat.event(LeaderElectEvent.class).registerHandler(new RaftLeaderElectionMonitor()); | 179 | copycat.event(LeaderElectEvent.class).registerHandler(new RaftLeaderElectionMonitor()); |
... | @@ -432,7 +432,7 @@ public class DatabaseManager implements DatabaseService, DatabaseAdminService { | ... | @@ -432,7 +432,7 @@ public class DatabaseManager implements DatabaseService, DatabaseAdminService { |
432 | new ClusterMessage( | 432 | new ClusterMessage( |
433 | clusterService.getLocalNode().id(), | 433 | clusterService.getLocalNode().id(), |
434 | RAFT_LEADER_ELECTION_EVENT, | 434 | RAFT_LEADER_ELECTION_EVENT, |
435 | - ClusterMessagingProtocol.SERIALIZER.encode(event))); | 435 | + ClusterMessagingProtocol.DB_SERIALIZER.encode(event))); |
436 | } | 436 | } |
437 | } catch (Exception e) { | 437 | } catch (Exception e) { |
438 | log.debug("LeaderAdvertiser failed with exception", e); | 438 | log.debug("LeaderAdvertiser failed with exception", e); |
... | @@ -454,7 +454,7 @@ public class DatabaseManager implements DatabaseService, DatabaseAdminService { | ... | @@ -454,7 +454,7 @@ public class DatabaseManager implements DatabaseService, DatabaseAdminService { |
454 | new ClusterMessage( | 454 | new ClusterMessage( |
455 | clusterService.getLocalNode().id(), | 455 | clusterService.getLocalNode().id(), |
456 | RAFT_LEADER_ELECTION_EVENT, | 456 | RAFT_LEADER_ELECTION_EVENT, |
457 | - ClusterMessagingProtocol.SERIALIZER.encode(event))); | 457 | + ClusterMessagingProtocol.DB_SERIALIZER.encode(event))); |
458 | } else { | 458 | } else { |
459 | if (myLeaderEvent != null) { | 459 | if (myLeaderEvent != null) { |
460 | log.debug("This node is no longer the Leader"); | 460 | log.debug("This node is no longer the Leader"); | ... | ... |
... | @@ -2,6 +2,7 @@ package org.onlab.onos.store.service.impl; | ... | @@ -2,6 +2,7 @@ package org.onlab.onos.store.service.impl; |
2 | 2 | ||
3 | import static org.onlab.util.Tools.namedThreads; | 3 | import static org.onlab.util.Tools.namedThreads; |
4 | import static org.slf4j.LoggerFactory.getLogger; | 4 | import static org.slf4j.LoggerFactory.getLogger; |
5 | +import static org.onlab.onos.store.service.impl.ClusterMessagingProtocol.DB_SERIALIZER; | ||
5 | 6 | ||
6 | import java.io.ByteArrayInputStream; | 7 | import java.io.ByteArrayInputStream; |
7 | import java.io.ByteArrayOutputStream; | 8 | import java.io.ByteArrayOutputStream; |
... | @@ -20,7 +21,6 @@ import net.kuujo.copycat.Query; | ... | @@ -20,7 +21,6 @@ import net.kuujo.copycat.Query; |
20 | import net.kuujo.copycat.StateMachine; | 21 | import net.kuujo.copycat.StateMachine; |
21 | 22 | ||
22 | import org.onlab.onos.store.cluster.messaging.MessageSubject; | 23 | import org.onlab.onos.store.cluster.messaging.MessageSubject; |
23 | -import org.onlab.onos.store.serializers.KryoSerializer; | ||
24 | import org.onlab.onos.store.service.BatchReadRequest; | 24 | import org.onlab.onos.store.service.BatchReadRequest; |
25 | import org.onlab.onos.store.service.BatchWriteRequest; | 25 | import org.onlab.onos.store.service.BatchWriteRequest; |
26 | import org.onlab.onos.store.service.ReadRequest; | 26 | import org.onlab.onos.store.service.ReadRequest; |
... | @@ -30,7 +30,6 @@ import org.onlab.onos.store.service.VersionedValue; | ... | @@ -30,7 +30,6 @@ import org.onlab.onos.store.service.VersionedValue; |
30 | import org.onlab.onos.store.service.WriteRequest; | 30 | import org.onlab.onos.store.service.WriteRequest; |
31 | import org.onlab.onos.store.service.WriteResult; | 31 | import org.onlab.onos.store.service.WriteResult; |
32 | import org.onlab.onos.store.service.WriteStatus; | 32 | import org.onlab.onos.store.service.WriteStatus; |
33 | -import org.onlab.util.KryoNamespace; | ||
34 | import org.slf4j.Logger; | 33 | import org.slf4j.Logger; |
35 | 34 | ||
36 | import com.google.common.base.MoreObjects; | 35 | import com.google.common.base.MoreObjects; |
... | @@ -39,7 +38,6 @@ import com.google.common.collect.ImmutableSet; | ... | @@ -39,7 +38,6 @@ import com.google.common.collect.ImmutableSet; |
39 | import com.google.common.collect.Lists; | 38 | import com.google.common.collect.Lists; |
40 | import com.google.common.collect.Maps; | 39 | import com.google.common.collect.Maps; |
41 | import com.google.common.collect.Sets; | 40 | import com.google.common.collect.Sets; |
42 | -import com.google.common.io.ByteStreams; | ||
43 | 41 | ||
44 | /** | 42 | /** |
45 | * StateMachine whose transitions are coordinated/replicated | 43 | * StateMachine whose transitions are coordinated/replicated |
... | @@ -59,33 +57,13 @@ public class DatabaseStateMachine implements StateMachine { | ... | @@ -59,33 +57,13 @@ public class DatabaseStateMachine implements StateMachine { |
59 | public static final MessageSubject DATABASE_UPDATE_EVENTS = | 57 | public static final MessageSubject DATABASE_UPDATE_EVENTS = |
60 | new MessageSubject("database-update-events"); | 58 | new MessageSubject("database-update-events"); |
61 | 59 | ||
62 | - // serializer used for snapshot | ||
63 | - public static final KryoSerializer SERIALIZER = new KryoSerializer() { | ||
64 | - @Override | ||
65 | - protected void setupKryoPool() { | ||
66 | - serializerPool = KryoNamespace.newBuilder() | ||
67 | - .register(VersionedValue.class) | ||
68 | - .register(State.class) | ||
69 | - .register(TableMetadata.class) | ||
70 | - .register(BatchReadRequest.class) | ||
71 | - .register(BatchWriteRequest.class) | ||
72 | - .register(ReadStatus.class) | ||
73 | - .register(WriteStatus.class) | ||
74 | - // TODO: Move this out ? | ||
75 | - .register(TableModificationEvent.class) | ||
76 | - .register(TableModificationEvent.Type.class) | ||
77 | - .register(ClusterMessagingProtocol.COMMON) | ||
78 | - .build() | ||
79 | - .populate(1); | ||
80 | - } | ||
81 | - }; | ||
82 | - | ||
83 | private final Set<DatabaseUpdateEventListener> listeners = Sets.newIdentityHashSet(); | 60 | private final Set<DatabaseUpdateEventListener> listeners = Sets.newIdentityHashSet(); |
84 | 61 | ||
85 | // durable internal state of the database. | 62 | // durable internal state of the database. |
86 | private State state = new State(); | 63 | private State state = new State(); |
87 | 64 | ||
88 | - private boolean compressSnapshot = false; | 65 | + // TODO make this configurable |
66 | + private boolean compressSnapshot = true; | ||
89 | 67 | ||
90 | @Command | 68 | @Command |
91 | public boolean createTable(String tableName) { | 69 | public boolean createTable(String tableName) { |
... | @@ -402,14 +380,14 @@ public class DatabaseStateMachine implements StateMachine { | ... | @@ -402,14 +380,14 @@ public class DatabaseStateMachine implements StateMachine { |
402 | public byte[] takeSnapshot() { | 380 | public byte[] takeSnapshot() { |
403 | try { | 381 | try { |
404 | if (compressSnapshot) { | 382 | if (compressSnapshot) { |
405 | - byte[] input = SERIALIZER.encode(state); | 383 | + byte[] input = DB_SERIALIZER.encode(state); |
406 | ByteArrayOutputStream comp = new ByteArrayOutputStream(input.length); | 384 | ByteArrayOutputStream comp = new ByteArrayOutputStream(input.length); |
407 | DeflaterOutputStream compressor = new DeflaterOutputStream(comp); | 385 | DeflaterOutputStream compressor = new DeflaterOutputStream(comp); |
408 | compressor.write(input, 0, input.length); | 386 | compressor.write(input, 0, input.length); |
409 | compressor.close(); | 387 | compressor.close(); |
410 | return comp.toByteArray(); | 388 | return comp.toByteArray(); |
411 | } else { | 389 | } else { |
412 | - return SERIALIZER.encode(state); | 390 | + return DB_SERIALIZER.encode(state); |
413 | } | 391 | } |
414 | } catch (Exception e) { | 392 | } catch (Exception e) { |
415 | log.error("Failed to take snapshot", e); | 393 | log.error("Failed to take snapshot", e); |
... | @@ -423,10 +401,9 @@ public class DatabaseStateMachine implements StateMachine { | ... | @@ -423,10 +401,9 @@ public class DatabaseStateMachine implements StateMachine { |
423 | if (compressSnapshot) { | 401 | if (compressSnapshot) { |
424 | ByteArrayInputStream in = new ByteArrayInputStream(data); | 402 | ByteArrayInputStream in = new ByteArrayInputStream(data); |
425 | InflaterInputStream decompressor = new InflaterInputStream(in); | 403 | InflaterInputStream decompressor = new InflaterInputStream(in); |
426 | - ByteStreams.toByteArray(decompressor); | 404 | + this.state = DB_SERIALIZER.decode(decompressor); |
427 | - this.state = SERIALIZER.decode(ByteStreams.toByteArray(decompressor)); | ||
428 | } else { | 405 | } else { |
429 | - this.state = SERIALIZER.decode(data); | 406 | + this.state = DB_SERIALIZER.decode(data); |
430 | } | 407 | } |
431 | 408 | ||
432 | updatesExecutor.submit(new Runnable() { | 409 | updatesExecutor.submit(new Runnable() { | ... | ... |
... | @@ -149,7 +149,7 @@ public class DistributedLockManager implements LockService { | ... | @@ -149,7 +149,7 @@ public class DistributedLockManager implements LockService { |
149 | private class LockEventMessageListener implements ClusterMessageHandler { | 149 | private class LockEventMessageListener implements ClusterMessageHandler { |
150 | @Override | 150 | @Override |
151 | public void handle(ClusterMessage message) { | 151 | public void handle(ClusterMessage message) { |
152 | - TableModificationEvent event = DatabaseStateMachine.SERIALIZER | 152 | + TableModificationEvent event = ClusterMessagingProtocol.DB_SERIALIZER |
153 | .decode(message.payload()); | 153 | .decode(message.payload()); |
154 | if (event.tableName().equals(ONOS_LOCK_TABLE_NAME) && | 154 | if (event.tableName().equals(ONOS_LOCK_TABLE_NAME) && |
155 | event.type().equals(TableModificationEvent.Type.ROW_DELETED)) { | 155 | event.type().equals(TableModificationEvent.Type.ROW_DELETED)) { | ... | ... |
... | @@ -90,9 +90,9 @@ public class DistributedStatisticStore implements StatisticStore { | ... | @@ -90,9 +90,9 @@ public class DistributedStatisticStore implements StatisticStore { |
90 | protected void setupKryoPool() { | 90 | protected void setupKryoPool() { |
91 | serializerPool = KryoNamespace.newBuilder() | 91 | serializerPool = KryoNamespace.newBuilder() |
92 | .register(KryoNamespaces.API) | 92 | .register(KryoNamespaces.API) |
93 | + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID) | ||
93 | // register this store specific classes here | 94 | // register this store specific classes here |
94 | - .build() | 95 | + .build(); |
95 | - .populate(1); | ||
96 | } | 96 | } |
97 | };; | 97 | };; |
98 | 98 | ... | ... |
... | @@ -95,7 +95,7 @@ public class MastershipBasedTimestampTest { | ... | @@ -95,7 +95,7 @@ public class MastershipBasedTimestampTest { |
95 | public final void testKryoSerializableWithHandcraftedSerializer() { | 95 | public final void testKryoSerializableWithHandcraftedSerializer() { |
96 | final ByteBuffer buffer = ByteBuffer.allocate(1 * 1024 * 1024); | 96 | final ByteBuffer buffer = ByteBuffer.allocate(1 * 1024 * 1024); |
97 | final KryoNamespace kryos = KryoNamespace.newBuilder() | 97 | final KryoNamespace kryos = KryoNamespace.newBuilder() |
98 | - .register(MastershipBasedTimestamp.class, new MastershipBasedTimestampSerializer()) | 98 | + .register(new MastershipBasedTimestampSerializer(), MastershipBasedTimestamp.class) |
99 | .build(); | 99 | .build(); |
100 | 100 | ||
101 | kryos.serialize(TS_1_2, buffer); | 101 | kryos.serialize(TS_1_2, buffer); | ... | ... |
... | @@ -22,7 +22,7 @@ import com.google.common.testing.EqualsTester; | ... | @@ -22,7 +22,7 @@ import com.google.common.testing.EqualsTester; |
22 | */ | 22 | */ |
23 | public class MapDBLogTest { | 23 | public class MapDBLogTest { |
24 | 24 | ||
25 | - private static final StoreSerializer SERIALIZER = ClusterMessagingProtocol.SERIALIZER; | 25 | + private static final StoreSerializer SERIALIZER = ClusterMessagingProtocol.DB_SERIALIZER; |
26 | private static final Entry TEST_ENTRY1 = new OperationEntry(1, "test1"); | 26 | private static final Entry TEST_ENTRY1 = new OperationEntry(1, "test1"); |
27 | private static final Entry TEST_ENTRY2 = new OperationEntry(2, "test12"); | 27 | private static final Entry TEST_ENTRY2 = new OperationEntry(2, "test12"); |
28 | private static final Entry TEST_ENTRY3 = new OperationEntry(3, "test123"); | 28 | private static final Entry TEST_ENTRY3 = new OperationEntry(3, "test123"); | ... | ... |
core/store/serializers/src/main/java/org/onlab/onos/store/serializers/ArraysAsListSerializer.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onlab.onos.store.serializers; | ||
18 | + | ||
19 | +import java.util.ArrayList; | ||
20 | +import java.util.List; | ||
21 | + | ||
22 | +import com.esotericsoftware.kryo.Kryo; | ||
23 | +import com.esotericsoftware.kryo.Serializer; | ||
24 | +import com.esotericsoftware.kryo.io.Input; | ||
25 | +import com.esotericsoftware.kryo.io.Output; | ||
26 | + | ||
27 | +/** | ||
28 | + * Kryo Serializer for {@link java.util.Arrays#asList(Object...)}. | ||
29 | + */ | ||
30 | +public final class ArraysAsListSerializer extends Serializer<List<?>> { | ||
31 | + | ||
32 | + @Override | ||
33 | + public void write(Kryo kryo, Output output, List<?> object) { | ||
34 | + output.writeInt(object.size(), true); | ||
35 | + for (Object elm : object) { | ||
36 | + kryo.writeClassAndObject(output, elm); | ||
37 | + } | ||
38 | + } | ||
39 | + | ||
40 | + @Override | ||
41 | + public List<?> read(Kryo kryo, Input input, Class<List<?>> type) { | ||
42 | + final int size = input.readInt(true); | ||
43 | + List<Object> list = new ArrayList<>(size); | ||
44 | + for (int i = 0; i < size; ++i) { | ||
45 | + list.add(kryo.readClassAndObject(input)); | ||
46 | + } | ||
47 | + return list; | ||
48 | + } | ||
49 | +} |
... | @@ -45,7 +45,7 @@ public class DefaultLinkSerializer extends Serializer<DefaultLink> { | ... | @@ -45,7 +45,7 @@ public class DefaultLinkSerializer extends Serializer<DefaultLink> { |
45 | kryo.writeClassAndObject(output, object.dst()); | 45 | kryo.writeClassAndObject(output, object.dst()); |
46 | kryo.writeClassAndObject(output, object.type()); | 46 | kryo.writeClassAndObject(output, object.type()); |
47 | kryo.writeClassAndObject(output, object.state()); | 47 | kryo.writeClassAndObject(output, object.state()); |
48 | - kryo.writeClassAndObject(output, object.isDurable()); | 48 | + output.writeBoolean(object.isDurable()); |
49 | } | 49 | } |
50 | 50 | ||
51 | @Override | 51 | @Override |
... | @@ -55,7 +55,7 @@ public class DefaultLinkSerializer extends Serializer<DefaultLink> { | ... | @@ -55,7 +55,7 @@ public class DefaultLinkSerializer extends Serializer<DefaultLink> { |
55 | ConnectPoint dst = (ConnectPoint) kryo.readClassAndObject(input); | 55 | ConnectPoint dst = (ConnectPoint) kryo.readClassAndObject(input); |
56 | Type linkType = (Type) kryo.readClassAndObject(input); | 56 | Type linkType = (Type) kryo.readClassAndObject(input); |
57 | State state = (State) kryo.readClassAndObject(input); | 57 | State state = (State) kryo.readClassAndObject(input); |
58 | - boolean isDurable = (boolean) kryo.readClassAndObject(input); | 58 | + boolean isDurable = input.readBoolean(); |
59 | return new DefaultLink(providerId, src, dst, linkType, state, isDurable); | 59 | return new DefaultLink(providerId, src, dst, linkType, state, isDurable); |
60 | } | 60 | } |
61 | } | 61 | } | ... | ... |
... | @@ -15,9 +15,8 @@ | ... | @@ -15,9 +15,8 @@ |
15 | */ | 15 | */ |
16 | package org.onlab.onos.store.serializers; | 16 | package org.onlab.onos.store.serializers; |
17 | 17 | ||
18 | -import org.onlab.util.KryoNamespace.FamilySerializer; | ||
19 | - | ||
20 | import com.esotericsoftware.kryo.Kryo; | 18 | import com.esotericsoftware.kryo.Kryo; |
19 | +import com.esotericsoftware.kryo.Serializer; | ||
21 | import com.esotericsoftware.kryo.io.Input; | 20 | import com.esotericsoftware.kryo.io.Input; |
22 | import com.esotericsoftware.kryo.io.Output; | 21 | import com.esotericsoftware.kryo.io.Output; |
23 | import com.google.common.collect.ImmutableList; | 22 | import com.google.common.collect.ImmutableList; |
... | @@ -26,7 +25,7 @@ import com.google.common.collect.ImmutableList.Builder; | ... | @@ -26,7 +25,7 @@ import com.google.common.collect.ImmutableList.Builder; |
26 | /** | 25 | /** |
27 | * Creates {@link ImmutableList} serializer instance. | 26 | * Creates {@link ImmutableList} serializer instance. |
28 | */ | 27 | */ |
29 | -public class ImmutableListSerializer extends FamilySerializer<ImmutableList<?>> { | 28 | +public class ImmutableListSerializer extends Serializer<ImmutableList<?>> { |
30 | 29 | ||
31 | /** | 30 | /** |
32 | * Creates {@link ImmutableList} serializer instance. | 31 | * Creates {@link ImmutableList} serializer instance. |
... | @@ -53,12 +52,4 @@ public class ImmutableListSerializer extends FamilySerializer<ImmutableList<?>> | ... | @@ -53,12 +52,4 @@ public class ImmutableListSerializer extends FamilySerializer<ImmutableList<?>> |
53 | } | 52 | } |
54 | return builder.build(); | 53 | return builder.build(); |
55 | } | 54 | } |
56 | - | ||
57 | - @Override | ||
58 | - public void registerFamilies(Kryo kryo) { | ||
59 | - kryo.register(ImmutableList.of(1).getClass(), this); | ||
60 | - kryo.register(ImmutableList.of(1, 2).getClass(), this); | ||
61 | - // TODO register required ImmutableList variants | ||
62 | - } | ||
63 | - | ||
64 | } | 55 | } | ... | ... |
... | @@ -19,9 +19,8 @@ import java.util.Collections; | ... | @@ -19,9 +19,8 @@ import java.util.Collections; |
19 | import java.util.HashMap; | 19 | import java.util.HashMap; |
20 | import java.util.Map; | 20 | import java.util.Map; |
21 | 21 | ||
22 | -import org.onlab.util.KryoNamespace.FamilySerializer; | ||
23 | - | ||
24 | import com.esotericsoftware.kryo.Kryo; | 22 | import com.esotericsoftware.kryo.Kryo; |
23 | +import com.esotericsoftware.kryo.Serializer; | ||
25 | import com.esotericsoftware.kryo.io.Input; | 24 | import com.esotericsoftware.kryo.io.Input; |
26 | import com.esotericsoftware.kryo.io.Output; | 25 | import com.esotericsoftware.kryo.io.Output; |
27 | import com.esotericsoftware.kryo.serializers.MapSerializer; | 26 | import com.esotericsoftware.kryo.serializers.MapSerializer; |
... | @@ -30,7 +29,7 @@ import com.google.common.collect.ImmutableMap; | ... | @@ -30,7 +29,7 @@ import com.google.common.collect.ImmutableMap; |
30 | /** | 29 | /** |
31 | * Kryo Serializer for {@link ImmutableMap}. | 30 | * Kryo Serializer for {@link ImmutableMap}. |
32 | */ | 31 | */ |
33 | -public class ImmutableMapSerializer extends FamilySerializer<ImmutableMap<?, ?>> { | 32 | +public class ImmutableMapSerializer extends Serializer<ImmutableMap<?, ?>> { |
34 | 33 | ||
35 | private final MapSerializer mapSerializer = new MapSerializer(); | 34 | private final MapSerializer mapSerializer = new MapSerializer(); |
36 | 35 | ||
... | @@ -56,12 +55,4 @@ public class ImmutableMapSerializer extends FamilySerializer<ImmutableMap<?, ?>> | ... | @@ -56,12 +55,4 @@ public class ImmutableMapSerializer extends FamilySerializer<ImmutableMap<?, ?>> |
56 | Map<?, ?> map = kryo.readObject(input, HashMap.class, mapSerializer); | 55 | Map<?, ?> map = kryo.readObject(input, HashMap.class, mapSerializer); |
57 | return ImmutableMap.copyOf(map); | 56 | return ImmutableMap.copyOf(map); |
58 | } | 57 | } |
59 | - | ||
60 | - @Override | ||
61 | - public void registerFamilies(Kryo kryo) { | ||
62 | - kryo.register(ImmutableMap.of().getClass(), this); | ||
63 | - kryo.register(ImmutableMap.of(1, 2).getClass(), this); | ||
64 | - kryo.register(ImmutableMap.of(1, 2, 3, 4).getClass(), this); | ||
65 | - // TODO register required ImmutableMap variants | ||
66 | - } | ||
67 | } | 58 | } | ... | ... |
... | @@ -18,9 +18,8 @@ package org.onlab.onos.store.serializers; | ... | @@ -18,9 +18,8 @@ package org.onlab.onos.store.serializers; |
18 | import java.util.ArrayList; | 18 | import java.util.ArrayList; |
19 | import java.util.List; | 19 | import java.util.List; |
20 | 20 | ||
21 | -import org.onlab.util.KryoNamespace.FamilySerializer; | ||
22 | - | ||
23 | import com.esotericsoftware.kryo.Kryo; | 21 | import com.esotericsoftware.kryo.Kryo; |
22 | +import com.esotericsoftware.kryo.Serializer; | ||
24 | import com.esotericsoftware.kryo.io.Input; | 23 | import com.esotericsoftware.kryo.io.Input; |
25 | import com.esotericsoftware.kryo.io.Output; | 24 | import com.esotericsoftware.kryo.io.Output; |
26 | import com.esotericsoftware.kryo.serializers.CollectionSerializer; | 25 | import com.esotericsoftware.kryo.serializers.CollectionSerializer; |
... | @@ -29,7 +28,7 @@ import com.google.common.collect.ImmutableSet; | ... | @@ -29,7 +28,7 @@ import com.google.common.collect.ImmutableSet; |
29 | /** | 28 | /** |
30 | * Kryo Serializer for {@link ImmutableSet}. | 29 | * Kryo Serializer for {@link ImmutableSet}. |
31 | */ | 30 | */ |
32 | -public class ImmutableSetSerializer extends FamilySerializer<ImmutableSet<?>> { | 31 | +public class ImmutableSetSerializer extends Serializer<ImmutableSet<?>> { |
33 | 32 | ||
34 | private final CollectionSerializer serializer = new CollectionSerializer(); | 33 | private final CollectionSerializer serializer = new CollectionSerializer(); |
35 | 34 | ||
... | @@ -39,6 +38,7 @@ public class ImmutableSetSerializer extends FamilySerializer<ImmutableSet<?>> { | ... | @@ -39,6 +38,7 @@ public class ImmutableSetSerializer extends FamilySerializer<ImmutableSet<?>> { |
39 | public ImmutableSetSerializer() { | 38 | public ImmutableSetSerializer() { |
40 | // non-null, immutable | 39 | // non-null, immutable |
41 | super(false, true); | 40 | super(false, true); |
41 | + serializer.setElementsCanBeNull(false); | ||
42 | } | 42 | } |
43 | 43 | ||
44 | @Override | 44 | @Override |
... | @@ -52,12 +52,4 @@ public class ImmutableSetSerializer extends FamilySerializer<ImmutableSet<?>> { | ... | @@ -52,12 +52,4 @@ public class ImmutableSetSerializer extends FamilySerializer<ImmutableSet<?>> { |
52 | List<?> elms = kryo.readObject(input, ArrayList.class, serializer); | 52 | List<?> elms = kryo.readObject(input, ArrayList.class, serializer); |
53 | return ImmutableSet.copyOf(elms); | 53 | return ImmutableSet.copyOf(elms); |
54 | } | 54 | } |
55 | - | ||
56 | - @Override | ||
57 | - public void registerFamilies(Kryo kryo) { | ||
58 | - kryo.register(ImmutableSet.of().getClass(), this); | ||
59 | - kryo.register(ImmutableSet.of(1).getClass(), this); | ||
60 | - kryo.register(ImmutableSet.of(1, 2).getClass(), this); | ||
61 | - // TODO register required ImmutableSet variants | ||
62 | - } | ||
63 | } | 55 | } | ... | ... |
... | @@ -19,6 +19,7 @@ import java.net.URI; | ... | @@ -19,6 +19,7 @@ import java.net.URI; |
19 | import java.time.Duration; | 19 | import java.time.Duration; |
20 | import java.util.ArrayList; | 20 | import java.util.ArrayList; |
21 | import java.util.Arrays; | 21 | import java.util.Arrays; |
22 | +import java.util.Collections; | ||
22 | import java.util.HashMap; | 23 | import java.util.HashMap; |
23 | import java.util.HashSet; | 24 | import java.util.HashSet; |
24 | import java.util.LinkedList; | 25 | import java.util.LinkedList; |
... | @@ -99,6 +100,15 @@ import org.onlab.onos.net.resource.LambdaResourceAllocation; | ... | @@ -99,6 +100,15 @@ import org.onlab.onos.net.resource.LambdaResourceAllocation; |
99 | import org.onlab.onos.net.resource.LambdaResourceRequest; | 100 | import org.onlab.onos.net.resource.LambdaResourceRequest; |
100 | import org.onlab.onos.net.resource.LinkResourceRequest; | 101 | import org.onlab.onos.net.resource.LinkResourceRequest; |
101 | import org.onlab.onos.store.Timestamp; | 102 | import org.onlab.onos.store.Timestamp; |
103 | +import org.onlab.onos.store.service.BatchReadRequest; | ||
104 | +import org.onlab.onos.store.service.BatchWriteRequest; | ||
105 | +import org.onlab.onos.store.service.ReadRequest; | ||
106 | +import org.onlab.onos.store.service.ReadResult; | ||
107 | +import org.onlab.onos.store.service.ReadStatus; | ||
108 | +import org.onlab.onos.store.service.VersionedValue; | ||
109 | +import org.onlab.onos.store.service.WriteRequest; | ||
110 | +import org.onlab.onos.store.service.WriteResult; | ||
111 | +import org.onlab.onos.store.service.WriteStatus; | ||
102 | import org.onlab.packet.ChassisId; | 112 | import org.onlab.packet.ChassisId; |
103 | import org.onlab.packet.IpAddress; | 113 | import org.onlab.packet.IpAddress; |
104 | import org.onlab.packet.Ip4Address; | 114 | import org.onlab.packet.Ip4Address; |
... | @@ -117,41 +127,62 @@ import com.google.common.collect.ImmutableSet; | ... | @@ -117,41 +127,62 @@ import com.google.common.collect.ImmutableSet; |
117 | public final class KryoNamespaces { | 127 | public final class KryoNamespaces { |
118 | 128 | ||
119 | public static final KryoNamespace BASIC = KryoNamespace.newBuilder() | 129 | public static final KryoNamespace BASIC = KryoNamespace.newBuilder() |
120 | - .register(ImmutableMap.class, new ImmutableMapSerializer()) | 130 | + .nextId(KryoNamespace.FLOATING_ID) |
121 | - .register(ImmutableList.class, new ImmutableListSerializer()) | 131 | + .register(byte[].class) |
122 | - .register(ImmutableSet.class, new ImmutableSetSerializer()) | 132 | + .register(new ImmutableListSerializer(), |
123 | - .register( | 133 | + ImmutableList.class, |
124 | - ArrayList.class, | 134 | + ImmutableList.of(1).getClass(), |
125 | - Arrays.asList().getClass(), | 135 | + ImmutableList.of(1, 2).getClass()) |
126 | - HashMap.class, | 136 | + .register(new ImmutableSetSerializer(), |
127 | - HashSet.class, | 137 | + ImmutableSet.class, |
138 | + ImmutableSet.of().getClass(), | ||
139 | + ImmutableSet.of(1).getClass(), | ||
140 | + ImmutableSet.of(1, 2).getClass()) | ||
141 | + .register(new ImmutableMapSerializer(), | ||
142 | + ImmutableMap.class, | ||
143 | + ImmutableMap.of().getClass(), | ||
144 | + ImmutableMap.of("a", 1).getClass(), | ||
145 | + ImmutableMap.of("R", 2, "D", 2).getClass()) | ||
146 | + .register(HashMap.class) | ||
147 | + .register(ArrayList.class, | ||
128 | LinkedList.class, | 148 | LinkedList.class, |
129 | - byte[].class, | 149 | + HashSet.class |
130 | - Duration.class | ||
131 | ) | 150 | ) |
151 | + .register(new ArraysAsListSerializer(), Arrays.asList().getClass()) | ||
152 | + .register(Collections.singletonList(1).getClass()) | ||
153 | + .register(Duration.class) | ||
132 | .build(); | 154 | .build(); |
133 | 155 | ||
134 | /** | 156 | /** |
135 | * KryoNamespace which can serialize ON.lab misc classes. | 157 | * KryoNamespace which can serialize ON.lab misc classes. |
136 | */ | 158 | */ |
137 | public static final KryoNamespace MISC = KryoNamespace.newBuilder() | 159 | public static final KryoNamespace MISC = KryoNamespace.newBuilder() |
138 | - .register(IpPrefix.class, new IpPrefixSerializer()) | 160 | + .nextId(KryoNamespace.FLOATING_ID) |
139 | - .register(Ip4Prefix.class, new Ip4PrefixSerializer()) | 161 | + .register(new IpPrefixSerializer(), IpPrefix.class) |
140 | - .register(Ip6Prefix.class, new Ip6PrefixSerializer()) | 162 | + .register(new Ip4PrefixSerializer(), Ip4Prefix.class) |
141 | - .register(IpAddress.class, new IpAddressSerializer()) | 163 | + .register(new Ip6PrefixSerializer(), Ip6Prefix.class) |
142 | - .register(Ip4Address.class, new Ip4AddressSerializer()) | 164 | + .register(new IpAddressSerializer(), IpAddress.class) |
143 | - .register(Ip6Address.class, new Ip6AddressSerializer()) | 165 | + .register(new Ip4AddressSerializer(), Ip4Address.class) |
144 | - .register(MacAddress.class, new MacAddressSerializer()) | 166 | + .register(new Ip6AddressSerializer(), Ip6Address.class) |
167 | + .register(new MacAddressSerializer(), MacAddress.class) | ||
145 | .register(VlanId.class) | 168 | .register(VlanId.class) |
146 | .build(); | 169 | .build(); |
147 | 170 | ||
171 | + /** | ||
172 | + * Kryo registration Id for user custom registration. | ||
173 | + */ | ||
174 | + public static final int BEGIN_USER_CUSTOM_ID = 300; | ||
175 | + | ||
148 | // TODO: Populate other classes | 176 | // TODO: Populate other classes |
149 | /** | 177 | /** |
150 | * KryoNamespace which can serialize API bundle classes. | 178 | * KryoNamespace which can serialize API bundle classes. |
151 | */ | 179 | */ |
152 | public static final KryoNamespace API = KryoNamespace.newBuilder() | 180 | public static final KryoNamespace API = KryoNamespace.newBuilder() |
153 | - .register(MISC) | 181 | + .nextId(KryoNamespace.INITIAL_ID) |
154 | .register(BASIC) | 182 | .register(BASIC) |
183 | + .nextId(KryoNamespace.INITIAL_ID + 30) | ||
184 | + .register(MISC) | ||
185 | + .nextId(KryoNamespace.INITIAL_ID + 30 + 10) | ||
155 | .register( | 186 | .register( |
156 | ControllerNode.State.class, | 187 | ControllerNode.State.class, |
157 | Device.Type.class, | 188 | Device.Type.class, |
... | @@ -242,19 +273,29 @@ public final class KryoNamespaces { | ... | @@ -242,19 +273,29 @@ public final class KryoNamespaces { |
242 | AnnotationConstraint.class, | 273 | AnnotationConstraint.class, |
243 | BooleanConstraint.class | 274 | BooleanConstraint.class |
244 | ) | 275 | ) |
245 | - .register(DefaultApplicationId.class, new DefaultApplicationIdSerializer()) | 276 | + .register(new DefaultApplicationIdSerializer(), DefaultApplicationId.class) |
246 | - .register(URI.class, new URISerializer()) | 277 | + .register(new URISerializer(), URI.class) |
247 | - .register(NodeId.class, new NodeIdSerializer()) | 278 | + .register(new NodeIdSerializer(), NodeId.class) |
248 | - .register(ProviderId.class, new ProviderIdSerializer()) | 279 | + .register(new ProviderIdSerializer(), ProviderId.class) |
249 | - .register(DeviceId.class, new DeviceIdSerializer()) | 280 | + .register(new DeviceIdSerializer(), DeviceId.class) |
250 | - .register(PortNumber.class, new PortNumberSerializer()) | 281 | + .register(new PortNumberSerializer(), PortNumber.class) |
251 | - .register(DefaultPort.class, new DefaultPortSerializer()) | 282 | + .register(new DefaultPortSerializer(), DefaultPort.class) |
252 | - .register(LinkKey.class, new LinkKeySerializer()) | 283 | + .register(new LinkKeySerializer(), LinkKey.class) |
253 | - .register(ConnectPoint.class, new ConnectPointSerializer()) | 284 | + .register(new ConnectPointSerializer(), ConnectPoint.class) |
254 | - .register(DefaultLink.class, new DefaultLinkSerializer()) | 285 | + .register(new DefaultLinkSerializer(), DefaultLink.class) |
255 | - .register(MastershipTerm.class, new MastershipTermSerializer()) | 286 | + .register(new MastershipTermSerializer(), MastershipTerm.class) |
256 | - .register(HostLocation.class, new HostLocationSerializer()) | 287 | + .register(new HostLocationSerializer(), HostLocation.class) |
257 | - .register(DefaultOutboundPacket.class, new DefaultOutboundPacketSerializer()) | 288 | + .register(new DefaultOutboundPacketSerializer(), DefaultOutboundPacket.class) |
289 | + .register(ReadRequest.class) | ||
290 | + .register(WriteRequest.class) | ||
291 | + .register(WriteRequest.Type.class) | ||
292 | + .register(WriteResult.class) | ||
293 | + .register(ReadResult.class) | ||
294 | + .register(BatchReadRequest.class) | ||
295 | + .register(BatchWriteRequest.class) | ||
296 | + .register(ReadStatus.class) | ||
297 | + .register(WriteStatus.class) | ||
298 | + .register(VersionedValue.class) | ||
258 | 299 | ||
259 | .build(); | 300 | .build(); |
260 | 301 | ... | ... |
... | @@ -15,10 +15,14 @@ | ... | @@ -15,10 +15,14 @@ |
15 | */ | 15 | */ |
16 | package org.onlab.onos.store.serializers; | 16 | package org.onlab.onos.store.serializers; |
17 | 17 | ||
18 | +import java.io.InputStream; | ||
19 | +import java.io.OutputStream; | ||
18 | import java.nio.ByteBuffer; | 20 | import java.nio.ByteBuffer; |
19 | 21 | ||
20 | import org.onlab.util.KryoNamespace; | 22 | import org.onlab.util.KryoNamespace; |
21 | 23 | ||
24 | +import com.google.common.base.MoreObjects; | ||
25 | + | ||
22 | /** | 26 | /** |
23 | * StoreSerializer implementation using Kryo. | 27 | * StoreSerializer implementation using Kryo. |
24 | */ | 28 | */ |
... | @@ -36,8 +40,8 @@ public class KryoSerializer implements StoreSerializer { | ... | @@ -36,8 +40,8 @@ public class KryoSerializer implements StoreSerializer { |
36 | protected void setupKryoPool() { | 40 | protected void setupKryoPool() { |
37 | serializerPool = KryoNamespace.newBuilder() | 41 | serializerPool = KryoNamespace.newBuilder() |
38 | .register(KryoNamespaces.API) | 42 | .register(KryoNamespaces.API) |
39 | - .build() | 43 | + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID) |
40 | - .populate(1); | 44 | + .build(); |
41 | } | 45 | } |
42 | 46 | ||
43 | @Override | 47 | @Override |
... | @@ -63,4 +67,20 @@ public class KryoSerializer implements StoreSerializer { | ... | @@ -63,4 +67,20 @@ public class KryoSerializer implements StoreSerializer { |
63 | return serializerPool.deserialize(buffer); | 67 | return serializerPool.deserialize(buffer); |
64 | } | 68 | } |
65 | 69 | ||
70 | + @Override | ||
71 | + public void encode(Object obj, OutputStream stream) { | ||
72 | + serializerPool.serialize(obj, stream); | ||
73 | + } | ||
74 | + | ||
75 | + @Override | ||
76 | + public <T> T decode(InputStream stream) { | ||
77 | + return serializerPool.deserialize(stream); | ||
78 | + } | ||
79 | + | ||
80 | + @Override | ||
81 | + public String toString() { | ||
82 | + return MoreObjects.toStringHelper(getClass()) | ||
83 | + .add("serializerPool", serializerPool) | ||
84 | + .toString(); | ||
85 | + } | ||
66 | } | 86 | } | ... | ... |
... | @@ -15,6 +15,8 @@ | ... | @@ -15,6 +15,8 @@ |
15 | */ | 15 | */ |
16 | package org.onlab.onos.store.serializers; | 16 | package org.onlab.onos.store.serializers; |
17 | 17 | ||
18 | +import java.io.InputStream; | ||
19 | +import java.io.OutputStream; | ||
18 | import java.nio.ByteBuffer; | 20 | import java.nio.ByteBuffer; |
19 | 21 | ||
20 | // TODO: To be replaced with SerializationService from IOLoop activity | 22 | // TODO: To be replaced with SerializationService from IOLoop activity |
... | @@ -40,6 +42,14 @@ public interface StoreSerializer { | ... | @@ -40,6 +42,14 @@ public interface StoreSerializer { |
40 | public void encode(final Object obj, ByteBuffer buffer); | 42 | public void encode(final Object obj, ByteBuffer buffer); |
41 | 43 | ||
42 | /** | 44 | /** |
45 | + * Serializes the specified object into bytes. | ||
46 | + * | ||
47 | + * @param obj object to be serialized | ||
48 | + * @param stream to write serialized bytes | ||
49 | + */ | ||
50 | + public void encode(final Object obj, final OutputStream stream); | ||
51 | + | ||
52 | + /** | ||
43 | * Deserializes the specified bytes into an object. | 53 | * Deserializes the specified bytes into an object. |
44 | * | 54 | * |
45 | * @param bytes bytes to be deserialized | 55 | * @param bytes bytes to be deserialized |
... | @@ -56,4 +66,13 @@ public interface StoreSerializer { | ... | @@ -56,4 +66,13 @@ public interface StoreSerializer { |
56 | * @param <T> decoded type | 66 | * @param <T> decoded type |
57 | */ | 67 | */ |
58 | public <T> T decode(final ByteBuffer buffer); | 68 | public <T> T decode(final ByteBuffer buffer); |
69 | + | ||
70 | + /** | ||
71 | + * Deserializes the specified bytes into an object. | ||
72 | + * | ||
73 | + * @param stream stream containing the bytes to be deserialized | ||
74 | + * @return deserialized object | ||
75 | + * @param <T> decoded type | ||
76 | + */ | ||
77 | + public <T> T decode(final InputStream stream); | ||
59 | } | 78 | } | ... | ... |
... | @@ -70,6 +70,7 @@ import org.onlab.packet.MacAddress; | ... | @@ -70,6 +70,7 @@ import org.onlab.packet.MacAddress; |
70 | import org.onlab.util.KryoNamespace; | 70 | import org.onlab.util.KryoNamespace; |
71 | 71 | ||
72 | import java.nio.ByteBuffer; | 72 | import java.nio.ByteBuffer; |
73 | +import java.util.Arrays; | ||
73 | import java.util.HashMap; | 74 | import java.util.HashMap; |
74 | import java.util.Map; | 75 | import java.util.Map; |
75 | import java.util.Set; | 76 | import java.util.Set; |
... | @@ -121,8 +122,8 @@ public class KryoSerializerTest { | ... | @@ -121,8 +122,8 @@ public class KryoSerializerTest { |
121 | protected void setupKryoPool() { | 122 | protected void setupKryoPool() { |
122 | serializerPool = KryoNamespace.newBuilder() | 123 | serializerPool = KryoNamespace.newBuilder() |
123 | .register(KryoNamespaces.API) | 124 | .register(KryoNamespaces.API) |
124 | - .build() | 125 | + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID) |
125 | - .populate(1); | 126 | + .build(); |
126 | } | 127 | } |
127 | }; | 128 | }; |
128 | } | 129 | } |
... | @@ -326,6 +327,11 @@ public class KryoSerializerTest { | ... | @@ -326,6 +327,11 @@ public class KryoSerializerTest { |
326 | } | 327 | } |
327 | 328 | ||
328 | @Test | 329 | @Test |
330 | + public void testArraysAsList() { | ||
331 | + testSerializedEquals(Arrays.asList(1, 2, 3)); | ||
332 | + } | ||
333 | + | ||
334 | + @Test | ||
329 | public void testAnnotationConstraint() { | 335 | public void testAnnotationConstraint() { |
330 | testSerializable(new AnnotationConstraint("distance", 100.0)); | 336 | testSerializable(new AnnotationConstraint("distance", 100.0)); |
331 | } | 337 | } | ... | ... |
providers/host/bin/pom.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2014 Open Networking Laboratory | ||
4 | - ~ | ||
5 | - ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | - ~ you may not use this file except in compliance with the License. | ||
7 | - ~ You may obtain a copy of the License at | ||
8 | - ~ | ||
9 | - ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | - ~ | ||
11 | - ~ Unless required by applicable law or agreed to in writing, software | ||
12 | - ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | - ~ See the License for the specific language governing permissions and | ||
15 | - ~ limitations under the License. | ||
16 | - --> | ||
17 | -<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
18 | - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
19 | - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
20 | - <modelVersion>4.0.0</modelVersion> | ||
21 | - | ||
22 | - <parent> | ||
23 | - <groupId>org.onlab.onos</groupId> | ||
24 | - <artifactId>onos-of-providers</artifactId> | ||
25 | - <version>1.0.0-SNAPSHOT</version> | ||
26 | - <relativePath>../pom.xml</relativePath> | ||
27 | - </parent> | ||
28 | - | ||
29 | - <artifactId>onos-of-provider-host</artifactId> | ||
30 | - <packaging>bundle</packaging> | ||
31 | - | ||
32 | - <description>ONOS OpenFlow protocol host provider</description> | ||
33 | - | ||
34 | -</project> |
... | @@ -15,10 +15,11 @@ | ... | @@ -15,10 +15,11 @@ |
15 | */ | 15 | */ |
16 | package org.onlab.util; | 16 | package org.onlab.util; |
17 | 17 | ||
18 | +import java.io.InputStream; | ||
19 | +import java.io.OutputStream; | ||
18 | import java.nio.ByteBuffer; | 20 | import java.nio.ByteBuffer; |
19 | import java.util.ArrayList; | 21 | import java.util.ArrayList; |
20 | import java.util.List; | 22 | import java.util.List; |
21 | -import java.util.concurrent.ConcurrentLinkedQueue; | ||
22 | 23 | ||
23 | import org.apache.commons.lang3.tuple.Pair; | 24 | import org.apache.commons.lang3.tuple.Pair; |
24 | 25 | ||
... | @@ -27,15 +28,17 @@ import com.esotericsoftware.kryo.Serializer; | ... | @@ -27,15 +28,17 @@ import com.esotericsoftware.kryo.Serializer; |
27 | import com.esotericsoftware.kryo.io.ByteBufferInput; | 28 | import com.esotericsoftware.kryo.io.ByteBufferInput; |
28 | import com.esotericsoftware.kryo.io.ByteBufferOutput; | 29 | import com.esotericsoftware.kryo.io.ByteBufferOutput; |
29 | import com.esotericsoftware.kryo.io.Input; | 30 | import com.esotericsoftware.kryo.io.Input; |
31 | +import com.esotericsoftware.kryo.pool.KryoCallback; | ||
30 | import com.esotericsoftware.kryo.pool.KryoFactory; | 32 | import com.esotericsoftware.kryo.pool.KryoFactory; |
33 | +import com.esotericsoftware.kryo.pool.KryoPool; | ||
34 | +import com.google.common.base.MoreObjects; | ||
31 | import com.google.common.collect.ImmutableList; | 35 | import com.google.common.collect.ImmutableList; |
32 | 36 | ||
33 | -// TODO Add tests for this class. | ||
34 | /** | 37 | /** |
35 | * Pool of Kryo instances, with classes pre-registered. | 38 | * Pool of Kryo instances, with classes pre-registered. |
36 | */ | 39 | */ |
37 | //@ThreadSafe | 40 | //@ThreadSafe |
38 | -public final class KryoNamespace implements KryoFactory { | 41 | +public final class KryoNamespace implements KryoFactory, KryoPool { |
39 | 42 | ||
40 | /** | 43 | /** |
41 | * Default buffer size used for serialization. | 44 | * Default buffer size used for serialization. |
... | @@ -45,17 +48,35 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -45,17 +48,35 @@ public final class KryoNamespace implements KryoFactory { |
45 | public static final int DEFAULT_BUFFER_SIZE = 4096; | 48 | public static final int DEFAULT_BUFFER_SIZE = 4096; |
46 | public static final int MAX_BUFFER_SIZE = 100 * 1000 * 1000; | 49 | public static final int MAX_BUFFER_SIZE = 100 * 1000 * 1000; |
47 | 50 | ||
48 | - private final ConcurrentLinkedQueue<Kryo> pool = new ConcurrentLinkedQueue<>(); | 51 | + /** |
49 | - private final ImmutableList<Pair<Class<?>, Serializer<?>>> registeredTypes; | 52 | + * ID to use if this KryoNamespace does not define registration id. |
53 | + */ | ||
54 | + public static final int FLOATING_ID = -1; | ||
55 | + | ||
56 | + /** | ||
57 | + * Smallest ID free to use for user defined registrations. | ||
58 | + */ | ||
59 | + public static final int INITIAL_ID = 11; | ||
60 | + | ||
61 | + | ||
62 | + private final KryoPool pool = new KryoPool.Builder(this) | ||
63 | + .softReferences() | ||
64 | + .build(); | ||
65 | + | ||
66 | + private final ImmutableList<RegistrationBlock> registeredBlocks; | ||
67 | + | ||
50 | private final boolean registrationRequired; | 68 | private final boolean registrationRequired; |
51 | 69 | ||
70 | + | ||
52 | /** | 71 | /** |
53 | * KryoNamespace builder. | 72 | * KryoNamespace builder. |
54 | */ | 73 | */ |
55 | //@NotThreadSafe | 74 | //@NotThreadSafe |
56 | public static final class Builder { | 75 | public static final class Builder { |
57 | 76 | ||
58 | - private final List<Pair<Class<?>, Serializer<?>>> types = new ArrayList<>(); | 77 | + private int blockHeadId = INITIAL_ID; |
78 | + private List<Pair<Class<?>, Serializer<?>>> types = new ArrayList<>(); | ||
79 | + private List<RegistrationBlock> blocks = new ArrayList<>(); | ||
59 | private boolean registrationRequired = true; | 80 | private boolean registrationRequired = true; |
60 | 81 | ||
61 | /** | 82 | /** |
... | @@ -64,7 +85,27 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -64,7 +85,27 @@ public final class KryoNamespace implements KryoFactory { |
64 | * @return KryoNamespace | 85 | * @return KryoNamespace |
65 | */ | 86 | */ |
66 | public KryoNamespace build() { | 87 | public KryoNamespace build() { |
67 | - return new KryoNamespace(types, registrationRequired); | 88 | + if (!types.isEmpty()) { |
89 | + blocks.add(new RegistrationBlock(this.blockHeadId, types)); | ||
90 | + } | ||
91 | + return new KryoNamespace(blocks, registrationRequired).populate(1); | ||
92 | + } | ||
93 | + | ||
94 | + /** | ||
95 | + * Sets the next Kryo registration Id for following register entries. | ||
96 | + * | ||
97 | + * @param id Kryo registration Id | ||
98 | + * @return this | ||
99 | + * | ||
100 | + * @see Kryo#register(Class, Serializer, int) | ||
101 | + */ | ||
102 | + public Builder nextId(final int id) { | ||
103 | + if (!types.isEmpty()) { | ||
104 | + blocks.add(new RegistrationBlock(this.blockHeadId, types)); | ||
105 | + types = new ArrayList<>(); | ||
106 | + } | ||
107 | + this.blockHeadId = id; | ||
108 | + return this; | ||
68 | } | 109 | } |
69 | 110 | ||
70 | /** | 111 | /** |
... | @@ -75,7 +116,7 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -75,7 +116,7 @@ public final class KryoNamespace implements KryoFactory { |
75 | */ | 116 | */ |
76 | public Builder register(final Class<?>... expectedTypes) { | 117 | public Builder register(final Class<?>... expectedTypes) { |
77 | for (Class<?> clazz : expectedTypes) { | 118 | for (Class<?> clazz : expectedTypes) { |
78 | - types.add(Pair.<Class<?>, Serializer<?>>of(clazz, null)); | 119 | + types.add(Pair.of(clazz, null)); |
79 | } | 120 | } |
80 | return this; | 121 | return this; |
81 | } | 122 | } |
... | @@ -83,26 +124,54 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -83,26 +124,54 @@ public final class KryoNamespace implements KryoFactory { |
83 | /** | 124 | /** |
84 | * Registers a class and it's serializer. | 125 | * Registers a class and it's serializer. |
85 | * | 126 | * |
86 | - * @param clazz the class to register | 127 | + * @param classes list of classes to register |
87 | * @param serializer serializer to use for the class | 128 | * @param serializer serializer to use for the class |
88 | * @return this | 129 | * @return this |
89 | */ | 130 | */ |
90 | - public Builder register(final Class<?> clazz, Serializer<?> serializer) { | 131 | + public Builder register(Serializer<?> serializer, final Class<?>... classes) { |
91 | - types.add(Pair.<Class<?>, Serializer<?>>of(clazz, serializer)); | 132 | + for (Class<?> clazz : classes) { |
133 | + types.add(Pair.of(clazz, serializer)); | ||
134 | + } | ||
135 | + return this; | ||
136 | + } | ||
137 | + | ||
138 | + private Builder register(RegistrationBlock block) { | ||
139 | + if (block.begin() != FLOATING_ID) { | ||
140 | + // flush pending types | ||
141 | + nextId(block.begin()); | ||
142 | + blocks.add(block); | ||
143 | + nextId(block.begin() + block.types().size()); | ||
144 | + } else { | ||
145 | + // flush pending types | ||
146 | + final int addedBlockBegin = blockHeadId + types.size(); | ||
147 | + nextId(addedBlockBegin); | ||
148 | + blocks.add(new RegistrationBlock(addedBlockBegin, block.types())); | ||
149 | + nextId(addedBlockBegin + block.types().size()); | ||
150 | + } | ||
92 | return this; | 151 | return this; |
93 | } | 152 | } |
94 | 153 | ||
95 | /** | 154 | /** |
96 | * Registers all the class registered to given KryoNamespace. | 155 | * Registers all the class registered to given KryoNamespace. |
97 | * | 156 | * |
98 | - * @param pool KryoNamespace | 157 | + * @param ns KryoNamespace |
99 | * @return this | 158 | * @return this |
100 | */ | 159 | */ |
101 | - public Builder register(final KryoNamespace pool) { | 160 | + public Builder register(final KryoNamespace ns) { |
102 | - types.addAll(pool.registeredTypes); | 161 | + for (RegistrationBlock block : ns.registeredBlocks) { |
162 | + this.register(block); | ||
163 | + } | ||
103 | return this; | 164 | return this; |
104 | } | 165 | } |
105 | 166 | ||
167 | + /** | ||
168 | + * Sets the registrationRequired flag. | ||
169 | + * | ||
170 | + * @param registrationRequired Kryo's registrationRequired flag | ||
171 | + * @return this | ||
172 | + * | ||
173 | + * @see Kryo#setRegistrationRequired(boolean) | ||
174 | + */ | ||
106 | public Builder setRegistrationRequired(boolean registrationRequired) { | 175 | public Builder setRegistrationRequired(boolean registrationRequired) { |
107 | this.registrationRequired = registrationRequired; | 176 | this.registrationRequired = registrationRequired; |
108 | return this; | 177 | return this; |
... | @@ -124,8 +193,8 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -124,8 +193,8 @@ public final class KryoNamespace implements KryoFactory { |
124 | * @param registeredTypes types to register | 193 | * @param registeredTypes types to register |
125 | * @param registrationRequired | 194 | * @param registrationRequired |
126 | */ | 195 | */ |
127 | - private KryoNamespace(final List<Pair<Class<?>, Serializer<?>>> registeredTypes, boolean registrationRequired) { | 196 | + private KryoNamespace(final List<RegistrationBlock> registeredTypes, boolean registrationRequired) { |
128 | - this.registeredTypes = ImmutableList.copyOf(registeredTypes); | 197 | + this.registeredBlocks = ImmutableList.copyOf(registeredTypes); |
129 | this.registrationRequired = registrationRequired; | 198 | this.registrationRequired = registrationRequired; |
130 | } | 199 | } |
131 | 200 | ||
... | @@ -136,39 +205,14 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -136,39 +205,14 @@ public final class KryoNamespace implements KryoFactory { |
136 | * @return this | 205 | * @return this |
137 | */ | 206 | */ |
138 | public KryoNamespace populate(int instances) { | 207 | public KryoNamespace populate(int instances) { |
139 | - List<Kryo> kryos = new ArrayList<>(instances); | 208 | + |
140 | for (int i = 0; i < instances; ++i) { | 209 | for (int i = 0; i < instances; ++i) { |
141 | - kryos.add(create()); | 210 | + release(create()); |
142 | } | 211 | } |
143 | - pool.addAll(kryos); | ||
144 | return this; | 212 | return this; |
145 | } | 213 | } |
146 | 214 | ||
147 | /** | 215 | /** |
148 | - * Gets a Kryo instance from the pool. | ||
149 | - * | ||
150 | - * @return Kryo instance | ||
151 | - */ | ||
152 | - public Kryo getKryo() { | ||
153 | - Kryo kryo = pool.poll(); | ||
154 | - if (kryo == null) { | ||
155 | - return create(); | ||
156 | - } | ||
157 | - return kryo; | ||
158 | - } | ||
159 | - | ||
160 | - /** | ||
161 | - * Returns a Kryo instance to the pool. | ||
162 | - * | ||
163 | - * @param kryo instance obtained from this pool. | ||
164 | - */ | ||
165 | - public void putKryo(Kryo kryo) { | ||
166 | - if (kryo != null) { | ||
167 | - pool.add(kryo); | ||
168 | - } | ||
169 | - } | ||
170 | - | ||
171 | - /** | ||
172 | * Serializes given object to byte array using Kryo instance in pool. | 216 | * Serializes given object to byte array using Kryo instance in pool. |
173 | * <p> | 217 | * <p> |
174 | * Note: Serialized bytes must be smaller than {@link #MAX_BUFFER_SIZE}. | 218 | * Note: Serialized bytes must be smaller than {@link #MAX_BUFFER_SIZE}. |
... | @@ -189,13 +233,13 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -189,13 +233,13 @@ public final class KryoNamespace implements KryoFactory { |
189 | */ | 233 | */ |
190 | public byte[] serialize(final Object obj, final int bufferSize) { | 234 | public byte[] serialize(final Object obj, final int bufferSize) { |
191 | ByteBufferOutput out = new ByteBufferOutput(bufferSize, MAX_BUFFER_SIZE); | 235 | ByteBufferOutput out = new ByteBufferOutput(bufferSize, MAX_BUFFER_SIZE); |
192 | - Kryo kryo = getKryo(); | 236 | + Kryo kryo = borrow(); |
193 | try { | 237 | try { |
194 | kryo.writeClassAndObject(out, obj); | 238 | kryo.writeClassAndObject(out, obj); |
195 | out.flush(); | 239 | out.flush(); |
196 | return out.toBytes(); | 240 | return out.toBytes(); |
197 | } finally { | 241 | } finally { |
198 | - putKryo(kryo); | 242 | + release(kryo); |
199 | } | 243 | } |
200 | } | 244 | } |
201 | 245 | ||
... | @@ -207,12 +251,40 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -207,12 +251,40 @@ public final class KryoNamespace implements KryoFactory { |
207 | */ | 251 | */ |
208 | public void serialize(final Object obj, final ByteBuffer buffer) { | 252 | public void serialize(final Object obj, final ByteBuffer buffer) { |
209 | ByteBufferOutput out = new ByteBufferOutput(buffer); | 253 | ByteBufferOutput out = new ByteBufferOutput(buffer); |
210 | - Kryo kryo = getKryo(); | 254 | + Kryo kryo = borrow(); |
255 | + try { | ||
256 | + kryo.writeClassAndObject(out, obj); | ||
257 | + out.flush(); | ||
258 | + } finally { | ||
259 | + release(kryo); | ||
260 | + } | ||
261 | + } | ||
262 | + | ||
263 | + /** | ||
264 | + * Serializes given object to OutputStream using Kryo instance in pool. | ||
265 | + * | ||
266 | + * @param obj Object to serialize | ||
267 | + * @param stream to write to | ||
268 | + */ | ||
269 | + public void serialize(final Object obj, final OutputStream stream) { | ||
270 | + serialize(obj, stream, DEFAULT_BUFFER_SIZE); | ||
271 | + } | ||
272 | + | ||
273 | + /** | ||
274 | + * Serializes given object to OutputStream using Kryo instance in pool. | ||
275 | + * | ||
276 | + * @param obj Object to serialize | ||
277 | + * @param stream to write to | ||
278 | + * @param bufferSize size of the buffer in front of the stream | ||
279 | + */ | ||
280 | + public void serialize(final Object obj, final OutputStream stream, final int bufferSize) { | ||
281 | + ByteBufferOutput out = new ByteBufferOutput(stream, bufferSize); | ||
282 | + Kryo kryo = borrow(); | ||
211 | try { | 283 | try { |
212 | kryo.writeClassAndObject(out, obj); | 284 | kryo.writeClassAndObject(out, obj); |
213 | out.flush(); | 285 | out.flush(); |
214 | } finally { | 286 | } finally { |
215 | - putKryo(kryo); | 287 | + release(kryo); |
216 | } | 288 | } |
217 | } | 289 | } |
218 | 290 | ||
... | @@ -225,13 +297,13 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -225,13 +297,13 @@ public final class KryoNamespace implements KryoFactory { |
225 | */ | 297 | */ |
226 | public <T> T deserialize(final byte[] bytes) { | 298 | public <T> T deserialize(final byte[] bytes) { |
227 | Input in = new Input(bytes); | 299 | Input in = new Input(bytes); |
228 | - Kryo kryo = getKryo(); | 300 | + Kryo kryo = borrow(); |
229 | try { | 301 | try { |
230 | @SuppressWarnings("unchecked") | 302 | @SuppressWarnings("unchecked") |
231 | T obj = (T) kryo.readClassAndObject(in); | 303 | T obj = (T) kryo.readClassAndObject(in); |
232 | return obj; | 304 | return obj; |
233 | } finally { | 305 | } finally { |
234 | - putKryo(kryo); | 306 | + release(kryo); |
235 | } | 307 | } |
236 | } | 308 | } |
237 | 309 | ||
... | @@ -244,18 +316,49 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -244,18 +316,49 @@ public final class KryoNamespace implements KryoFactory { |
244 | */ | 316 | */ |
245 | public <T> T deserialize(final ByteBuffer buffer) { | 317 | public <T> T deserialize(final ByteBuffer buffer) { |
246 | ByteBufferInput in = new ByteBufferInput(buffer); | 318 | ByteBufferInput in = new ByteBufferInput(buffer); |
247 | - Kryo kryo = getKryo(); | 319 | + Kryo kryo = borrow(); |
320 | + try { | ||
321 | + @SuppressWarnings("unchecked") | ||
322 | + T obj = (T) kryo.readClassAndObject(in); | ||
323 | + return obj; | ||
324 | + } finally { | ||
325 | + release(kryo); | ||
326 | + } | ||
327 | + } | ||
328 | + | ||
329 | + /** | ||
330 | + * Deserializes given InputStream to an Object using Kryo instance in pool. | ||
331 | + * | ||
332 | + * @param stream input stream | ||
333 | + * @param <T> deserialized Object type | ||
334 | + * @return deserialized Object | ||
335 | + */ | ||
336 | + public <T> T deserialize(final InputStream stream) { | ||
337 | + return deserialize(stream, DEFAULT_BUFFER_SIZE); | ||
338 | + } | ||
339 | + | ||
340 | + /** | ||
341 | + * Deserializes given InputStream to an Object using Kryo instance in pool. | ||
342 | + * | ||
343 | + * @param stream input stream | ||
344 | + * @param <T> deserialized Object type | ||
345 | + * @return deserialized Object | ||
346 | + * @param bufferSize size of the buffer in front of the stream | ||
347 | + */ | ||
348 | + public <T> T deserialize(final InputStream stream, final int bufferSize) { | ||
349 | + ByteBufferInput in = new ByteBufferInput(stream, bufferSize); | ||
350 | + Kryo kryo = borrow(); | ||
248 | try { | 351 | try { |
249 | @SuppressWarnings("unchecked") | 352 | @SuppressWarnings("unchecked") |
250 | T obj = (T) kryo.readClassAndObject(in); | 353 | T obj = (T) kryo.readClassAndObject(in); |
251 | return obj; | 354 | return obj; |
252 | } finally { | 355 | } finally { |
253 | - putKryo(kryo); | 356 | + release(kryo); |
254 | } | 357 | } |
255 | } | 358 | } |
256 | 359 | ||
257 | /** | 360 | /** |
258 | - * Creates a Kryo instance with {@link #registeredTypes} pre-registered. | 361 | + * Creates a Kryo instance. |
259 | * | 362 | * |
260 | * @return Kryo instance | 363 | * @return Kryo instance |
261 | */ | 364 | */ |
... | @@ -263,42 +366,68 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -263,42 +366,68 @@ public final class KryoNamespace implements KryoFactory { |
263 | public Kryo create() { | 366 | public Kryo create() { |
264 | Kryo kryo = new Kryo(); | 367 | Kryo kryo = new Kryo(); |
265 | kryo.setRegistrationRequired(registrationRequired); | 368 | kryo.setRegistrationRequired(registrationRequired); |
266 | - for (Pair<Class<?>, Serializer<?>> registry : registeredTypes) { | 369 | + for (RegistrationBlock block : registeredBlocks) { |
267 | - final Serializer<?> serializer = registry.getRight(); | 370 | + int id = block.begin(); |
371 | + if (id == FLOATING_ID) { | ||
372 | + id = kryo.getNextRegistrationId(); | ||
373 | + } | ||
374 | + for (Pair<Class<?>, Serializer<?>> entry : block.types()) { | ||
375 | + final Serializer<?> serializer = entry.getRight(); | ||
268 | if (serializer == null) { | 376 | if (serializer == null) { |
269 | - kryo.register(registry.getLeft()); | 377 | + kryo.register(entry.getLeft(), id++); |
270 | } else { | 378 | } else { |
271 | - kryo.register(registry.getLeft(), serializer); | 379 | + kryo.register(entry.getLeft(), serializer, id++); |
272 | - if (serializer instanceof FamilySerializer) { | ||
273 | - FamilySerializer<?> fser = (FamilySerializer<?>) serializer; | ||
274 | - fser.registerFamilies(kryo); | ||
275 | } | 380 | } |
276 | } | 381 | } |
277 | } | 382 | } |
278 | return kryo; | 383 | return kryo; |
279 | } | 384 | } |
280 | 385 | ||
281 | - /** | 386 | + @Override |
282 | - * Serializer implementation, which required registration of family of Classes. | 387 | + public Kryo borrow() { |
283 | - * @param <T> base type of this serializer. | 388 | + return pool.borrow(); |
284 | - */ | 389 | + } |
285 | - public abstract static class FamilySerializer<T> extends Serializer<T> { | 390 | + |
391 | + @Override | ||
392 | + public void release(Kryo kryo) { | ||
393 | + pool.release(kryo); | ||
394 | + } | ||
286 | 395 | ||
396 | + @Override | ||
397 | + public <T> T run(KryoCallback<T> callback) { | ||
398 | + return pool.run(callback); | ||
399 | + } | ||
287 | 400 | ||
288 | - public FamilySerializer(boolean acceptsNull) { | 401 | + @Override |
289 | - super(acceptsNull); | 402 | + public String toString() { |
403 | + return MoreObjects.toStringHelper(getClass()) | ||
404 | + .add("registeredBlocks", registeredBlocks) | ||
405 | + .toString(); | ||
290 | } | 406 | } |
291 | 407 | ||
292 | - public FamilySerializer(boolean acceptsNull, boolean immutable) { | 408 | + static final class RegistrationBlock { |
293 | - super(acceptsNull, immutable); | 409 | + private final int begin; |
410 | + private final ImmutableList<Pair<Class<?>, Serializer<?>>> types; | ||
411 | + | ||
412 | + public RegistrationBlock(int begin, List<Pair<Class<?>, Serializer<?>>> types) { | ||
413 | + this.begin = begin; | ||
414 | + this.types = ImmutableList.copyOf(types); | ||
294 | } | 415 | } |
295 | 416 | ||
296 | - /** | 417 | + public int begin() { |
297 | - * Registers other classes this Serializer supports. | 418 | + return begin; |
298 | - * | 419 | + } |
299 | - * @param kryo instance to register classes to | 420 | + |
300 | - */ | 421 | + public ImmutableList<Pair<Class<?>, Serializer<?>>> types() { |
301 | - public void registerFamilies(Kryo kryo) { | 422 | + return types; |
423 | + } | ||
424 | + | ||
425 | + @Override | ||
426 | + public String toString() { | ||
427 | + return MoreObjects.toStringHelper(getClass()) | ||
428 | + .add("begin", begin) | ||
429 | + .add("types", types) | ||
430 | + .toString(); | ||
302 | } | 431 | } |
303 | } | 432 | } |
304 | } | 433 | } | ... | ... |
... | @@ -22,20 +22,11 @@ import com.google.common.base.MoreObjects; | ... | @@ -22,20 +22,11 @@ import com.google.common.base.MoreObjects; |
22 | /** | 22 | /** |
23 | * Representation of a TCP/UDP communication end point. | 23 | * Representation of a TCP/UDP communication end point. |
24 | */ | 24 | */ |
25 | -public class Endpoint { | 25 | +public final class Endpoint { |
26 | 26 | ||
27 | private final int port; | 27 | private final int port; |
28 | private final String host; | 28 | private final String host; |
29 | 29 | ||
30 | - /** | ||
31 | - * Used for serialization. | ||
32 | - */ | ||
33 | - @SuppressWarnings("unused") | ||
34 | - private Endpoint() { | ||
35 | - port = 0; | ||
36 | - host = null; | ||
37 | - } | ||
38 | - | ||
39 | public Endpoint(String host, int port) { | 30 | public Endpoint(String host, int port) { |
40 | this.host = host; | 31 | this.host = host; |
41 | this.port = port; | 32 | this.port = port; | ... | ... |
... | @@ -34,6 +34,13 @@ public final class InternalMessage implements Message { | ... | @@ -34,6 +34,13 @@ public final class InternalMessage implements Message { |
34 | // Must be created using the Builder. | 34 | // Must be created using the Builder. |
35 | private InternalMessage() {} | 35 | private InternalMessage() {} |
36 | 36 | ||
37 | + InternalMessage(long id, Endpoint sender, String type, byte[] payload) { | ||
38 | + this.id = id; | ||
39 | + this.sender = sender; | ||
40 | + this.type = type; | ||
41 | + this.payload = payload; | ||
42 | + } | ||
43 | + | ||
37 | public long id() { | 44 | public long id() { |
38 | return id; | 45 | return id; |
39 | } | 46 | } | ... | ... |
... | @@ -17,11 +17,13 @@ package org.onlab.netty; | ... | @@ -17,11 +17,13 @@ package org.onlab.netty; |
17 | 17 | ||
18 | import org.onlab.util.KryoNamespace; | 18 | import org.onlab.util.KryoNamespace; |
19 | 19 | ||
20 | +import com.esotericsoftware.kryo.Kryo; | ||
21 | +import com.esotericsoftware.kryo.Serializer; | ||
22 | +import com.esotericsoftware.kryo.io.Input; | ||
23 | +import com.esotericsoftware.kryo.io.Output; | ||
24 | + | ||
20 | import java.nio.ByteBuffer; | 25 | import java.nio.ByteBuffer; |
21 | -import java.util.ArrayList; | ||
22 | -import java.util.HashMap; | ||
23 | 26 | ||
24 | -//FIXME: Should be move out to test or app | ||
25 | /** | 27 | /** |
26 | * Kryo Serializer. | 28 | * Kryo Serializer. |
27 | */ | 29 | */ |
... | @@ -37,17 +39,11 @@ public class KryoSerializer { | ... | @@ -37,17 +39,11 @@ public class KryoSerializer { |
37 | * Sets up the common serialzers pool. | 39 | * Sets up the common serialzers pool. |
38 | */ | 40 | */ |
39 | protected void setupKryoPool() { | 41 | protected void setupKryoPool() { |
40 | - // FIXME Slice out types used in common to separate pool/namespace. | ||
41 | serializerPool = KryoNamespace.newBuilder() | 42 | serializerPool = KryoNamespace.newBuilder() |
42 | - .register(ArrayList.class, | 43 | + .register(byte[].class) |
43 | - HashMap.class, | 44 | + .register(new InternalMessageSerializer(), InternalMessage.class) |
44 | - ArrayList.class, | 45 | + .register(new EndPointSerializer(), Endpoint.class) |
45 | - InternalMessage.class, | 46 | + .build(); |
46 | - Endpoint.class, | ||
47 | - byte[].class | ||
48 | - ) | ||
49 | - .build() | ||
50 | - .populate(1); | ||
51 | } | 47 | } |
52 | 48 | ||
53 | 49 | ||
... | @@ -66,4 +62,45 @@ public class KryoSerializer { | ... | @@ -66,4 +62,45 @@ public class KryoSerializer { |
66 | public void encode(Object obj, ByteBuffer buffer) { | 62 | public void encode(Object obj, ByteBuffer buffer) { |
67 | serializerPool.serialize(obj, buffer); | 63 | serializerPool.serialize(obj, buffer); |
68 | } | 64 | } |
65 | + | ||
66 | + public static final class InternalMessageSerializer | ||
67 | + extends Serializer<InternalMessage> { | ||
68 | + | ||
69 | + @Override | ||
70 | + public void write(Kryo kryo, Output output, InternalMessage object) { | ||
71 | + output.writeLong(object.id()); | ||
72 | + kryo.writeClassAndObject(output, object.sender()); | ||
73 | + output.writeString(object.type()); | ||
74 | + output.writeInt(object.payload().length, true); | ||
75 | + output.writeBytes(object.payload()); | ||
76 | + } | ||
77 | + | ||
78 | + @Override | ||
79 | + public InternalMessage read(Kryo kryo, Input input, | ||
80 | + Class<InternalMessage> type) { | ||
81 | + long id = input.readLong(); | ||
82 | + Endpoint sender = (Endpoint) kryo.readClassAndObject(input); | ||
83 | + String msgtype = input.readString(); | ||
84 | + int length = input.readInt(true); | ||
85 | + byte[] payload = input.readBytes(length); | ||
86 | + return new InternalMessage(id, sender, msgtype, payload); | ||
87 | + } | ||
88 | + | ||
89 | + } | ||
90 | + | ||
91 | + public static final class EndPointSerializer extends Serializer<Endpoint> { | ||
92 | + | ||
93 | + @Override | ||
94 | + public void write(Kryo kryo, Output output, Endpoint object) { | ||
95 | + output.writeString(object.host()); | ||
96 | + output.writeInt(object.port()); | ||
97 | + } | ||
98 | + | ||
99 | + @Override | ||
100 | + public Endpoint read(Kryo kryo, Input input, Class<Endpoint> type) { | ||
101 | + String host = input.readString(); | ||
102 | + int port = input.readInt(); | ||
103 | + return new Endpoint(host, port); | ||
104 | + } | ||
105 | + } | ||
69 | } | 106 | } | ... | ... |
-
Please register or login to post a comment