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

com.github.rainbow.initialization.ClientConfigPropertisInitialization Maven / Gradle / Ivy

The newest version!
package com.github.rainbow.initialization;

import com.alibaba.fastjson.JSONObject;
import com.github.rainbow.common.ClientHelper;
import com.github.rainbow.common.HeartbeatHandler;
import com.github.rainbow.config.RainbowConfig;
import com.github.rainbow.config.RainbowConfigHelper;
import com.github.rainbow.config.RainbowConstants;
import com.github.rainbow.netty.NettyClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.PropertiesPropertySource;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Order(value = Integer.MIN_VALUE)
public class ClientConfigPropertisInitialization  implements ApplicationContextInitializer {

    private static final Logger logger = LoggerFactory.getLogger(ClientConfigPropertisInitialization.class);

    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        Properties properties = initializeConfigCenterProperties();
        if(properties.isEmpty()){
            //TODO 获取远程连接从远程拉去配置 如果拉去失败则从本地拉取
        }
        //将配置装配到spring容器中
        setPropertiesToSpringEnviroment(configurableApplicationContext, properties);

        NettyClient nettyClient = NettyClient.getInstance();
        nettyClient.start();
    }

    private void setPropertiesToSpringEnviroment(ConfigurableApplicationContext configurableApplicationContext, Properties properties) {
        PropertiesPropertySource propertySource = new PropertiesPropertySource(RainbowConstants.RAINBOW_CONFIG_PROPERTIES_NAME, properties);
        configurableApplicationContext.getEnvironment().getPropertySources().addFirst(propertySource);
    }

    //init server remote rainbow server pull properties
    public Properties initializeConfigCenterProperties(){
        //配置中心host
        final String serverAddress = RainbowConfigHelper.getInstance().getServerAddress();
        logger.info("serverAddress{}",serverAddress);

        try {
              // 拉取服务配置文件
             String propertiesStr = pullRemoteServerProperties();
            //反射调用
            Method reloadProperties = RainbowConfig.class.getDeclaredMethod("reloadProperties", JSONObject.class);
            //private 方法
            reloadProperties.setAccessible(true);
            JSONObject parse = JSONObject.parseObject(propertiesStr);
            reloadProperties.invoke(JSONObject.class,parse);

            //将配置文件重新写入本地缓存文件中
            RainbowConfigHelper.getInstance().savePropertiesToLocalCache(RainbowConfig.getProperties());

            } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException exception ) {
                logger.error("connection Rainbow Server error",exception);
                return new Properties();
            }

    return RainbowConfig.getProperties();
    }

    private String pullRemoteServerProperties() {
        String listen = null;
        try {
            String[] split = RainbowConfigHelper.getInstance().getServerAddress().split(":");
            String host = split[0];
            int port = Integer.parseInt(split[1]);
            logger.info("host={}",host);
            logger.info("port={}",port);
            listen = new Client().init(host,port).listen();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return listen;
    }


    private void pullRemoteServerProperties(ConcurrentHashMap source) {
        source.put("config.username","高瞻");
    }
    class Client{
        /** 管道管理器 */
        private Selector selector;

        public Client init(String serverIp, int port) throws IOException {
            //获取socket通道
            SocketChannel channel = SocketChannel.open();

            channel.configureBlocking(false);
            //获得通道管理器
            selector=Selector.open();

            //客户端连接服务器,需要调用channel.finishConnect();才能实际完成连接。
            channel.connect(new InetSocketAddress(serverIp, port));
            //为该通道注册SelectionKey.OP_CONNECT事件
            channel.register(selector, SelectionKey.OP_CONNECT);
            return this;
        }

        public String listen() throws IOException {
            JSONObject request = new JSONObject();
            Properties properties = RainbowConfig.getProperties();
            request.put(RainbowConstants.RAINBOW_SERVER_APP,properties.getProperty(RainbowConstants.RAINBOW_APPNAME));
            request.put(RainbowConstants.RAINBOW_SERVER_ENV,properties.getProperty(RainbowConstants.RAINBOW_ENV));
            request.put(RainbowConstants.RAINBOW_SERVER_ROUPSNAME,properties.getProperty(RainbowConstants.RAINBOW_GROUPSNAME));

            while(true){
                //选择注册过的io操作的事件(第一次为SelectionKey.OP_CONNECT)
                selector.select();
                Iterator ite = selector.selectedKeys().iterator();
                while(ite.hasNext()){
                    SelectionKey key = ite.next();
                    //删除已选的key,防止重复处理
                    ite.remove();
                    if(key.isConnectable()){
                        SocketChannel channel=(SocketChannel)key.channel();

                        //如果正在连接,则完成连接
                        if(channel.isConnectionPending()){
                            channel.finishConnect();
                        }

                        channel.configureBlocking(false);
                        //向服务器发送消息
                        byte[] body = request.toJSONString().getBytes();
                        int bodyLength = body.length;
                        int totalLength = 5 + bodyLength;
                        byte[] data = new byte[totalLength];

                        data[0] = (byte) ((totalLength >> 24) & 0xFF);
                        data[1] = (byte) ((totalLength >> 16) & 0xFF);
                        data[2] = (byte) ((totalLength >> 8) & 0xFF);
                        data[3] = (byte) (totalLength & 0xFF);
                        data[4] = HeartbeatHandler.DATA_MSG;
                        for (int i = 5; i < data.length; i++) {
                            data[i] = body[i-5];
                        }
                        channel.write(ByteBuffer.wrap(data));

                        //连接成功后,注册接收服务器消息的事件
                        channel.register(selector, SelectionKey.OP_READ);
                        logger.debug("首次连接config-center-server成功");
                        //有可读数据事件。
                    }else if(key.isReadable()){
                        SocketChannel channel = (SocketChannel)key.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(0x200000);
                        channel.read(buffer);
                        byte[] data = buffer.array();
                        String msg = new String(data,5,data.length - 5);
                        logger.debug("首次连接config-center-server,并接受到返回值:{}",msg);

                        channel.close();
                        return msg;
                    }
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy