Java tutorial
/* * Copyright 2008-2009 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 net.hasor.registry.client; import io.netty.util.Timeout; import io.netty.util.TimerTask; import net.hasor.registry.RsfCenterRegister; import net.hasor.registry.RsfCenterResult; import net.hasor.registry.RsfCenterSettings; import net.hasor.registry.domain.client.ConsumerPublishInfo; import net.hasor.registry.domain.client.ProviderPublishInfo; import net.hasor.registry.domain.client.PublishInfo; import net.hasor.rsf.InterAddress; import net.hasor.rsf.RsfBindInfo; import net.hasor.rsf.RsfContext; import net.hasor.rsf.domain.RsfServiceType; import net.hasor.rsf.utils.StringUtils; import net.hasor.rsf.utils.TimerManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; import java.util.Set; import static net.hasor.registry.RegistryConstants.Center_Ticket; /** * RSF?? * @version : 2016218 * @author (zyc@hasor.net) */ class RegistryClientManager implements TimerTask { protected Logger logger = LoggerFactory.getLogger(getClass()); private final RsfContext rsfContext; private final TimerManager timerManager; private final RsfCenterRegister centerRegister; // public RegistryClientManager(RsfContext rsfContext) { this.rsfContext = rsfContext; RsfCenterSettings settings = this.rsfContext.getAppContext().getInstance(RsfCenterSettings.class); ClassLoader loader = rsfContext.getClassLoader(); this.timerManager = new TimerManager(settings.getHeartbeatTime(), "RsfCenterBeatTimer", loader); this.centerRegister = rsfContext.getRsfClient().wrapper(RsfCenterRegister.class); } @Override public void run(Timeout timeout) { try { this.run(); } catch (Exception e) { logger.error(e.getMessage(), e); } this.timerManager.atTime(this); } private void run() throws Exception { if (!this.rsfContext.isOnline()) { return; } List<RsfBindInfo<?>> needBeat = new ArrayList<RsfBindInfo<?>>(); // ? List<RsfBindInfo<?>> needRegister = new ArrayList<RsfBindInfo<?>>();// ? List<RsfBindInfo<?>> needRepair = new ArrayList<RsfBindInfo<?>>(); // ?? // //1.? List<String> serviceIDs = rsfContext.getServiceIDs(); List<RsfBindInfo<?>> iterator = new ArrayList<RsfBindInfo<?>>(serviceIDs.size()); for (String serviceID : serviceIDs) { iterator.add(rsfContext.getServiceInfo(serviceID)); } for (RsfBindInfo<?> domain : iterator) { // .????? if (domain == null || domain.isShadow()) { continue; } // - String ticketInfo = (String) domain.getMetaData(Center_Ticket); if (StringUtils.isEmpty(ticketInfo)) { needRegister.add(domain);//? } else { needBeat.add(domain);//?? } } // //2.? for (RsfBindInfo<?> domain : needRegister) { this.onlineService(domain); } // //3.? if (!needBeat.isEmpty()) { for (RsfBindInfo<?> domain : needBeat) { String serviceID = domain.getBindID(); String registerID = (String) domain.getMetaData(Center_Ticket); try { RsfCenterResult<Boolean> beatResult = this.centerRegister.serviceBeat(registerID, serviceID); if (beatResult == null || !beatResult.isSuccess()) { needRepair.add(domain); if (beatResult == null) { logger.error("serviceBeat failed -> beatResult is null , serviceID ={} ,registerID ={}", serviceID, registerID); } else { logger.error( "serviceBeat failed -> error , serviceID ={} ,registerID ={} ,errorCode ={} ,errorMessage ={}", // serviceID, registerID, beatResult.getErrorCode(), beatResult.getErrorMessage()); } continue; } // logger.info("serviceBeat complete -> serviceID ={} ,registerID ={}", serviceID, registerID); } catch (Exception e) { logger.error("serviceBeat error -> serviceID ={} ,registerID ={} , error = {}", serviceID, registerID, e.getMessage(), e); } } } // //4.?? for (RsfBindInfo<?> domain : needRepair) { domain.removeMetaData(Center_Ticket); onlineService(domain); } } // // /**?*/ public synchronized void offline() { logger.info("rsfCenterBeat-> received online signal."); List<String> serviceIDs = rsfContext.getServiceIDs(); for (String serviceID : serviceIDs) { RsfBindInfo<Object> serviceInfo = rsfContext.getServiceInfo(serviceID); if (serviceInfo != null) { this.offlineService(serviceInfo); } } } /**?*/ public void offlineService(RsfBindInfo<?> domain) { if (domain == null || !this.rsfContext.isOnline()) { return; } // String serviceID = domain.getBindID(); String registerID = (String) domain.getMetaData(Center_Ticket); try { // // .? if (StringUtils.isBlank(registerID)) { logger.warn("deleteService -> service is not registered, serviceID={}", serviceID); return; } // RsfCenterResult<Boolean> result = this.centerRegister.unRegister(registerID, serviceID); if (result != null && result.isSuccess()) { logger.info("deleteService -> complete.", serviceID); } else { if (result == null) { logger.error("deleteService -> failed , serviceID={} ,result is null.", serviceID); } else { logger.error("deleteService -> failed , serviceID={} ,errorCode={} ,errorMessage={}.", // serviceID, result.getErrorCode(), result.getErrorMessage()); } } } catch (Exception e) { logger.error("deleteService -> failed , serviceID={} ,error={}", domain.getBindID(), e.getMessage(), e); } } // /**??*/ public synchronized void online() { logger.info("rsfCenterBeat-> received online signal."); List<String> serviceIDs = rsfContext.getServiceIDs(); for (String serviceID : serviceIDs) { RsfBindInfo<Object> serviceInfo = rsfContext.getServiceInfo(serviceID); if (serviceInfo != null) { this.onlineService(serviceInfo); } } } /**?*/ public void onlineService(RsfBindInfo<?> domain) { if (domain == null || !this.rsfContext.isOnline()) { return; } try { // .?(??/) RsfCenterResult<String> registerInfo = null; if (RsfServiceType.Provider == domain.getServiceType()) { // ProviderPublishInfo info = fillTo(domain, new ProviderPublishInfo()); info.setQueueMaxSize(this.rsfContext.getSettings().getQueueMaxSize()); info.setSharedThreadPool(domain.isSharedThreadPool()); registerInfo = this.centerRegister.registerProvider(info); logger.info("publishService service {} register to center -> {}", domain.getBindID(), registerInfo); } else if (RsfServiceType.Consumer == domain.getServiceType()) { // ConsumerPublishInfo info = fillTo(domain, new ConsumerPublishInfo()); info.setClientMaximumRequest(this.rsfContext.getSettings().getMaximumRequest()); info.setMessage(domain.isMessage()); registerInfo = this.centerRegister.registerConsumer(info); logger.info("receiveService service {} register to center -> {}", domain.getBindID(), registerInfo); } // // .???? if (registerInfo != null && registerInfo.isSuccess()) { domain.setMetaData(Center_Ticket, registerInfo.getResult()); pullAddress(domain);//? } } catch (Exception e) { logger.error("service {} register to center error-> {}", domain.getBindID(), e.getMessage(), e); } } // /** ? */ private void pullAddress(RsfBindInfo<?> domain) { if (RsfServiceType.Consumer != domain.getServiceType()) { return;/*?Consumer??pull?*/ } // .?3? String serviceID = domain.getBindID(); String registerID = (String) domain.getMetaData(Center_Ticket); String protocol = this.rsfContext.getDefaultProtocol(); logger.info("pullAddress[{}] '{}' 1st.", protocol, serviceID); RsfCenterResult<List<String>> providerResult = this.centerRegister.pullProviders(registerID, serviceID, protocol); if (providerResult == null || !providerResult.isSuccess()) { logger.warn("pullAddress[{}] '{}' 2st.", protocol, serviceID); providerResult = this.centerRegister.pullProviders(registerID, serviceID, protocol); if (providerResult == null || !providerResult.isSuccess()) { logger.error("pullAddress[{}] '{}' 3st.", protocol, serviceID); providerResult = this.centerRegister.pullProviders(registerID, serviceID, protocol); } } // if (providerResult == null || !providerResult.isSuccess()) { if (providerResult == null) { logger.error("pullAddress[{}] {} failed at 3st. -> result is null.", protocol, serviceID); } else { logger.error("pullAddress[{}] {} failed at 3st. -> errorCode ={} ,errorMessage = {}", // protocol, serviceID, providerResult.getErrorCode(), providerResult.getErrorMessage()); } // InterAddress callBackAddress = this.rsfContext.publishAddress(protocol); String callBackTo = callBackAddress.toHostSchema(); logger.info("pullAddress[{}] {} failed try async request pullProviders. callBack is {}", protocol, serviceID, callBackTo); RsfCenterResult<Boolean> result = this.centerRegister.requestPushProviders(registerID, serviceID, protocol, callBackTo); if (result == null || !result.isSuccess()) { if (result == null) { logger.error("asyncPullAddress[{}] {} failed -> result is null.", protocol, serviceID); } else { logger.error("asyncPullAddress[{}] {} failed -> errorCode ={} ,errorMessage = {}", // protocol, serviceID, result.getErrorCode(), result.getErrorMessage()); } } else { logger.info("asyncPullAddress[{}] {} successful -> waiting for the center pull providers.", protocol, serviceID); } return; } // // .??? List<String> providerList = providerResult.getResult(); List<InterAddress> newHostSet = new ArrayList<InterAddress>(); if (providerList != null && !providerList.isEmpty()) { for (String providerAddress : providerList) { try { newHostSet.add(new InterAddress(providerAddress)); } catch (Throwable e) { logger.error("pullAddress[{}] '" + providerAddress + "' formater error ->" + e.getMessage(), protocol, e); } } } else { logger.warn("pullAddress[{}] already up-to-date. pull empty.", protocol); } // // .???? try { this.rsfContext.getUpdater().appendAddress(serviceID, newHostSet); } catch (Throwable e) { logger.error("pullAddress[{}] -> appendAddress failed ,serviceID={} ,message={}.", protocol, serviceID, e.getMessage(), e); } } private <T extends PublishInfo> T fillTo(RsfBindInfo<?> eventData, T info) { // Set<String> protocols = this.rsfContext.runProtocols(); if (protocols == null || protocols.isEmpty()) { throw new IllegalStateException("not running any protocol, please check the configuration."); } StringBuilder addressList = new StringBuilder(""); if (RsfServiceType.Provider == eventData.getServiceType()) { // - ???? for (String protocol : protocols) { InterAddress interAddress = this.rsfContext.publishAddress(protocol); String rsfURL = interAddress.toHostSchema(); this.logger.info("rsfContext -> doStart , bindAddress : {}", rsfURL); if (addressList.length() > 0) { addressList.append(','); } addressList.append(rsfURL); } } else { // - ??? String protocol = this.rsfContext.getDefaultProtocol(); InterAddress interAddress = this.rsfContext.publishAddress(protocol); String rsfURL = interAddress.toHostSchema(); addressList.append(rsfURL); } // info.setBindID(eventData.getBindID()); info.setBindGroup(eventData.getBindGroup()); info.setBindName(eventData.getBindName()); info.setBindVersion(eventData.getBindVersion()); info.setBindType(eventData.getBindType().getName()); info.setClientTimeout(eventData.getClientTimeout()); info.setSerializeType(eventData.getSerializeType()); info.setTargetList(addressList.toString()); return info; } }