Browse Source

动态路由加载

lingfeng 8 years ago
parent
commit
6f92e9b2d2

+ 91 - 0
Hos-Framework/src/main/java/com/yihu/ehr/framework/util/operator/ClassFileUtil.java

@ -0,0 +1,91 @@
package com.yihu.ehr.framework.util.operator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.URL;
public class ClassFileUtil {
    /**
     * 工具类不允许进行实例化
     */
    private ClassFileUtil() {
    }
    private static Logger logger = LogManager.getLogger();
    /**
     * 通过这个工具方法,可以进行class文件的创建
     * @param systemRootURL 本次进行系统创建的system业务系统存储class文件的根目录
     * @param packageName class文件的包信息
     * @param className class文件的类名信息
     * @param path class文件的路径
     */
    public static void createClassfile(URL systemRootURL , String packageName, String className, String path) {
        // 开始输出文件内容
        try {
            FileInputStream in = new FileInputStream(new File(path));
            String classPath = systemRootURL.getPath() + "/" + packageName + "/" + className;
            File file = new File(classPath);
            if (file.isFile() && file.exists()) {
                return;
            } else {
                file.createNewFile();
            }
            FileOutputStream out = new FileOutputStream(classPath);
            int n = 0;// 每次读取的字节长度
            byte[] bb = new byte[1024];// 存储每次读取的内容
            while ((n = in.read(bb)) != -1) {
                out.write(bb, 0, n);// 将读取的内容,写入到输出流当中
            }
            out.close();
            in.close();
        } catch (Exception e) {
            logger.error(e.getMessage() , e);
            return;
        }
    }
    public static void updateClassfile(URL systemRootURL , String packageName, String className, String path) {
        // 开始输出文件内容
        try {
            FileInputStream in = new FileInputStream(new File(path));
            String classPath = systemRootURL.getPath() + "/" + packageName + "/" + className;
            File file = new File(classPath);
            if (file.isFile() && file.exists()) {
                file.delete();
            } else {
                file.createNewFile();
            }
            FileOutputStream out = new FileOutputStream(classPath);
            int n = 0;// 每次读取的字节长度
            byte[] bb = new byte[1024];// 存储每次读取的内容
            while ((n = in.read(bb)) != -1) {
                out.write(bb, 0, n);// 将读取的内容,写入到输出流当中
            }
            out.close();
            in.close();
        } catch (Exception e) {
            logger.error(e.getMessage() , e);
            return;
        }
    }
    public static void deleteClassfile(URL systemRootURL , String packageName, String className) {
        // 开始输出文件内容
        try {
            String classPath = systemRootURL.getPath() + "/" + packageName + "/" + className;
            File file = new File(classPath);
            if (file.isFile() && file.exists()) {
                file.delete();
            }
        } catch (Exception e) {
            logger.error(e.getMessage() , e);
            return;
        }
    }
}

+ 5 - 5
hos-broker/pom.xml

@ -85,11 +85,11 @@
			<!--<artifactId>camel-test</artifactId>-->
			<!--<scope>test</scope>-->
		<!--</dependency>-->
		<!--<dependency>-->
			<!--<groupId>com.yihu.hos.resource</groupId>-->
			<!--<artifactId>Hos-Framework</artifactId>-->
			<!--<version>1.0.7</version>-->
		<!--</dependency>-->
		<dependency>
			<groupId>com.yihu.hos.resource</groupId>
			<artifactId>Hos-Framework</artifactId>
			<version>1.0.7</version>
		</dependency>
	</dependencies>

+ 13 - 2
hos-broker/src/main/java/com/yihu/hos/HosBrokerApplication.java

@ -1,12 +1,23 @@
package com.yihu.hos;
import com.yihu.hos.listener.ApplicationStartListener;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
@SpringBootApplication
public class HosBrokerApplication{
public class HosBrokerApplication extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(HosBrokerApplication.class);
    }
    public static void main(String[] args) {
        SpringApplication.run(HosBrokerApplication.class, args);
        SpringApplication app = new SpringApplication(HosBrokerApplication.class);
        app.run(args);
        app.addListeners(new ApplicationStartListener());
    }
}

+ 97 - 0
hos-broker/src/main/java/com/yihu/hos/controllers/ESBCamelController.java

@ -0,0 +1,97 @@
package com.yihu.hos.controllers;
import com.yihu.ehr.framework.model.Result;
import com.yihu.hos.services.ESBCamelService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
/**
 * Created by lingfeng on 2016/8/4.
 */
