diff --git a/examples/fit-example/08-nacos-complicated-apps/app-assistant/pom.xml b/examples/fit-example/08-nacos-complicated-apps/app-assistant/pom.xml
new file mode 100644
index 00000000..5251602c
--- /dev/null
+++ b/examples/fit-example/08-nacos-complicated-apps/app-assistant/pom.xml
@@ -0,0 +1,116 @@
+
+
+ 4.0.0
+
+ org.fitframework.example
+ nacos-assistant-for-complicated
+ 1.0-SNAPSHOT
+
+
+ UTF-8
+ 17
+
+
+ 3.6.0-SNAPSHOT
+
+
+ 3.14.0
+
+
+
+
+ org.fitframework.example
+ nacos-weather-for-complicated
+ 1.0-SNAPSHOT
+
+
+ org.fitframework
+ fit-starter
+ ${fit.version}
+
+
+
+
+ org.fitframework
+ fit-plugins-starter-web
+ ${fit.version}
+
+
+
+
+ org.fitframework.plugin
+ fit-client-http
+ ${fit.version}
+ runtime
+
+
+ org.fitframework.plugin
+ fit-http-client-okhttp
+ ${fit.version}
+ runtime
+
+
+ org.fitframework.plugin
+ fit-heartbeat-client
+ ${fit.version}
+ runtime
+
+
+ org.fitframework.plugin
+ fit-service-registry
+ ${fit.version}
+ runtime
+
+
+ org.fitframework.plugin
+ fit-service-discovery
+ ${fit.version}
+ runtime
+
+
+ org.fitframework.plugin
+ fit-service-coordination-locator
+ ${fit.version}
+ runtime
+
+
+
+ org.fitframework.plugin
+ fit-service-coordination-nacos
+ ${fit.version}
+ runtime
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven.compiler.version}
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+ -parameters
+
+
+
+
+ org.fitframework
+ fit-build-maven-plugin
+ ${fit.version}
+
+
+ package-app
+
+ package-app
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/fit-example/08-nacos-complicated-apps/app-assistant/src/main/java/modelengine/fit/example/AssistantStarter.java b/examples/fit-example/08-nacos-complicated-apps/app-assistant/src/main/java/modelengine/fit/example/AssistantStarter.java
new file mode 100644
index 00000000..5adec082
--- /dev/null
+++ b/examples/fit-example/08-nacos-complicated-apps/app-assistant/src/main/java/modelengine/fit/example/AssistantStarter.java
@@ -0,0 +1,25 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
+ * This file is a part of the ModelEngine Project.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+package modelengine.fit.example;
+
+import modelengine.fitframework.annotation.Component;
+import modelengine.fitframework.annotation.ScanPackages;
+import modelengine.fitframework.runtime.FitStarter;
+
+/**
+ * 启动类。
+ *
+ * @author 董智豪
+ * @since 2025-06-21
+ */
+@Component
+@ScanPackages("modelengine")
+public class AssistantStarter {
+ public static void main(String[] args) {
+ FitStarter.start(AssistantStarter.class, args);
+ }
+}
diff --git a/examples/fit-example/08-nacos-complicated-apps/app-assistant/src/main/java/modelengine/fit/example/controller/AssistantController.java b/examples/fit-example/08-nacos-complicated-apps/app-assistant/src/main/java/modelengine/fit/example/controller/AssistantController.java
new file mode 100644
index 00000000..8bc50aac
--- /dev/null
+++ b/examples/fit-example/08-nacos-complicated-apps/app-assistant/src/main/java/modelengine/fit/example/controller/AssistantController.java
@@ -0,0 +1,37 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
+ * This file is a part of the ModelEngine Project.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+package modelengine.fit.example.controller;
+
+import modelengine.fit.example.Weather;
+import modelengine.fit.http.annotation.GetMapping;
+import modelengine.fitframework.annotation.Component;
+import modelengine.fitframework.annotation.Fit;
+
+/**
+ * 表示助手的控制器。
+ *
+ * @author 董智豪
+ * @since 2025-06-21
+ */
+@Component
+public class AssistantController {
+ private final Weather weather;
+
+ public AssistantController(@Fit Weather weather) {
+ this.weather = weather;
+ }
+
+ /**
+ * 获取天气信息。
+ *
+ * @return 表示天气信息的 {@link String}。
+ */
+ @GetMapping(path = "/weather")
+ public String getWeather() {
+ return this.weather.get();
+ }
+}
diff --git a/examples/fit-example/08-nacos-complicated-apps/app-assistant/src/main/resources/application.yml b/examples/fit-example/08-nacos-complicated-apps/app-assistant/src/main/resources/application.yml
new file mode 100644
index 00000000..a97d7939
--- /dev/null
+++ b/examples/fit-example/08-nacos-complicated-apps/app-assistant/src/main/resources/application.yml
@@ -0,0 +1,19 @@
+application:
+ name: 'assistant'
+
+worker:
+ id: 'assistant'
+ host: '127.0.0.1'
+ environment: 'local'
+ environment-sequence: 'local'
+
+matata:
+ registry:
+ mode: 'PROXY'
+ host: '127.0.0.1'
+ port: 8848
+ environment: 'local'
+
+server:
+ http:
+ port: 8080
\ No newline at end of file
diff --git a/examples/fit-example/08-nacos-complicated-apps/app-default-weather/pom.xml b/examples/fit-example/08-nacos-complicated-apps/app-default-weather/pom.xml
new file mode 100644
index 00000000..116e3a5a
--- /dev/null
+++ b/examples/fit-example/08-nacos-complicated-apps/app-default-weather/pom.xml
@@ -0,0 +1,115 @@
+
+
+ 4.0.0
+
+ org.fitframework.example
+ nacos-default-weather-for-complicated
+ 1.0-SNAPSHOT
+
+
+ UTF-8
+ 17
+
+
+ 3.6.0-SNAPSHOT
+
+
+ 3.14.0
+
+
+
+
+ org.fitframework.example
+ nacos-weather-for-complicated
+ 1.0-SNAPSHOT
+
+
+ org.fitframework
+ fit-starter
+ ${fit.version}
+
+
+
+
+ org.fitframework
+ fit-plugins-starter-web
+ ${fit.version}
+
+
+
+
+ org.fitframework.plugin
+ fit-client-http
+ ${fit.version}
+ runtime
+
+
+ org.fitframework.plugin
+ fit-http-client-okhttp
+ ${fit.version}
+ runtime
+
+
+ org.fitframework.plugin
+ fit-heartbeat-client
+ ${fit.version}
+ runtime
+
+
+ org.fitframework.plugin
+ fit-service-registry
+ ${fit.version}
+ runtime
+
+
+ org.fitframework.plugin
+ fit-service-discovery
+ ${fit.version}
+ runtime
+
+
+ org.fitframework.plugin
+ fit-service-coordination-locator
+ ${fit.version}
+ runtime
+
+
+ org.fitframework.plugin
+ fit-service-coordination-nacos
+ ${fit.version}
+ runtime
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven.compiler.version}
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+ -parameters
+
+
+
+
+ org.fitframework
+ fit-build-maven-plugin
+ ${fit.version}
+
+
+ package-app
+
+ package-app
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/fit-example/08-nacos-complicated-apps/app-default-weather/src/main/java/modelengine/fit/example/DefaultWeather.java b/examples/fit-example/08-nacos-complicated-apps/app-default-weather/src/main/java/modelengine/fit/example/DefaultWeather.java
new file mode 100644
index 00000000..8f441da1
--- /dev/null
+++ b/examples/fit-example/08-nacos-complicated-apps/app-default-weather/src/main/java/modelengine/fit/example/DefaultWeather.java
@@ -0,0 +1,25 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
+ * This file is a part of the ModelEngine Project.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+package modelengine.fit.example;
+
+import modelengine.fitframework.annotation.Component;
+import modelengine.fitframework.annotation.Fitable;
+
+/**
+ * 表示 {@link Weather} 的默认实现。
+ *
+ * @author 董智豪
+ * @since 2025-06-21
+ */
+@Component
+public class DefaultWeather implements Weather {
+ @Override
+ @Fitable(id = "default-weather")
+ public String get() {
+ return "Default weather application is working.";
+ }
+}
diff --git a/examples/fit-example/08-nacos-complicated-apps/app-default-weather/src/main/java/modelengine/fit/example/DefaultWeatherStarter.java b/examples/fit-example/08-nacos-complicated-apps/app-default-weather/src/main/java/modelengine/fit/example/DefaultWeatherStarter.java
new file mode 100644
index 00000000..94c797f2
--- /dev/null
+++ b/examples/fit-example/08-nacos-complicated-apps/app-default-weather/src/main/java/modelengine/fit/example/DefaultWeatherStarter.java
@@ -0,0 +1,25 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
+ * This file is a part of the ModelEngine Project.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+package modelengine.fit.example;
+
+import modelengine.fitframework.annotation.Component;
+import modelengine.fitframework.annotation.ScanPackages;
+import modelengine.fitframework.runtime.FitStarter;
+
+/**
+ * 启动类。
+ *
+ * @author 董智豪
+ * @since 2025-06-21
+ */
+@Component
+@ScanPackages("modelengine")
+public class DefaultWeatherStarter {
+ public static void main(String[] args) {
+ FitStarter.start(DefaultWeatherStarter.class, args);
+ }
+}
diff --git a/examples/fit-example/08-nacos-complicated-apps/app-default-weather/src/main/resources/application.yml b/examples/fit-example/08-nacos-complicated-apps/app-default-weather/src/main/resources/application.yml
new file mode 100644
index 00000000..035e846d
--- /dev/null
+++ b/examples/fit-example/08-nacos-complicated-apps/app-default-weather/src/main/resources/application.yml
@@ -0,0 +1,19 @@
+application:
+ name: 'default-weather'
+
+worker:
+ id: 'default-weather'
+ host: '127.0.0.1'
+ environment: 'local'
+ environment-sequence: 'local'
+
+matata:
+ registry:
+ mode: 'PROXY'
+ host: '127.0.0.1'
+ port: 8848
+ environment: 'local'
+
+server:
+ http:
+ port: 8081
\ No newline at end of file
diff --git a/examples/fit-example/08-nacos-complicated-apps/pom.xml b/examples/fit-example/08-nacos-complicated-apps/pom.xml
new file mode 100644
index 00000000..e0a4848f
--- /dev/null
+++ b/examples/fit-example/08-nacos-complicated-apps/pom.xml
@@ -0,0 +1,16 @@
+
+
+ 4.0.0
+
+ org.fitframework.example
+ nacos-complicated-apps
+ 1.0-SNAPSHOT
+ pom
+
+
+ app-assistant
+ app-default-weather
+ service
+
+
\ No newline at end of file
diff --git a/examples/fit-example/08-nacos-complicated-apps/service/pom.xml b/examples/fit-example/08-nacos-complicated-apps/service/pom.xml
new file mode 100644
index 00000000..9e52396c
--- /dev/null
+++ b/examples/fit-example/08-nacos-complicated-apps/service/pom.xml
@@ -0,0 +1,64 @@
+
+
+ 4.0.0
+
+ org.fitframework.example
+ nacos-weather-for-complicated
+ 1.0-SNAPSHOT
+
+
+ UTF-8
+ 17
+
+
+ 3.6.0-SNAPSHOT
+
+
+ 3.14.0
+
+
+
+
+ org.fitframework
+ fit-api
+ ${fit.version}
+
+
+ org.fitframework
+ fit-util
+ ${fit.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven.compiler.version}
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+ -parameters
+
+
+
+
+ org.fitframework
+ fit-build-maven-plugin
+ ${fit.version}
+
+
+ build-service
+
+ build-service
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/fit-example/08-nacos-complicated-apps/service/src/main/java/modelengine/fit/example/Weather.java b/examples/fit-example/08-nacos-complicated-apps/service/src/main/java/modelengine/fit/example/Weather.java
new file mode 100644
index 00000000..3f1581a5
--- /dev/null
+++ b/examples/fit-example/08-nacos-complicated-apps/service/src/main/java/modelengine/fit/example/Weather.java
@@ -0,0 +1,25 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
+ * This file is a part of the ModelEngine Project.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+package modelengine.fit.example;
+
+import modelengine.fitframework.annotation.Genericable;
+
+/**
+ * 表示通用接口服务。
+ *
+ * @author 董智豪
+ * @since 2025-06-21
+ */
+public interface Weather {
+ /**
+ * 获取天气信息。
+ *
+ * @return 表示天气信息的 {@link String}。
+ */
+ @Genericable(id = "Weather")
+ String get();
+}
diff --git a/examples/fit-example/pom.xml b/examples/fit-example/pom.xml
index 769be155..080850cc 100644
--- a/examples/fit-example/pom.xml
+++ b/examples/fit-example/pom.xml
@@ -16,5 +16,6 @@
05-aop-log-plugin
06-spring-boot-starter
07-http-client-proxy
+ 08-nacos-complicated-apps
diff --git a/framework/fit/java/fit-api/src/main/java/modelengine/fitframework/conf/runtime/MatataConfig.java b/framework/fit/java/fit-api/src/main/java/modelengine/fitframework/conf/runtime/MatataConfig.java
index 808c9b56..9852075e 100644
--- a/framework/fit/java/fit-api/src/main/java/modelengine/fitframework/conf/runtime/MatataConfig.java
+++ b/framework/fit/java/fit-api/src/main/java/modelengine/fitframework/conf/runtime/MatataConfig.java
@@ -36,6 +36,13 @@ interface Registry {
*/
String host();
+ /**
+ * 获取 {@code 'matata.registry.mode'} 的配置项。
+ *
+ * @return 表示 {@code 'matata.registry.mode'} 的配置项的 {@link RegistryConnectMode}。
+ */
+ RegistryConnectMode mode();
+
/**
* 获取 {@code 'matata.registry.port'} 的配置项。
*
@@ -199,4 +206,4 @@ interface SecureAccess {
String secretKey();
}
}
-}
+}
\ No newline at end of file
diff --git a/framework/fit/java/fit-api/src/main/java/modelengine/fitframework/conf/runtime/RegistryConnectMode.java b/framework/fit/java/fit-api/src/main/java/modelengine/fitframework/conf/runtime/RegistryConnectMode.java
new file mode 100644
index 00000000..5eff26e7
--- /dev/null
+++ b/framework/fit/java/fit-api/src/main/java/modelengine/fitframework/conf/runtime/RegistryConnectMode.java
@@ -0,0 +1,58 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
+ * This file is a part of the ModelEngine Project.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+package modelengine.fitframework.conf.runtime;
+
+import static modelengine.fitframework.inspection.Validation.notBlank;
+
+import modelengine.fitframework.util.StringUtils;
+
+import java.util.Arrays;
+
+/**
+ * 注册中心连接模式枚举,用于标识客户端连接注册中心的方式。
+ *
+ *
支持的连接模式包括:
+ *
+ * - {@code DIRECT}:直连注册中心,不经过代理。
+ * - {@code PROXY}:通过本地设置的代理连接注册中心。
+ *
+ *
+ * @author 董智豪
+ * @since 2025-08-04
+ */
+public enum RegistryConnectMode {
+ /** 直连注册中心模式(不经过代理)。 */
+ DIRECT("DIRECT"),
+
+ /** 通过代理连接注册中心(例如本地 Socks/HTTP 代理)。 */
+ PROXY("PROXY");
+
+ /** 模式标识符字符串(如:DIRECT、PROXY)。 */
+ private final String mode;
+
+ /**
+ * 构造函数,初始化连接模式标识符。
+ *
+ * @param mode 注册中心连接模式的标识符(不能为空)。
+ */
+ RegistryConnectMode(String mode) {
+ this.mode = notBlank(mode, "The registry connect mode cannot be blank.");
+ }
+
+ /**
+ * 根据字符串标识获取对应的枚举值。
+ *
+ * @param mode 字符串标识(如 "DIRECT"、"PROXY")。
+ * @return 匹配的 {@link RegistryConnectMode} 枚举值;如果无匹配项则返回 {@code DIRECT},默认为直连模式。
+ */
+ public static RegistryConnectMode fromMode(String mode) {
+ return Arrays.stream(RegistryConnectMode.values())
+ .filter(registryConnectMode -> StringUtils.equals(registryConnectMode.mode, mode))
+ .findFirst()
+ .orElse(DIRECT);
+ }
+}
\ No newline at end of file
diff --git a/framework/fit/java/fit-builtin/plugins/fit-service-coordination-locator/src/main/java/modelengine/fit/service/locator/AddressRepository.java b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-locator/src/main/java/modelengine/fit/service/locator/AddressRepository.java
index b8e3e77c..173a9b39 100644
--- a/framework/fit/java/fit-builtin/plugins/fit-service-coordination-locator/src/main/java/modelengine/fit/service/locator/AddressRepository.java
+++ b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-locator/src/main/java/modelengine/fit/service/locator/AddressRepository.java
@@ -6,6 +6,8 @@
package modelengine.fit.service.locator;
+import static modelengine.fitframework.conf.runtime.RegistryConnectMode.PROXY;
+import static modelengine.fitframework.inspection.Validation.greaterThan;
import static modelengine.fitframework.inspection.Validation.notNull;
import modelengine.fit.server.FitServer;
@@ -13,6 +15,7 @@
import modelengine.fitframework.annotation.Component;
import modelengine.fitframework.broker.Endpoint;
import modelengine.fitframework.broker.Target;
+import modelengine.fitframework.conf.runtime.CommunicationProtocol;
import modelengine.fitframework.conf.runtime.MatataConfig;
import modelengine.fitframework.conf.runtime.WorkerConfig;
import modelengine.fitframework.log.Logger;
@@ -41,25 +44,38 @@ public class AddressRepository implements RegistryLocator {
* @param servers 表示 FIT 的服务器的列表的 {@link List}{@code <}{@link FitServer}{@code >}。
* @param worker 表示进程配置的 {@link WorkerConfig}。
* @param matata 表示 matata 配置的 {@link MatataConfig}。
+ * @param fitServer 表示 FIT 服务器的 {@link FitServer}。
*/
- public AddressRepository(List servers, WorkerConfig worker, MatataConfig matata) {
+ public AddressRepository(List servers, WorkerConfig worker, MatataConfig matata, FitServer fitServer) {
List actualServers = ObjectUtils.getIfNull(servers, Collections::emptyList);
notNull(worker, "The worker config cannot be null.");
notNull(matata, "The matata config cannot be null.");
- boolean isRegistryLocalhost = isRegistryLocalhost(actualServers,
- worker.host(),
- worker.domain(),
- matata.registry().host(),
- matata.registry().port(),
- matata.registry().protocolCode());
- String registryWorkerId =
- isRegistryLocalhost ? worker.id() : matata.registry().host() + ":" + matata.registry().port();
+ notNull(fitServer, "The fitserver cannot be null.");
+ int port = matata.registry().port();
+ int protocolCode = matata.registry().protocolCode();
+ CommunicationProtocol protocol = matata.registry().protocol();
+ String host = matata.registry().host();
+
+ if (PROXY == matata.registry().mode()) {
+ log.debug("The registry mode is Nacos, using the local proxy registry center.");
+ int size = fitServer.endpoints().size();
+ greaterThan(size, 0, "The fit server must have at least one endpoint.");
+ Endpoint endpoint = fitServer.endpoints().get(0);
+ port = endpoint.port();
+ protocolCode = endpoint.protocolCode();
+ protocol = CommunicationProtocol.from(endpoint.protocol());
+ host = worker.host();
+ }
+
+ boolean isRegistryLocalhost =
+ isRegistryLocalhost(actualServers, worker.host(), worker.domain(), host, port, protocolCode);
+ String registryWorkerId = isRegistryLocalhost ? worker.id() : host + ":" + port;
this.registryTarget = Target.custom()
.workerId(registryWorkerId)
- .host(matata.registry().host())
+ .host(host)
.endpoints(Collections.singletonList(Endpoint.custom()
- .port(matata.registry().port())
- .protocol(matata.registry().protocol().name(), matata.registry().protocolCode())
+ .port(port)
+ .protocol(protocol.name(), protocolCode)
.build()))
.environment(matata.registry().environment())
.extensions(matata.registry().visualExtensions())
diff --git a/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/pom.xml b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/pom.xml
new file mode 100644
index 00000000..48c2f398
--- /dev/null
+++ b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/pom.xml
@@ -0,0 +1,95 @@
+
+
+ 4.0.0
+
+
+ org.fitframework.plugin
+ fit-plugin-parent
+ 3.6.0-SNAPSHOT
+
+
+ fit-service-coordination-nacos
+
+ FIT Service Coordination Nacos
+ FIT Framework Service Coordination Nacos Plugin module provides a nacos-based implementation of FIT
+ service registry center.
+
+ https://github.com/ModelEngine-Group/fit-framework
+
+
+
+
+ org.fitframework
+ fit-api
+
+
+ org.fitframework
+ fit-util
+
+
+
+
+ org.fitframework.service
+ fit-heartbeat
+
+
+ org.fitframework.service
+ fit-service-registry-and-discovery
+
+
+ org.fitframework.service
+ fit-http-classic
+
+
+
+
+ org.projectlombok
+ lombok
+
+
+ com.alibaba.nacos
+ nacos-client
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+
+
+ package
+
+
+
+
+
+
+ run
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/src/main/java/modelengine/fit/heartbeat/server/HeartbeatServer.java b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/src/main/java/modelengine/fit/heartbeat/server/HeartbeatServer.java
new file mode 100644
index 00000000..424ccfe4
--- /dev/null
+++ b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/src/main/java/modelengine/fit/heartbeat/server/HeartbeatServer.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
+ * This file is a part of the ModelEngine Project.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ */
+
+package modelengine.fit.heartbeat.server;
+
+import modelengine.fit.heartbeat.HeartbeatService;
+import modelengine.fitframework.annotation.Component;
+import modelengine.fitframework.annotation.Fitable;
+
+import java.util.List;
+
+/**
+ * Service for providing heartbeat-related functionality.
+ *
+ * @author 董智豪
+ * @since 2025-06-04
+ */
+@Component
+public class HeartbeatServer implements HeartbeatService {
+ @Override
+ @Fitable(id = "send-heartbeat")
+ public Boolean sendHeartbeat(List heartbeatInfo, Address address) {
+ return true;
+ }
+
+ @Override
+ @Fitable(id = "stop-heartbeat")
+ public Boolean stopHeartbeat(List heartbeatInfo, Address address) {
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/src/main/java/modelengine/fit/service/server/NacosConfig.java b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/src/main/java/modelengine/fit/service/server/NacosConfig.java
new file mode 100644
index 00000000..d7c78d72
--- /dev/null
+++ b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/src/main/java/modelengine/fit/service/server/NacosConfig.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
+ * This file is a part of the ModelEngine Project.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ */
+
+package modelengine.fit.service.server;
+
+import lombok.Data;
+
+/**
+ * Represents the configuration prefixed with {@code 'matata.registry.nacos.'}.
+ *
+ * @author 董智豪
+ * @since 2025-08-06
+ */
+@Data
+public class NacosConfig {
+ /**
+ * Login username for Nacos authentication.
+ * Required when Nacos server has authentication enabled.
+ */
+ private String username;
+
+ /**
+ * Login password for Nacos authentication.
+ * Used together with username for authentication when connecting to secured Nacos server.
+ */
+ private String password;
+
+ /**
+ * Access key for Nacos authentication.
+ * Used for access control in cloud environments or when using AK/SK authentication.
+ */
+ private String accessKey;
+
+ /**
+ * Secret key for Nacos authentication.
+ * Used together with access key for AK/SK authentication mechanism.
+ */
+ private String secretKey;
+
+ /**
+ * Whether it is an ephemeral instance.
+ * Ephemeral instances will be automatically removed from the registry after service deregistration.
+ */
+ private Boolean isEphemeral;
+
+ /**
+ * Service weight.
+ * Used for weight calculation during load balancing.
+ */
+ private Float weight;
+
+ /**
+ * Heartbeat interval time (unit: milliseconds).
+ * Defines the time interval for services to send heartbeats.
+ */
+ private Long heartbeatInterval;
+
+ /**
+ * Heartbeat timeout time (unit: milliseconds).
+ * Defines the time after which a service is considered timed out when no heartbeat is received.
+ */
+ private Long heartbeatTimeout;
+}
\ No newline at end of file
diff --git a/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/src/main/java/modelengine/fit/service/server/NacosRegistryServer.java b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/src/main/java/modelengine/fit/service/server/NacosRegistryServer.java
new file mode 100644
index 00000000..3262a1d7
--- /dev/null
+++ b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/src/main/java/modelengine/fit/service/server/NacosRegistryServer.java
@@ -0,0 +1,508 @@
+/*
+ * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
+ * This file is a part of the ModelEngine Project.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ */
+
+package modelengine.fit.service.server;
+
+import static com.alibaba.nacos.api.naming.PreservedMetadataKeys.HEART_BEAT_INTERVAL;
+import static com.alibaba.nacos.api.naming.PreservedMetadataKeys.HEART_BEAT_TIMEOUT;
+import static modelengine.fitframework.inspection.Validation.notBlank;
+import static modelengine.fitframework.inspection.Validation.notNull;
+
+import com.alibaba.nacos.api.exception.NacosException;
+import com.alibaba.nacos.api.naming.NamingFactory;
+import com.alibaba.nacos.api.naming.NamingService;
+import com.alibaba.nacos.api.naming.listener.EventListener;
+import com.alibaba.nacos.api.naming.listener.NamingEvent;
+import com.alibaba.nacos.api.naming.pojo.Instance;
+import com.alibaba.nacos.api.naming.pojo.ListView;
+import com.alibaba.nacos.client.naming.listener.NamingChangeEvent;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import modelengine.fit.service.Notify;
+import modelengine.fit.service.RegistryService;
+import modelengine.fit.service.entity.Address;
+import modelengine.fit.service.entity.Application;
+import modelengine.fit.service.entity.ApplicationInstance;
+import modelengine.fit.service.entity.Endpoint;
+import modelengine.fit.service.entity.FitableAddressInstance;
+import modelengine.fit.service.entity.FitableInfo;
+import modelengine.fit.service.entity.FitableMeta;
+import modelengine.fit.service.entity.FitableMetaInstance;
+import modelengine.fit.service.entity.GenericableInfo;
+import modelengine.fit.service.entity.Worker;
+import modelengine.fitframework.annotation.Component;
+import modelengine.fitframework.annotation.Fitable;
+import modelengine.fitframework.conf.Config;
+import modelengine.fitframework.conf.runtime.CommunicationProtocol;
+import modelengine.fitframework.conf.runtime.MatataConfig;
+import modelengine.fitframework.conf.runtime.WorkerConfig;
+import modelengine.fitframework.log.Logger;
+import modelengine.fitframework.util.ObjectUtils;
+import modelengine.fitframework.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Service for providing Nacos registry center functionality.
+ *
+ * @author 董智豪
+ * @since 2025-06-04
+ */
+@Component
+public class NacosRegistryServer implements RegistryService {
+ private static final Logger log = Logger.get(NacosRegistryServer.class);
+ private static final String CLUSTER_DOMAIN_KEY = "cluster.domain";
+ private static final Pattern CLUSTER_PORT_PATTERN = Pattern.compile("cluster\\.(.*?)\\.port");
+ private static final String WORKER_KEY = "worker";
+ private static final String APPLICATION_KEY = "application";
+ private static final String FITABLE_META_KEY = "fitable-meta";
+ private static final String SEPARATOR = "::";
+
+ private final NamingService namingService;
+ private final ObjectMapper objectMapper = new ObjectMapper();
+ private final NacosConfig nacosConfig;
+ private final MatataConfig matata;
+ private final Notify notify;
+ private final WorkerConfig worker;
+ private final Map serviceSubscriptions =
+ new ConcurrentHashMap<>();
+
+ public NacosRegistryServer(Notify notify, WorkerConfig worker, Config config,MatataConfig matata)
+ throws NacosException {
+ notNull(config, "The configuration cannot be null.");
+ this.matata = notNull(matata, "The matata configuration cannot be null.");
+ this.notify = notNull(notify, "The registry listener cannot be null.");
+ this.worker = notNull(worker, "The worker config cannot be null.");
+ this.nacosConfig = config.get("matata.registry.nacos", NacosConfig.class);
+ this.namingService = NamingFactory.createNamingService(getNacosProperties());
+ }
+
+ private Properties getNacosProperties() {
+ Properties properties = new Properties();
+ String serverAddr = this.matata.registry().host() + ":" + this.matata.registry().port();
+ notBlank(serverAddr, "The Nacos server address cannot be blank.");
+ properties.put("serverAddr", serverAddr);
+ properties.put("username", ObjectUtils.nullIf(this.nacosConfig.getUsername(), StringUtils.EMPTY));
+ properties.put("password", ObjectUtils.nullIf(this.nacosConfig.getPassword(), StringUtils.EMPTY));
+ properties.put("namespace", ObjectUtils.nullIf(this.matata.registry().environment(), StringUtils.EMPTY));
+ properties.put("accessKey", ObjectUtils.nullIf(this.nacosConfig.getAccessKey(), StringUtils.EMPTY));
+ properties.put("secretKey", ObjectUtils.nullIf(this.nacosConfig.getSecretKey(), StringUtils.EMPTY));
+ return properties;
+ }
+
+ /**
+ * Builds a unique key in the format {@code ::} for {@code }.
+ *
+ * @param groupName The group name as {@link String}.
+ * @param serviceName The service name as {@link String}.
+ * @return A concatenated key like {@code groupName::serviceName}.
+ */
+ private String buildServiceKey(String groupName, String serviceName) {
+ return groupName + SEPARATOR + serviceName;
+ }
+
+ @Override
+ @Fitable(id = "register-fitables")
+ public void registerFitables(List fitableMetas, Worker worker, Application application) {
+ try {
+ log.debug("Registering fitables. [fitableMetas={}, worker={}, aplication={}]",
+ fitableMetas,
+ worker.getId(),
+ application.getNameVersion());
+ for (FitableMeta meta : fitableMetas) {
+ FitableInfo fitable = meta.getFitable();
+ String groupName = this.getGroupName(fitable);
+ String serviceName = this.getServiceName(fitable);
+ List instances = createInstance(worker, application, meta);
+ for (Instance instance : instances) {
+ this.namingService.registerInstance(serviceName, groupName, instance);
+ }
+ }
+ } catch (NacosException e) {
+ log.error("Failed to register fitables due to registry error.", e);
+ }
+ }
+
+ private String getServiceName(FitableInfo fitable) {
+ return fitable.getFitableId() + SEPARATOR + fitable.getFitableVersion();
+ }
+
+ private String getGroupName(FitableInfo fitable) {
+ return fitable.getGenericableId() + SEPARATOR + fitable.getGenericableVersion();
+ }
+
+ private String getGroupName(GenericableInfo genericable) {
+ return genericable.getGenericableId() + SEPARATOR + genericable.getGenericableVersion();
+ }
+
+ private List createInstance(Worker worker, Application application, FitableMeta meta) {
+ log.debug("Creating instance for worker. [worker={}, application={}, meta={}]",
+ worker.getId(),
+ application.getNameVersion(),
+ meta);
+ List instances = new ArrayList<>();
+ for (Address address : worker.getAddresses()) {
+ List endpoints = address.getEndpoints();
+ for (Endpoint endpoint : endpoints) {
+ Instance instance = new Instance();
+ instance.setIp(address.getHost());
+ instance.setPort(endpoint.getPort());
+ HashMap metadata = this.buildInstanceMetadata(worker, application, meta);
+ instance.setMetadata(metadata);
+ this.setInstanceProperties(instance);
+ instances.add(instance);
+ }
+ }
+ return instances;
+ }
+
+ /**
+ * Build metadata for service instance, including worker, application and FitableMeta information.
+ *
+ * @param worker The worker node object.
+ * @param application The application object.
+ * @param meta The {@link FitableMeta} metadata object.
+ * @return A {@link Map} containing all serialized metadata.
+ */
+ private HashMap buildInstanceMetadata(Worker worker, Application application, FitableMeta meta) {
+ HashMap metadata = new HashMap<>();
+ if (this.nacosConfig.getHeartbeatInterval() != null) {
+ metadata.put(HEART_BEAT_INTERVAL, String.valueOf(this.nacosConfig.getHeartbeatInterval()));
+ }
+ if (this.nacosConfig.getHeartbeatTimeout() != null) {
+ metadata.put(HEART_BEAT_TIMEOUT, String.valueOf(this.nacosConfig.getHeartbeatTimeout()));
+ }
+ try {
+ metadata.put(WORKER_KEY, this.objectMapper.writeValueAsString(worker));
+ metadata.put(APPLICATION_KEY, this.objectMapper.writeValueAsString(application));
+ metadata.put(FITABLE_META_KEY, this.objectMapper.writeValueAsString(meta));
+ } catch (JsonProcessingException e) {
+ log.error("Failed to serialize metadata for worker.", e);
+ }
+ return metadata;
+ }
+
+ private void setInstanceProperties(Instance instance) {
+ if (!this.nacosConfig.getIsEphemeral()) {
+ instance.setEphemeral(false);
+ }
+ if (this.nacosConfig.getWeight() != null) {
+ instance.setWeight(this.nacosConfig.getWeight());
+ }
+ }
+
+ @Override
+ @Fitable(id = "unregister-fitables")
+ public void unregisterFitables(List fitables, String workerId) {
+ log.debug("Unregistering fitables for worker. [fitables={}, workerId={}]", fitables, workerId);
+ for (FitableInfo fitable : fitables) {
+ this.unregisterSingleFitable(fitable, workerId);
+ }
+ }
+
+ private void unregisterSingleFitable(FitableInfo fitable, String workerId) {
+ String groupName = this.getGroupName(fitable);
+ String serviceName = this.getServiceName(fitable);
+ try {
+ List instances = this.namingService.selectInstances(serviceName, groupName, true);
+ this.unregisterMatchingInstances(instances, workerId, serviceName, groupName);
+ } catch (NacosException e) {
+ log.error("Failed to unregister fitable due to registry error.", e);
+ }
+ }
+
+ private void unregisterMatchingInstances(List instances, String workerId, String serviceName,
+ String groupName) {
+ for (Instance instance : instances) {
+ try {
+ Worker worker = this.objectMapper.readValue(instance.getMetadata().get(WORKER_KEY), Worker.class);
+ if (Objects.equals(workerId, worker.getId())) {
+ this.namingService.deregisterInstance(serviceName, groupName, instance);
+ }
+ } catch (JsonProcessingException e) {
+ log.error("Failed to parse worker metadata for fitable.", e);
+ } catch (NacosException e) {
+ log.error("Failed to deregister instance.", e);
+ }
+ }
+ }
+
+ @Override
+ @Fitable(id = "query-fitables-addresses")
+ public List queryFitables(List fitables, String workerId) {
+ log.debug("Querying fitables for worker. [fitables={}, workerId={}]", fitables, workerId);
+ Map resultMap = new HashMap<>();
+ for (FitableInfo fitable : fitables) {
+ try {
+ List instances = this.queryInstances(fitable);
+ if (instances.isEmpty()) {
+ continue;
+ }
+ this.processApplicationInstances(resultMap, fitable, instances);
+ } catch (Exception e) {
+ log.error("Failed to query fitables for genericableId.", e);
+ }
+ }
+ return new ArrayList<>(resultMap.values());
+ }
+
+ private void processApplicationInstances(Map resultMap, FitableInfo fitable,
+ List instances) {
+ Map> appInstancesMap = groupInstancesByApplication(instances);
+ for (Map.Entry> entry : appInstancesMap.entrySet()) {
+ Application application = entry.getKey();
+ List appInstances = entry.getValue();
+ FitableMeta meta = parseFitableMeta(appInstances.get(0));
+ Set workers = extractWorkers(appInstances, application);
+ FitableAddressInstance fai = resultMap.computeIfAbsent(fitable, k -> {
+ FitableAddressInstance newFai = new FitableAddressInstance();
+ newFai.setFitable(fitable);
+ newFai.setApplicationInstances(new ArrayList<>());
+ return newFai;
+ });
+ ApplicationInstance appInstance = new ApplicationInstance();
+ appInstance.setApplication(application);
+ appInstance.setFormats(meta.getFormats());
+ appInstance.setWorkers(new ArrayList<>(workers));
+ fai.getApplicationInstances().add(appInstance);
+ }
+ }
+
+ /**
+ * Extract all workers corresponding to instances and adjust addresses based on application extension information.
+ *
+ * @param appInstances The list of application instances.
+ * @param application The application object.
+ * @return Set of workers.
+ */
+ private Set extractWorkers(List appInstances, Application application) {
+ Set workers = new HashSet<>();
+ for (Instance instance : appInstances) {
+ Worker worker = parseWorker(instance);
+ workers.add(worker);
+ }
+ if (application.getExtensions().containsKey(CLUSTER_DOMAIN_KEY)) {
+ this.replaceAddresses(workers, application);
+ }
+ return workers;
+ }
+
+ private Map> groupInstancesByApplication(List instances) {
+ Map> map = new HashMap<>();
+ for (Instance instance : instances) {
+ Application app = this.parseApplication(instance);
+ map.computeIfAbsent(app, k -> new ArrayList<>()).add(instance);
+ }
+ return map;
+ }
+
+ private List queryInstances(FitableInfo fitable) throws NacosException {
+ String groupName = this.getGroupName(fitable);
+ String serviceName = this.getServiceName(fitable);
+ return this.namingService.selectInstances(serviceName, groupName, true);
+ }
+
+ private FitableMeta parseFitableMeta(Instance instance) {
+ try {
+ return this.objectMapper.readValue(instance.getMetadata().get(FITABLE_META_KEY), FitableMeta.class);
+ } catch (JsonProcessingException e) {
+ log.error("Failed to parse fitable meta for instance.", e);
+ FitableMeta meta = new FitableMeta();
+ meta.setFitable(new FitableInfo());
+ return meta;
+ }
+ }
+
+ private Application parseApplication(Instance instance) {
+ try {
+ return this.objectMapper.readValue(instance.getMetadata().get(APPLICATION_KEY), Application.class);
+ } catch (JsonProcessingException e) {
+ log.error("Failed to parse application metadata for instance.", e);
+ Application app = new Application();
+ app.setNameVersion("unknown");
+ return app;
+ }
+ }
+
+ private Worker parseWorker(Instance instance) {
+ try {
+ return this.objectMapper.readValue(instance.getMetadata().get(WORKER_KEY), Worker.class);
+ } catch (JsonProcessingException e) {
+ log.error("Failed to parse worker metadata for instance.", e);
+ Worker worker = new Worker();
+ Address address = new Address();
+ address.setHost(instance.getIp());
+
+ Endpoint endpoint = new Endpoint();
+ endpoint.setPort(instance.getPort());
+ endpoint.setProtocol(1);
+
+ address.setEndpoints(Collections.singletonList(endpoint));
+ worker.setAddresses(Collections.singletonList(address));
+ return worker;
+ }
+ }
+
+ private void replaceAddresses(Set workers, Application application) {
+ Address address = new Address();
+ address.setHost(application.getExtensions().get(CLUSTER_DOMAIN_KEY));
+ address.setEndpoints(buildEndPoints(application.getExtensions()));
+ workers.forEach(w -> w.setAddresses(Collections.singletonList(address)));
+ }
+
+ private List buildEndPoints(Map extensions) {
+ List endpoints = new ArrayList<>();
+ for (Map.Entry entry : extensions.entrySet()) {
+ Matcher matcher = CLUSTER_PORT_PATTERN.matcher(entry.getKey());
+ if (matcher.matches()) {
+ String protocolName = matcher.group(1);
+ CommunicationProtocol protocol = CommunicationProtocol.valueOf(StringUtils.toUpperCase(protocolName));
+ Endpoint endpoint = new Endpoint();
+ endpoint.setPort(Integer.valueOf(entry.getValue()));
+ endpoint.setProtocol(protocol.code());
+ endpoints.add(endpoint);
+ }
+ }
+ return endpoints;
+ }
+
+ @Override
+ @Fitable(id = "subscribe-fitables")
+ public List subscribeFitables(List fitables, String workerId,
+ String callbackFitableId) {
+ log.debug("Subscribing to fitables for worker. [fitables={}, workerId={}, callbackFitableId={}]",
+ fitables,
+ workerId,
+ callbackFitableId);
+ for (FitableInfo fitable : fitables) {
+ try {
+ String groupName = this.getGroupName(fitable);
+ String serviceName = this.getServiceName(fitable);
+ if (this.serviceSubscriptions.containsKey(buildServiceKey(groupName, serviceName))) {
+ log.debug("Already subscribed to service. [groupName={}, serviceName={}]", groupName, serviceName);
+ continue;
+ }
+ EventListener eventListener =
+ this.serviceSubscriptions.computeIfAbsent(buildServiceKey(groupName, serviceName),
+ k -> event -> {
+ if (event instanceof NamingEvent || event instanceof NamingChangeEvent) {
+ onServiceChanged(fitable);
+ }
+ });
+ this.namingService.subscribe(serviceName, groupName, eventListener);
+ } catch (NacosException e) {
+ log.error("Failed to subscribe to Nacos service.", e);
+ }
+ }
+ return this.queryFitables(fitables, workerId);
+ }
+
+ @Override
+ @Fitable(id = "unsubscribe-fitables")
+ public void unsubscribeFitables(List fitables, String workerId, String callbackFitableId) {
+ log.debug("Unsubscribing from fitables for worker. [fitables={}, workerId={}, callbackFitableId={}]",
+ fitables,
+ workerId,
+ callbackFitableId);
+ for (FitableInfo fitable : fitables) {
+ try {
+ String groupName = this.getGroupName(fitable);
+ String serviceName = this.getServiceName(fitable);
+ EventListener listener = this.serviceSubscriptions.get(buildServiceKey(groupName, serviceName));
+ this.namingService.unsubscribe(serviceName, groupName, listener);
+ this.serviceSubscriptions.remove(buildServiceKey(groupName, serviceName));
+ } catch (NacosException e) {
+ log.error("Failed to unsubscribe from Nacos service.", e);
+ }
+ }
+ }
+
+ /**
+ * Handle service change events, query and notify updates to Fitables instance information.
+ *
+ * @param fitableInfo The changed Fitables information.
+ */
+ private void onServiceChanged(FitableInfo fitableInfo) {
+ List fitableAddressInstances =
+ this.queryFitables(Collections.singletonList(fitableInfo), this.worker.id());
+ this.notify.notifyFitables(fitableAddressInstances);
+ }
+
+ @Override
+ @Fitable(id = "query-running-fitables")
+ public List queryFitableMetas(List genericables) {
+ log.debug("Querying fitable metas for genericables. [genericables={}]", genericables);
+ Map> metaEnvironments = new HashMap<>();
+
+ for (GenericableInfo genericable : genericables) {
+ this.processGenericableServices(genericable, metaEnvironments);
+ }
+
+ return this.buildFitableMetaInstances(metaEnvironments);
+ }
+
+ private void processGenericableServices(GenericableInfo genericable,
+ Map> metaEnvironments) {
+ String groupName = this.getGroupName(genericable);
+ try {
+ ListView services = this.namingService.getServicesOfServer(1, Integer.MAX_VALUE, groupName);
+ for (String serviceName : services.getData()) {
+ this.processServiceInstances(serviceName, groupName, metaEnvironments);
+ }
+ } catch (NacosException e) {
+ log.error("Failed to query fitable metas.", e);
+ }
+ }
+
+ private void processServiceInstances(String serviceName, String groupName,
+ Map> metaEnvironments) {
+ try {
+ List instances = this.namingService.selectInstances(serviceName, groupName, true);
+ if (instances.isEmpty()) {
+ return;
+ }
+ FitableMeta meta = parseFitableMeta(instances.get(0));
+ this.collectEnvironmentsFromInstances(instances, meta, metaEnvironments);
+ } catch (NacosException e) {
+ log.error("Failed to select instances for service: " + serviceName, e);
+ }
+ }
+
+ private void collectEnvironmentsFromInstances(List instances, FitableMeta meta,
+ Map> metaEnvironments) {
+ for (Instance instance : instances) {
+ try {
+ Worker worker = this.objectMapper.readValue(instance.getMetadata().get(WORKER_KEY), Worker.class);
+ metaEnvironments.computeIfAbsent(meta, k -> new HashSet<>()).add(worker.getEnvironment());
+ } catch (JsonProcessingException e) {
+ log.error("Failed to parse worker metadata.", e);
+ }
+ }
+ }
+
+ private List buildFitableMetaInstances(Map> metaEnvironments) {
+ List results = new ArrayList<>();
+ for (Map.Entry> entry : metaEnvironments.entrySet()) {
+ FitableMetaInstance instance = new FitableMetaInstance();
+ instance.setMeta(entry.getKey());
+ instance.setEnvironments(new ArrayList<>(entry.getValue()));
+ results.add(instance);
+ }
+ return results;
+ }
+}
\ No newline at end of file
diff --git a/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/src/main/resources/application.yml b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/src/main/resources/application.yml
new file mode 100644
index 00000000..211ee7d8
--- /dev/null
+++ b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-nacos/src/main/resources/application.yml
@@ -0,0 +1,11 @@
+fit:
+ beans:
+ packages:
+ - 'modelengine.fit.service'
+ - 'modelengine.fit.heartbeat'
+
+matata:
+ registry:
+ nacos:
+ weight: 1
+ isEphemeral: true
\ No newline at end of file
diff --git a/framework/fit/java/fit-builtin/plugins/fit-service-coordination-simple/src/main/java/modelengine/fit/heartbeat/server/HeartbeatServer.java b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-simple/src/main/java/modelengine/fit/heartbeat/server/HeartbeatServer.java
index ca179f20..6730083e 100644
--- a/framework/fit/java/fit-builtin/plugins/fit-service-coordination-simple/src/main/java/modelengine/fit/heartbeat/server/HeartbeatServer.java
+++ b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-simple/src/main/java/modelengine/fit/heartbeat/server/HeartbeatServer.java
@@ -34,7 +34,7 @@ public HeartbeatServer(WorkerCache cache) {
}
@Override
- @Fitable(id = "DBC9E2F7C0E443F1AC986BBC3D58C27B")
+ @Fitable(id = "send-heartbeat")
public Boolean sendHeartbeat(List beatInfos, Address address) {
if (address == null || StringUtils.isBlank(address.getId())) {
return false;
diff --git a/framework/fit/java/fit-builtin/plugins/fit-service-coordination-simple/src/main/java/modelengine/fit/service/server/RegistryServer.java b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-simple/src/main/java/modelengine/fit/service/server/RegistryServer.java
index d2841d82..14baeaee 100644
--- a/framework/fit/java/fit-builtin/plugins/fit-service-coordination-simple/src/main/java/modelengine/fit/service/server/RegistryServer.java
+++ b/framework/fit/java/fit-builtin/plugins/fit-service-coordination-simple/src/main/java/modelengine/fit/service/server/RegistryServer.java
@@ -88,7 +88,7 @@ public Map> getApplicationMetas() {
}
@Override
- @Fitable(id = "dedaa28cfb2742819a9b0271bc34f72a")
+ @Fitable(id = "register-fitables")
public void registerFitables(List fitableMetas, Worker worker, Application application) {
if (!this.workers.containsKey(worker.getId()) && this.workers.size() >= MAX_WORKER_NUM) {
throw new IllegalStateException("Too many workers.");
@@ -121,10 +121,11 @@ private int getActualExpire(Worker worker) {
}
@Override
+ @Fitable(id = "unregister-fitables")
public void unregisterFitables(List fitables, String workerId) {}
@Override
- @Fitable(id = "5807f06a3a704708b264ea3c6cfbbd53")
+ @Fitable(id = "query-fitables-addresses")
public List queryFitables(List fitables, String workerId) {
List instances = new ArrayList<>();
for (Map.Entry> entry : this.applicationMetas.entrySet()) {
@@ -203,17 +204,18 @@ private boolean isMetaInFitables(FitableMeta meta, List fitables) {
}
@Override
- @Fitable(id = "ee0a8337d3654a22a548d5d5abe1d5f3")
+ @Fitable(id = "subscribe-fitables")
public List subscribeFitables(List fitables, String workerId,
String callbackFitableId) {
return this.queryFitables(fitables, workerId);
}
@Override
+ @Fitable(id = "unsubscribe-fitables")
public void unsubscribeFitables(List fitables, String workerId, String callbackFitableId) {}
@Override
- @Fitable(id = "33b1f9b8f1cc49d19719a6536c96e854")
+ @Fitable(id = "query-running-fitables")
public List queryFitableMetas(List genericables) {
Map instances = new HashMap<>();
for (Map.Entry> entry : this.applicationMetas.entrySet()) {
diff --git a/framework/fit/java/fit-builtin/plugins/fit-service-discovery/src/main/java/modelengine/fit/service/RegistryListener.java b/framework/fit/java/fit-builtin/plugins/fit-service-discovery/src/main/java/modelengine/fit/service/RegistryListener.java
index 5760bbdb..4d032087 100644
--- a/framework/fit/java/fit-builtin/plugins/fit-service-discovery/src/main/java/modelengine/fit/service/RegistryListener.java
+++ b/framework/fit/java/fit-builtin/plugins/fit-service-discovery/src/main/java/modelengine/fit/service/RegistryListener.java
@@ -96,9 +96,9 @@
* @since 2020-08-19
*/
@Component
-public class RegistryListener implements Registry {
+public class RegistryListener implements Registry, Notify {
private static final Logger log = Logger.get(RegistryListener.class);
- private static final String NOTIFY_FITABLE_ID = "347fd33f3cde4aa891614a9e244ae5e8";
+ private static final String NOTIFY_FITABLE_ID = "notify-fitables";
private static final long INITIAL_DELAY = 10L;
private static final int BATCH_NUM = 10;
private static final Pattern CLUSTER_PORT_PATTERN = Pattern.compile("cluster\\.(.*?)\\.port");
@@ -471,7 +471,8 @@ private void unsubscribe(List fitables) {
* @param fitableInstances 表示本地监听的服务地址的更新列表的 {@link List}{@code <}{@link FitableAddressInstance}
* {@code >}。
*/
- @Fitable(genericable = "b69df5e8cbcd4166aa5029602e7a58cf", id = NOTIFY_FITABLE_ID)
+ @Override
+ @Fitable(NOTIFY_FITABLE_ID)
public void notifyFitables(List fitableInstances) {
if (CollectionUtils.isEmpty(fitableInstances)) {
log.info("Received latest fitable instances, but ignored: no data.");
diff --git a/framework/fit/java/fit-builtin/plugins/pom.xml b/framework/fit/java/fit-builtin/plugins/pom.xml
index d8883496..b4e52efd 100644
--- a/framework/fit/java/fit-builtin/plugins/pom.xml
+++ b/framework/fit/java/fit-builtin/plugins/pom.xml
@@ -19,6 +19,7 @@
1.18.36
+ 3.0.1
@@ -38,6 +39,7 @@
fit-server-http
fit-service-coordination-locator
fit-service-coordination-simple
+ fit-service-coordination-nacos
fit-service-discovery
fit-service-registry
fit-value-fastjson
@@ -50,6 +52,11 @@
lombok
${lombok.version}
+
+ com.alibaba.nacos
+ nacos-client
+ ${nacos.version}
+
diff --git a/framework/fit/java/fit-builtin/services/fit-heartbeat/definition/src/main/java/modelengine/fit/heartbeat/HeartbeatService.java b/framework/fit/java/fit-builtin/services/fit-heartbeat/definition/src/main/java/modelengine/fit/heartbeat/HeartbeatService.java
index fc8a04ce..e8fea6cc 100644
--- a/framework/fit/java/fit-builtin/services/fit-heartbeat/definition/src/main/java/modelengine/fit/heartbeat/HeartbeatService.java
+++ b/framework/fit/java/fit-builtin/services/fit-heartbeat/definition/src/main/java/modelengine/fit/heartbeat/HeartbeatService.java
@@ -24,7 +24,7 @@ public interface HeartbeatService {
* @param address 表示本地地址的 {@link Address}。
* @return 表示发送结果的 {@link Boolean}。
*/
- @Genericable(id = "e12fd1c57fd84f50a673d93d13074082")
+ @Genericable(id = "modelengine.fit.heartbeat.send-heartbeat")
Boolean sendHeartbeat(List heartbeatInfo, Address address);
/**
@@ -34,7 +34,7 @@ public interface HeartbeatService {
* @param address 表示本地地址的 {@link Address}。
* @return 表示发送结果的 {@link Boolean}。
*/
- @Genericable(id = "67e6370725df427ebab9a6a6f1ada60c")
+ @Genericable(id = "modelengine.fit.heartbeat.stop-heartbeat")
Boolean stopHeartbeat(List heartbeatInfo, Address address);
/**
diff --git a/framework/fit/java/fit-builtin/services/fit-service/definition/src/main/java/modelengine/fit/service/Notify.java b/framework/fit/java/fit-builtin/services/fit-service/definition/src/main/java/modelengine/fit/service/Notify.java
new file mode 100644
index 00000000..d4fbfcbf
--- /dev/null
+++ b/framework/fit/java/fit-builtin/services/fit-service/definition/src/main/java/modelengine/fit/service/Notify.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
+ * This file is a part of the ModelEngine Project.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ */
+
+package modelengine.fit.service;
+
+import modelengine.fit.service.entity.FitableAddressInstance;
+import modelengine.fitframework.annotation.Genericable;
+
+import java.util.List;
+
+/**
+ * Represents notification service for updating Fitables instance information.
+ *
+ * @author 董智豪
+ * @since 2025-06-20
+ */
+public interface Notify {
+ /**
+ * Notify to update Fitables instances.
+ *
+ * @param fitableInstances A {@link List}{@code <}{@link FitableAddressInstance}{@code >} representing all instance
+ * information for specified service implementations.
+ */
+ @Genericable(id = "modelengine.fit.service.registry-listener.notify-fitables")
+ void notifyFitables(List fitableInstances);
+}
\ No newline at end of file
diff --git a/framework/fit/java/fit-builtin/services/fit-service/definition/src/main/java/modelengine/fit/service/RegistryService.java b/framework/fit/java/fit-builtin/services/fit-service/definition/src/main/java/modelengine/fit/service/RegistryService.java
index 1b2c4a60..c6d1d15a 100644
--- a/framework/fit/java/fit-builtin/services/fit-service/definition/src/main/java/modelengine/fit/service/RegistryService.java
+++ b/framework/fit/java/fit-builtin/services/fit-service/definition/src/main/java/modelengine/fit/service/RegistryService.java
@@ -31,7 +31,7 @@ public interface RegistryService {
* @param worker 表示服务实现所在的进程信息的 {@link Worker}。
* @param application 表示服务实现所在的应用信息的 {@link Application}。
*/
- @Genericable(id = "85bdce64cf724589b87cb6b6a950999d")
+ @Genericable(id = "modelengine.fit.registry.registry-service.register-fitables")
void registerFitables(List fitableMetas, Worker worker, Application application);
/**
@@ -40,7 +40,7 @@ public interface RegistryService {
* @param fitables 表示待取消注册的服务实现列表的 {@link List}{@code <}{@link FitableInfo}{@code >}。
* @param workerId 表示服务实现所在的进程的唯一标识的 {@link String}。
*/
- @Genericable(id = "c02af9dafb5b4a609f8c586a8e884710")
+ @Genericable(id = "modelengine.fit.registry.registry-service.unregister-fitables")
void unregisterFitables(List fitables, String workerId);
/**
@@ -50,7 +50,7 @@ public interface RegistryService {
* @param workerId 表示指定的进程的唯一标识的 {@link String}。
* @return 表示指定服务实现的所有实例信息的 {@link List}{@code <}{@link FitableAddressInstance}{@code >}。
*/
- @Genericable(id = "33be4142494e4742aa122555a451d996")
+ @Genericable(id = "modelengine.fit.registry.registry-service.query-fitables-addresses")
List queryFitables(List fitables, String workerId);
/**
@@ -61,7 +61,7 @@ public interface RegistryService {
* @param callbackFitableId 表示订阅回调服务实现的唯一标识的 {@link String}。
* @return 表示指定服务实现的所有实例信息的 {@link List}{@code <}{@link FitableAddressInstance}{@code >}。
*/
- @Genericable(id = "c9aa580f3fa845c99c2c6145a0499e45")
+ @Genericable(id = "modelengine.fit.registry.registry-service.subscribe-fitables")
List subscribeFitables(List fitables, String workerId,
String callbackFitableId);
@@ -72,7 +72,7 @@ List subscribeFitables(List fitables, Strin
* @param workerId 表示指定的进程的唯一标识的 {@link String}。
* @param callbackFitableId 表示取消订阅回调服务实现的唯一标识的 {@link String}。
*/
- @Genericable(id = "087994fc907b4f76b9f9b2a62e07ef2c")
+ @Genericable(id = "modelengine.fit.registry.registry-service.unsubscribe-fitables")
void unsubscribeFitables(List fitables, String workerId, String callbackFitableId);
/**
@@ -81,6 +81,6 @@ List subscribeFitables(List fitables, Strin
* @param genericables 表示指定服务列表的 {@link List}{@code <}{@link GenericableInfo}{@code >}。
* @return 表示正在运行的服务实现元数据列表的 {@link List}{@code <}{@link FitableMetaInstance}{@code >}。
*/
- @Genericable(id = "7c52fb4fdfa243af928f23607fbbee02")
+ @Genericable(id = "modelengine.fit.registry.registry-service.query-running-fitables")
List queryFitableMetas(List genericables);
}
diff --git a/framework/fit/java/fit-conf/fit-conf/src/main/java/modelengine/fitframework/conf/runtime/DefaultRegistry.java b/framework/fit/java/fit-conf/fit-conf/src/main/java/modelengine/fitframework/conf/runtime/DefaultRegistry.java
index 3cc2ff0f..be283b43 100644
--- a/framework/fit/java/fit-conf/fit-conf/src/main/java/modelengine/fitframework/conf/runtime/DefaultRegistry.java
+++ b/framework/fit/java/fit-conf/fit-conf/src/main/java/modelengine/fitframework/conf/runtime/DefaultRegistry.java
@@ -31,6 +31,7 @@ public class DefaultRegistry implements Registry {
private List authRequiredServices;
private Map extensions;
private DefaultSecureAccess secureAccess;
+ private String mode = RegistryConnectMode.DIRECT.name();
/**
* 设置主机地址的配置。
@@ -106,11 +107,25 @@ public void setExtensions(Map extensions) {
this.extensions = extensions;
}
+ /**
+ * 设置注册中心连接模式。
+ *
+ * @param mode 表示待设置的模式配置的 {@link String}。
+ */
+ public void setMode(String mode) {
+ this.mode = mode;
+ }
+
@Override
public String host() {
return this.host;
}
+ @Override
+ public RegistryConnectMode mode() {
+ return RegistryConnectMode.fromMode(this.mode);
+ }
+
@Override
public int port() {
return this.port;
@@ -184,4 +199,4 @@ public String toString() {
this.extensions,
this.secureAccess);
}
-}
+}
\ No newline at end of file
diff --git a/framework/fit/java/fit-runtime/src/main/resources/fitframework.yml b/framework/fit/java/fit-runtime/src/main/resources/fitframework.yml
index 37c9444d..e735382e 100644
--- a/framework/fit/java/fit-runtime/src/main/resources/fitframework.yml
+++ b/framework/fit/java/fit-runtime/src/main/resources/fitframework.yml
@@ -1,105 +1,102 @@
application:
- name: 'application' # 默认应用名
+ name: "application" # 默认应用名
worker:
- id: 'default-worker-id' # 默认的进程唯一标识,该配置需要进行覆盖,避免workerId相同注册服务混乱
- host: 'localhost' # 该配置需要修改为真实启动的本地ip地址
- environment: 'local' # 默认环境标
- environment-sequence: 'local' # 默认环境调用链
+ id: "default-worker-id" # 默认的进程唯一标识,该配置需要进行覆盖,避免workerId相同注册服务混乱
+ host: "localhost" # 该配置需要修改为真实启动的本地ip地址
+ environment: "local" # 默认环境标
+ environment-sequence: "local" # 默认环境调用链
exit:
graceful: true
matata:
registry:
- host: 'localhost' # 默认连接的注册中心为本地
- port: 8080 # 默认连接注册中心的端口为本地默认的 8080 端口
- protocol: 2 # 注册中心默认使用 Http 的传输协议
- environment: 'local' # 默认注册中心的环境标和本地默认配置一致
+ environment: "local" # 默认注册中心的环境标和本地默认配置一致
available-services: # 将注册中心和获取地址相关的服务进行配置,其他服务都可以通过以下服务进行地址获取
- # 订阅服务并获取所订阅服务地址的接口
- - genericable-name: 'modelengine.fit.registry.RegistryService.subscribeFitables'
- genericable-id: 'c9aa580f3fa845c99c2c6145a0499e45'
- genericable-version: '1.0.0'
- fitable-id: 'ee0a8337d3654a22a548d5d5abe1d5f3'
- fitable-version: '1.0.0'
- formats:
- - 1
- # 直接获取服务地址的接口
- - genericable-name: 'modelengine.fit.registry.RegistryService.queryFitablesAddresses'
- genericable-id: '33be4142494e4742aa122555a451d996'
- genericable-version: '1.0.0'
- fitable-id: '5807f06a3a704708b264ea3c6cfbbd53'
- fitable-version: '1.0.0'
- formats:
- - 1
- # 查询注册中心正在运行的服务实现信息的接口
- - genericable-name: 'modelengine.fit.registry.RegistryService.queryRunningFitables'
- genericable-id: '7c52fb4fdfa243af928f23607fbbee02'
- genericable-version: '1.0.0'
- fitable-id: '33b1f9b8f1cc49d19719a6536c96e854'
- fitable-version: '1.0.0'
- formats:
- - 1
- # 向注册中心申请令牌的接口
- - genericable-name: 'modelengine.fit.registry.TokenService.applyToken'
- genericable-id: 'matata.registry.secure-access.apply-token'
- genericable-version: '1.0.0'
- fitable-id: 'apply_token'
- fitable-version: '1.0.0'
- formats:
- - 1
- # 向注册中心刷新令牌的接口
- - genericable-name: 'modelengine.fit.registry.TokenService.refreshToken'
- genericable-id: 'matata.registry.secure-access.refresh-token'
- genericable-version: '1.0.0'
- fitable-id: 'refresh_token_for_registry_server'
- fitable-version: '1.0.0'
- formats:
- - 1
- # 向注册中心发送心跳
- - genericable-name: 'modelengine.fit.heartbeat.sendHeartbeat'
- genericable-id: 'e12fd1c57fd84f50a673d93d13074082'
- genericable-version: '1.0.0'
- fitable-id: 'DBC9E2F7C0E443F1AC986BBC3D58C27B'
- fitable-version: '1.0.0'
- formats:
- - 1
- # 向注册中心注册服务信息
- - genericable-name: 'modelengine.fit.registry.RegistryService.registerFitables'
- genericable-id: '85bdce64cf724589b87cb6b6a950999d'
- genericable-version: '1.0.0'
- fitable-id: 'dedaa28cfb2742819a9b0271bc34f72a'
- fitable-version: '1.0.0'
- formats:
- - 1
+ # 订阅服务并获取所订阅服务地址的接口
+ - genericable-name: "modelengine.fit.registry.RegistryService.subscribeFitables"
+ genericable-id: "modelengine.fit.registry.registry-service.subscribe-fitables"
+ genericable-version: "1.0.0"
+ fitable-id: "subscribe-fitables"
+ fitable-version: "1.0.0"
+ formats:
+ - 1
+ # 直接获取服务地址的接口
+ - genericable-name: "modelengine.fit.registry.RegistryService.queryFitablesAddresses"
+ genericable-id: "modelengine.fit.registry.registry-service.query-fitables-addresses"
+ genericable-version: "1.0.0"
+ fitable-id: "query-fitables-addresses"
+ fitable-version: "1.0.0"
+ formats:
+ - 1
+ # 查询注册中心正在运行的服务实现信息的接口
+ - genericable-name: "modelengine.fit.registry.RegistryService.queryRunningFitables"
+ genericable-id: "modelengine.fit.registry.registry-service.query-running-fitables"
+ genericable-version: "1.0.0"
+ fitable-id: "query-running-fitables"
+ fitable-version: "1.0.0"
+ formats:
+ - 1
+ # 向注册中心申请令牌的接口
+ - genericable-name: "modelengine.fit.registry.TokenService.applyToken"
+ genericable-id: "matata.registry.secure-access.apply-token"
+ genericable-version: "1.0.0"
+ fitable-id: "apply-token"
+ fitable-version: "1.0.0"
+ formats:
+ - 1
+ # 向注册中心刷新令牌的接口
+ - genericable-name: "modelengine.fit.registry.TokenService.refreshToken"
+ genericable-id: "matata.registry.secure-access.refresh-token"
+ genericable-version: "1.0.0"
+ fitable-id: "refresh-token-for-registry-server"
+ fitable-version: "1.0.0"
+ formats:
+ - 1
+ # 向注册中心发送心跳
+ - genericable-name: "modelengine.fit.heartbeat.sendHeartbeat"
+ genericable-id: "modelengine.fit.heartbeat.send-heartbeat"
+ genericable-version: "1.0.0"
+ fitable-id: "send-heartbeat"
+ fitable-version: "1.0.0"
+ formats:
+ - 1
+ # 向注册中心注册服务信息
+ - genericable-name: "modelengine.fit.registry.RegistryService.registerFitables"
+ genericable-id: "modelengine.fit.registry.registry-service.register-fitables"
+ genericable-version: "1.0.0"
+ fitable-id: "register-fitables"
+ fitable-version: "1.0.0"
+ formats:
+ - 1
auth-required-services: # 将注册中心和心跳相关的服务进行配置,表示其需要认证鉴权
- # 订阅服务并获取所订阅服务地址的接口
- - genericable-name: 'modelengine.fit.registry.RegistryService.subscribeFitables'
- genericable-id: 'c9aa580f3fa845c99c2c6145a0499e45'
- # 直接获取服务地址的接口
- - genericable-name: 'modelengine.fit.registry.RegistryService.queryFitablesAddresses'
- genericable-id: '33be4142494e4742aa122555a451d996'
- # 查询注册中心正在运行的服务实现信息的接口
- - genericable-name: 'modelengine.fit.registry.RegistryService.queryRunningFitables'
- genericable-id: '7c52fb4fdfa243af928f23607fbbee02'
- # 向注册中心服务端注册服务实现列表
- - genericable-name: 'modelengine.fit.registry.RegistryService.registerFitables'
- genericable-id: '85bdce64cf724589b87cb6b6a950999d'
- # 向注册中心服务端取消注册服务实现列表
- - genericable-name: 'modelengine.fit.registry.RegistryService.unregisterFitables'
- genericable-id: 'c02af9dafb5b4a609f8c586a8e884710'
- # 向注册中心服务端取消订阅指定服务实现的实例信息
- - genericable-name: 'modelengine.fit.registry.RegistryService.unsubscribeFitables'
- genericable-id: '087994fc907b4f76b9f9b2a62e07ef2c'
- # 发送心跳信息
- - genericable-name: 'modelengine.fit.heartbeat.sendHeartbeat'
- genericable-id: 'e12fd1c57fd84f50a673d93d13074082'
- # 发送停止心跳信息
- - genericable-name: 'modelengine.fit.heartbeat.stopHeartbeat'
- genericable-id: '67e6370725df427ebab9a6a6f1ada60c'
+ # 订阅服务并获取所订阅服务地址的接口
+ - genericable-name: "modelengine.fit.registry.RegistryService.subscribeFitables"
+ genericable-id: "modelengine.fit.registry.registry-service.subscribe-fitables"
+ # 直接获取服务地址的接口
+ - genericable-name: "modelengine.fit.registry.RegistryService.queryFitablesAddresses"
+ genericable-id: "modelengine.fit.registry.registry-service.query-fitables-addresses"
+ # 查询注册中心正在运行的服务实现信息的接口
+ - genericable-name: "modelengine.fit.registry.RegistryService.queryRunningFitables"
+ genericable-id: "modelengine.fit.registry.registry-service.query-running-fitables"
+ # 向注册中心服务端注册服务实现列表
+ - genericable-name: "modelengine.fit.registry.RegistryService.registerFitables"
+ genericable-id: "modelengine.fit.registry.registry-service.register-fitables"
+ # 向注册中心服务端取消注册服务实现列表
+ - genericable-name: "modelengine.fit.registry.RegistryService.unregisterFitables"
+ genericable-id: "modelengine.fit.registry.registry-service.unregister-fitables"
+ # 向注册中心服务端取消订阅指定服务实现的实例信息
+ - genericable-name: "modelengine.fit.registry.RegistryService.unsubscribeFitables"
+ genericable-id: "modelengine.fit.registry.registry-service.unsubscribe-fitables"
+ # 发送心跳信息
+ - genericable-name: "modelengine.fit.heartbeat.sendHeartbeat"
+ genericable-id: "modelengine.fit.heartbeat.send-heartbeat"
+ # 发送停止心跳信息
+ - genericable-name: "modelengine.fit.heartbeat.stopHeartbeat"
+ genericable-id: "modelengine.fit.heartbeat.stop-heartbeat"
fit:
beans:
packages:
- - 'modelengine.fitframework'
- - 'modelengine.fit'
\ No newline at end of file
+ - "modelengine.fitframework"
+ - "modelengine.fit"
diff --git a/framework/fit/python/conf/fit.yml b/framework/fit/python/conf/fit.yml
index c4329f69..51f86858 100644
--- a/framework/fit/python/conf/fit.yml
+++ b/framework/fit/python/conf/fit.yml
@@ -1,502 +1,502 @@
fit.public.genericables.9289a2a4322d47d38f33fc32c47f04d2:
- name: 'StartServer'
+ name: "StartServer"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fitables:
911533a440e541a2900da06e01d3e6de:
aliases:
- - 'fit.http.server.py'
+ - "fit.http.server.py"
8f1e46e8a25a4ed391cb115b766d76db:
aliases:
- - 'fit.grpc.server.py'
+ - "fit.grpc.server.py"
FIT_SERVER_START_UC_FITABLE_ID:
aliases:
- - 'fit.uc.server.py'
+ - "fit.uc.server.py"
fit.public.genericables.d45f8ecbfb9c4d11a38143233c878a8f:
tags:
- - 'localOnly'
+ - "localOnly"
fitables:
913d6d1c47ed4c4481dd84a5b667a1ef:
2fb08101aa94495face6aeef49cdc98a:
fit.public.genericables.1b9bfc4a2b2141d5b31aa06791d645b4:
- name: 'StopServer'
+ name: "StopServer"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fitables:
2f661c07515f43cf802e30f7d81efbae:
aliases:
- - 'fit.http.server.py'
+ - "fit.http.server.py"
0970e120501047fa800078edd7437fa4:
aliases:
- - 'fit.grpc.server.py'
+ - "fit.grpc.server.py"
FIT_SERVER_STOP_UC_FITABLE_ID:
aliases:
- - 'fit.uc.server.py'
+ - "fit.uc.server.py"
fit.public.genericables.8f69322009a8411ca7df1e3a67a856e5:
- name: 'GetServerAddress'
+ name: "GetServerAddress"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fitables:
FIT_SERVER_GET_ADDRESS_HTTP_FITABLE_ID:
aliases:
- - 'fit.http.server.py'
+ - "fit.http.server.py"
FIT_SERVER_GET_ADDRESS_GRPC_FITABLE_ID:
aliases:
- - 'fit.grpc.server.py'
+ - "fit.grpc.server.py"
FIT_SERVER_GET_ADDRESS_UC_FITABLE_ID:
aliases:
- - 'fit.uc.server.py'
+ - "fit.uc.server.py"
fit.public.genericables.9046fe29c2a947448d86bf8178c745e1:
- name: 'load-balancer'
+ name: "load-balancer"
route:
- default: 'c5fcfc2cd8b54fa6940ad8ef67f257b4'
+ default: "c5fcfc2cd8b54fa6940ad8ef67f257b4"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fitables:
c5fcfc2cd8b54fa6940ad8ef67f257b4:
aliases:
- - 'python_default_lb'
+ - "python_default_lb"
fit.public.genericables.d58a444c9cd546b5b284353c0326209c:
- name: 'load-balance-filter'
+ name: "load-balance-filter"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
route:
- default: '8a67f9e84e7e4077897a9b615c067dd4'
+ default: "8a67f9e84e7e4077897a9b615c067dd4"
fitables:
8a67f9e84e7e4077897a9b615c067dd4:
aliases:
- - 'lb_filter_python_impl'
+ - "lb_filter_python_impl"
fit.public.genericables.093325db3dfa4b42872512d91e865ccb:
- name: 'config-subscribeConfiguration'
+ name: "config-subscribeConfiguration"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fitables:
753f1399a2754d1ea6c749e41c25bfd0:
aliases:
- - 'default'
+ - "default"
fit.public.genericables.2514453162a4498791b59e7e299b36d1:
- name: 'config-unsubscribeConfiguration'
+ name: "config-unsubscribeConfiguration"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fitables:
9cf969d1e56d48e2a15435750b6358d2:
aliases:
- - 'default'
+ - "default"
fit.public.genericables.4c0e733d04e94f488c122925052aceb1: # 测试环境下,需使用生产配置;实际生产环境下不需要
- name: 'config-download'
+ name: "config-download"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fitables:
ef327ef3a9a040bcb223311a70959872:
aliases:
- - 'default'
+ - "default"
fit.public.genericables.ae024f34dd7a4dc88e19a1a8cf801f29:
- name: 'server-config-upload'
+ name: "server-config-upload"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
route:
- default: '2ae9d88f46894f7bb0fcd45cf544cb52'
+ default: "2ae9d88f46894f7bb0fcd45cf544cb52"
fit.public.genericables.887837e5d33f4fdfa76b05c75458fa0c:
- name: 'request_response'
+ name: "request_response"
route:
- dynamic: 'b0d8a8e116a34f1b8e45ce2be8dde6b9'
+ dynamic: "b0d8a8e116a34f1b8e45ce2be8dde6b9"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fit.public.genericables.bf2e1029e8844fe9afb698affb95d39c:
- name: 'heart-beat-online'
+ name: "heart-beat-online"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fitables:
6bd00d54d5684a0480cb567a058210f7:
aliases:
- - 'heart_beat_online_fit_python'
+ - "heart_beat_online_fit_python"
CM_ONLINE_HEART_BEAT_FIT_ID:
aliases:
- - 'heart_beat_online_om_python'
+ - "heart_beat_online_om_python"
fit.public.genericables.HEART_BEAT_EXIT_UNEXPECTEDLY_GEN_ID:
- name: 'heart-beat-exit-unexpectedly'
+ name: "heart-beat-exit-unexpectedly"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
route:
- default: 'HEART_BEAT_EXIT_UNEXPECTEDLY_FIT_ID'
+ default: "HEART_BEAT_EXIT_UNEXPECTEDLY_FIT_ID"
fit.public.genericables.18e47e184fd44c70af63eec3227bee2e:
- name: 'heart-beat-offline'
+ name: "heart-beat-offline"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fitables:
4e01a11d760a4614b431f760ee7f51ac:
aliases:
- - 'heart_beat_offline_python'
+ - "heart_beat_offline_python"
fit.public.genericables.564286f7db6349b2b29db49feac3b7da:
- name: 'get_fit_service_address_list'
+ name: "get_fit_service_address_list"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fitables:
9602150ac5694585ab9a9e3d7561f48b:
aliases:
- - 'get_service_address_list_python'
+ - "get_service_address_list_python"
fit.public.genericables.2ac926e6e40245b78b7bdda23bcb727b:
- name: 'online_fit_services'
+ name: "online_fit_services"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fitables:
ONLINE_FIT_SERVICE_FITABLE_ID:
aliases:
- - 'online_fit_services_python'
+ - "online_fit_services_python"
route:
- default: 'ONLINE_FIT_SERVICE_FITABLE_ID'
-fit.public.genericables.7c52fb4fdfa243af928f23607fbbee02:
- name: 'QUERY_FITABLE_METAS_GEN_ID'
+ default: "ONLINE_FIT_SERVICE_FITABLE_ID"
+fit.public.genericables.modelengine.fit.registry.registry-service.query-running-fitables:
+ name: "QUERY_FITABLE_METAS_GEN_ID"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
route:
- default: '33b1f9b8f1cc49d19719a6536c96e854'
+ default: "query-running-fitables"
fit.public.genericables.GET_FITABLES_OF_GENERICABLE_GEN_ID:
- name: 'get_fitables_of_genericable'
+ name: "get_fitables_of_genericable"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
route:
- default: 'GET_FITABLES_OF_GENERICABLE_FIT_ID'
+ default: "GET_FITABLES_OF_GENERICABLE_FIT_ID"
fit.public.genericables.8b7f3c01ec4f4a5aa6a291e82587e946:
- name: 'offline_fit_service'
+ name: "offline_fit_service"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fitables:
d4b42ada0f744441a8b1eca9f2919a8a:
aliases:
- - 'offline_fit_service_python'
+ - "offline_fit_service_python"
fit.public.genericables.49612be00e38424cac2e8ea812936cb4:
- name: 'get_registry_address'
+ name: "get_registry_address"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fitables:
e482bcfaded042be87873bb63884bc14:
aliases:
- - 'get_registry_address_fit_python'
+ - "get_registry_address_fit_python"
route:
- default: 'e482bcfaded042be87873bb63884bc14'
+ default: "e482bcfaded042be87873bb63884bc14"
fit.public.genericables.e5f5a8809c534d21a6639e0e1ae2ccae:
- name: 'set_fitable_instance_status'
+ name: "set_fitable_instance_status"
fitables:
711de8c45e3d498b885801b5bc7394ad:
aliases:
- - 'set_fitable_status_python'
+ - "set_fitable_status_python"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fit.public.genericables.0e166105f93c46a49966ba774d9ec10a:
- name: 'remove_fit_listener'
+ name: "remove_fit_listener"
fitables:
af0d9d541ac94da7a8d28cfd465107f5:
aliases:
- - 'remove_fit_listener_python'
+ - "remove_fit_listener_python"
tags:
- - 'localOnly'
- - 'nonTraceable'
-fit.public.genericables.c9aa580f3fa845c99c2c6145a0499e45:
- name: 'registry_server_subscribe'
+ - "localOnly"
+ - "nonTraceable"
+fit.public.genericables.modelengine.fit.registry.registry-service.subscribe-fitables:
+ name: "registry_server_subscribe"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
route:
- default: 'ee0a8337d3654a22a548d5d5abe1d5f3'
-fit.public.genericables.33be4142494e4742aa122555a451d996:
- name: 'query_fitable_addresses'
+ default: "subscribe-fitables"
+fit.public.genericables.modelengine.fit.registry.registry-service.query-fitables-addresses:
+ name: "query_fitable_addresses"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
route:
- default: '5807f06a3a704708b264ea3c6cfbbd53'
+ default: "query-fitables-addresses"
fit.public.genericables.2d47d38f33fc32c47f049289a2a432d2:
- name: 'dynamic_loading_start'
+ name: "dynamic_loading_start"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
route:
- default: '6e01d3e6911533a440e541a2900da0de'
+ default: "6e01d3e6911533a440e541a2900da0de"
fit.public.genericables.fd059427d2b742f590533ea95391144a:
- name: 'configuration_server_append'
+ name: "configuration_server_append"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
route:
- default: '0c3217aa311a405e8a7cff40e9fee60a'
+ default: "0c3217aa311a405e8a7cff40e9fee60a"
fitables:
0c3217aa311a405e8a7cff40e9fee60a:
aliases:
- - 'default'
+ - "default"
fit.public.genericables.01c48f78a6964f4392d026df694b33e5:
- name: 'configuration_server_remove'
+ name: "configuration_server_remove"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
route:
- default: '87736d2ff21d4e57923bd1760e1bca3f'
+ default: "87736d2ff21d4e57923bd1760e1bca3f"
fitables:
87736d2ff21d4e57923bd1760e1bca3f:
aliases:
- - 'default'
+ - "default"
fit.public.genericables.d166effd0ef842fe85b8133d02568057:
- name: 'configuration_agent_unsubscribe'
+ name: "configuration_agent_unsubscribe"
route:
- default: 'unsubscribe'
+ default: "unsubscribe"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fit.public.genericables.918fbf55d64b4de8910d08cfcb41d31c:
- name: 'configuration_agent_download'
+ name: "configuration_agent_download"
fitables:
ef64c99ddeeb48259e10828bc62c211f:
aliases:
- - 'py_impl'
+ - "py_impl"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fit.public.genericables.90c52daf8cc14e22ad8cfb9a19d21157:
- name: 'configuration_agent_upload'
+ name: "configuration_agent_upload"
fitables:
CONFIGURATION_AGENT_UPLOAD_FIT_ID:
aliases:
- - 'python_configuration_upload'
+ - "python_configuration_upload"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fit.public.genericables.63ee92ae39c54ee7a529460e29aee542:
- name: 'server_response'
+ name: "server_response"
fitables:
25827389e64248f1807a015118509326:
aliases:
- - 'python_default_server_response'
+ - "python_default_server_response"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fit.public.genericables.782eed4bb8ed4867a67d66894719ad09:
- name: 'recycle'
+ name: "recycle"
route:
- default: '37210e40e78c46beb148a05b99d6fd72'
+ default: "37210e40e78c46beb148a05b99d6fd72"
fit.public.genericables.ea9c023c1c154cc8a72b1f012d828183:
route:
- default: '98a7e567803c4a4eac0ffd29b4e0a505'
+ default: "98a7e567803c4a4eac0ffd29b4e0a505"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fit.public.genericables.f54d01848ca146d7aa450afe77027ddf:
- name: 'fit.matata.ruleEngine.rule.json.Execute'
+ name: "fit.matata.ruleEngine.rule.json.Execute"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
route:
- default: 'f11c6ee7826f4efeab22c0b7675ee1d8'
+ default: "f11c6ee7826f4efeab22c0b7675ee1d8"
fitables:
f11c6ee7826f4efeab22c0b7675ee1d8:
aliases:
- - 'default'
+ - "default"
fit.public.genericables.41151994d1e74245ad1416b75c8eff39:
- name: 'fit.matata.tagCenter.tagger.Tag'
+ name: "fit.matata.tagCenter.tagger.Tag"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
route:
- default: 'aeb64b5c96cf4e68be4b557bf5cde49a'
+ default: "aeb64b5c96cf4e68be4b557bf5cde49a"
fitables:
aeb64b5c96cf4e68be4b557bf5cde49a:
aliases:
- - 'default'
+ - "default"
fit.public.genericables.f770d409efe54555ac7c1ed53efaf1aa:
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.d1a7264b528a41708905463385e0148f:
- name: 'notify_fit_service'
+ name: "notify_fit_service"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.7a896417dc764a7fbb0381bcf128e9ec:
- name: 'mq_agent_subscribe'
+ name: "mq_agent_subscribe"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fitables:
MQ_AGENT_SUBSCRIBE_FIT_ID:
aliases:
- - 'mq_agent_subscribe_python'
+ - "mq_agent_subscribe_python"
fit.public.genericables.9815d4c839e24e038a71b387de2150ea:
- name: 'mq_agent_unsubscribe'
+ name: "mq_agent_unsubscribe"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fitables:
MQ_AGENT_UNSUBSCRIBE_FIT_ID:
aliases:
- - 'mq_agent_unsubscribe_python'
+ - "mq_agent_unsubscribe_python"
fit.public.genericables.bd82ccd28c6047afa85818e835a4c3d7:
- name: 'mq_agent_consume'
+ name: "mq_agent_consume"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fitables:
MQ_AGENT_CONSUME_FIT_ID:
aliases:
- - 'mq_agent_consume_python'
+ - "mq_agent_consume_python"
fit.public.genericables.3788e36a1faf4fed8c50410ebc9bffa8:
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fitables:
FIT_GET_ALL_GLOBAL_CONTEXT_FIT_ID:
aliases:
- - 'py_impl'
+ - "py_impl"
fit.public.genericables.bc3e4e7d642e4acb8a48fb28cf74376f:
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fitables:
FIT_PUT_GLOBAL_CONTEXT_FIT_ID:
aliases:
- - 'py_impl'
+ - "py_impl"
fit.public.genericables.327426d21bda4fe58bc6dc7ef726ffa2:
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fitables:
FIT_RESTORE_GLOBAL_CONTEXT_FIT_ID:
aliases:
- - 'py_impl'
+ - "py_impl"
fit.public.genericables.bfbc3d446c324e0a9ddc2ea55255a168:
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fitables:
FIT_GET_GLOBAL_CONTEXT_FIT_ID:
aliases:
- - 'py_impl'
+ - "py_impl"
fit.public.genericables.fd3244e74b044cf0af5a43c045601160:
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fitables:
FIT_GET_ALL_ROUTE_CONTEXT_FIT_ID:
aliases:
- - 'py_impl'
+ - "py_impl"
fit.public.genericables.23e5a8c3e98d4639913799cde09f34ab:
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fitables:
FIT_PUT_ROUTE_CONTEXT_FIT_ID:
aliases:
- - 'py_impl'
+ - "py_impl"
fit.public.genericables.ce40a173086a4cf795559441cdffd71f:
- name: 'is_ready'
+ name: "is_ready"
route:
- default: 'e117c6fc9be044b8be7f6273e0a3a55b'
+ default: "e117c6fc9be044b8be7f6273e0a3a55b"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.ac31756b9122448eae9a701e7691ac55:
- name: 'hi'
+ name: "hi"
route:
- default: '3ee4572b5aa34b448ec6419ac62715b1'
+ default: "3ee4572b5aa34b448ec6419ac62715b1"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.1f54daa450848ca1e77027dd46d70aff:
- name: 'dynamic_loading_start'
+ name: "dynamic_loading_start"
route:
- default: 'd14167424b75c8eff351994d1e5a4119'
+ default: "d14167424b75c8eff351994d1e5a4119"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.bigdata.cache.read.meta:
- name: 'read_meta_from_big_data_cache'
+ name: "read_meta_from_big_data_cache"
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.bigdata.cache.create.str:
- name: 'create_str_in_big_data_cache'
+ name: "create_str_in_big_data_cache"
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.bigdata.cache.create.bytes:
- name: 'create_bytes_in_big_data_cache'
+ name: "create_bytes_in_big_data_cache"
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.bigdata.cache.read.str:
- name: 'read_str_from_big_data_cache'
+ name: "read_str_from_big_data_cache"
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.bigdata.cache.read.bytes:
- name: 'read_bytes_from_big_data_cache'
+ name: "read_bytes_from_big_data_cache"
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.bigdata.cache.delete:
- name: 'delete_value_in_big_data_cache'
+ name: "delete_value_in_big_data_cache"
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.bigdata.cache.validate.capacity:
- name: 'validate_capacity_in_big_data_cache'
+ name: "validate_capacity_in_big_data_cache"
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.bigdata.cache.get.info:
- name: 'get_info_in_big_data_cache'
+ name: "get_info_in_big_data_cache"
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.bigdata.cache.is_databus:
- name: 'get_is_databus_cache'
+ name: "get_is_databus_cache"
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'nonTraceable'
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.get.all.plugins.ready:
- name: 'modelengine.fit.get.all.plugins.ready'
+ name: "modelengine.fit.get.all.plugins.ready"
fitables:
local-worker:
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.get.running.async.task.count:
- name: 'modelengine.fit.get.running.async.task.count'
+ name: "modelengine.fit.get.running.async.task.count"
fitables:
local-worker:
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.get.should.terminate.main:
- name: 'modelengine.fit.get.should.terminate.main'
+ name: "modelengine.fit.get.should.terminate.main"
fitables:
local-worker:
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.get.last.success.time:
- name: 'modelengine.fit.get.last.success.time'
+ name: "modelengine.fit.get.last.success.time"
fitables:
local-worker:
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'localOnly'
- - 'nonTraceable'
+ - "localOnly"
+ - "nonTraceable"
fit.public.genericables.modelengine.fit.get.earliest.start.time:
- name: 'modelengine.fit.get.earliest.start.time'
+ name: "modelengine.fit.get.earliest.start.time"
fitables:
local-worker:
route:
- default: 'local-worker'
+ default: "local-worker"
tags:
- - 'localOnly'
- - 'nonTraceable'
\ No newline at end of file
+ - "localOnly"
+ - "nonTraceable"
diff --git a/framework/fit/python/fitframework/const.py b/framework/fit/python/fitframework/const.py
index d0e19d15..766edf53 100644
--- a/framework/fit/python/fitframework/const.py
+++ b/framework/fit/python/fitframework/const.py
@@ -161,7 +161,7 @@
GET_FIT_SERVICE_ADDRESS_LIST_GEN_ID = '564286f7db6349b2b29db49feac3b7da'
GET_FIT_SERVICE_ADDRESS_LIST_FITABLE_ID = '9602150ac5694585ab9a9e3d7561f48b'
-NOTIFY_FIT_SERVICE_GEN_ID = 'b69df5e8cbcd4166aa5029602e7a58cf'
+NOTIFY_FIT_SERVICE_GEN_ID = 'modelengine.fit.service.registry-listener.notify-fitables'
NOTIFY_FIT_SERVICE_FITABLE_ID = 'NOTIFY_FIT_SERVICE_FITABLE_ID'
ONLINE_FIT_SERVICE_GEN_ID = '2ac926e6e40245b78b7bdda23bcb727b'
@@ -230,13 +230,13 @@
FIT_CONFIGURATION_SERVER_UPLOAD_FIT_ID = '2ae9d88f46894f7bb0fcd45cf544cb52'
# registry server
-QUERY_FIT_SERVICE_GEN_ID = '33be4142494e4742aa122555a451d996'
-SUBSCRIBE_FIT_SERVICE_GEN_ID = 'c9aa580f3fa845c99c2c6145a0499e45'
-REGISTER_FIT_SERVICE_GEN_ID = '85bdce64cf724589b87cb6b6a950999d'
-QUERY_FITABLE_METAS_GEN_ID = '7c52fb4fdfa243af928f23607fbbee02'
+QUERY_FIT_SERVICE_GEN_ID = 'modelengine.fit.registry.registry-service.query-fitables-addresses'
+SUBSCRIBE_FIT_SERVICE_GEN_ID = 'modelengine.fit.registry.registry-service.subscribe-fitables'
+REGISTER_FIT_SERVICE_GEN_ID = 'modelengine.fit.registry.registry-service.register-fitables'
+QUERY_FITABLE_METAS_GEN_ID = 'modelengine.fit.registry.registry-service.query-running-fitables'
# heartbeat server
-HEART_BEAT_GEN_ID = 'e12fd1c57fd84f50a673d93d13074082'
+HEART_BEAT_GEN_ID = 'modelengine.fit.heartbeat.send-heartbeat'
# debugger
DEBUGGER_START_FIT_ID = 'debugger_start_fitable_id'
diff --git a/framework/fit/python/plugin/fit_py_registry_client/conf/application.yml b/framework/fit/python/plugin/fit_py_registry_client/conf/application.yml
index 3c3c7b27..2151c63e 100644
--- a/framework/fit/python/plugin/fit_py_registry_client/conf/application.yml
+++ b/framework/fit/python/plugin/fit_py_registry_client/conf/application.yml
@@ -1,22 +1,21 @@
registry-center:
client:
service_id: 2
- mode: 'pull' # pull or push
+ mode: "pull" # pull or push
pull-frequency: 60
registry_fitable_frequency: 15
registered-fitables-expire-interval: 30 # expected expire interval used by server
invalid_address_ttl: 60
server:
addresses:
- - 'localhost:8080'
+ - "localhost:8080"
protocol: 2
formats:
- 1
context-path: ""
service_ids:
- - '85bdce64cf724589b87cb6b6a950999d'
- - 'bcad5d59d90b4ee88f195cd7356389fc'
- - '33be4142494e4742aa122555a451d996'
- - 'c9aa580f3fa845c99c2c6145a0499e45'
- - '7c52fb4fdfa243af928f23607fbbee02'
- - 'e12fd1c57fd84f50a673d93d13074082'
+ - "modelengine.fit.registry.registry-service.register-fitables"
+ - "modelengine.fit.registry.registry-service.query-fitables-addresses"
+ - "modelengine.fit.registry.registry-service.subscribe-fitables"
+ - "modelengine.fit.registry.registry-service.query-running-fitables"
+ - "modelengine.fit.heartbeat.send-heartbeat"