All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.baidu.jprotobuf.pbrpc.data.RpcDataPackage Maven / Gradle / Ivy

/*
 * Copyright 2002-2014 the original author or authors.
 *
 * 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 com.baidu.jprotobuf.pbrpc.data;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import com.baidu.jprotobuf.pbrpc.ClientAttachmentHandler;
import com.baidu.jprotobuf.pbrpc.LogIDGenerator;
import com.baidu.jprotobuf.pbrpc.client.RpcMethodInfo;
import com.baidu.jprotobuf.pbrpc.utils.ArrayUtils;

/**
 * 
 * RPC 包数据完整定义实现
 * 
 * @author xiemalin
 * @since 1.0
 */
public class RpcDataPackage implements Readable, Writerable {

    private RpcHeadMeta head;
    private RpcMeta rpcMeta;
    private byte[] data;
    private byte[] attachment;
    
    private long timeStamp;

    public void mergeData(byte[] data) {
        if (data == null) {
            return;
        }
        if (this.data == null) {
            this.data = data;
            return;
        }

        int len = this.data.length + data.length;
        byte[] newData = new byte[len];
        System.arraycopy(this.data, 0, newData, 0, this.data.length);
        System.arraycopy(data, 0, newData, this.data.length, data.length);
        this.data = newData;
    }

    public boolean isChunkPackage() {
        return getChunkStreamId() != null;
    }

    public boolean isFinalPackage() {
        if (rpcMeta == null) {
            return true;
        }
        ChunkInfo chunkInfo = rpcMeta.getChunkInfo();
        if (chunkInfo == null) {
            return true;
        }

        return chunkInfo.getChunkId() == -1;
    }

    public Long getChunkStreamId() {
        if (rpcMeta == null) {
            return null;
        }
        ChunkInfo chunkInfo = rpcMeta.getChunkInfo();
        if (chunkInfo == null) {
            return null;
        }

        return chunkInfo.getStreamId();
    }