@Controller
@RequestMapping("/esb")
public class ESBCamelController {
    @Resource(name= ESBCamelService.BEAN_ID)
    ESBCamelService esbCamelService;
    @RequestMapping(value = "/processor", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "新增Processor处理器", produces = "application/json", notes = "当外界组件通知一个新的processor处理器被定义时,该事件被触发")
    public Result onProcessorAdded(
            @ApiParam(name = "serviceFlow", value = "服务名称", required = true)
            @RequestParam(value = "serviceFlow") String serviceFlow,
            @ApiParam(name = "packageName", value = "包名", required = true)
            @RequestParam(value = "packageName") String packageName,
            @ApiParam(name = "className", value = "类名", required = true)
            @RequestParam(value = "className") String className,
            @ApiParam(name = "path", value = "class文件路径", required = true)
            @RequestParam(value = "path") String path) {
        return Result.success("成功!");
//        return esbCamelService.onProcessorAdded(serviceFlow, packageName, className, path);
    }
    @RequestMapping(value = "/processor", produces = "application/json;charset=UTF-8", method = RequestMethod.PUT)
    @ResponseBody
    @ApiOperation(value = "修改Processor处理器", produces = "application/json", notes = "当外界组件通知一个已有的processor处理器data部分发生变化时,该事件被触发")
    public Result onProcessorDataChanged(
            @ApiParam(name = "serviceFlow", value = "服务名称", required = true)
            @RequestParam(value = "serviceFlow") String serviceFlow,
            @ApiParam(name = "packageName", value = "包名", required = true)
            @RequestParam(value = "packageName") String packageName,
            @ApiParam(name = "className", value = "类名", required = true)
            @RequestParam(value = "className") String className,
            @ApiParam(name = "path", value = "class文件路径", required = true)
            @RequestParam(value = "path") String path) {
        return esbCamelService.onProcessorDataChanged(serviceFlow, packageName, className, path);
    }
    @RequestMapping(value = "/route", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "新增Route路由", produces = "application/json", notes = "当外界组件通知一个新的RouteDefine路由被定义时,该事件被触发")
    public Result onRouteDefineAdded(
            @ApiParam(name = "serviceFlow", value = "服务名称", required = true)
            @RequestParam(value = "serviceFlow") String serviceFlow,
            @ApiParam(name = "packageName", value = "包名", required = true)
            @RequestParam(value = "packageName") String packageName,
            @ApiParam(name = "className", value = "类名", required = true)
            @RequestParam(value = "className") String className,
            @ApiParam(name = "path", value = "class文件路径", required = true)
            @RequestParam(value = "path") String path) {
        return esbCamelService.onRouteDefineAdded(serviceFlow, packageName, className, path);
    }
    @RequestMapping(value = "/route", produces = "application/json;charset=UTF-8", method = RequestMethod.PUT)
    @ResponseBody
    @ApiOperation(value = "修改Route路由", produces = "application/json", notes = "当外界组件通知一个已有的RouteDefine路由定义被改变时,主要就是路由定义内容被改变时,该事件被触发")
    public Result onRouteDefineChanged(
            @ApiParam(name = "serviceFlow", value = "服务名称", required = true)
            @RequestParam(value = "serviceFlow") String serviceFlow,
            @ApiParam(name = "packageName", value = "包名", required = true)
            @RequestParam(value = "packageName") String packageName,
            @ApiParam(name = "className", value = "类名", required = true)
            @RequestParam(value = "className") String className,
            @ApiParam(name = "path", value = "class文件路径", required = true)
            @RequestParam(value = "path") String path) {
        return esbCamelService.onRouteDefineChanged(serviceFlow, packageName, className, path);
    }
    @RequestMapping(value = "/route", produces = "application/json;charset=UTF-8", method = RequestMethod.DELETE)
    @ResponseBody
    @ApiOperation(value = "删除Route路由", produces = "application/json", notes = "当外界组件通知一个已有的RouteDefine路由定义被删除时,该事件被触发")
    public Result onRouteDefineDelete(
            @ApiParam(name = "serviceFlow", value = "服务名称", required = true)
            @RequestParam(value = "serviceFlow") String serviceFlow,
            @ApiParam(name = "packageName", value = "包名", required = true)
            @RequestParam(value = "packageName") String packageName,
            @ApiParam(name = "className", value = "类名", required = true)
            @RequestParam(value = "className") String className) {
        return esbCamelService.onRouteDefineDelete(serviceFlow, packageName, className);
    }
}

