All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.apache.dubbo.rpc.rocketmq.codec.DecodeableRpcInvocation Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dubbo.rpc.rocketmq.codec;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.serialize.Cleanable;
import org.apache.dubbo.common.serialize.ObjectInput;
import org.apache.dubbo.common.utils.Assert;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.ReflectUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.remoting.Channel;
import org.apache.dubbo.remoting.Codec;
import org.apache.dubbo.remoting.Decodeable;
import org.apache.dubbo.remoting.exchange.Request;
import org.apache.dubbo.remoting.transport.CodecSupport;
import org.apache.dubbo.rpc.RpcInvocation;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.model.FrameworkServiceRepository;
import org.apache.dubbo.rpc.model.MethodDescriptor;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ProviderModel;
import org.apache.dubbo.rpc.model.ServiceDescriptor;
import org.apache.dubbo.rpc.protocol.tri.TripleConstant;
import org.apache.dubbo.rpc.support.RpcUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import static org.apache.dubbo.common.BaseServiceMetadata.keyWithoutGroup;
import static org.apache.dubbo.common.URL.buildKey;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
import static org.apache.dubbo.rpc.Constants.SERIALIZATION_ID_KEY;
@SuppressWarnings({"deprecation", "serial"})
public class DecodeableRpcInvocation extends RpcInvocation implements Codec, Decodeable {
private static final Logger log = LoggerFactory.getLogger(DecodeableRpcInvocation.class);
protected final FrameworkModel frameworkModel;
private Channel channel;
private byte serializationType;
private InputStream inputStream;
private Request request;
private volatile boolean hasDecoded;
public DecodeableRpcInvocation(FrameworkModel frameworkModel, Channel channel, Request request, InputStream is, byte id) {
this.frameworkModel = frameworkModel;
Assert.notNull(channel, "channel == null");
Assert.notNull(request, "request == null");
Assert.notNull(is, "inputStream == null");
this.channel = channel;
this.request = request;
this.inputStream = is;
this.serializationType = id;
}
@Override
public void decode() throws Exception {
if (!hasDecoded && channel != null && inputStream != null) {
try {
decode(channel, inputStream);
} catch (Throwable e) {
if (log.isWarnEnabled()) {
log.warn("Decode rpc invocation failed: " + e.getMessage(), e);
}
request.setBroken(true);
request.setData(e);
} finally {
hasDecoded = true;
}
}
}
@Override
public void encode(Channel channel, OutputStream output, Object message) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public Object decode(Channel channel, InputStream input) throws IOException {
URL url = channel.getUrl();
ObjectInput in = CodecSupport.getSerialization(url)
.deserialize(url, input);
this.put(SERIALIZATION_ID_KEY, serializationType);
String dubboVersion = in.readUTF();
request.setVersion(dubboVersion);
setAttachment(DUBBO_VERSION_KEY, dubboVersion);
String path = in.readUTF();
setAttachment(PATH_KEY, path);
String version = in.readUTF();
setAttachment(VERSION_KEY, version);
setMethodName(in.readUTF());
String desc = in.readUTF();
setParameterTypesDesc(desc);
ClassLoader originClassLoader = Thread.currentThread().getContextClassLoader();
try {
Object[] args = RocketMQCodec.EMPTY_OBJECT_ARRAY;
Class>[] pts = RocketMQCodec.EMPTY_CLASS_ARRAY;
if (desc.length() > 0) {
FrameworkServiceRepository repository = frameworkModel.getServiceRepository();
List providerModels = repository.lookupExportedServicesWithoutGroup(keyWithoutGroup(path, version));
ServiceDescriptor serviceDescriptor = null;
if (CollectionUtils.isNotEmpty(providerModels)) {
for (ProviderModel providerModel : providerModels) {
serviceDescriptor = providerModel.getServiceModel();
if (serviceDescriptor != null) {
break;
}
}
}
if (serviceDescriptor == null) {
// Unable to find ProviderModel from Exported Services
for (ApplicationModel applicationModel : frameworkModel.getApplicationModels()) {
for (ModuleModel moduleModel : applicationModel.getModuleModels()) {
serviceDescriptor = moduleModel.getServiceRepository().lookupService(path);
if (serviceDescriptor != null) {
break;
}
}
}
}
if (serviceDescriptor != null) {
MethodDescriptor methodDescriptor = serviceDescriptor.getMethod(getMethodName(), desc);
if (methodDescriptor != null) {
pts = methodDescriptor.getParameterClasses();
this.setReturnTypes(methodDescriptor.getReturnTypes());
// switch TCCL
if (CollectionUtils.isNotEmpty(providerModels)) {
if (providerModels.size() == 1) {
Thread.currentThread().setContextClassLoader(providerModels.get(0).getClassLoader());
} else {
// try all providerModels' classLoader can load pts, use the first one
for (ProviderModel providerModel : providerModels) {
ClassLoader classLoader = providerModel.getClassLoader();
boolean match = true;
for (Class> pt : pts) {
try {
if (!pt.equals(classLoader.loadClass(pt.getName()))) {
match = false;
}
} catch (ClassNotFoundException e) {
match = false;
}
}
if (match) {
Thread.currentThread().setContextClassLoader(classLoader);
break;
}
}
}
}
}
}
if (pts == RocketMQCodec.EMPTY_CLASS_ARRAY) {
if (!RpcUtils.isGenericCall(desc, getMethodName()) && !RpcUtils.isEcho(desc, getMethodName())) {
throw new IllegalArgumentException("Service not found:" + path + ", " + getMethodName());
}
pts = ReflectUtils.desc2classArray(desc);
}
// }
args = new Object[pts.length];
for (int i = 0; i < args.length; i++) {
args[i] = in.readObject(pts[i]);
}
}
setParameterTypes(pts);
Map map = in.readAttachments();
if (CollectionUtils.isNotEmptyMap(map)) {
addObjectAttachments(map);
}
setArguments(args);
String targetServiceName = buildKey(getAttachment(PATH_KEY),
getAttachment(GROUP_KEY),
getAttachment(VERSION_KEY));
setTargetServiceUniqueName(targetServiceName);
} catch (ClassNotFoundException e) {
throw new IOException(StringUtils.toString("Read invocation data failed.", e));
} finally {
Thread.currentThread().setContextClassLoader(originClassLoader);
if (in instanceof Cleanable) {
((Cleanable) in).cleanup();
}
}
return this;
}
private static String convertHessianFromWrapper(String serializeType) {
if (TripleConstant.HESSIAN4.equals(serializeType)) {
return TripleConstant.HESSIAN2;
}
return serializeType;
}
}