Search in sources :

Example 11 with ObjectOutput

use of org.apache.dubbo.common.serialize.ObjectOutput in project dubbo by alibaba.

the class RedisProtocol method protocolBindingRefer.

@Override
protected <T> Invoker<T> protocolBindingRefer(final Class<T> type, final URL url) throws RpcException {
    try {
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setTestOnBorrow(url.getParameter("test.on.borrow", true));
        config.setTestOnReturn(url.getParameter("test.on.return", false));
        config.setTestWhileIdle(url.getParameter("test.while.idle", false));
        if (url.getParameter("max.idle", 0) > 0) {
            config.setMaxIdle(url.getParameter("max.idle", 0));
        }
        if (url.getParameter("min.idle", 0) > 0) {
            config.setMinIdle(url.getParameter("min.idle", 0));
        }
        if (url.getParameter("max.active", 0) > 0) {
            config.setMaxTotal(url.getParameter("max.active", 0));
        }
        if (url.getParameter("max.total", 0) > 0) {
            config.setMaxTotal(url.getParameter("max.total", 0));
        }
        if (url.getParameter("max.wait", 0) > 0) {
            config.setMaxWaitMillis(url.getParameter("max.wait", 0));
        }
        if (url.getParameter("num.tests.per.eviction.run", 0) > 0) {
            config.setNumTestsPerEvictionRun(url.getParameter("num.tests.per.eviction.run", 0));
        }
        if (url.getParameter("time.between.eviction.runs.millis", 0) > 0) {
            config.setTimeBetweenEvictionRunsMillis(url.getParameter("time.between.eviction.runs.millis", 0));
        }
        if (url.getParameter("min.evictable.idle.time.millis", 0) > 0) {
            config.setMinEvictableIdleTimeMillis(url.getParameter("min.evictable.idle.time.millis", 0));
        }
        final JedisPool jedisPool = new JedisPool(config, url.getHost(), url.getPort(DEFAULT_PORT), url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), StringUtils.isBlank(url.getPassword()) ? null : url.getPassword(), url.getParameter("db.index", 0));
        final int expiry = url.getParameter("expiry", 0);
        final String get = url.getParameter("get", "get");
        final String set = url.getParameter("set", Map.class.equals(type) ? "put" : "set");
        final String delete = url.getParameter("delete", Map.class.equals(type) ? "remove" : "delete");
        return new AbstractInvoker<T>(type, url) {

            @Override
            protected Result doInvoke(Invocation invocation) throws Throwable {
                Jedis jedis = null;
                try {
                    jedis = jedisPool.getResource();
                    if (get.equals(invocation.getMethodName())) {
                        if (invocation.getArguments().length != 1) {
                            throw new IllegalArgumentException("The redis get method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
                        }
                        byte[] value = jedis.get(String.valueOf(invocation.getArguments()[0]).getBytes());
                        if (value == null) {
                            return AsyncRpcResult.newDefaultAsyncResult(invocation);
                        }
                        ObjectInput oin = getSerialization(url).deserialize(url, new ByteArrayInputStream(value));
                        return AsyncRpcResult.newDefaultAsyncResult(oin.readObject(), invocation);
                    } else if (set.equals(invocation.getMethodName())) {
                        if (invocation.getArguments().length != 2) {
                            throw new IllegalArgumentException("The redis set method arguments mismatch, must be two arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
                        }
                        byte[] key = String.valueOf(invocation.getArguments()[0]).getBytes();
                        ByteArrayOutputStream output = new ByteArrayOutputStream();
                        ObjectOutput value = getSerialization(url).serialize(url, output);
                        value.writeObject(invocation.getArguments()[1]);
                        jedis.set(key, output.toByteArray());
                        if (expiry > 1000) {
                            jedis.expire(key, expiry / 1000);
                        }
                        return AsyncRpcResult.newDefaultAsyncResult(invocation);
                    } else if (delete.equals(invocation.getMethodName())) {
                        if (invocation.getArguments().length != 1) {
                            throw new IllegalArgumentException("The redis delete method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
                        }
                        jedis.del(String.valueOf(invocation.getArguments()[0]).getBytes());
                        return AsyncRpcResult.newDefaultAsyncResult(invocation);
                    } else {
                        throw new UnsupportedOperationException("Unsupported method " + invocation.getMethodName() + " in redis service.");
                    }
                } catch (Throwable t) {
                    RpcException re = new RpcException("Failed to invoke redis service method. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url + ", cause: " + t.getMessage(), t);
                    if (t instanceof SocketTimeoutException) {
                        re.setCode(RpcException.TIMEOUT_EXCEPTION);
                    } else if (t instanceof JedisConnectionException || t instanceof IOException) {
                        re.setCode(RpcException.NETWORK_EXCEPTION);
                    } else if (t instanceof JedisDataException) {
                        re.setCode(RpcException.SERIALIZATION_EXCEPTION);
                    }
                    throw re;
                } finally {
                    if (jedis != null) {
                        try {
                            jedis.close();
                        } catch (Throwable t) {
                            logger.warn("returnResource error: " + t.getMessage(), t);
                        }
                    }
                }
            }

            @Override
            public void destroy() {
                super.destroy();
                try {
                    jedisPool.destroy();
                } catch (Throwable e) {
                    logger.warn(e.getMessage(), e);
                }
            }
        };
    } catch (Throwable t) {
        throw new RpcException("Failed to refer redis service. interface: " + type.getName() + ", url: " + url + ", cause: " + t.getMessage(), t);
    }
}
Also used : Invocation(org.apache.dubbo.rpc.Invocation) ObjectOutput(org.apache.dubbo.common.serialize.ObjectOutput) AbstractInvoker(org.apache.dubbo.rpc.protocol.AbstractInvoker) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) JedisDataException(redis.clients.jedis.exceptions.JedisDataException) Jedis(redis.clients.jedis.Jedis) SocketTimeoutException(java.net.SocketTimeoutException) GenericObjectPoolConfig(org.apache.commons.pool2.impl.GenericObjectPoolConfig) ByteArrayInputStream(java.io.ByteArrayInputStream) RpcException(org.apache.dubbo.rpc.RpcException) JedisPool(redis.clients.jedis.JedisPool) ObjectInput(org.apache.dubbo.common.serialize.ObjectInput) JedisConnectionException(redis.clients.jedis.exceptions.JedisConnectionException)

Example 12 with ObjectOutput

use of org.apache.dubbo.common.serialize.ObjectOutput in project dubbo by alibaba.

the class TransportCodec method encode.

@Override
public void encode(Channel channel, ChannelBuffer buffer, Object message) throws IOException {
    OutputStream output = new ChannelBufferOutputStream(buffer);
    ObjectOutput objectOutput = getSerialization(channel).serialize(channel.getUrl(), output);
    encodeData(channel, objectOutput, message);
    objectOutput.flushBuffer();
    if (objectOutput instanceof Cleanable) {
        ((Cleanable) objectOutput).cleanup();
    }
}
Also used : ChannelBufferOutputStream(org.apache.dubbo.remoting.buffer.ChannelBufferOutputStream) ObjectOutput(org.apache.dubbo.common.serialize.ObjectOutput) OutputStream(java.io.OutputStream) ChannelBufferOutputStream(org.apache.dubbo.remoting.buffer.ChannelBufferOutputStream) Cleanable(org.apache.dubbo.common.serialize.Cleanable)

Example 13 with ObjectOutput

use of org.apache.dubbo.common.serialize.ObjectOutput in project dubbo by alibaba.

the class CodecSupport method getNullBytesOf.

/**
 * Get the null object serialize result byte[] of Serialization from the cache,
 * if not, generate it first.
 *
 * @param s Serialization Instances
 * @return serialize result of null object
 */
public static byte[] getNullBytesOf(Serialization s) {
    return ID_NULLBYTES_MAP.computeIfAbsent(s.getContentTypeId(), k -> {
        // Pre-generated Null object bytes
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] nullBytes = new byte[0];
        try {
            ObjectOutput out = s.serialize(null, baos);
            out.writeObject(null);
            out.flushBuffer();
            nullBytes = baos.toByteArray();
            baos.close();
        } catch (Exception e) {
            logger.warn("Serialization extension " + s.getClass().getName() + " not support serializing null object, return an empty bytes instead.");
        }
        return nullBytes;
    });
}
Also used : ObjectOutput(org.apache.dubbo.common.serialize.ObjectOutput) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException)

Example 14 with ObjectOutput

use of org.apache.dubbo.common.serialize.ObjectOutput in project dubbo by alibaba.

the class ExchangeCodec method encodeResponse.

protected void encodeResponse(Channel channel, ChannelBuffer buffer, Response res) throws IOException {
    int savedWriteIndex = buffer.writerIndex();
    try {
        Serialization serialization = getSerialization(channel, res);
        // header.
        byte[] header = new byte[HEADER_LENGTH];
        // set magic number.
        Bytes.short2bytes(MAGIC, header);
        // set request and serialization flag.
        header[2] = serialization.getContentTypeId();
        if (res.isHeartbeat()) {
            header[2] |= FLAG_EVENT;
        }
        // set response status.
        byte status = res.getStatus();
        header[3] = status;
        // set request id.
        Bytes.long2bytes(res.getId(), header, 4);
        buffer.writerIndex(savedWriteIndex + HEADER_LENGTH);
        ChannelBufferOutputStream bos = new ChannelBufferOutputStream(buffer);
        // encode response data or error message.
        if (status == Response.OK) {
            if (res.isHeartbeat()) {
                // heartbeat response data is always null
                bos.write(CodecSupport.getNullBytesOf(serialization));
            } else {
                ObjectOutput out = serialization.serialize(channel.getUrl(), bos);
                if (res.isEvent()) {
                    encodeEventData(channel, out, res.getResult());
                } else {
                    encodeResponseData(channel, out, res.getResult(), res.getVersion());
                }
                out.flushBuffer();
                if (out instanceof Cleanable) {
                    ((Cleanable) out).cleanup();
                }
            }
        } else {
            ObjectOutput out = serialization.serialize(channel.getUrl(), bos);
            out.writeUTF(res.getErrorMessage());
            out.flushBuffer();
            if (out instanceof Cleanable) {
                ((Cleanable) out).cleanup();
            }
        }
        bos.flush();
        bos.close();
        int len = bos.writtenBytes();
        checkPayload(channel, len);
        Bytes.int2bytes(len, header, 12);
        // write
        buffer.writerIndex(savedWriteIndex);
        // write header.
        buffer.writeBytes(header);
        buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len);
    } catch (Throwable t) {
        // clear buffer
        buffer.writerIndex(savedWriteIndex);
        // send error message to Consumer, otherwise, Consumer will wait till timeout.
        if (!res.isEvent() && res.getStatus() != Response.BAD_RESPONSE) {
            Response r = new Response(res.getId(), res.getVersion());
            r.setStatus(Response.BAD_RESPONSE);
            if (t instanceof ExceedPayloadLimitException) {
                logger.warn(t.getMessage(), t);
                try {
                    r.setErrorMessage(t.getMessage());
                    channel.send(r);
                    return;
                } catch (RemotingException e) {
                    logger.warn("Failed to send bad_response info back: " + t.getMessage() + ", cause: " + e.getMessage(), e);
                }
            } else {
                // FIXME log error message in Codec and handle in caught() of IoHanndler?
                logger.warn("Fail to encode response: " + res + ", send bad_response info instead, cause: " + t.getMessage(), t);
                try {
                    r.setErrorMessage("Failed to send response: " + res + ", cause: " + StringUtils.toString(t));
                    channel.send(r);
                    return;
                } catch (RemotingException e) {
                    logger.warn("Failed to send bad_response info back: " + res + ", cause: " + e.getMessage(), e);
                }
            }
        }
        // Rethrow exception
        if (t instanceof IOException) {
            throw (IOException) t;
        } else if (t instanceof RuntimeException) {
            throw (RuntimeException) t;
        } else if (t instanceof Error) {
            throw (Error) t;
        } else {
            throw new RuntimeException(t.getMessage(), t);
        }
    }
}
Also used : ChannelBufferOutputStream(org.apache.dubbo.remoting.buffer.ChannelBufferOutputStream) ObjectOutput(org.apache.dubbo.common.serialize.ObjectOutput) IOException(java.io.IOException) Serialization(org.apache.dubbo.common.serialize.Serialization) Response(org.apache.dubbo.remoting.exchange.Response) RemotingException(org.apache.dubbo.remoting.RemotingException) ExceedPayloadLimitException(org.apache.dubbo.remoting.transport.ExceedPayloadLimitException) Cleanable(org.apache.dubbo.common.serialize.Cleanable)

