Archived
This forum has been archived. Please start a new discussion on GitHub.
Dynamic Ice: Using serialised Ice 3.4.2 data in Ice 3.5.0
Hello all,
I have a lot of stored data from an IceStorm-using system where I serialised all of the published messages using Base64 by subscribing a "Blobject" to each IceStorm topic with the following body:
So what I now have is lots of log files from a recent experiment, all full of tuples of the form: (topic name, op name, Base64-encoded). I now need to re-publish all of that recorded IceStorm data back through the system.
Unfortunately, I've since upgraded my desktop machine to Ice 3.5, and I note in the Ice 3.5 release notes that there's a specific warning about dynamic Ice: namely, that the parameters are now "Ice Encapsulations". And indeed, when I try to do something like the following, I get an Ice.EncapsulationException:
Is there any easy way to convert those Ice 3.4.2 bytes into an Ice 3.5.0 encapsulation? As an alternative, I can downgrade my desktop to Ice 3.4.2, but I'd rather not do that unless I have to.
Thanks for any suggestions,
MEF
I have a lot of stored data from an IceStorm-using system where I serialised all of the published messages using Base64 by subscribing a "Blobject" to each IceStorm topic with the following body:
public boolean ice_invoke (byte[] inParams, ByteSeqHolder outParams, Current current) { logger.trace (current.operation, DatatypeConverter.printBase64Binary (inParams)); return true; }
So what I now have is lots of log files from a recent experiment, all full of tuples of the form: (topic name, op name, Base64-encoded). I now need to re-publish all of that recorded IceStorm data back through the system.
Unfortunately, I've since upgraded my desktop machine to Ice 3.5, and I note in the Ice 3.5 release notes that there's a specific warning about dynamic Ice: namely, that the parameters are now "Ice Encapsulations". And indeed, when I try to do something like the following, I get an Ice.EncapsulationException:
publisher.ice_invoke(opName, Ice.OperationMode.Normal, DatatypeConverter.parseBase64Binary(str), null);
Is there any easy way to convert those Ice 3.4.2 bytes into an Ice 3.5.0 encapsulation? As an alternative, I can downgrade my desktop to Ice 3.4.2, but I'd rather not do that unless I have to.
Thanks for any suggestions,
MEF
0
Comments
-
p.s. -- I just did a small test, and it did work to explicitly unserialise the bytes using the appropriate stream helper class and then to use Ice.OutputStream to create a new encapsulation for use in the ice_invoke. But I'm not excited about doing that manually for every argument of every message that was published; that's what I'd hoped to avoid by saving each message as bytes in the first place. (And if I'm going to deserialise, I might as well just publish everything in the normal way in any case ...)0
-
Hi,
You just need to wrap your data within an encapsulation. An encapsulation contains the encoding version (1.0 for you, encoded on 2 bytes), the size of the data (encoded on 4 bytes, little endian) and the data. So something like the following should do the job:// C# byte[] data = DatatypeConverter.parseBase64Binary(str); byte[] encaps = new byte[data.Length + 6]; encaps[0] = 0x01; encaps[1] = 0x00; byte[] sz = BitConverter.getBytes(data.Length + 6); if(BitConverter.IsLittleEndian) { encaps[2] = sz[0]; encaps[3] = sz[1]; encaps[4] = sz[2]; encaps[5] = sz[3]; } else { encaps[2] = sz[3]; encaps[3] = sz[2]; encaps[4] = sz[1]; encaps[5] = sz[0]; } System.Buffer.BlockCopy(data, 0, encaps, 6, data.Length); publisher.ice_invoke(opName, Ice.OperationMode.Normal, encaps, null);
Cheers,
Benoit.0 -
Thanks for the help! I had to modify the sample a bit -- it seems that the size is actually the first four bytes, and then the encoding is the next two? Anyway, here's my current Java implementation, which is now working great.
byte[] bytes = DatatypeConverter.parseBase64Binary(str); byte[] encapsBytes = new byte[bytes.length + 6]; // First four bytes: size ByteBuffer bb = ByteBuffer.allocate(4); bb.order(ByteOrder.LITTLE_ENDIAN); bb.putInt(encapsBytes.length); System.arraycopy(bb.array(), 0, encapsBytes, 0, 4); // Next two bytes: encoding version (1.0) encapsBytes[4] = 0x01; encapsBytes[5] = 0x00; // Finally, the data System.arraycopy(bytes, 0, encapsBytes, 6, bytes.length); if (publisher != null) { publisher.ice_invoke(opName, Ice.OperationMode.Normal, encapsBytes, null); }
Thanks again,
MEF0