    /**
     * To split current {@link RpcDataPackage} by chunkSize. if chunkSize great than data length will not do split.
* {@link List} return will never be {@code null} or empty. * * @param chunkSize target size to split * @return {@link List} of {@link RpcDataPackage} after split */ public List chunk(long chunkSize) { if (chunkSize < 1 || data == null || chunkSize > data.length) { return Arrays.asList(this); } long streamId = UUID.randomUUID().toString().hashCode(); int chunkId = 0; int startPos = 0; int cSize = Long.valueOf(chunkSize).intValue(); List ret = new ArrayList(); while (startPos < data.length) { byte[] subarray = ArrayUtils.subarray(data, startPos, startPos + cSize); RpcDataPackage clone = copy(); clone.data(subarray); if (startPos > 0) { clone.attachment(null); } startPos += cSize; if (startPos >= data.length) { chunkId = -1; } clone.chunkInfo(streamId, chunkId); ret.add(clone); chunkId++; } return ret; } public RpcDataPackage copy() { RpcDataPackage rpcDataPackage = new RpcDataPackage(); if (head != null) { rpcDataPackage.setHead(head.copy()); } if (rpcMeta != null) { rpcDataPackage.setRpcMeta(rpcMeta.copy()); } rpcDataPackage.setData(data); rpcDataPackage.setAttachment(attachment); return rpcDataPackage; } /** * set magic code * * @param magicCode * @return */ public RpcDataPackage magicCode(String magicCode) { setMagicCode(magicCode); return this; } /** * @param serviceName * @return */ public RpcDataPackage serviceName(String serviceName) { RpcRequestMeta request = initRequest(); request.setServiceName(serviceName); return this; } public RpcDataPackage methodName(String methodName) { RpcRequestMeta request = initRequest(); request.setMethodName(methodName); return this; } public RpcDataPackage data(byte[] data) { setData(data); return this; } public RpcDataPackage attachment(byte[] attachment) { setAttachment(attachment); return this; } public RpcDataPackage authenticationData(byte[] authenticationData) { RpcMeta rpcMeta = initRpcMeta(); rpcMeta.setAuthenticationData(authenticationData); return this; } public RpcDataPackage correlationId(long correlationId) { RpcMeta rpcMeta = initRpcMeta(); rpcMeta.setCorrelationId(correlationId); return this; } public RpcDataPackage compressType(int compressType) { RpcMeta rpcMeta = initRpcMeta(); rpcMeta.setCompressType(compressType); return this; } public RpcDataPackage logId(long logId) { RpcRequestMeta request = initRequest(); request.setLogId(logId); return this; } public RpcDataPackage errorCode(int errorCode) { RpcResponseMeta response = initResponse(); response.setErrorCode(errorCode); return this; } public RpcDataPackage errorText(String errorText) { RpcResponseMeta response = initResponse(); response.setErrorText(errorText); return this; } public RpcDataPackage extraParams(byte[] params) { RpcRequestMeta request = initRequest(); request.setExtraParam(params); return this; } public RpcDataPackage chunkInfo(long streamId, int chunkId) { ChunkInfo chunkInfo = new ChunkInfo(); chunkInfo.setStreamId(streamId); chunkInfo.setChunkId(chunkId); RpcMeta rpcMeta = initRpcMeta(); rpcMeta.setChunkInfo(chunkInfo); return this; } /** * */ private RpcRequestMeta initRequest() { RpcMeta rpcMeta = initRpcMeta(); RpcRequestMeta request = rpcMeta.getRequest(); if (request == null) { request = new RpcRequestMeta(); rpcMeta.setRequest(request); } return request; } private RpcResponseMeta initResponse() { RpcMeta rpcMeta = initRpcMeta(); RpcResponseMeta response = rpcMeta.getResponse(); if (response == null) { response = new RpcResponseMeta(); rpcMeta.setResponse(response); } return response; } /** * */ private RpcMeta initRpcMeta() { if (rpcMeta == null) { rpcMeta = new RpcMeta(); } return rpcMeta; } public void setMagicCode(String magicCode) { if (head == null) { head = new RpcHeadMeta(); } head.setMagicCode(magicCode); } /** * get the head * * @return the head */ public RpcHeadMeta getHead() { return head; } /** * set head value to head * * @param head * the head to set */ public void setHead(RpcHeadMeta head) { this.head = head; } /** * get the rpcMeta * * @return the rpcMeta */ public RpcMeta getRpcMeta() { return rpcMeta; } /** * set rpcMeta value to rpcMeta * * @param rpcMeta * the rpcMeta to set */ protected void setRpcMeta(RpcMeta rpcMeta) { this.rpcMeta = rpcMeta; } /** * get the data * * @return the data */ public byte[] getData() { return data; } /** * set data value to data * * @param data * the data to set */ public void setData(byte[] data) { this.data = data; } /** * get the timeStamp * @return the timeStamp */ public long getTimeStamp() { return timeStamp; } /** * set timeStamp value to timeStamp * @param timeStamp the timeStamp to set */ public void setTimeStamp(long timeStamp) { this.timeStamp = timeStamp; } /** * get the attachment * * @return the attachment */ public byte[] getAttachment() { return attachment; } /** * set attachment value to attachment * * @param attachment * the attachment to set */ public void setAttachment(byte[] attachment) { this.attachment = attachment; } public RpcDataPackage getErrorResponseRpcDataPackage(int errorCode, String errorText) { return getErrorResponseRpcDataPackage(new RpcResponseMeta(errorCode, errorText)); } public RpcDataPackage getErrorResponseRpcDataPackage(RpcResponseMeta responseMeta) { RpcDataPackage response = new RpcDataPackage(); RpcMeta eRpcMeta = rpcMeta; if (eRpcMeta == null) { eRpcMeta = new RpcMeta(); } eRpcMeta.setResponse(responseMeta); eRpcMeta.setRequest(null); response.setRpcMeta(eRpcMeta); response.setHead(head); return response; } /* * (non-Javadoc) * * @see com.baidu.jprotobuf.remoting.pbrpc.Writerable#write() */ public byte[] write() { if (head == null) { throw new RuntimeException("property 'head' is null."); } if (rpcMeta == null) { throw new RuntimeException("property 'rpcMeta' is null."); } int totolSize = 0; // set dataSize int dataSize = 0; if (data != null) { dataSize = data.length; totolSize += dataSize; } // set attachment size int attachmentSize = 0; if (attachment != null) { attachmentSize = attachment.length; totolSize += attachmentSize; } rpcMeta.setAttachmentSize(attachmentSize); // get RPC meta data byte[] rpcMetaBytes = rpcMeta.write(); int rpcMetaSize = rpcMetaBytes.length; totolSize += rpcMetaSize; head.setMetaSize(rpcMetaSize); head.setMessageSize(totolSize); // set message body size // total size should add head size totolSize = totolSize + RpcHeadMeta.SIZE; try { // join all byte array ByteArrayOutputStream baos = new ByteArrayOutputStream(totolSize); // write head baos.write(head.write()); // write meta data baos.write(rpcMetaBytes); // write data if (data != null) { baos.write(data); } if (attachment != null) { baos.write(attachment); } return baos.toByteArray(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } /* * (non-Javadoc) * * @see com.baidu.jprotobuf.remoting.pbrpc.Readable#read(byte[]) */ public void read(byte[] bytes) { if (bytes == null) { throw new IllegalArgumentException("param 'bytes' is null."); } ByteArrayInputStream bais = new ByteArrayInputStream(bytes); // read head data byte[] headBytes = new byte[RpcHeadMeta.SIZE]; bais.read(headBytes, 0, RpcHeadMeta.SIZE); // parse RPC head head = new RpcHeadMeta(); head.read(headBytes); // get RPC meta size int metaSize = head.getMetaSize(); // read meta data byte[] metaBytes = new byte[metaSize]; bais.read(metaBytes, 0, metaSize); rpcMeta = new RpcMeta(); rpcMeta.read(metaBytes); int attachmentSize = rpcMeta.getAttachmentSize(); // read message data // message data size = totalsize - metasize - attachmentSize int totalSize = head.getMessageSize(); int dataSize = totalSize - metaSize - attachmentSize; if (dataSize > 0) { data = new byte[dataSize]; bais.read(data, 0, dataSize); } // if need read attachment if (attachmentSize > 0) { attachment = new byte[attachmentSize]; bais.read(attachment, 0, attachmentSize); } } public static RpcDataPackage buildRpcDataPackage(RpcMethodInfo methodInfo, Object[] args) throws IOException { RpcDataPackage dataPackage = new RpcDataPackage(); dataPackage.magicCode(ProtocolConstant.MAGIC_CODE); dataPackage.serviceName(methodInfo.getServiceName()).methodName(methodInfo.getMethodName()); dataPackage.compressType(methodInfo.getProtobufPRC().compressType().value()); // set data if (args != null && args.length == 1) { byte[] data = methodInfo.inputEncode(args[0]); if (data != null) { dataPackage.data(data); } } // set logid LogIDGenerator logIDGenerator = methodInfo.getLogIDGenerator(); if (logIDGenerator != null) { long logId = logIDGenerator.generate(methodInfo.getServiceName(), methodInfo.getMethod().getName(), args); dataPackage.logId(logId); } // set attachment ClientAttachmentHandler attachmentHandler = methodInfo.getClientAttachmentHandler(); if (attachmentHandler != null) { byte[] attachment = attachmentHandler.handleRequest(methodInfo.getServiceName(), methodInfo.getMethod() .getName(), args); if (attachment != null) { dataPackage.attachment(attachment); } } return dataPackage; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy