Java tutorial
/* * Copyright 2018 Qunar, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package qunar.tc.qmq.protocol; import com.google.common.collect.Maps; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import qunar.tc.qmq.base.BaseMessage; import qunar.tc.qmq.base.MessageHeader; import qunar.tc.qmq.base.RawMessage; import qunar.tc.qmq.protocol.producer.SendResult; import qunar.tc.qmq.utils.CharsetUtils; import qunar.tc.qmq.utils.Crc32; import qunar.tc.qmq.utils.Flags; import qunar.tc.qmq.utils.PayloadHolderUtils; import java.nio.ByteBuffer; import java.util.*; /** * @author yunfeng.yang * @since 2017/7/14 */ public class QMQSerializer { private static final int VALUE_SIZE_NEGATIVE_COMPENSATE = 1 << 16; public static RawMessage deserializeRawMessage(ByteBuf body) { int headerStart = body.readerIndex(); body.markReaderIndex(); MessageHeader header = deserializeMessageHeader(body); int bodyLen = body.readInt(); int headerLen = body.readerIndex() - headerStart; int totalLen = headerLen + bodyLen; body.resetReaderIndex(); byte[] data = new byte[totalLen]; body.readBytes(data); header.setBodyCrc(Crc32.crc32(data)); return new RawMessage(header, Unpooled.wrappedBuffer(data), totalLen); } public static MessageHeader deserializeMessageHeader(ByteBuf body) { byte flag = body.readByte(); long createdTime = body.readLong(); long expiredTime = body.readLong(); String subject = PayloadHolderUtils.readString(body); String messageId = PayloadHolderUtils.readString(body); MessageHeader header = new MessageHeader(); if (Flags.hasTags(flag)) { final Set<String> tags = new HashSet<>(); final byte tagsSize = body.readByte(); for (int i = 0; i < tagsSize; i++) { String tag = PayloadHolderUtils.readString(body); tags.add(tag); } header.setTags(tags); } header.setFlag(flag); header.setCreateTime(createdTime); header.setExpireTime(expiredTime); header.setSubject(subject); header.setMessageId(messageId); return header; } public static Map<String, SendResult> deserializeSendResultMap(ByteBuf buf) { Map<String, SendResult> result = Maps.newHashMap(); while (buf.isReadable()) { String messageId = PayloadHolderUtils.readString(buf); int code = buf.readInt(); String remark = PayloadHolderUtils.readString(buf); result.put(messageId, new SendResult(code, remark)); } return result; } public static HashMap<String, Object> deserializeMap(byte[] bytes) { if (bytes == null || bytes.length <= 0) return null; HashMap<String, Object> map = new HashMap<>(); ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); try { while (byteBuffer.hasRemaining()) { short keySize = byteBuffer.getShort(); byte[] keyBs = new byte[keySize]; byteBuffer.get(keyBs); int valSize = byteBuffer.getShort(); if (valSize < 0) { valSize += VALUE_SIZE_NEGATIVE_COMPENSATE; } byte[] valBs = new byte[valSize]; byteBuffer.get(valBs); map.put(CharsetUtils.toUTF8String(keyBs), CharsetUtils.toUTF8String(valBs)); } return map; } catch (Exception e) { HashMap<String, Object> result = new HashMap<>(); result.put(BaseMessage.keys.qmq_corruptData.name(), "true"); result.put(BaseMessage.keys.qmq_createTime.name(), new Date().getTime()); return result; } } }