From b5fa21f2b22a97fb5e43bfd02b77827c158d02f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Wed, 15 Jan 2020 01:24:27 +0100 Subject: Fix value query serialization --- .../pl/edu/mimuw/cloudatlas/ByteSerializer.java | 75 ++++++- .../edu/mimuw/cloudatlas/agent/modules/Stanik.java | 2 +- .../mimuw/cloudatlas/agent/modules/UDUPClient.java | 6 +- .../cloudatlas/agent/modules/UDUPSerializer.java | 236 --------------------- .../mimuw/cloudatlas/agent/modules/UDUPServer.java | 9 +- .../pl/edu/mimuw/cloudatlas/model/ValueQuery.java | 44 ++-- 6 files changed, 98 insertions(+), 274 deletions(-) delete mode 100644 src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/UDUPSerializer.java diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/ByteSerializer.java b/src/main/java/pl/edu/mimuw/cloudatlas/ByteSerializer.java index 94c8d65..74aaf31 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/ByteSerializer.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/ByteSerializer.java @@ -10,6 +10,7 @@ import pl.edu.mimuw.cloudatlas.agent.modules.RecursiveScheduledTask; import pl.edu.mimuw.cloudatlas.agent.modules.TimerScheduledTask; import pl.edu.mimuw.cloudatlas.model.*; import pl.edu.mimuw.cloudatlas.querysigner.QueryData; +import pl.edu.mimuw.cloudatlas.querysigner.QueryUtils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -17,10 +18,8 @@ import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.rmi.Remote; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.HashMap; -import java.util.LinkedHashMap; +import java.text.DateFormat; +import java.util.*; /** * Serializes classes to and from byte arrays @@ -79,12 +78,16 @@ public class ByteSerializer { public void write(Kryo kryo, Output output, Object object) { ValueList vl = (ValueList) object; kryo.writeObject(output, ((TypeCollection) vl.getType()).getElementType()); - kryo.writeObject(output, vl.getValue()); + ArrayList al = new ArrayList<>(); + for (Value v : vl.getValue()) { + al.add(v); + } + kryo.writeObject(output, al); } @Override public Object read(Kryo kryo, Input input, Class type) { - Type t = kryo.readObject(input, Type.class); + TypePrimitive t = kryo.readObject(input, TypePrimitive.class); ArrayList list = kryo.readObject(input, ArrayList.class); return new ValueList(list, t); } @@ -95,25 +98,75 @@ public class ByteSerializer { public void write(Kryo kryo, Output output, Object object) { ValueSet vs = (ValueSet) object; kryo.writeObject(output, ((TypeCollection) vs.getType()).getElementType()); - kryo.writeObject(output, vs.getValue()); + HashSet hs = new HashSet(); + for (Value v : vs.getValue()) { + hs.add(v); + } + kryo.writeObject(output, hs); } @Override public Object read(Kryo kryo, Input input, Class type) { - Type t = kryo.readObject(input, Type.class); + TypePrimitive t = kryo.readObject(input, TypePrimitive.class); HashSet set = kryo.readObject(input, HashSet.class); return new ValueSet(set, t); } }); + kryo.register(AttributesMap.class, new Serializer() { + @Override + public void write(Kryo kryo, Output output, Object object) { + AttributesMap attribMap = (AttributesMap) object; + HashMap hashMap = new HashMap<>(); + + for (Map.Entry e : attribMap) { + hashMap.put(e.getKey(), e.getValue()); + } + + kryo.writeObject(output, hashMap); + } + + @Override + public Object read(Kryo kryo, Input input, Class type) { + HashMap hashMap = kryo.readObject(input, HashMap.class); + AttributesMap attribMap = new AttributesMap(); + for (Map.Entry e : hashMap.entrySet()) { + attribMap.add(e.getKey(), e.getValue()); + } + return attribMap; + } + }); + + kryo.register(ValueQuery.class, new Serializer() { + @Override + public void write(Kryo kryo, Output output, Object object) { + ValueQuery vq = (ValueQuery) object; + kryo.writeObject(output, QueryUtils.constructQueryData(vq)); + } + + @Override + public Object read(Kryo kryo, Input input, Class type) { + QueryData qd = kryo.readObject(input, QueryData.class); + ValueQuery vq = null; + try { + vq = new ValueQuery(qd); + } catch (Exception e) { + System.out.println("Value query deserialization failed"); + e.printStackTrace(); + } + return vq; + } + }); + // model kryo.register(Value.class); kryo.register(ValueBoolean.class); kryo.register(ValueContact.class); + kryo.register(ValueDouble.class); kryo.register(ValueDuration.class); + kryo.register(ValueDouble.class); kryo.register(ValueInt.class); kryo.register(ValueNull.class); - kryo.register(ValueQuery.class); kryo.register(ValueSet.class); kryo.register(ValueString.class); kryo.register(ValueTime.class); @@ -125,6 +178,7 @@ public class ByteSerializer { kryo.register(AttributesUtil.class); kryo.register(Type.class); + kryo.register(Type.PrimaryType.class); kryo.register(TypeCollection.class); kryo.register(TypePrimitive.class); @@ -160,7 +214,10 @@ public class ByteSerializer { kryo.register(byte[].class); kryo.register(LinkedHashMap.class); kryo.register(HashMap.class); + kryo.register(HashSet.class); kryo.register(ModuleType.class); + kryo.register(DateFormat.class); + kryo.register(ArrayList.class); kryo.register(QueryData.class); } diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java index 382160e..c9c6cc7 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java @@ -56,7 +56,7 @@ public class Stanik extends Module { private void setDefaultQuery(String name, String query) { try { - ValueQuery queryValue = new ValueQuery(query); + ValueQuery queryValue = new ValueQuery(query, 0); queries.put(new Attribute(name), queryValue); } catch (Exception e) { System.out.println("ERROR: failed to compile default query"); diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/UDUPClient.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/UDUPClient.java index 089cad2..97b68d1 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/UDUPClient.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/UDUPClient.java @@ -1,17 +1,19 @@ package pl.edu.mimuw.cloudatlas.agent.modules; +import pl.edu.mimuw.cloudatlas.ByteSerializer; import pl.edu.mimuw.cloudatlas.agent.messages.UDUPMessage; import pl.edu.mimuw.cloudatlas.model.ValueTime; import pl.edu.mimuw.cloudatlas.model.ValueUtils; import javax.xml.crypto.Data; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.*; import java.nio.ByteBuffer; public class UDUPClient { private UDUP udp; - private UDUPSerializer serializer; + private ByteSerializer serializer; private int serverPort; private DatagramSocket socket; private int bufsize; @@ -22,7 +24,7 @@ public class UDUPClient { this.serverPort = serverPort; this.socket = new DatagramSocket(); this.bufsize = bufferSize; - this.serializer = new UDUPSerializer(); + this.serializer = new ByteSerializer(); this.lastTransmission = 0; } diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/UDUPSerializer.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/UDUPSerializer.java deleted file mode 100644 index cfaa37e..0000000 --- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/UDUPSerializer.java +++ /dev/null @@ -1,236 +0,0 @@ -package pl.edu.mimuw.cloudatlas.agent.modules; - -import com.esotericsoftware.kryo.Kryo; -import com.esotericsoftware.kryo.Serializer; -import com.esotericsoftware.kryo.io.Input; -import com.esotericsoftware.kryo.io.Output; -import org.assertj.core.data.MapEntry; -import pl.edu.mimuw.cloudatlas.agent.messages.*; -import pl.edu.mimuw.cloudatlas.interpreter.query.Absyn.Program; -import pl.edu.mimuw.cloudatlas.model.*; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.net.Inet4Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.rmi.Remote; -import java.text.DateFormat; -import java.util.*; - -/** - * Serializes classes to and from byte arrays for UDP use - */ -public class UDUPSerializer { - private Kryo kryo; - - UDUPSerializer() { - kryo = new Kryo(); - kryo.setReferences(true); - kryo.setRegistrationRequired(true); - registerClasses(); - } - - private void registerClasses() { - - kryo.register(Inet4Address.class, new Serializer() { - - @Override - public void write(Kryo kryo, Output output, Object object) { - InetAddress ia = (InetAddress) object; - kryo.writeObject(output, ia.getAddress()); - } - - @Override - public Object read(Kryo kryo, Input input, Class type) { - try { - byte[] buf = kryo.readObject(input, byte[].class); - InetAddress addr = Inet4Address.getByAddress(buf); - return addr; - } catch (UnknownHostException e) { - System.out.println("Custom InetAddress read failed"); - e.printStackTrace(); - return null; - } - } - }); - - kryo.register(PathName.class, new Serializer() { - - @Override - public void write(Kryo kryo, Output output, Object object) { - PathName pn = (PathName) object; - kryo.writeObject(output, pn.getName()); - } - - @Override - public Object read(Kryo kryo, Input input, Class type) { - String addr = input.readString(); - return new PathName(addr); - } - }); - - kryo.register(ValueList.class, new Serializer() { - @Override - public void write(Kryo kryo, Output output, Object object) { - ValueList vl = (ValueList) object; - kryo.writeObject(output, ((TypeCollection) vl.getType()).getElementType()); - ArrayList al = new ArrayList<>(); - for (Value v : vl.getValue()) { - al.add(v); - } - kryo.writeObject(output, al); - } - - @Override - public Object read(Kryo kryo, Input input, Class type) { - TypePrimitive t = kryo.readObject(input, TypePrimitive.class); - ArrayList list = kryo.readObject(input, ArrayList.class); - return new ValueList(list, t); - } - }); - - kryo.register(ValueSet.class, new Serializer() { - @Override - public void write(Kryo kryo, Output output, Object object) { - ValueSet vs = (ValueSet) object; - kryo.writeObject(output, ((TypeCollection) vs.getType()).getElementType()); - HashSet hs = new HashSet(); - for (Value v : vs.getValue()) { - hs.add(v); - } - kryo.writeObject(output, hs); - } - - @Override - public Object read(Kryo kryo, Input input, Class type) { - TypePrimitive t = kryo.readObject(input, TypePrimitive.class); - HashSet set = kryo.readObject(input, HashSet.class); - return new ValueSet(set, t); - } - }); - - kryo.register(AttributesMap.class, new Serializer() { - @Override - public void write(Kryo kryo, Output output, Object object) { - AttributesMap attribMap = (AttributesMap) object; - HashMap hashMap = new HashMap<>(); - - for (Map.Entry e : attribMap) { - hashMap.put(e.getKey(), e.getValue()); - } - - kryo.writeObject(output, hashMap); - } - - @Override - public Object read(Kryo kryo, Input input, Class type) { - HashMap hashMap = kryo.readObject(input, HashMap.class); - AttributesMap attribMap = new AttributesMap(); - for (Map.Entry e : hashMap.entrySet()) { - attribMap.add(e.getKey(), e.getValue()); - } - return attribMap; - } - }); - - kryo.register(ValueQuery.class, new Serializer() { - @Override - public void write(Kryo kryo, Output output, Object object) { - ValueQuery vq = (ValueQuery) object; - kryo.writeObject(output, vq.getCode()); - } - - @Override - public Object read(Kryo kryo, Input input, Class type) { - String code = kryo.readObject(input, String.class); - ValueQuery vq = null; - try { - vq = new ValueQuery(code); - } catch (Exception e) { - System.out.println("Value query deserialization failed"); - e.printStackTrace(); - } - return vq; - } - }); - - // model - kryo.register(Value.class); - kryo.register(ValueBoolean.class); - kryo.register(ValueContact.class); - kryo.register(ValueDouble.class); - kryo.register(ValueDuration.class); - kryo.register(ValueDouble.class); - kryo.register(ValueInt.class); - kryo.register(ValueNull.class); - kryo.register(ValueSet.class); - kryo.register(ValueString.class); - kryo.register(ValueTime.class); - kryo.register(ValueUtils.class); - kryo.register(ZMI.class); - - kryo.register(Attribute.class); - kryo.register(AttributesMap.class); - kryo.register(AttributesUtil.class); - - kryo.register(Type.class); - kryo.register(Type.PrimaryType.class); - kryo.register(TypeCollection.class); - kryo.register(TypePrimitive.class); - - // messages in chronological order so it's easier to keep track - kryo.register(AgentMessage.class); - kryo.register(AttributesMessage.class); - kryo.register(GetStateMessage.class); - kryo.register(HejkaMessage.class); - kryo.register(NoCoTamMessage.class); - kryo.register(QueryMessage.class); - kryo.register(QurnikMessage.class); - kryo.register(RemikMessage.class); - kryo.register(RemoveZMIMessage.class); - kryo.register(RequestStateMessage.class); - kryo.register(ResponseMessage.class); - kryo.register(RunQueriesMessage.class); - kryo.register(SetAttributeMessage.class); - kryo.register(StanikMessage.Type.class); - kryo.register(StanikMessage.class); - kryo.register(TimerSchedulerMessage.class); - kryo.register(UDUPMessage.class); - kryo.register(UpdateAttributesMessage.class); - kryo.register(UpdateQueriesMessage.class); - kryo.register(GossipGirlMessage.class); - kryo.register(GossipGirlMessage.Type.class); - kryo.register(RemoteGossipGirlMessage.class); - - // modules - kryo.register(TimerScheduledTask.class); - kryo.register(RecursiveScheduledTask.class); - - // other - kryo.register(byte[].class); - kryo.register(LinkedHashMap.class); - kryo.register(HashMap.class); - kryo.register(HashSet.class); - kryo.register(ModuleType.class); - kryo.register(DateFormat.class); - kryo.register(ArrayList.class); - } - - public UDUPMessage deserialize(byte[] packetData) { - ByteArrayInputStream in = new ByteArrayInputStream(packetData); - Input kryoInput = new Input(in); - UDUPMessage msg = kryo.readObject(kryoInput, UDUPMessage.class); - return msg; - } - - public byte[] serialize(UDUPMessage msg) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - Output kryoOut = new Output(out); - System.out.println("SERIALIZING " + msg.getContent()); - kryo.writeObject(kryoOut, msg); - kryoOut.flush(); - kryoOut.close(); - return out.toByteArray(); - } -} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/UDUPServer.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/UDUPServer.java index 3da380c..dae0420 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/UDUPServer.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/UDUPServer.java @@ -1,6 +1,7 @@ package pl.edu.mimuw.cloudatlas.agent.modules; import com.google.common.primitives.Bytes; +import pl.edu.mimuw.cloudatlas.ByteSerializer; import pl.edu.mimuw.cloudatlas.agent.messages.UDUPMessage; import pl.edu.mimuw.cloudatlas.model.ValueUtils; @@ -15,7 +16,7 @@ import java.util.concurrent.atomic.AtomicBoolean; public class UDUPServer implements Runnable { private UDUP udp; - private UDUPSerializer serializer; + private ByteSerializer serializer; private DatagramSocket socket; private InetAddress address; private HashMap> partialPackets; @@ -27,7 +28,7 @@ public class UDUPServer implements Runnable { this.address = addr; this.bufSize = bufSize; this.partialPackets = new HashMap<>(); - this.serializer = new UDUPSerializer(); + this.serializer = new ByteSerializer(); this.running = new AtomicBoolean(false); } @@ -58,7 +59,7 @@ public class UDUPServer implements Runnable { UDUPMessage msg; if (packetNo == 1 && packet.getLength() < this.bufSize) { - msg = this.serializer.deserialize(packetData); + msg = (UDUPMessage) this.serializer.deserialize(packetData, UDUPMessage.class); System.out.println("UDP received message " + msg.getContent().getMessageId()); } else { System.out.println("UDP received partial message with transmission id " + transmissionID + " packet no " + packetNo); @@ -137,7 +138,7 @@ public class UDUPServer implements Runnable { if (this.partialPackets.containsKey(transmissionID)) { try { byte[] allPacketData = concatPacketData(transmissionID, newPacketNo, packetData); - msg = this.serializer.deserialize(allPacketData); + msg = (UDUPMessage) this.serializer.deserialize(allPacketData, UDUPMessage.class); this.partialPackets.remove(transmissionID); System.out.println("Kryo put together whole transmission for msg " + msg.getContent().getMessageId()); } catch (Error | Exception e) { diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueQuery.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueQuery.java index 95f826a..e577c13 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueQuery.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueQuery.java @@ -28,27 +28,27 @@ public class ValueQuery extends Value { * * @param query the code of the query */ - public ValueQuery(String query) throws Exception { - this.code = query; - if (!query.isEmpty()) { - Yylex lex = new Yylex(new ByteArrayInputStream(query.getBytes())); - this.query = (new parser(lex)).pProgram(); - } - this.signature = null; - this.timestamp = System.currentTimeMillis(); - this.installed = true; - } - - public ValueQuery(String query, byte[] querySignature) throws Exception { - this.code = query; - if (!query.isEmpty()) { - Yylex lex = new Yylex(new ByteArrayInputStream(query.getBytes())); - this.query = (new parser(lex)).pProgram(); - } - this.signature = querySignature; - this.timestamp = System.currentTimeMillis(); - this.installed = true; - } +// public ValueQuery(String query) throws Exception { +// this.code = query; +// if (!query.isEmpty()) { +// Yylex lex = new Yylex(new ByteArrayInputStream(query.getBytes())); +// this.query = (new parser(lex)).pProgram(); +// } +// this.signature = null; +// this.timestamp = System.currentTimeMillis(); +// this.installed = true; +// } + +// public ValueQuery(String query, byte[] querySignature) throws Exception { +// this.code = query; +// if (!query.isEmpty()) { +// Yylex lex = new Yylex(new ByteArrayInputStream(query.getBytes())); +// this.query = (new parser(lex)).pProgram(); +// } +// this.signature = querySignature; +// this.timestamp = System.currentTimeMillis(); +// this.installed = true; +// } public ValueQuery(QueryData queryData) throws Exception { this.code = queryData.getCode(); @@ -57,7 +57,7 @@ public class ValueQuery extends Value { this.query = (new parser(lex)).pProgram(); } this.signature = queryData.getSignature(); - this.timestamp = System.currentTimeMillis(); + this.timestamp = queryData.getTimestamp(); this.installed = queryData.isInstalled(); } -- cgit v1.2.3