第一家中文商务网站,福田网站建设费用,西安企业名录大全,wordpress不显示分类目录【squids.cn】 全网zui低价RDS#xff0c;免费的迁移工具DBMotion、数据库备份工具DBTwin、SQL开发工具等
Apache Camel 绝非Java企业技术栈领域的新手。它由James Strachan在2007年创建#xff0c;旨在实现著名的 EIP 书#xff08;由Gregor Hohpe和Bobby W…【squids.cn】 全网zui低价RDS免费的迁移工具DBMotion、数据库备份工具DBTwin、SQL开发工具等
Apache Camel 绝非Java企业技术栈领域的新手。它由James Strachan在2007年创建旨在实现著名的 EIP 书由Gregor Hohpe和Bobby Woolf编写Addison Wesley于2003年10月出版的企业集成模式。在2010年初成为最受欢迎的Java集成框架之一后Apache Camel正处于被历史所遗忘的边缘原因是人们更青睐一种名为企业服务总线ESB的新架构模型并视其为面向服务架构SOA的灵丹妙药。
然而在SOA失败后Apache Camel与此同时已被包括但不限于Progress Software和Red Hat的多家编辑采纳并以商业名称如Mediation Router或Fuse进行分发正在强势回归并且为下一个集成的十年变得更为强大。这种复出也得益于Quarkus这是一个新的超音速和次原子Java平台。
本文旨在提出一种非常便利的微服务实现方法使用Apache Camel作为Java开发工具Quarkus作为运行时以及不同的KubernetesK8s集群从本地的Minikube到像EKSElastic Kubernetes Service、OpenShift或Heroku这样的PaaS作为基础设施。
项目概述
本项目旨在通过一个简化的货币转账应用程序来阐明相关观点该程序包含四个微服务具体如下
aws-camelk-file: 该微服务轮询本地文件夹一旦有XML文件传入它就将其存储在一个新创建的AWS S3 bucket中该bucket的名称以mys3开头后接一个随机后缀。
aws-camelk-s3: 该微服务监听首个找到的AWS S3 bucket该bucket的名称以mys3开头。一旦有XML文件传入它将对文件进行分割、标记化和流处理然后将每个消息发送到名为myQueue的AWS SQS简单队列服务队列。
aws-camelk-sqs: 该微服务订阅名为myQueue的AWS SQS队列上的消息并对每个传入消息执行从XML到Java对象的解组操作然后将其组织为JSON格式再将其发送到下面的REST服务。
aws-camelk-jaxrs: 该微服务提供了一个REST API具有用于创建、读取、更新和删除货币转账订单的端点。它接收/生成JSON输入/输出数据。它使用一个服务该服务展现了由aws-camelk-api模块定义的接口。可能存在此接口的多个实现但为简单起见在当前情况下我们使用由aws-camelk-provider模块定义并命名为DefaultMoneyTransferProvider的实现该实现仅在内存哈希图中处理货币转账订单请求。
项目的源代码可以在此处找到。这是一个多模块的Maven项目下面解释了各个模块。下面显示了最重要的Maven依赖项 dependencyManagement dependencies dependency groupIdio.quarkus.platform/groupId artifactIdquarkus-bom/artifactId version${quarkus.platform.version}/version typepom/type scopeimport/scope /dependency dependency groupIdio.quarkus.platform/groupId artifactIdquarkus-camel-bom/artifactId version${quarkus.platform.version}/version typepom/type scopeimport/scope /dependency dependency groupIdcom.amazonaws/groupId artifactIdaws-java-sdk-bom/artifactId version1.12.454/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement
模块 aws-camelk-model
此模块定义了应用程序的域该域由诸如MoneyTransfer、Bank、BankAddress等业务对象组成。集成应用的特点之一是其业务域是遗留的通常是几十年前由忽略了您作为软件开发者当前正在使用的工具集的业务分析师和专家设计的。这种遗留以各种形式存在如Excel表格以及CSV或XML文件。
因此我们在这里考虑了一个典型的情景根据该情景我们的域模型被定义为XML语法由一对XSD文件定义。这些XSD文件位于src/main/resources/xsd目录中并由jaxb2-maven-plugin处理以生成相关联的Java对象。下面的列表显示了插件的配置 plugingroupIdorg.codehaus.mojo/groupIdartifactIdjaxb2-maven-plugin/artifactIddependenciesdependencygroupIdorg.jvnet.jaxb2_commons/groupIdartifactIdjaxb2-value-constructor/artifactIdversion3.0/version/dependency/dependenciesexecutionsexecutiongoalsgoalxjc/goal/goals/execution/executionsconfigurationpackageNamefr.simplex_software.quarkus.camel.integrations.jaxb/packageNamesourcessource${basedir}/src/main/resources/xsd/source/sourcesargumentsargument-Xvalue-constructor/argument/argumentsextensiontrue/extension/configuration/plugin
在这里我们运行xjc模式编译器工具在目标包fr.simplex_software.quarkus.camel.integrations.jaxb中基于项目的src/main/resources/xsd目录中的XSD模式生成Java类。默认情况下这些自动生成的Java对象具有JAXBJava Architecture for XML Binding注释但没有构造函数这使得它们有点难以使用特别是对于必须通过setter实例化的具有许多属性的类。因此在上面的列表中我们将jaxb2-maven-plugin配置为依赖于jaxb3-value-constructor工件。通过这样做我们要求xjc编译器为每个随后的JAXB处理类生成完整参数构造函数。
此模块的最终结果是一个JAR文件其中包含我们的领域模型形式为Java类层次结构所有其他应用程序模块将其用作依赖项。这种方法比手动实现再次用Java由XML语法已经定义的域对象的方法更为实用。
模块 aws-camelk-api
此模块非常简单因为它仅由一个接口组成。这个接口名为MoneyTransferFacade是由资金转账服务公开的接口。此服务必须实现公开的接口。实际上这样的服务可能有许多不同的实现具体取决于资金转移的性质、银行、客户类型以及许多其他可能的条件。在我们的例子中我们只考虑了该接口的简单实现如下一节所示。
模块 aws-camelk-provider
此模块为MoneyTransferFacade接口定义了服务提供商。在这里使用的SPISoftware Provider Interface软件提供商接口模式是非常强大的它允许将服务接口与其实现解耦。
我们对MoneyTransferFacade接口的实现是DefaultMoneyTransferProvider类它也非常简单因为它只是在内存哈希映射中创建、读取、更新和删除资金转账订单。
模块 aws-camelk-jaxrs
与仅仅是通用类库的前面几个模块不同此模块和接下来的模块是Quarkus可运行服务。这意味着它们使用quarkus-maven-plugin来创建一个可执行的JAR。
如其名称所示此模块公开了一个JAX-RSJava API for RESTful Web ServicesAPI来处理资金转账订单。Quarkus带有RESTeasy这是Red Hat对JAX-RS规范的完全实现这就是我们在这里使用的。
就MoneyTransferResource类而言没有什么特别的要提及的该类实现了REST API。它提供了创建、读取、更新和删除资金转账订单的端点并且额外提供了两个端点目的是检查应用程序的活动状态和准备状态。
模块 aws-camelk-file
此模块是Camel管道中的第一个模块由此模块将包含资金转账订单的XML文件从其初始登陆目录传送到REST API该API代表服务提供商处理它们。它使用Camel Java DSLDomain Specific Language领域特定语言来执行此操作如下面的列表所示
fromF(file://%s?include.*.xmldeletetrueidempotenttruebridgeErrorHandlertrue, inBox).doTry().to(validator:xsd/money-transfers.xsd).setHeader(AWS2S3Constants.KEY, header(FileConstants.FILE_NAME)).to(aws2S3(s3Name RANDOM).autoCreateBucket(true).useDefaultCredentialsProvider(true)).doCatch(ValidationException.class).log(LoggingLevel.ERROR, failureMsg ${exception.message}).doFinally().end();
该代码轮询一个输入目录该目录被定义为一个外部属性以检查任何XML文件具有.xml扩展名的文件的存在。一旦这样的文件落在给定的目录中它将根据src/main/resources/xsd/money-transfers.xsd文件中定义的模式进行验证。如果验证有效它将被存储在一个AWS S3存储桶中其名称被计算为等于外部定义的常量后跟一个随机后缀。所有内容都封装在一个try...catch结构中以一致地处理异常情况。
在这里为了定义外部属性我们使用由Quarkus实现的Eclipse MP配置规范以及其他规范如下面的列表所示 private static final String RANDOM new Random().ints(a, z).limit(5).collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();ConfigProperty(nameinBox)String inBox;ConfigProperty(names3Name)String s3Name;后缀RANDOM代表类java.util.Random和属性生成inBox 并s3Name从文件中注入src/resource/application.properties。使用由常量和随机后缀组成的S3存储桶名称的原因是AWS S3存储桶需要具有跨区域唯一的名称因此我们需要这样的随机后缀来保证唯一性。
模块aws-camelk-s3
该模块实现了一个 Camel 路由每当文件到达专用 S3 存储桶时AWS 基础设施就会触发该路由。这是代码 from(aws2S3(s3BucketName).useDefaultCredentialsProvider(true)) .split().tokenizeXML(moneyTransfer).streaming() .to(aws2Sqs(queueName).autoCreateQueue(true).useDefaultCredentialsProvider(true));
一旦触发Camel 路由会在对输入 XML 文件进行标记后按顺序对其进行拆分。这个想法是输入文件可能包含多个汇款订单并且这些订单将被单独处理。queueName因此从此标记化和拆分过程发出的每个汇款订单都会发送到 AWS SQS 队列该队列的名称由从文件注入的属性值指定application.properties。
模块aws-camelk-sqs
这是我们的 Camel 管道的最后一个模块。 from(aws2Sqs(queueName).useDefaultCredentialsProvider(true)) .unmarshal(jaxbDataFormat) .marshal().json(JsonLibrary.Jsonb) .setHeader(Exchange.HTTP_METHOD, constant(POST)) .to(http(uri));
此 Camel 路由订阅 AWS SQS 队列其名称由属性指定queueName并将收到的每条 XML 消息解组为 Java 对象。鉴于每个 XML 消息都包含一个汇款订单它在相应的MoneyTransferJava 类实例中被解组。然后一旦解组每个MoneyTransferJava 类实例就会再次编组到 JSON 有效负载中。这是必需的因为我们的 REST 接口使用 JSON 有效负载并且与能够自动执行从 Java 对象到 JSON 的转换的标准 JAX-RS 客户端相反http()这里使用的 Camel 组件不是。因此我们需要手动完成。通过将交换的标头设置为 POST 常量我们设置将发送到 REST API 的 HTTP 请求的类型。最后但并非最不重要的一点是端点 URI 像往常一样从文件中作为外部定义的属性注入application.properties。
单元测试
在部署和运行微服务之前我们需要对它们进行单元测试。该项目包括几乎所有模块的几个单元测试 - 从aws-camelk-model测试域模型以及从/到 XML/Java 的各种转换到aws-camelk-jaxrs这是我们的终点微服务。运行单元测试很简单。只需执行 $ cd aws-camelk
$ ./delete-all-buckets.sh #Delete all the buckets named mys3* if any
$ ./purge-sqs-queue.sh #Purge the SQS queue named myQueue if it exists and isnt empty
$ mvn clean package #Clean-up, run unit tests and create JARs
完整的单元测试报告将由maven-surefile-plugin. 为了使单元测试按预期运行需要一个 AWS 帐户并且应在本地机器上安装和配置 AWS CLI。这意味着该文件除其他外还~/.aws/credentials包含您的aws_access_key_id和aws_secret_access_key properties及其关联值。
原因是单元测试使用AWS SDK软件开发工具包来处理S3存储桶和SQS队列这使得它们不完全是单元测试而是单元测试和集成测试的组合。
部署和运行
现在要部署和运行我们的微服务我们需要考虑许多不同的情景 - 从简单的本地独立执行到像OpenShift或EKS这样的PaaS部署再到像Minikube这样的本地K8s集群。因此为了避免在这里产生一些混淆我们更倾向于为每种部署情景单独撰写一篇文章。
所以请关注下一篇文章。 作者Nicolas Duminil
更多内容请关注公号【云原生数据库】
squids.cn云数据库RDS迁移工具DBMotion云备份DBTwin等数据库生态工具。