Example 15 with ObjectOutput

use of org.apache.dubbo.common.serialize.ObjectOutput in project dubbo by alibaba.

the class ExchangeCodec method encodeRequest.

protected void encodeRequest(Channel channel, ChannelBuffer buffer, Request req) throws IOException {
    Serialization serialization = getSerialization(channel, req);
    // header.
    byte[] header = new byte[HEADER_LENGTH];
    // set magic number.
    Bytes.short2bytes(MAGIC, header);
    // set request and serialization flag.
    header[2] = (byte) (FLAG_REQUEST | serialization.getContentTypeId());
    if (req.isTwoWay()) {
        header[2] |= FLAG_TWOWAY;
    }
    if (req.isEvent()) {
        header[2] |= FLAG_EVENT;
    }
    // set request id.
    Bytes.long2bytes(req.getId(), header, 4);
    // encode request data.
    int savedWriteIndex = buffer.writerIndex();
    buffer.writerIndex(savedWriteIndex + HEADER_LENGTH);
    ChannelBufferOutputStream bos = new ChannelBufferOutputStream(buffer);
    if (req.isHeartbeat()) {
        // heartbeat request data is always null
        bos.write(CodecSupport.getNullBytesOf(serialization));
    } else {
        ObjectOutput out = serialization.serialize(channel.getUrl(), bos);
        if (req.isEvent()) {
            encodeEventData(channel, out, req.getData());
        } else {
            encodeRequestData(channel, out, req.getData(), req.getVersion());
        }
        out.flushBuffer();
        if (out instanceof Cleanable) {
            ((Cleanable) out).cleanup();
        }
    }
    bos.flush();
    bos.close();
    int len = bos.writtenBytes();
    checkPayload(channel, len);
    Bytes.int2bytes(len, header, 12);
    // write
    buffer.writerIndex(savedWriteIndex);
    // write header.
    buffer.writeBytes(header);
    buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len);
}
Also used : Serialization(org.apache.dubbo.common.serialize.Serialization) ChannelBufferOutputStream(org.apache.dubbo.remoting.buffer.ChannelBufferOutputStream) ObjectOutput(org.apache.dubbo.common.serialize.ObjectOutput) Cleanable(org.apache.dubbo.common.serialize.Cleanable)