+ 23 - 0
hos-broker/src/main/java/com/yihu/hos/dao/BrokerDao.java

@ -0,0 +1,23 @@
package com.yihu.hos.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
@Repository("BrokerDao")
public class BrokerDao {
    public static final String BEAN_ID = "BrokerDao";
    @Autowired
    private JdbcTemplate jdbcTemplate;
    public List<Map<String, Object>> getSystemServiceFlowList() throws Exception {
        return jdbcTemplate.queryForList("select * from system_service_flow");
    }
    public List<Map<String, Object>> getSystemServiceFlowClassList() throws Exception {
        return jdbcTemplate.queryForList("select * from system_service_flow_class");
    }
}

+ 173 - 0
hos-broker/src/main/java/com/yihu/hos/listener/ApplicationStartListener.java

@ -0,0 +1,173 @@
package com.yihu.hos.listener;
import com.yihu.ehr.framework.util.operator.ClassFileUtil;
import com.yihu.hos.dao.BrokerDao;
import com.yihu.hos.model.CamelContextQueue;
import com.yihu.hos.model.SystemPathMapping;
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.SynchronousQueue;
/**
 * 项目启动执行
 * add by hzp at 2016-01-25
 */
@Repository("ApplicationStartListener")
public class ApplicationStartListener implements ApplicationListener {
    public static final String BEAN_ID = "ApplicationStartListener";
    @Resource(name = BrokerDao.BEAN_ID)
    BrokerDao brokerDao;
    private static Logger logger = LogManager.getLogger();
    /**
     * 这是一个固定的存储class文件的根路径
     * 正式系统中,这个值可来自于系统的配置文件
     */
    private static final String CLASSROOTPATH = "D:/testCamelRoot";
    private void camelRouteStart() throws Exception {
         /*
         * 启动顺序为:
         *
         * 1、首先使用Apache Curator组件进行zookeeper服务端连接,
         *
         * 2、通过Apache Curator组件查询目前已有的业务系统ID信息,
         * 以便依据这些业务系统ID,建立本地ClassLoader的根路径(当然,有就不需要创建了)
         * 并且注册Apache Curator封装层的监听。
         *
         * 3、检查第2步得到的业务系统下,已经存在的processor处理器定义和已有的route定义
         * 以便生成class信息。
         *
         * 4、启动Apache Camel服务,将第三步那些route定义进行动态加载
         *
         * 5、经过以上步骤,整个启动过程完成了。现在主线程需要一直等待从SynchronousQueue队列发来的动态加载请求了。
         * */
        // 1、===============
        // 连接到zookeeper
//        CuratorFramework zkClient = CuratorFrameworkFactory.newClient("192.168.61.140:2181", 30000, 30000, new RetryNTimes(50, 3000));
//        zkClient.start();
//        BootStartup.LOGGER.info("完成zookeeper服务端的连接工作!");
        // 2、===============
        // 取得已存在的系统
//        List<String> systemNames = zkClient.getChildren().forPath("/");
        List<Map<String, Object>> systemServiceFlowList = brokerDao.getSystemServiceFlowList();
        List<Map<String, Object>> systemServiceFlowClassList = brokerDao.getSystemServiceFlowClassList();
        Map<String, List<Map<String, Object>>> systemServiceFlowClassGroupMap = new HashMap<>();
        for (Map<String, Object> systemServiceFlowClassMap : systemServiceFlowClassList) {
            Integer flowId = (Integer) systemServiceFlowClassMap.get("flow_id");
            if (systemServiceFlowClassGroupMap.containsKey(flowId)) {
                List<Map<String, Object>> classList = systemServiceFlowClassGroupMap.get(flowId);
                classList.add(systemServiceFlowClassMap);
                String type = (String) systemServiceFlowClassMap.get("type");
                systemServiceFlowClassGroupMap.put(type + flowId.toString()  , classList);
            } else {
                List<Map<String, Object>> classList = new ArrayList<>();
                classList.add(systemServiceFlowClassMap);
                String type = (String) systemServiceFlowClassMap.get("type");
                systemServiceFlowClassGroupMap.put(type + flowId.toString()  , classList);
            }
        }
        List<File> systemClassRootPaths = new ArrayList<>();
        List<RouteBuilder> alreadyRouteBuilders = new ArrayList<>();
        for (Map<String, Object> systemNameMap : systemServiceFlowList) {
            Integer flowId = (Integer) systemNameMap.get("id");
            String code = (String) systemNameMap.get("code");
            // 这是system业务系统在本地存储class的根目录
            File systemClassRootPath = new File(CLASSROOTPATH + "/" + code);
            if (!systemClassRootPath.exists()) {
                systemClassRootPath.mkdirs();
            }
            Map<String, URL> systemRootPathMapping = SystemPathMapping.getSystemRootPathMapping();
            // 记录到工具类中,以便其它线程需要时进行取用
            systemRootPathMapping.put(code, systemClassRootPath.toURI().toURL());
            if (!systemClassRootPaths.contains(systemClassRootPath)) {
                systemClassRootPaths.add(systemClassRootPath);
            }
            List<Map<String, Object>> processesClassList = systemServiceFlowClassGroupMap.get("processor" + flowId);
            List<Map<String, Object>> routesClassList = systemServiceFlowClassGroupMap.get("route" + flowId);
            // 创建processor文件
            for (Map<String, Object> processesClass : processesClassList) {
                String className = (String) processesClass.get("name");
                String packageName = (String) processesClass.get("package");
                String classPath = (String) processesClass.get("path");
                // 创建文件
                ClassFileUtil.createClassfile(systemClassRootPath.toURI().toURL(), packageName, className, classPath);
            }
            // 创建route文件
            for (Map<String, Object> routesClass : routesClassList) {
                String className = (String) routesClass.get("name");
                String packageName = (String) routesClass.get("package");
                String classPath = (String) routesClass.get("path");
                // 创建文件
                ClassFileUtil.createClassfile(systemClassRootPath.toURI().toURL(), packageName, className, classPath);
                RouteBuilder routeBuilder = (RouteBuilder)Class.forName(packageName + "." + className).newInstance();
                alreadyRouteBuilders.add(routeBuilder);
            }
        }
        // 4、=============
        // 首先启动Apache Camel服务
        CamelContext camelContext = new DefaultCamelContext();
        camelContext.start();
        logger.info("Apache Camel Context 启动完成......");
        // 加载和设置ClassLoader
        List<URL> URLs = new ArrayList<>();
        for (File systemClassRootPath : systemClassRootPaths) {
            URLs.add(systemClassRootPath.toURI().toURL());
        }
        ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
        ClassLoader camelESBClassLoader = new URLClassLoader(URLs.toArray(new URL[]{}) , currentClassLoader);
        Thread.currentThread().setContextClassLoader(camelESBClassLoader);
        camelContext.setApplicationContextClassLoader(camelESBClassLoader);
        // 然后就可以进行RouteBuilder的加载
        for (RouteBuilder routeBuilder : alreadyRouteBuilders) {
            try {
                camelContext.addRoutes(routeBuilder);
            } catch(Exception e) {
                logger.warn(e.getMessage() , e);
            }
        }
        // 5、=============
        // 开始监控CamelContext动态操作队列
        SynchronousQueue<String> camelContextOperateQueue = CamelContextQueue.getCamelCamelContextQueue();
        String mustLoadedClassName = null;
        // 如果没有收到其它线程的加载请求,主线程将停止在这里
        while((mustLoadedClassName = camelContextOperateQueue.take()) != null) {
            Class<RouteBuilder> routeBuilderClass = (Class<RouteBuilder>)camelESBClassLoader.loadClass(mustLoadedClassName);
            if(routeBuilderClass != null) {
                RouteBuilder routeBuilder = routeBuilderClass.newInstance();
                camelContext.addRoutes(routeBuilder);
            }
        }
    }
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        try {
            camelRouteStart();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

+ 16 - 0
hos-broker/src/main/java/com/yihu/hos/model/CamelContextQueue.java

@ -0,0 +1,16 @@
package com.yihu.hos.model;
import java.util.concurrent.SynchronousQueue;
/**
 * Created by lingfeng on 2016/8/4.
 */
public class CamelContextQueue {
    private static SynchronousQueue<String> camelContextOperateQueue;
    public static SynchronousQueue<String> getCamelCamelContextQueue() {
        if (camelContextOperateQueue == null) {
            camelContextOperateQueue = new SynchronousQueue<>(true);
        }
        return camelContextOperateQueue;
    }
}

+ 18 - 0
hos-broker/src/main/java/com/yihu/hos/model/SystemPathMapping.java

@ -0,0 +1,18 @@
package com.yihu.hos.model;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
/**
 * Created by lingfeng on 2016/8/4.
 */
public class SystemPathMapping {
    private static Map<String, URL> systemRootPathMapping ;
    public static Map<String, URL> getSystemRootPathMapping() {
        if (systemRootPathMapping == null) {
            systemRootPathMapping = new HashMap<>();
        }
        return systemRootPathMapping;
    }
}

+ 165 - 0
hos-broker/src/main/java/com/yihu/hos/services/ESBCamelService.java

@ -0,0 +1,165 @@
package com.yihu.hos.services;
import com.yihu.ehr.framework.model.Result;
import com.yihu.ehr.framework.util.operator.ClassFileUtil;
import com.yihu.ehr.framework.util.operator.StringUtil;
import com.yihu.hos.model.CamelContextQueue;
import com.yihu.hos.model.SystemPathMapping;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.SynchronousQueue;
/**
 * Created by lingfeng on 2016/8/4.
 */
@Service("ESBCamelService")
public class ESBCamelService {
    public static final String BEAN_ID = "ESBCamelService";
    private static Logger logger = LogManager.getLogger();
    /**
     * 当外界组件通知一个新的processor处理器被定义时,该事件被触发。
     * @param serviceFlow 本次processor处理器变化,所涉及的业务系统唯一标识。
     * @param packageName processor处理器定义涉及的class包名
     * @param className processor处理器定义涉及的class类名
     * @param path processor处理器定义涉及的class对应路径
     */
    public Result onProcessorAdded(String serviceFlow, String packageName, String className, String path) {
 /*
         * 当一个处理器进行添加时,要做以下处理
         * 1、首先根据serviceFlow的信息,在ESB-Broker Server的映射容器中寻
         * 找个业务系统定义的各种Server Class 文件在ESB-Broker Server节点本地存储的根路径
         * 2、然后按照packageName、className、contents的信息将这个class文件写入到正确的位置
         *
         * 注意:由于此时只是完成了class了文件的写入,所以这个class文件还没有被classloader进行初始化。
         * 另外由于,CamelContext并没有提供单独进行processor处理器加载的功能,而是随着routes实例的加载而加载
         * 而这个工作将在onRouteDefineChanged事件中完成,所以在完成processor-class文件的写入后,就不需要再做其它事情了。
         * */
        if(StringUtil.isEmpty(serviceFlow) || StringUtil.isEmpty(packageName)
                || StringUtil.isEmpty(className) || StringUtil.isEmpty(path)) {
            logger.error("必要的入参数据不正确,请检查!");
            return Result.error("必要的入参数据不正确,请检查!");
        }
        this.createClassfile(serviceFlow, packageName, className, path);
        return Result.success("新增处理器成功!");
    }
    /**
     * 当外界组件通知一个已有的processor处理器data部分发生变化时,该事件被触发。
     */
    public Result onProcessorDataChanged(String serviceFlow , String packageName , String className , String path) {
        if(StringUtil.isEmpty(serviceFlow) || StringUtil.isEmpty(packageName)
                || StringUtil.isEmpty(className) || StringUtil.isEmpty(path)) {
            logger.error("必要的入参数据不正确,请检查!");
            return Result.error("必要的入参数据不正确,请检查!");
        }
        this.updateClassfile(serviceFlow, packageName, className, path);
        return Result.success("修改处理器成功!");
    }
    /**
     * 当外界组件通知一个新的RouteDefine路由被定义时,该事件被触发
     */
    public Result onRouteDefineAdded(String serviceFlow , String packageName , String className , String path) {
/*
         * 当一个新的路由定义事件发生时,要做以下几件事情:
         *
         * 1、根据serviceFlow的信息,在ESB-Broker Server的映射容器中寻
         * 找个业务系统定义的各种Server Class 文件在ESB-Broker Server节点本地存储的根路径
         * 2、然后按照packageName、className、contents的信息将这个class文件写入到正确的位置
         * 3、不能在本线程操作Apache Camel,只能通过一个同步队列通知Apache Camel主线程
         * */
        if(StringUtil.isEmpty(serviceFlow) || StringUtil.isEmpty(packageName)
                || StringUtil.isEmpty(className) || StringUtil.isEmpty(path)) {
            logger.error("必要的入参数据不正确,请检查!");
            return Result.error("必要的入参数据不正确,请检查!");
        }
        // 第1、2两步处理过程,都是在这里完成
        this.createClassfile(serviceFlow, packageName, className, path);
        // 3、===============加载到CamelContext中
        SynchronousQueue<String> camelContextOperateQueue = CamelContextQueue.getCamelCamelContextQueue();
        try {
            camelContextOperateQueue.put(packageName + "." + className);
        } catch (InterruptedException e) {
            logger.error(e.getMessage() , e);
        }
        return Result.success("新增路由成功!");
    }
    /**
     * 当外界组件通知一个已有的RouteDefine路由定义被改变时,主要就是路由定义内容被改变时,该事件被触发。
     */
    public Result onRouteDefineChanged(String serviceFlow, String packageName, String className, String path) {
        if(StringUtil.isEmpty(serviceFlow) || StringUtil.isEmpty(packageName)
                || StringUtil.isEmpty(className) || StringUtil.isEmpty(path)) {
            logger.error("必要的入参数据不正确,请检查!");
            return Result.error("必要的入参数据不正确,请检查!");
        }
        this.updateClassfile(serviceFlow, packageName, className, path);
        return Result.success("修改路由成功!");
    }
    /**
     * 当外界组件通知一个已有的RouteDefine路由定义被删除时,该事件被触发。
     */
    public Result onRouteDefineDelete(String serviceFlow, String packageName, String className) {
        if(StringUtil.isEmpty(serviceFlow) || StringUtil.isEmpty(packageName)
                || StringUtil.isEmpty(className)) {
            logger.error("必要的入参数据不正确,请检查!");
            return Result.error("必要的入参数据不正确,请检查!");
        }
        this.deleteClassfile(serviceFlow, packageName, className);
        return Result.success("删除路由成功!");
    }
    private void createClassfile(String serviceFlow, String packageName, String className, String path) {
        // 1、============
        Map<String, URL> systemPathMapping = SystemPathMapping.getSystemRootPathMapping();
        URL systemRootURL = systemPathMapping.get(serviceFlow);
        if(systemRootURL == null) {
            return;
        }
        // 2、============开始写入class文件
        ClassFileUtil.createClassfile(systemRootURL, packageName, className, path);
        // 完成
        logger.info("===================" + packageName + "." + className + ".class 生成过程结束");
    }
    private void updateClassfile(String serviceFlow, String packageName, String className, String path) {
        // 1、============
        Map<String, URL> systemPathMapping = SystemPathMapping.getSystemRootPathMapping();
        URL systemRootURL = systemPathMapping.get(serviceFlow);
        if(systemRootURL == null) {
            return;
        }
        // 2、============开始写入class文件
        ClassFileUtil.updateClassfile(systemRootURL, packageName, className, path);
        // 完成
        logger.info("===================" + packageName + "." + className + ".class 修改过程结束");
    }
    private void deleteClassfile(String serviceFlow, String packageName, String className) {
        // 1、============
        Map<String, URL> systemPathMapping = SystemPathMapping.getSystemRootPathMapping();
        URL systemRootURL = systemPathMapping.get(serviceFlow);
        if(systemRootURL == null) {
            return;
        }
        // 2、============开始写入class文件
        ClassFileUtil.deleteClassfile(systemRootURL, packageName, className);
        // 完成
        logger.info("===================" + packageName + "." + className + ".class 删除过程结束");
    }
}

+ 15 - 3
hos-broker/src/main/resources/application.properties

@ -1,7 +1,19 @@
server.port=0
hos.arbiter=http://127.0.0.1:10135
server.port=8099
hos.arbiter=http://192.168.131.38:10135
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.1.220:3306/hos2_resource??useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true
spring.datasource.username=hos2
spring.datasource.password=hos2
spring.datasource.test-on-borrow=true
spring.datasource.validation-query=SELECT 1
spring.datasource.test-while-idle=true
spring.datasource.max-active=30
spring.datasource.default-auto-commit=true
spring.datasource.max-idle=30
spring.datasource.min-idle=10
spring.datasource.initial-size=10
security.basic.enabled=false
# the name of Camel
camel.springboot.name = HosBrokerServer

+ 8 - 0
hos-broker/src/test/java/com/yihu/hos/ESBCamelServiceTest.java

@ -0,0 +1,8 @@
package com.yihu.hos;
/**
 * Created by lingfeng on 2016/8/5.
 */
public class ESBCamelServiceTest {
}

+ 1 - 0
hos-broker/src/test/java/com/yihu/hos/HosBrokerApplicationTests.java

@ -13,6 +13,7 @@ public class HosBrokerApplicationTests {
	@Test
	public void contextLoads() {
	}
}