ESBCamelService.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. package com.yihu.hos.services;
  2. import com.mongodb.client.MongoDatabase;
  3. import com.yihu.hos.common.classLoader.DynamicClassLoader;
  4. import com.yihu.hos.common.compiler.CamelCompiler;
  5. import com.yihu.hos.common.compiler.ClassParams;
  6. import com.yihu.hos.common.configuration.MongoConfiguration;
  7. import com.yihu.hos.common.constants.BrokerConstant;
  8. import com.yihu.hos.core.constants.CoreConstant;
  9. import com.yihu.hos.core.datatype.ClassFileUtil;
  10. import com.yihu.hos.core.datatype.StringUtil;
  11. import com.yihu.hos.core.encrypt.DES;
  12. import com.yihu.hos.models.SystemCamelContext;
  13. import com.yihu.hos.models.SystemClassMapping;
  14. import com.yihu.hos.web.framework.model.Result;
  15. import com.yihu.hos.web.framework.util.GridFSUtil;
  16. import org.apache.camel.Processor;
  17. import org.apache.camel.builder.RouteBuilder;
  18. import org.apache.log4j.LogManager;
  19. import org.apache.log4j.Logger;
  20. import org.springframework.beans.factory.annotation.Autowired;
  21. import org.springframework.stereotype.Service;
  22. import java.io.File;
  23. import java.io.FileOutputStream;
  24. import java.io.IOException;
  25. import java.net.MalformedURLException;
  26. import java.net.URL;
  27. import java.net.URLClassLoader;
  28. import java.util.Map;
  29. /**
  30. * Created by lingfeng on 2016/8/4.
  31. */
  32. @Service("ESBCamelService")
  33. public class ESBCamelService {
  34. public static final String BEAN_ID = "ESBCamelService";
  35. @Autowired
  36. private MongoConfiguration mongoConfig;
  37. private String dbName = "upload";
  38. private static Logger logger = LogManager.getLogger(ESBCamelService.class);
  39. /**
  40. * 当外界组件通知一个新的processor处理器被定义时,该事件被触发。
  41. * @param serviceFlow 本次processor处理器变化,所涉及的业务系统唯一标识。
  42. * @param packageName processor处理器定义涉及的class包名
  43. * @param className processor处理器定义涉及的class类名
  44. * @param path processor处理器定义涉及的class对应路径
  45. */
  46. public Result onProcessorAdded(String serviceFlow, String packageName, String className, String path) {
  47. try {
  48. if(StringUtil.isEmpty(serviceFlow) || StringUtil.isEmpty(packageName)
  49. || StringUtil.isEmpty(className) || StringUtil.isEmpty(path)) {
  50. logger.error("必要的入参数据不正确,请检查!");
  51. return Result.error("必要的入参数据不正确,请检查!");
  52. }
  53. FileOutputStream out = this.createClassfile(serviceFlow, packageName, className, BrokerConstant.PROCESSOR);
  54. String fileName = DES.decrypt(path, DES.COMMON_PASSWORD);
  55. MongoDatabase db = mongoConfig.mongoClient().getDatabase(dbName);
  56. if (GridFSUtil.readFile(db, out, fileName)) {
  57. return Result.success("新增处理器成功!");
  58. } else {
  59. return Result.error("新增处理器失败!");
  60. }
  61. } catch (Exception e) {
  62. logger.error(e);
  63. return Result.error("新增处理器失败!");
  64. }
  65. }
  66. /**
  67. * 当外界组件通知一个已有的processor处理器data部分发生变化时,该事件被触发。
  68. */
  69. public Result onProcessorDataChanged(String serviceFlow , String packageName , String className , String path) {
  70. try {
  71. if(StringUtil.isEmpty(serviceFlow) || StringUtil.isEmpty(packageName)
  72. || StringUtil.isEmpty(className) || StringUtil.isEmpty(path)) {
  73. logger.error("必要的入参数据不正确,请检查!");
  74. return Result.error("必要的入参数据不正确,请检查!");
  75. }
  76. FileOutputStream out = this.updateClassfile(serviceFlow, packageName, className, BrokerConstant.PROCESSOR);
  77. String fileName = DES.decrypt(path, DES.COMMON_PASSWORD);
  78. MongoDatabase db = mongoConfig.mongoClient().getDatabase(dbName);
  79. if (GridFSUtil.readFile(db, out, fileName)) {
  80. SystemCamelContext.getDefaultCamelContext().stopRoute(serviceFlow);
  81. SystemCamelContext.getDefaultCamelContext().removeRoute(serviceFlow);
  82. DynamicClassLoader classLoader = new DynamicClassLoader(DynamicClassLoader.class.getClassLoader());
  83. Class<RouteBuilder> routeBuilderClass = (Class<RouteBuilder>) classLoader.loadClass(this.getClass().getProtectionDomain().getClassLoader().getResource("").getPath(), SystemClassMapping.getSystemClassNameMapping().get(serviceFlow + BrokerConstant.ROUTE + className));
  84. classLoader.loadClass(ClassLoader.getSystemResource(CoreConstant.EMPTY).getPath(), SystemClassMapping.getSystemClassNameMapping().get(serviceFlow + BrokerConstant.PROCESSOR + className));
  85. if (routeBuilderClass != null) {
  86. RouteBuilder routeBuilder = routeBuilderClass.newInstance();
  87. SystemCamelContext.getDefaultCamelContext().addRoutes(routeBuilder);
  88. return Result.success("修改处理器成功!");
  89. }
  90. }
  91. return Result.error("修改处理器失败!");
  92. } catch (Exception e) {
  93. logger.error(e);
  94. return Result.error("修改处理器失败!");
  95. }
  96. }
  97. /**
  98. * 当外界组件通知一个已有的Processor路由定义被删除时,该事件被触发。
  99. */
  100. public Result onProcessorDataDelete(String serviceFlow, String packageName, String className) {
  101. try {
  102. if(StringUtil.isEmpty(serviceFlow) || StringUtil.isEmpty(packageName)
  103. || StringUtil.isEmpty(className)) {
  104. logger.error("必要的入参数据不正确,请检查!");
  105. return Result.error("必要的入参数据不正确,请检查!");
  106. }
  107. SystemCamelContext.getDefaultCamelContext().stopRoute(serviceFlow);
  108. SystemCamelContext.getDefaultCamelContext().removeRoute(serviceFlow);
  109. this.deleteClassfile(serviceFlow, packageName, className, BrokerConstant.PROCESSOR);
  110. return Result.success("删除路由成功!");
  111. } catch (Exception e) {
  112. return Result.error("删除路由失败!");
  113. }
  114. }
  115. /**
  116. * 当外界组件通知一个新的RouteDefine路由被定义时,该事件被触发
  117. */
  118. public Result onRouteDefineAdded(String serviceFlow, String packageName, String className, String path) {
  119. try {
  120. if(StringUtil.isEmpty(serviceFlow) || StringUtil.isEmpty(packageName)
  121. || StringUtil.isEmpty(className) || StringUtil.isEmpty(path)) {
  122. logger.error("必要的入参数据不正确,请检查!");
  123. return Result.error("必要的入参数据不正确,请检查!");
  124. }
  125. // 第1、2两步处理过程,都是在这里完成
  126. FileOutputStream out = this.createClassfile(serviceFlow, packageName, className, BrokerConstant.ROUTE);
  127. String fileName = DES.decrypt(path, DES.COMMON_PASSWORD);
  128. MongoDatabase db = mongoConfig.mongoClient().getDatabase(dbName);
  129. if (GridFSUtil.readFile(db, out, fileName)) {
  130. // 3、===============加载到CamelContext中
  131. DynamicClassLoader classLoader = new DynamicClassLoader(DynamicClassLoader.class.getClassLoader());
  132. Class<RouteBuilder> routeBuilderClass = (Class<RouteBuilder>) classLoader.loadClass(SystemClassMapping.getSystemClassNameMapping().get(serviceFlow + BrokerConstant.ROUTE + className));
  133. if(routeBuilderClass != null) {
  134. RouteBuilder routeBuilder = routeBuilderClass.newInstance();
  135. SystemCamelContext.getDefaultCamelContext().addRoutes(routeBuilder);
  136. }
  137. return Result.success("新增路由成功!");
  138. } else {
  139. return Result.error("新增路由失败!");
  140. }
  141. } catch (Exception e) {
  142. logger.error(e);
  143. return Result.error("新增路由失败!");
  144. }
  145. }
  146. /**
  147. * 当外界组件通知一个已有的RouteDefine路由定义被改变时,主要就是路由定义内容被改变时,该事件被触发。
  148. */
  149. public Result onRouteDefineChanged(String serviceFlow, String packageName, String className, String path) {
  150. try {
  151. if (StringUtil.isEmpty(serviceFlow) || StringUtil.isEmpty(packageName)
  152. || StringUtil.isEmpty(className) || StringUtil.isEmpty(path)) {
  153. logger.error("必要的入参数据不正确,请检查!");
  154. return Result.error("必要的入参数据不正确,请检查!");
  155. }
  156. SystemCamelContext.getDefaultCamelContext().stopRoute(serviceFlow);
  157. SystemCamelContext.getDefaultCamelContext().removeRoute(serviceFlow);
  158. FileOutputStream out = this.updateClassfile(serviceFlow, packageName, className, BrokerConstant.ROUTE);
  159. String fileName = DES.decrypt(path, DES.COMMON_PASSWORD);
  160. MongoDatabase db = mongoConfig.mongoClient().getDatabase(dbName);
  161. if (GridFSUtil.readFile(db, out, fileName)) {
  162. // 3、===============加载到CamelContext中
  163. DynamicClassLoader classLoader = new DynamicClassLoader(DynamicClassLoader.class.getClassLoader());
  164. Class<RouteBuilder> routeBuilderClass = (Class<RouteBuilder>) classLoader.loadClass(ClassLoader.getSystemResource(CoreConstant.EMPTY).getPath(), SystemClassMapping.getSystemClassNameMapping().get(serviceFlow + BrokerConstant.ROUTE+className));
  165. if (routeBuilderClass != null) {
  166. RouteBuilder routeBuilder = routeBuilderClass.newInstance();
  167. SystemCamelContext.getDefaultCamelContext().addRoutes(routeBuilder);
  168. return Result.success("修改路由成功!");
  169. }
  170. }
  171. return Result.error("修改路由失败!");
  172. } catch (Exception e) {
  173. return Result.error("修改路由失败!");
  174. }
  175. }
  176. /**
  177. * 当外界组件通知一个已有的RouteDefine路由定义被删除时,该事件被触发。
  178. */
  179. public Result onRouteDefineDelete(String serviceFlow, String packageName, String className) {
  180. try {
  181. if(StringUtil.isEmpty(serviceFlow) || StringUtil.isEmpty(packageName)
  182. || StringUtil.isEmpty(className)) {
  183. logger.error("必要的入参数据不正确,请检查!");
  184. return Result.error("必要的入参数据不正确,请检查!");
  185. }
  186. SystemCamelContext.getDefaultCamelContext().stopRoute(serviceFlow);
  187. SystemCamelContext.getDefaultCamelContext().removeRoute(serviceFlow);
  188. this.deleteClassfile(serviceFlow, packageName, className, BrokerConstant.ROUTE);
  189. return Result.success("删除路由成功!");
  190. } catch (Exception e) {
  191. return Result.error("删除路由失败!");
  192. }
  193. }
  194. /**
  195. * 启动路由时,该事件被触发。
  196. */
  197. public Result onRouteDefineStart(String serviceFlow) {
  198. try {
  199. if(StringUtil.isEmpty(serviceFlow)) {
  200. logger.error("必要的入参数据不正确,请检查!");
  201. return Result.error("必要的入参数据不正确,请检查!");
  202. }
  203. SystemCamelContext.getDefaultCamelContext().startRoute(serviceFlow);
  204. return Result.success("启动路由成功!");
  205. } catch (Exception e) {
  206. return Result.error("启动路由失败!");
  207. }
  208. }
  209. /**
  210. * 停止路由时,该事件被触发。
  211. */
  212. public Result onRouteDefineStop(String serviceFlow) {
  213. try {
  214. if(StringUtil.isEmpty(serviceFlow)) {
  215. logger.error("必要的入参数据不正确,请检查!");
  216. return Result.error("必要的入参数据不正确,请检查!");
  217. }
  218. SystemCamelContext.getDefaultCamelContext().stopRoute(serviceFlow);
  219. return Result.success("停止路由成功!");
  220. } catch (Exception e) {
  221. return Result.error("停止路由失败!");
  222. }
  223. }
  224. private FileOutputStream createClassfile(String serviceFlow, String packageName, String className, String type) throws MalformedURLException {
  225. // 1、============
  226. File systemClassFlowPath = new File(this.getClass().getProtectionDomain().getClassLoader().getResource("").getPath());
  227. // 记录到工具类中,以便其它线程需要时进行取用
  228. SystemClassMapping.getSystemClassNameMapping().put(serviceFlow + type + className, packageName + CoreConstant.DOT + className);
  229. // 2、============开始写入class文件
  230. FileOutputStream out = ClassFileUtil.createClassfile(systemClassFlowPath.toURI().toURL(), packageName, className);
  231. // 完成
  232. logger.info("===================" + packageName + CoreConstant.DOT + className + ".class 生成过程结束");
  233. return out;
  234. }
  235. private FileOutputStream updateClassfile(String serviceFlow, String packageName, String className, String type) throws MalformedURLException {
  236. // 1、============
  237. Map<String, String> systemClassNameMapping = SystemClassMapping.getSystemClassNameMapping();
  238. String systemClassName = systemClassNameMapping.get(serviceFlow + type + className);
  239. if(StringUtil.isEmpty(systemClassName)) {
  240. return null;
  241. }
  242. File systemClassFlowPath = new File(this.getClass().getProtectionDomain().getClassLoader().getResource("").getPath());
  243. // 2、============开始写入class文件
  244. FileOutputStream out = ClassFileUtil.updateClassfile(systemClassFlowPath.toURI().toURL(), packageName, className);
  245. // 完成
  246. logger.info("===================" + packageName + CoreConstant.DOT + className + ".class 修改过程结束");
  247. return out;
  248. }
  249. private void deleteClassfile(String serviceFlow, String packageName, String className, String type) {
  250. // 1、============
  251. Map<String, String> systemClassNameMapping = SystemClassMapping.getSystemClassNameMapping();
  252. String systemClassName = systemClassNameMapping.get(serviceFlow + type + className);
  253. if(StringUtil.isEmpty(systemClassName)) {
  254. return;
  255. }
  256. String packagePath = StringUtil.replaceStrAll(packageName, ".", "/");
  257. String classPath = ClassLoader.getSystemResource("").getPath() + "/" + packagePath + "/" + className + ".class";
  258. // 2、============开始写入class文件
  259. ClassFileUtil.deleteClassfile(classPath);
  260. // 完成
  261. logger.info("===================" + packageName + CoreConstant.DOT + className + ".class 删除过程结束");
  262. }
  263. /* ************************** 修改任务cron生成新的camel文件 add by hzy *********************************** */
  264. public Result onProcessorClassAdded(String serviceFlow, String packageName, String className, String path) {
  265. try {
  266. if(StringUtil.isEmpty(serviceFlow) || StringUtil.isEmpty(packageName)
  267. || StringUtil.isEmpty(className) || StringUtil.isEmpty(path)) {
  268. logger.error("必要的入参数据不正确,请检查!");
  269. return Result.error("必要的入参数据不正确,请检查!");
  270. }
  271. return this.genProcessorFile(serviceFlow, packageName, className, path);
  272. } catch (Exception e) {
  273. e.printStackTrace();
  274. logger.error(e);
  275. return Result.error("新增处理器失败!");
  276. }
  277. }
  278. /**
  279. * 当外界组件通知一个新的RouteDefine路由被定义时,该事件被触发
  280. */
  281. public Result onRouteClassAdded(ClassParams params) {
  282. try {
  283. if(StringUtil.isEmpty(params.getRouteId()) || StringUtil.isEmpty(params.getPackageName())
  284. || StringUtil.isEmpty(params.getOldClassName()) || StringUtil.isEmpty(params.getFilePath())) {
  285. logger.error("必要的入参数据不正确,请检查!");
  286. return Result.error("必要的入参数据不正确,请检查!");
  287. }
  288. // 第1、2两步处理过程,都是在这里完成
  289. this.genRouteFile(params);
  290. // 3、===============加载到CamelContext中
  291. ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
  292. Class<RouteBuilder> routeBuilderClass = (Class<RouteBuilder>) currentClassLoader.loadClass(SystemClassMapping.getSystemClassNameMapping().get(params.getRouteId() + BrokerConstant.ROUTE + params.getNewClassName()));
  293. if(routeBuilderClass != null) {
  294. RouteBuilder routeBuilder = routeBuilderClass.newInstance();
  295. SystemCamelContext.getDefaultCamelContext().addRoutes(routeBuilder);
  296. }
  297. return Result.success("新增路由成功!");
  298. } catch (Exception e) {
  299. e.printStackTrace();
  300. logger.error(e);
  301. return Result.error("新增路由失败!");
  302. }
  303. }
  304. public Result onRouteClassChanged(ClassParams params) {
  305. try {
  306. if(StringUtil.isEmpty(params.getRouteId()) || StringUtil.isEmpty(params.getPackageName())
  307. || StringUtil.isEmpty(params.getOldClassName()) || StringUtil.isEmpty(params.getFilePath())) {
  308. logger.error("必要的入参数据不正确,请检查!");
  309. return Result.error("必要的入参数据不正确,请检查!");
  310. }
  311. // 第1、2两步处理过程,都是在这里完成
  312. SystemCamelContext.getDefaultCamelContext().stopRoute(params.getRouteId());
  313. SystemCamelContext.getDefaultCamelContext().removeRoute(params.getRouteId());
  314. this.genRouteFile(params);
  315. // 3、===============加载到CamelContext中
  316. DynamicClassLoader classLoader = new DynamicClassLoader(DynamicClassLoader.class.getClassLoader());
  317. Class<RouteBuilder> routeBuilderClass = (Class<RouteBuilder>) classLoader.loadClass(ClassLoader.getSystemResource(CoreConstant.EMPTY).getPath(), SystemClassMapping.getSystemClassNameMapping().get(params.getRouteId() + BrokerConstant.ROUTE + params.getNewClassName()));
  318. if (routeBuilderClass != null) {
  319. RouteBuilder routeBuilder = routeBuilderClass.newInstance();
  320. SystemCamelContext.getDefaultCamelContext().addRoutes(routeBuilder);
  321. }
  322. return Result.success("新增路由成功!");
  323. } catch (Exception e) {
  324. e.printStackTrace();
  325. logger.error(e);
  326. return Result.error("新增路由失败!");
  327. }
  328. }
  329. public Result genProcessorFile(String serviceFlow, String packageName, String className, String path) {
  330. try {
  331. String filePath= CamelCompiler.genProcessClass(serviceFlow, path, packageName, className);
  332. if (filePath !=null){
  333. return Result.success(filePath);
  334. }else {
  335. return Result.error("生成新文件失败1!");
  336. }
  337. } catch (IOException e) {
  338. e.printStackTrace();
  339. return Result.error("生成新文件失败2!");
  340. }
  341. }
  342. public Result genRouteFile(ClassParams params) {
  343. try {
  344. String path = CamelCompiler.genRouteClass(params);
  345. return Result.success(path);
  346. } catch (IOException e) {
  347. e.printStackTrace();
  348. return Result.error("生成新文件失败!");
  349. }
  350. }
  351. }