Aggregations

ObjectOutput (org.apache.dubbo.common.serialize.ObjectOutput)94 Test (org.junit.jupiter.api.Test)80 ByteArrayInputStream (java.io.ByteArrayInputStream)73 ObjectInput (org.apache.dubbo.common.serialize.ObjectInput)73 IOException (java.io.IOException)42 NotSerializableException (java.io.NotSerializableException)7 AbstractSerializationPersonFailTest (org.apache.dubbo.common.serialize.base.AbstractSerializationPersonFailTest)7 AbstractSerializationPersonOkTest (org.apache.dubbo.common.serialize.base.AbstractSerializationPersonOkTest)7 Person (org.apache.dubbo.common.serialize.model.Person)7 OutputStream (java.io.OutputStream)6 HashMap (java.util.HashMap)6 Serialization (org.apache.dubbo.common.serialize.Serialization)5 ByteArrayOutputStream (java.io.ByteArrayOutputStream)4 UnsafeByteArrayOutputStream (org.apache.dubbo.common.io.UnsafeByteArrayOutputStream)4 ArrayList (java.util.ArrayList)3 Cleanable (org.apache.dubbo.common.serialize.Cleanable)3 BigPerson (org.apache.dubbo.common.serialize.model.person.BigPerson)3 ChannelBufferOutputStream (org.apache.dubbo.remoting.buffer.ChannelBufferOutputStream)3 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2