Yuta HIGUCHI
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
......
...@@ -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");
......
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 }
......
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 }
......