diff --git a/build.gradle b/build.gradle index 0a0d1b2d04..b9595e53e8 100644 --- a/build.gradle +++ b/build.gradle @@ -77,6 +77,7 @@ allprojects { // 注册前端依赖 implementation 'com.fr.license:fine-license-webui:' + apiVersion // 认证前端依赖 + implementation 'com.fr.cbb:fine-cbb-common:' + cbbVersion implementation 'com.fr.auth:fine-auth-webui:' + apiVersion implementation 'com.fr.portal:fine-portal-api:' + apiVersion implementation 'com.fr.essential:fine-essential:' + cbbVersion diff --git a/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvComponent.java b/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvComponent.java index d42a973282..6af8b4715d 100644 --- a/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvComponent.java +++ b/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvComponent.java @@ -3,6 +3,7 @@ package com.fanruan.boot.env; import com.fanruan.boot.FSProperties; import com.fanruan.boot.KVProperties; import com.fanruan.boot.LoggerProperties; +import com.fanruan.boot.SchedulerCoreComponent; import com.fanruan.carina.Carina; import com.fanruan.carina.annotions.FineComponent; import com.fanruan.carina.annotions.JPAEntityScan; @@ -26,6 +27,8 @@ import com.fanruan.kv.manager.CarinaKVManager; import com.fanruan.kv.store.KVStore; import com.fanruan.kv.store.KVStoreHolder; import com.fr.cbb.dialect.security.InsecurityElementFactory; +import com.fr.cluster.ClusterBridge; +import com.fr.cluster.lock.ClusterLock; import com.fr.config.BaseDBEnv; import com.fr.config.ConfigContext; import com.fr.config.ConfigEvent; @@ -65,6 +68,9 @@ import com.fr.record.analyzer.AnalyzerKey; import com.fr.record.analyzer.AnalyzerMutableGroup; import com.fr.record.analyzer.Assistant; import com.fr.record.analyzer.DBMetrics; +import com.fr.scheduler.QuartzContext; +import com.fr.scheduler.SchedulerEvent; +import com.fr.scheduler.tenant.ScheduleThreadCurrentTenantProvider; import com.fr.security.encryption.EncryptionInitialization; import com.fr.security.encryption.core.EncryptionScaffold; import com.fr.security.encryption.provider.SecuritySeedProvider; @@ -74,12 +80,16 @@ import com.fr.stable.GraphDrawHelper; import com.fr.stable.StringUtils; import com.fr.stable.db.DBContext; import com.fr.stable.db.properties.FineMicroServicesDBProperties; +import com.fr.stable.db.session.DBSession; import com.fr.stable.project.ProjectConstants; +import com.fr.tenant.context.TenantContext; +import com.fr.tenant.context.provider.CurrentTenantKey; import com.fr.third.net.bytebuddy.description.type.TypeDescription; import com.fr.third.net.bytebuddy.dynamic.DynamicType; import com.fr.third.net.bytebuddy.implementation.MethodDelegation; import com.fr.third.net.bytebuddy.matcher.ElementMatchers; import com.fr.third.net.bytebuddy.utility.JavaModule; +import com.fr.third.org.hibernate.jdbc.AbstractWork; import com.fr.tolerance.FaultTolerance; import com.fr.tolerance.FaultToleranceInterceptor; import com.fr.transaction.Configurations; @@ -90,7 +100,10 @@ import com.fr.transaction.TransactorFactory; import com.fr.workspace.WorkContext; import java.net.URI; +import java.sql.Connection; +import java.sql.SQLException; import java.util.Objects; +import java.util.Properties; /** * 设计器env模块,环境切换的底层模块 @@ -129,6 +142,7 @@ public class DesignEnvComponent { Carina.getApplicationContext().group(AnalyzerMutableGroup.class).add(AnalyzerConfiguration.create((builder, typeDescription, classLoader, module) -> builder .method(ElementMatchers.isAnnotatedWith(FaultTolerance.class)) .intercept(MethodDelegation.to(FaultToleranceInterceptor.class)))); + Carina.getApplicationContext().group(CurrentTenantKey.class).add(ScheduleThreadCurrentTenantProvider.INSTANCE); } @Start @@ -147,13 +161,44 @@ public class DesignEnvComponent { startLogger(); // 7.kv startKv(); + // 8.scheduler + startScheduler(); } - + private void startScheduler() { + TenantContext.doIsolatedWork(() -> { + ClusterLock lock = ClusterBridge.getLockFactory().get(SchedulerCoreComponent.class); + // 多节点同时启动quartz模块可能会产生脏数据,导致报错,使用集群锁控制一下 + try { + lock.lock(); + final DBContextProvider context = BaseDBEnv.getDBContext(); + if (context == null) { + throw new IllegalArgumentException("ConfigDBActivator must start before SchedulerActivator"); + } + DBSession dbSession = context.openSession(); + dbSession.doWork(new AbstractWork() { + + @Override + public void execute(Connection connection) throws SQLException { + //quartz需要的数据库方言 + Properties properties = context.getDBProperties(); + QuartzContext.getInstance().initScheduler(properties); + } + }); + dbSession.closeSession(); + EventDispatcher.fire(SchedulerEvent.START); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + lock.unlock(); + } + }, "default"); + } @Stop public void stop() { + stopScheduler(); stopLogger(); stopFileServer(); stopConfConfig(); @@ -162,6 +207,11 @@ public class DesignEnvComponent { stopEnvPrepare(); } + private void stopScheduler() { + EventDispatcher.fire(SchedulerEvent.STOP); + QuartzContext.getInstance().destroy(); + } + /** * -------------------private------------------- @@ -171,6 +221,7 @@ public class DesignEnvComponent { * ----------kv--------- */ private void startKv() { + // KVProperties没有的话默认走内存 KVStore kvStore = KVStoreFactory.createFineKVStore(Carina.properties(KVProperties.class).getType()); KVStoreHolder.getInstance().setStore(kvStore); CarinaKV.switchTo(new CarinaKVManager());