/* * Copyright 2009-2016 Weibo, 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 com.weibo.api.motan.protocol.rpc; import java.util.HashMap; import java.util.Map; import com.weibo.api.motan.common.URLParamType; import com.weibo.api.motan.core.extension.ExtensionLoader; import com.weibo.api.motan.core.extension.SpiMeta; import com.weibo.api.motan.exception.MotanServiceException; import com.weibo.api.motan.protocol.AbstractProtocol; import com.weibo.api.motan.rpc.AbstractExporter; import com.weibo.api.motan.rpc.AbstractReferer; import com.weibo.api.motan.rpc.Exporter; import com.weibo.api.motan.rpc.Future; import com.weibo.api.motan.rpc.FutureListener; import com.weibo.api.motan.rpc.Provider; import com.weibo.api.motan.rpc.Referer; import com.weibo.api.motan.rpc.Request; import com.weibo.api.motan.rpc.Response; import com.weibo.api.motan.rpc.URL; import com.weibo.api.motan.transport.Client; import com.weibo.api.motan.transport.EndpointFactory; import com.weibo.api.motan.transport.ProviderMessageRouter; import com.weibo.api.motan.transport.ProviderProtectedMessageRouter; import com.weibo.api.motan.transport.Server; import com.weibo.api.motan.transport.TransportException; import com.weibo.api.motan.util.LoggerUtil; import com.weibo.api.motan.util.MotanFrameworkUtil; /** * @author maijunsheng * @version 创建时间:2013-5-22 */ @SpiMeta(name = "motan") public class DefaultRpcProtocol extends AbstractProtocol { // 多个service可能在相同端口进行服务暴露,因此来自同个端口的请求需要进行路由以找到相应的服务,同时不在该端口暴露的服务不应该被找到 private Map<String, ProviderMessageRouter> ipPort2RequestRouter = new HashMap<String, ProviderMessageRouter>(); @Override protected <T> Exporter<T> createExporter(Provider<T> provider, URL url) { return new DefaultRpcExporter<T>(provider, url); } @Override protected <T> Referer<T> createReferer(Class<T> clz, URL url, URL serviceUrl) { return new DefaultRpcReferer<T>(clz, url, serviceUrl); } /** * rpc provider * * @param <T> * @author maijunsheng */ class DefaultRpcExporter<T> extends AbstractExporter<T> { private Server server; private EndpointFactory endpointFactory; public DefaultRpcExporter(Provider<T> provider, URL url) { super(provider, url); ProviderMessageRouter requestRouter = initRequestRouter(url); endpointFactory = ExtensionLoader.getExtensionLoader(EndpointFactory.class).getExtension( url.getParameter(URLParamType.endpointFactory.getName(), URLParamType.endpointFactory.getValue())); server = endpointFactory.createServer(url, requestRouter); } @SuppressWarnings("unchecked") @Override public void unexport() { String protocolKey = MotanFrameworkUtil.getProtocolKey(url); String ipPort = url.getServerPortStr(); Exporter<T> exporter = (Exporter<T>) exporterMap.remove(protocolKey); if (exporter != null) { exporter.destroy(); } synchronized (ipPort2RequestRouter) { ProviderMessageRouter requestRouter = ipPort2RequestRouter.get(ipPort); if (requestRouter != null) { requestRouter.removeProvider(provider); } } LoggerUtil.info("DefaultRpcExporter unexport Success: url={}", url); } @Override protected boolean doInit() { boolean result = server.open(); return result; } @Override public boolean isAvailable() { return server.isAvailable(); } @Override public void destroy() { endpointFactory.safeReleaseResource(server, url); LoggerUtil.info("DefaultRpcExporter destory Success: url={}", url); } private ProviderMessageRouter initRequestRouter(URL url) { ProviderMessageRouter requestRouter = null; String ipPort = url.getServerPortStr(); synchronized (ipPort2RequestRouter) { requestRouter = ipPort2RequestRouter.get(ipPort); if (requestRouter == null) { requestRouter = new ProviderProtectedMessageRouter(provider); ipPort2RequestRouter.put(ipPort, requestRouter); } else { requestRouter.addProvider(provider); } } return requestRouter; } } /** * rpc referer * * @param <T> * @author maijunsheng */ class DefaultRpcReferer<T> extends AbstractReferer<T> { private Client client; private EndpointFactory endpointFactory; public DefaultRpcReferer(Class<T> clz, URL url, URL serviceUrl) { super(clz, url, serviceUrl); endpointFactory = ExtensionLoader.getExtensionLoader(EndpointFactory.class).getExtension( url.getParameter(URLParamType.endpointFactory.getName(), URLParamType.endpointFactory.getValue())); client = endpointFactory.createClient(url); } @Override protected Response doCall(Request request) { try { // 为了能够实现跨group请求,需要使用server端的group。 request.setAttachment(URLParamType.group.getName(), serviceUrl.getGroup()); return client.request(request); } catch (TransportException exception) { throw new MotanServiceException("DefaultRpcReferer call Error: url=" + url.getUri(), exception); } } @Override protected void decrActiveCount(Request request, Response response) { if (response == null || !(response instanceof Future)) { activeRefererCount.decrementAndGet(); return; } Future future = (Future) response; future.addListener(new FutureListener() { @Override public void operationComplete(Future future) throws Exception { activeRefererCount.decrementAndGet(); } }); } @Override protected boolean doInit() { boolean result = client.open(); return result; } @Override public boolean isAvailable() { return client.isAvailable(); } @Override public void destroy() { endpointFactory.safeReleaseResource(client, url); LoggerUtil.info("DefaultRpcReferer destory client: url={}" + url); } } }