21.3. 使用自定义客户端 API 扩展 KIE 服务器客户端


KIE 服务器使用预定义的客户端 API,您可以与之交互以使用 KIE 服务器服务。您可以使用自定义客户端 API 扩展 KIE 服务器客户端,以满足您的业务需求。

例如,这个步骤将自定义客户端 API 添加到 KIE 服务器,以适应自定义数据传输(之前为本情景)基于 Apache MINA(开源 Java 网络应用程序框架)。

流程

  1. 创建一个空的 Maven 项目,并在项目的 pom.xml 文件中定义以下打包类型和依赖项:

    示例项目中的 pom.xml 文件示例

    <packaging>jar</packaging>
    
    <properties>
       <version.org.kie>7.67.0.Final-redhat-00024</version.org.kie>
     </properties>
    
     <dependencies>
       <dependency>
         <groupId>org.kie.server</groupId>
         <artifactId>kie-server-api</artifactId>
         <version>${version.org.kie}</version>
       </dependency>
       <dependency>
          <groupId>org.kie.server</groupId>
          <artifactId>kie-server-client</artifactId>
          <version>${version.org.kie}</version>
        </dependency>
       <dependency>
         <groupId>org.drools</groupId>
         <artifactId>drools-compiler</artifactId>
         <version>${version.org.kie}</version>
       </dependency>
     </dependencies>
    Copy to Clipboard Toggle word wrap

  2. 在项目中的 Java 类中实施相关的 ServicesClient 接口,如下例所示:

    RulesMinaServicesClient 接口示例

    public interface RulesMinaServicesClient extends RuleServicesClient {
    
    }
    Copy to Clipboard Toggle word wrap

    需要特定的接口,因为您必须基于接口注册客户端实施,而且只能有一个给定接口的实施。

    在本例中,基于自定义 MINA 的数据传输使用 Drools 扩展,因此本例 RulesMinaServicesClient 接口扩展了 Drools 扩展中现有的 RuleServicesClient 客户端 API。

  3. 实施 KIE 服务器可以用来为新的 MINA 传输提供额外客户端功能的 RulesMinaServicesClient 接口,如下例所示:

    RulesMinaServicesClient 接口的实现示例

    public class RulesMinaServicesClientImpl implements RulesMinaServicesClient {
    
        private String host;
        private Integer port;
    
        private Marshaller marshaller;
    
        public RulesMinaServicesClientImpl(KieServicesConfiguration configuration, ClassLoader classloader) {
            String[] serverDetails = configuration.getServerUrl().split(":");
    
            this.host = serverDetails[0];
            this.port = Integer.parseInt(serverDetails[1]);
    
            this.marshaller = MarshallerFactory.getMarshaller(configuration.getExtraJaxbClasses(), MarshallingFormat.JSON, classloader);
        }
    
        public ServiceResponse<String> executeCommands(String id, String payload) {
    
            try {
                String response = sendReceive(id, payload);
                if (response.startsWith("{")) {
                    return new ServiceResponse<String>(ResponseType.SUCCESS, null, response);
                } else {
                    return new ServiceResponse<String>(ResponseType.FAILURE, response);
                }
            } catch (Exception e) {
                throw new KieServicesException("Unable to send request to KIE Server", e);
            }
        }
    
        public ServiceResponse<String> executeCommands(String id, Command<?> cmd) {
            try {
                String response = sendReceive(id, marshaller.marshall(cmd));
                if (response.startsWith("{")) {
                    return new ServiceResponse<String>(ResponseType.SUCCESS, null, response);
                } else {
                    return new ServiceResponse<String>(ResponseType.FAILURE, response);
                }
            } catch (Exception e) {
                throw new KieServicesException("Unable to send request to KIE Server", e);
            }
        }
    
        protected String sendReceive(String containerId, String content) throws Exception {
    
            // Flatten the content to be single line:
            content = content.replaceAll("\\n", "");
    
            Socket minaSocket = null;
            PrintWriter out = null;
            BufferedReader in = null;
    
            StringBuffer data = new StringBuffer();
            try {
                minaSocket = new Socket(host, port);
                out = new PrintWriter(minaSocket.getOutputStream(), true);
                in = new BufferedReader(new InputStreamReader(minaSocket.getInputStream()));
    
                // Prepare and send data:
                out.println(containerId + "|" + content);
                // Wait for the first line:
                data.append(in.readLine());
                // Continue as long as data is available:
                while (in.ready()) {
                    data.append(in.readLine());
                }
    
                return data.toString();
            } finally {
                out.close();
                in.close();
                minaSocket.close();
            }
        }
    }
    Copy to Clipboard Toggle word wrap

    这个实现示例指定了以下数据和行为:

    • 使用基于套接字的通讯进行简单性
    • 依赖于 KIE 服务器客户端的默认配置,并使用 ServerUrl 提供 MINA 服务器的主机和端口
    • 将 JSON 指定为 marshalling 格式
    • 需要接收消息作为以 open bracket {开头的 JSON 对象
    • 在等待响应的第一行时,使用直接套接字与阻塞 API 通信,然后读取所有可用的行
    • 不要使用 流模式, 因此在调用命令后断开 KIE 服务器会话
  4. 在项目中的 Java 类中实施 org.kie.client.client.helper.KieServicesClientBuilder 接口,如下例所示:

    KieServicesClientBuilder 接口的实现示例

    public class MinaClientBuilderImpl implements KieServicesClientBuilder {  
    1
    
    
        public String getImplementedCapability() {  
    2
    
            return "BRM-Mina";
        }
    
        public Map<Class<?>, Object> build(KieServicesConfiguration configuration, ClassLoader classLoader) {  
    3
    
            Map<Class<?>, Object> services = new HashMap<Class<?>, Object>();
    
            services.put(RulesMinaServicesClient.class, new RulesMinaServicesClientImpl(configuration, classLoader));
    
            return services;
        }
    
    }
    Copy to Clipboard Toggle word wrap

    1
    可让您向通用 KIE 服务器客户端基础架构提供额外的客户端 API
    2
    定义客户端使用的 KIE 服务器功能(extension)
    3
    提供客户端实施的映射,其中键是接口,值是完全初始化的实现
  5. 要使新客户端 API 发现 KIE 服务器客户端,请在 文件中创建一个 META-INF/services/org.kie.client.client.helper. KieServicesClientBuilder 文件,并在文件中添加完全限定的类名称。在本例中,该文件包含一行 org.kie.server.ext.mina.client.MinaClientBuilderImpl
  6. 构建您的项目,并将生成的 JAR 文件复制到项目的 ~/kie-server.war/WEB-INF/lib 目录中。例如,在红帽 JBoss EAP 上,此目录的路径是 EAP_HOME/standalone/deployments/kie-server.war/WEB-INF/lib
  7. 启动 KIE 服务器并将构建的项目部署到正在运行的 KIE 服务器中。您可以使用 Business Central 接口或 KIE 服务器 REST API 部署项目( PUT 请求到 http://SERVER:PORT/kie-server/services/rest/server/containers/{containerId})。

    在某个正在运行的 KIE 服务器上部署项目后,您可以开始与新的 KIE 服务器客户端交互。您可以采用与标准 KIE 服务器客户端相同的方法,创建客户端配置和客户端实例,并通过类型检索服务客户端,以及调用客户端方法。

    在本例中,您可以创建一个 RulesMinaServiceClient 客户端实例,并通过 MINA 传输调用 KIE 服务器上的操作:

    创建 RulesMinaServiceClient 客户端的实现示例

    protected RulesMinaServicesClient buildClient() {
        KieServicesConfiguration configuration = KieServicesFactory.newRestConfiguration("localhost:9123", null, null);
        List<String> capabilities = new ArrayList<String>();
        // Explicitly add capabilities (the MINA client does not respond to `get-server-info` requests):
        capabilities.add("BRM-Mina");
    
        configuration.setCapabilities(capabilities);
        configuration.setMarshallingFormat(MarshallingFormat.JSON);
    
        configuration.addJaxbClasses(extraClasses);
    
        KieServicesClient kieServicesClient =  KieServicesFactory.newKieServicesClient(configuration);
    
        RulesMinaServicesClient rulesClient = kieServicesClient.getServicesClient(RulesMinaServicesClient.class);
    
        return rulesClient;
    }
    Copy to Clipboard Toggle word wrap

    通过 MINA 传输调用 KIE 服务器操作的示例配置

    RulesMinaServicesClient rulesClient = buildClient();
    
    List<Command<?>> commands = new ArrayList<Command<?>>();
    BatchExecutionCommand executionCommand = commandsFactory.newBatchExecution(commands, "defaultKieSession");
    
    Person person = new Person();
    person.setName("mary");
    commands.add(commandsFactory.newInsert(person, "person"));
    commands.add(commandsFactory.newFireAllRules("fired"));
    
    ServiceResponse<String> response = rulesClient.executeCommands(containerId, executionCommand);
    Assert.assertNotNull(response);
    
    Assert.assertEquals(ResponseType.SUCCESS, response.getType());
    
    String data = response.getResult();
    
    Marshaller marshaller = MarshallerFactory.getMarshaller(extraClasses, MarshallingFormat.JSON, this.getClass().getClassLoader());
    
    ExecutionResultImpl results = marshaller.unmarshall(data, ExecutionResultImpl.class);
    Assert.assertNotNull(results);
    
    Object personResult = results.getValue("person");
    Assert.assertTrue(personResult instanceof Person);
    
    Assert.assertEquals("mary", ((Person) personResult).getName());
    Assert.assertEquals("JBoss Community", ((Person) personResult).getAddress());
    Assert.assertEquals(true, ((Person) personResult).isRegistered());
    Copy to Clipboard Toggle word wrap

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat