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

com.taobao.hsf.lightapi.ServiceFactory Maven / Gradle / Ivy

The newest version!
package com.taobao.hsf.lightapi;

import com.taobao.hsf.lightapi.report.LightApiReporter;
import com.taobao.hsf.lightapi.util.LightConstant;
import com.taobao.hsf.standalone.HSFEasyStarter;
import com.taobao.hsf.standalone.util.Constant;
import com.taobao.middleware.pandora.toolkit.SarFetcher;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 单例,可以在任何地方getInstance()来获得实例,并拿出对应的服务。
 * Created by huangsheng.hs on 2014/10/25.
 */
public class ServiceFactory {
    private static String sarPath = HSFEasyStarter.DEFAULT_RELEASE_PATH;
    private static ConcurrentHashMap systemProps = new ConcurrentHashMap();
    private static HashMap providers = new HashMap();
    private static HashMap consumers = new HashMap();
    private static volatile ServiceFactory factory;
    private static LightApiReporter reporter = new LightApiReporter();

    static {
        System.out.println("LightApi is starting.");
    }

    private ServiceFactory() {
        this(null);
    }

    private ServiceFactory(String id) {
        this(id, -1, null);
    }

    private ServiceFactory(String id, String downloadURL) {
        this(id, -1, downloadURL);
    }

    private ServiceFactory(String id, int port, String downloadURL) {
        if (isPandoraInited()) {
            LightConstant.pandoraInited = true;
        } else {
            startPandora(id, port, downloadURL);
            LightConstant.pandoraInited = true;
        }
        reporter.doReport();
    }


    private void startPandora(String uniqueId, int port, String downloadURL) {

        addJVMProperties();

        String version = SarFetcher.getDefaultSarVersion();
        if(version == null)
            version = "";

        if (downloadURL != null) {
            Constant.perferDownloadUrl.set(downloadURL);
        }

        if (uniqueId == null) {
            HSFEasyStarter.start(sarPath, version);
        } else {
            HSFEasyStarter.startWithVersionAndIdentifier(version, uniqueId, port);
        }
    }


    /**
     * 返回所有已经注册给LightApi的服务提供者
     *
     * @return
     */
    public List providers() {
        return new ArrayList(providers.values());
    }

    /**
     * 返回所有通过LightApi消费的服务消费者
     *
     * @return
     */
    public List consumers() {
        return new ArrayList(consumers.values());
    }

    /**
     * 获取一个HSF服务提供者实例,非HSFSpringProviderBean。
     * 会缓存发布过的服务!
     *
     * @param id 一个服务的描述,通常取接口名,可以用此描述获得服务单例
     * @return {@link ProviderService} 设置各个属性后,调用publish()方法来发布服务
     */
    public synchronized ProviderService provider(String id) {
        if (providers.get(id) == null) {
            providers.put(id, new ProviderService().newProvider());
            return providers.get(id);
        } else {
            return providers.get(id);
        }
    }

    /**
     * 获取一个HSF服务消费者实例,非HSFConsumerProviderBean。
     * 会缓存消费过的服务!
     *
     * @param id 一个服务的描述,通常取接口名,可以用此描述获得服务单例
     * @return {@link ConsumerService} 设置各个属性后,调用getInterface()方法来获得对应的接口
     */
    public synchronized ConsumerService consumer(String id) {
        if (consumers.get(id) == null) {
            consumers.put(id, new ConsumerService().newConsumer());
            return consumers.get(id);
        } else {
            if (!consumers.get(id).isConsumed()) {
                throw new RuntimeException(LightConstant.NOT_CONS);
            }
            return consumers.get(id);
        }
    }

    /**
     * 下线服务并销毁对应的服务端实例
     *
     * @param id
     */
    public synchronized void destroy(String id) {
        ProviderService provider = providers.get(id);
        if (provider != null) {
            provider.offline();
            clearProvider(id);
        }
    }

    /**
     * 仅仅remove掉所持有的consumer对象
     * 无法注销configserver和diamond的订阅资源(受限于底层HSF未实现)
     *
     * @param id
     */
    public synchronized void clearConsumer(String id) {
        consumers.remove(id);
    }

    /**
     * 请使用{@link this#destroy(String id)}方法
     *
     * @param id
     */
    @Deprecated
    public synchronized void clearProvider(String id) {
        providers.remove(id);
    }

    /**
     * 初始化LightApi和HSF资源,非多进程支持。多进程支持请使用带有id参数的重载方法,例如{@link #getInstance(String id)}
     *
     * @return
     */
    public static synchronized ServiceFactory getInstance() {
        return getInstance(null);
    }

    /**
     * 初始化LightApi和HSF资源,多进程支持
     *
     * @param uniqueId 保证每个进程拥有不同的id
     * @return
     */
    public static synchronized ServiceFactory getInstance(String uniqueId) {
        return getInstance(uniqueId, -1, null);
    }


    /**
     * 初始化LightApi和HSF资源,多进程支持
     *
     * @param uniqueId 保证每个进程拥有不同的id
     * @param port     指定端口号
     * @return
     */
    public static synchronized ServiceFactory getInstance(String uniqueId, int port) {
        return getInstance(uniqueId, port, null);
    }

    /**
     * 初始化LightApi和HSF资源,多进程支持
     *
     * @param uniqueId    保证每个进程拥有不同的id
     * @param downloadURL 自定义的sar包下载路径,LightApi会从 downloadURL/taobao-hsf.tgz这个路径去下载sar包
     * @return
     */
    public static synchronized ServiceFactory getInstance(String uniqueId, String downloadURL) {
        return getInstance(uniqueId, -1, downloadURL);
    }


    /**
     * 初始化LightApi和HSF资源,多进程支持
     *
     * @param uniqueId    保证每个进程拥有不同的id
     * @param port        指定端口号
     * @param downloadURL 自定义的sar包下载路径
     * @return
     */
    public static synchronized ServiceFactory getInstance(String uniqueId, int port, String downloadURL) {
        if (factory == null) {
            factory = new ServiceFactory(uniqueId, port, downloadURL);
        }
        return factory;
    }

    /**
     * 初始化LightApi和HSF资源,多进程支持
     *
     * @param sarPath sar包的绝对路径
     * @return
     */
    public static synchronized ServiceFactory getInstanceWithPath(String sarPath) {
        ServiceFactory.sarPath = sarPath;
        return getInstance();
    }



    /**
     * 在Pandora容器启动之前放置系统参数
     *
     * @param key
     * @param value
     */
    public static void addJVMProperty(String key, String value) {
        systemProps.put(key, value);
    }

    public static void addJVMProperty(Map props) {
        systemProps.putAll(props);
    }

    private static boolean isPandoraInited() {
        Class HSFClazz;
        try {
            /**
             * 为了判断Pandora是否已经启动,尝试初始化一个HSF的类,判断其classloader是否属于Pandora
             * 这里初始化了GlobalRule这个类,会导致AppClassLoader下这个类可见,有隐患,而且不优雅,但绝大多数情况下,业务不会用到这个类
             */
            HSFClazz = Class.forName("com.taobao.hsf.globalrule.GlobalRule", false,
                    ServiceFactory.class.getClassLoader());
        } catch (ClassNotFoundException e) {
            return false;
        }
        if (HSFClazz != null) {
            String loader = HSFClazz.getClassLoader().getClass().getName().toLowerCase();
            return loader.contains("pandora");
        } else {
            return false;
        }
    }


    private static void addJVMProperties() {
        for (Map.Entry propEntry : systemProps.entrySet()) {
            System.setProperty(propEntry.getKey(), propEntry.getValue());
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy