Как создать саму конфигурацию маршрутов динамически - PullRequest
0 голосов
/ 16 мая 2019

В одном из моих вариантов использования у меня есть вся информация о маршруте в файле json, и я хочу прочитать файл и соответственно создать маршруты.

, например,

, если яобъявил маршрут, как это в моем файле конфигурации JSON

{
  "config": [
    {
      "routeSrcSystem": "System1",
      "routes": [
        {
          "fromRoute": {
            "type": "default",
            "typeValue": "direct:CMStart"
            },  
          "toRoute": {
            "type": "http"
            "typeMethod": "POST",
            "typeContent": "application/json",
            "typeValue": "http://localhost:8080/v1/System1/inboundMessage"
            }
        }
      ]
    }
  ]
}

, тогда я смог динамически создавать маршруты, как показано ниже.но здесь, хотя это и динамично, определение маршрута не является динамическим, потому что я использовал одно определение «от» и одно «к», но параметр для этого определения я передаю динамически.

public class GenerateRouter extends RouteBuilder {

        private RoutesMetadata routesMetadata;

        public GenerateRouter(CamelContext context,RoutesMetadata routesMetadata) {
            super(context);
            this.routesMetadata=routesMetadata;
        }

        @Override
        public void configure() throws Exception {
            from(routesMetadata.getFromRoute().getTypeValue())
            .setHeader(Exchange.HTTP_METHOD, simple(routesMetadata.getToRoute().getTypeMethod()))
            .setHeader(Exchange.CONTENT_TYPE, constant(routesMetadata.getToRoute().getTypeContent()))
            .to(routesMetadata.getToRoute().getTypeValue());
        }
    }

Но я бы хотелсделать само определение маршрута динамически.например, у меня есть конфигурация маршрута, подобная этой,

{
  "config": [
    {
      "routeSrcSystem": "System1",
      "routes": [
        {
          "fromRoute": {
            "type": "default",
            "typeValue": "direct:CMStart"
            },  
          "toRoute1": {
            "type": "http"
            "typeMethod": "POST",
            "typeContent": "application/json",
            "typeValue": "http://localhost:8080/v1/System1/inboundMessage"
            }
         "toRoute2": {
            "type": "http"
            "typeMethod": "POST",
            "typeContent": "application/json",
            "typeValue": "http://localhost:8080/v1/System2/inboundMessage"
            }
        }
      ]
    }
  ]
}

, тогда в моем определении маршрута мне нужно динамически добавить еще одно определение «к».это просто пример.это может быть более динамичным.например, конфигурация может быть изменена, чтобы ввести определение «процесса», «компонента» или «класса».поэтому, основываясь на конфиге, мы должны решить, сколько «to» будет создано и сколько «process» будет создано и т. д. Мне может понадобиться вызвать следующую конечную точку отдыха после некоторой проверки и т. д., а иногда и мне нужнопозвонить кафке, чтобы поставить сообщение в очередь.я вижу возможность перечислить все маршруты в списке и выполнить его, но я думаю, что нам нужно иметь гибкость, чтобы добавить процесс или определение класса, прежде чем мы вызовем следующую конечную точку, и это должно быть основано на конфигурации.

public class GenerateRouter extends RouteBuilder {

        private RoutesMetadata routesMetadata;

        public GenerateRouter(CamelContext context,RoutesMetadata routesMetadata) {
            super(context);
            this.routesMetadata=routesMetadata;
        }

        @Override
        public void configure() throws Exception {
            from(routesMetadata.getFromRoute().getTypeValue())
            .setHeader(Exchange.HTTP_METHOD, simple(routesMetadata.getToRoute().getTypeMethod()))
            .setHeader(Exchange.CONTENT_TYPE, constant(routesMetadata.getToRoute().getTypeContent()))
            .to(routesMetadata.getToRoute().getTypeValue())
            .setHeader(Exchange.HTTP_METHOD, simple(routesMetadata.getToRoute().getTypeMethod()))
            .setHeader(Exchange.CONTENT_TYPE, constant(routesMetadata.getToRoute().getTypeContent()))
            .to(routesMetadata.getToRoute().getTypeValue());
        }
    }

Я видел некоторую информацию, в которой само определение маршрута может быть определено динамически, и я изучаю его.но пока я хотел бы опубликовать это здесь, чтобы получить мнение экспертов.Также, пожалуйста, подскажите, правильно ли я использую верблюда?потому что в моем случае использования я думаю добавить определение «к», которому динамически передается имя класса на основе файла конфигурации, чтобы разработчик приложения мог выполнять свою логику для преобразования, обогащения или манипулирования этим классом на лету, прежде чем доставить его в цельсистема.пожалуйста, дайте мне знать, если у нас есть лучший подход.Кроме того, дайте мне знать, является ли способ работы XML хорошим способом или определение собственного файла конфигурации в формате json является хорошим способом создания динамического маршрута.

Я планирую прочитать файл json и динамически создать определение маршрутизатора в виде строки.но мне нужно было бы загрузить эту строку в качестве определения в контексте, кажется.я думаю, что мне не хватает этой части.

.to ("class: com.xxx.camel.layoutTransform? method = layout ()")

, если мы предоставимвсе эти конфигурации в xml-файле, и если верблюд поддерживает автоматическое создание определения маршрута с использованием этого файла, то мы можем рассмотреть и эту опцию.

Ниже приведен один из способов создания определения маршрутизатора с использованием другого источника.XML-файлв XML у нас есть определенная информация о маршрутизаторе, и этот xml рассматривается как строка, и эта строка преобразуется как объект определения маршрутизатора и, наконец, добавляется в контекст.

<routes
  xmlns=\"http://camel.apache.org/schema/spring\">
  <route>
      <from uri='direct:c'/>
      <to uri='mock:d'/>
  </route>
</routes>
CamelContext context = new DefaultCamelContext(); 
context.setTracing(true); 
String xmlString = "<routes  xmlns=\"http://camel.apache.org/schema/spring\"><route><from uri='direct:c'/><to uri='mock:d'/></route></routes>"; 

InputStream is = new ByteArrayInputStream(xmlString.getBytes()); 
RoutesDefinition routes = context.loadRoutesDefinition(is); 
context.addRouteDefinitions(routes.getRoutes()); 

context.start(); 

ProducerTemplate template = null; 
template = context.createProducerTemplate(); 
template.start(); 
template.sendBody("direct:c", "HelloC"); 
Thread.sleep(10000); 
context.stop();

Я хотел бы сделать аналогичную концепцию, используя определение java dsl в качестве строки. Например,

, если у меня есть строка, как показано ниже, можно ли это преобразовать в определение маршрутизатора?

String dslString = "from (" direct: start "). To (" seda: end ")";

Вот мой пример использования.Иногда мы хотим вызвать 2 службы http, как показано ниже:

от ("direct: start"). До (http://localhost:8080/service1).to("http://localhost:8080/service2")

Иногда нам может потребоваться вызвать 3 службы, как показано ниже

из ("direct: start"). В (http://localhost:8080/service1).to(" http://localhost:8080/service2").to(" http://localhost:8080/service3")

иногда нам нужно выполнить преобразование, прежде чем мы вызовем service2, как показано ниже.

от ("direct: start"). До (http://localhost:8080/service1).to("class:com.xxx.yyy").to(" http://localhost:8080/service2").to(" http://localhost:8080/service3")

В четной архитектуре мы будем иметь набор маршрутов, которые должны быть определены для каждого типа событий.идея заключается в том, что если мы определим эти маршруты в таблице для каждого типа события, то во время запуска службы все маршруты будут загружены в контексте и будут запущены.Я могу сделать то же самое в XML DSL, но я пытаюсь сделать то же самое в Java DSL.

Заранее спасибо!

1 Ответ

2 голосов
/ 17 мая 2019

Camel поддерживает определение всех деталей о маршрутах в определенном формате на основе XML. На этой странице есть ссылки на эти (и другие) DSL.

Вы определенно могли бы придумать свой собственный DSL и динамически строить маршруты, но это большая работа, если вы хотите поддерживать все, что поддерживает полный Camel DSL. Я подозреваю, что это не правильное решение для любого варианта использования.

Если у вас есть определенные шаблоны для ваших маршрутов, вы можете создавать довольно динамичные компоновщики маршрутов Camel, управляемые некоторой конфигурацией. Чтобы сделать это конкретным, скажем, у вас есть много вариантов использования, которые следуют очень похожему шаблону ... скажем, данные о потребителях из файлов в папке, выполнить несколько преобразований из меню (скажем) 10-15 преобразований, а затем отправить вывод в одну из множества очередей.

Поскольку у вас есть различные возможные комбинации, может иметь смысл сконфигурировать эти детали в файле и т. Д., А затем построить некоторые маршруты из этого. Компромисс не отличается от любого другого места, где вы должны решить, будет ли понятнее просто кодировать 10 вещей, которые вы хотите, или сделать что-то более сложное, но общее.

По сути, вы все равно будете создавать DSL или сортировку, но такую, которая ближе к вашему варианту использования.

...