private void declareRoutes(ConstructDeclarer router, List<ExtensionParameter> routes) { routes.forEach(route -> { NestedRouteDeclarer routeDeclarer = router .withRoute(route.getAlias()) .describedAs(route.getDescription()) .withMinOccurs(route.isRequired() ? 1 : 0); route.getType().getDeclaringClass() .ifPresent(clazz -> routeDeclarer.withModelProperty(new ImplementingTypeModelProperty(clazz))); final List<FieldElement> parameters = route.getType().getAnnotatedFields(Parameter.class); loader.getFieldParametersLoader().declare(routeDeclarer, parameters, new ParameterDeclarationContext(CONSTRUCT, router.getDeclaration())); }); }
private void declareFirstSuccessful(ExtensionDeclarer extensionDeclarer) { ConstructDeclarer firstSuccessful = extensionDeclarer.withConstruct("firstSuccessful") .describedAs("Sends a message to a list of message processors until one processes it successfully."); firstSuccessful.withRoute("route").withChain(); }
router.withModelProperty(new ExtensionOperationDescriptorModelProperty(routerMethod)); Optional<Method> method = routerMethod.getMethod(); Optional<Class<?>> declaringClass = enclosingType.getDeclaringClass(); .withModelProperty(new ImplementingMethodModelProperty(method.get())) .withModelProperty(new ComponentExecutorModelProperty(new ReflectiveOperationExecutorFactory<>(declaringClass.get(), method.get()))); new ParameterDeclarationContext(CONSTRUCT, router.getDeclaration()));
private void declareErrorHandler(ExtensionDeclarer extensionDeclarer, ClassTypeLoader typeLoader) { ConstructDeclarer errorHandler = extensionDeclarer.withConstruct("errorHandler") .withStereotype(ERROR_HANDLER) .allowingTopLevelDefinition() .describedAs("Allows the definition of internal selective handlers. It will route the error to the first handler that matches it." + " If there's no match, then a default error handler will be executed."); errorHandler.onDefaultParameterGroup() .withOptionalParameter("ref") .withAllowedStereotypes(singletonList(ERROR_HANDLER)) NestedRouteDeclarer onErrorContinue = errorHandler.withRoute("onErrorContinue") .describedAs( "Error handler used to handle exceptions. It will commit any transaction as if the message was consumed successfully."); declareOnErrorRoute(typeLoader, onErrorContinue); NestedRouteDeclarer onErrorPropagate = errorHandler.withRoute("onErrorPropagate") .describedAs("Error handler used to propagate errors. It will rollback any transaction and not consume messages."); declareOnErrorRoute(typeLoader, onErrorPropagate); errorHandler.withOptionalComponent("onError") .withAllowedStereotypes(ON_ERROR) .describedAs("Error handler used to reference other ones."); .withStereotype(ON_ERROR) .describedAs("Error handler used to reference other ones."); onError.onDefaultParameterGroup() .withRequiredParameter("ref") .ofType(typeLoader.load(String.class))
private void declareConfigurationProperties(ExtensionDeclarer extensionDeclarer, ClassTypeLoader typeLoader) { ConstructDeclarer configuration = extensionDeclarer.withConstruct("configurationProperties") .allowingTopLevelDefinition() .withStereotype(APP_CONFIG) .describedAs("References a file with configuration properties. Each property has a key and a value. \n" + "The key can be referenced from the mule configuration files using the following semantics: \n" + "${key_name}. This allows to externalize configuration and change it based\n" + "on the environment the application is being deployed to."); configuration.onDefaultParameterGroup() .withRequiredParameter("file") .ofType(typeLoader.load(String.class)) .withExpressionSupport(NOT_SUPPORTED) .withDisplayModel(DisplayModel.builder().path(new PathModel(FILE, false, EMBEDDED, new String[] {"properties"})).build()) .describedAs(" The location of the file with the configuration properties to use. " + "It may be a location in the classpath or an absolute location. The file location\n" + " value may also contains references to properties that will only be resolved based on " + "system properties or properties set at deployment time."); }
private void declareFlow(ExtensionDeclarer extensionDeclarer, ClassTypeLoader typeLoader) { ConstructDeclarer flow = extensionDeclarer.withConstruct(FLOW_ELEMENT_IDENTIFIER) .allowingTopLevelDefinition() .withStereotype(FLOW); flow.onDefaultParameterGroup().withOptionalParameter("initialState").defaultingTo("started") .ofType(BaseTypeBuilder.create(JAVA).stringType().enumOf("started", "stopped").build()); flow.onDefaultParameterGroup().withOptionalParameter("maxConcurrency") .ofType(typeLoader.load(Integer.class)); flow.withComponent("source") .withAllowedStereotypes(MuleStereotypes.SOURCE); flow.withChain().setRequired(true); flow.withComponent("errorHandler") .withAllowedStereotypes(ERROR_HANDLER); }
private void declareScatterGather(ExtensionDeclarer extensionDeclarer, ClassTypeLoader typeLoader) { ConstructDeclarer scatterGather = extensionDeclarer.withConstruct("scatterGather") .describedAs("Sends the same message to multiple message processors in parallel.") .withErrorModel(compositeRoutingError); scatterGather.withRoute("route").withMinOccurs(2).withChain(); scatterGather.onDefaultParameterGroup() .withOptionalParameter("timeout") .ofType(typeLoader.load(Long.class)) .withExpressionSupport(NOT_SUPPORTED) .describedAs("Sets a timeout in milliseconds for each route. Values lower or equals than zero means no timeout."); scatterGather.onDefaultParameterGroup() .withOptionalParameter("maxConcurrency") .ofType(typeLoader.load(Integer.class)) .withExpressionSupport(NOT_SUPPORTED) .describedAs("This value determines the maximum level of parallelism that will be used by this router. ."); scatterGather.onDefaultParameterGroup() .withOptionalParameter(TARGET_PARAMETER_NAME) .ofType(typeLoader.load(String.class)) .withLayout(LayoutModel.builder().tabName(ADVANCED_TAB).build()); scatterGather.onDefaultParameterGroup() .withOptionalParameter(TARGET_VALUE_PARAMETER_NAME) .ofType(typeLoader.load(String.class))
private void declareAsync(ExtensionDeclarer extensionDeclarer, ClassTypeLoader typeLoader) { ConstructDeclarer async = extensionDeclarer.withConstruct("async") .describedAs("Processes the nested list of message processors asynchronously using a thread pool"); async.withChain(); async.onDefaultParameterGroup() .withOptionalParameter("name") .withExpressionSupport(NOT_SUPPORTED) .ofType(typeLoader.load(String.class)) .describedAs("Name that will be used to name the async scheduler"); }
private void declareChoice(ExtensionDeclarer extensionDeclarer, ClassTypeLoader typeLoader) { ConstructDeclarer choice = extensionDeclarer.withConstruct("choice") .describedAs("Sends the message to the first message processor whose condition has been satisfied. " + "If no conditions were satisfied, sends to the configured default message processor if configured, " + "or throws an exception if not configured.") .withErrorModel(routingError); NestedRouteDeclarer when = choice.withRoute("when").withMinOccurs(1); when.withChain(); when.onDefaultParameterGroup() .withRequiredParameter("expression") .ofType(typeLoader.load(boolean.class)) .describedAs("The expression to evaluate."); choice.withRoute("otherwise").withMaxOccurs(1).withChain(); }
private void declareTry(ExtensionDeclarer extensionDeclarer, ClassTypeLoader typeLoader) { ConstructDeclarer tryScope = extensionDeclarer.withConstruct("try") .describedAs("Processes the nested list of message processors, " + "within a transaction and with it's own error handler if required."); tryScope.onDefaultParameterGroup() .withOptionalParameter("transactionalAction") .ofType(BaseTypeBuilder.create(JAVA).stringType() .enumOf("INDIFFERENT", "ALWAYS_BEGIN", "BEGIN_OR_JOIN").build()) .defaultingTo("INDIFFERENT") .withExpressionSupport(NOT_SUPPORTED) .withLayout(LayoutModel.builder().tabName("Transactions").build()) .describedAs("The action to take regarding transactions. By default nothing will be done."); tryScope.onDefaultParameterGroup() .withOptionalParameter("transactionType") .ofType(BaseTypeBuilder.create(JAVA).stringType().enumOf("LOCAL", "XA").build()) .defaultingTo("LOCAL") .withExpressionSupport(NOT_SUPPORTED) .describedAs("Transaction type supported. Availability will depend on the runtime version, " + "though LOCAL is always available."); tryScope.withChain(); tryScope.withOptionalComponent("errorHandler") .withAllowedStereotypes(ERROR_HANDLER); }
private void declareSubflow(ExtensionDeclarer extensionDeclarer) { ConstructDeclarer flow = extensionDeclarer.withConstruct("subFlow") .allowingTopLevelDefinition(); flow.withChain().setRequired(true).withAllowedStereotypes(PROCESSOR); }
private void declareConfiguration(ExtensionDeclarer extensionDeclarer, ClassTypeLoader typeLoader) { ConstructDeclarer configuration = extensionDeclarer.withConstruct("configuration") .allowingTopLevelDefinition() .withStereotype(APP_CONFIG) .describedAs("Specifies defaults and general settings for the Mule instance."); addReconnectionStrategyParameter(configuration.getDeclaration()); configuration.onDefaultParameterGroup() .withOptionalParameter("defaultResponseTimeout") .ofType(typeLoader.load(String.class)) configuration.onDefaultParameterGroup() .withOptionalParameter("defaultTransactionTimeout") .ofType(typeLoader.load(String.class)) configuration.onDefaultParameterGroup() .withOptionalParameter("defaultErrorHandler-ref") .ofType(typeLoader.load(String.class)) configuration.onDefaultParameterGroup() .withOptionalParameter("shutdownTimeout") .ofType(typeLoader.load(Integer.class)) configuration.onDefaultParameterGroup() .withOptionalParameter("maxQueueTransactionFilesSize") .ofType(typeLoader.load(Integer.class)) configuration.onDefaultParameterGroup() .withOptionalParameter("defaultObjectSerializer-ref")
private void declareUntilSuccessful(ExtensionDeclarer extensionDeclarer, ClassTypeLoader typeLoader) { ConstructDeclarer untilSuccessful = extensionDeclarer.withConstruct("untilSuccessful") .describedAs("Attempts to route a message to the message processor it contains in an asynchronous manner. " + "Routing is considered successful if no exception has been raised and, optionally, if the response matches an expression"); untilSuccessful.withChain(); untilSuccessful.onDefaultParameterGroup() .withOptionalParameter("maxRetries") .ofType(typeLoader.load(Integer.class)) .defaultingTo(5) .withExpressionSupport(NOT_SUPPORTED) .describedAs("Specifies the maximum number of processing retries that will be performed."); untilSuccessful.onDefaultParameterGroup() .withOptionalParameter("millisBetweenRetries") .ofType(typeLoader.load(Integer.class)) .defaultingTo(60000) .withExpressionSupport(NOT_SUPPORTED) .describedAs("Specifies the minimum time interval between two process retries in milliseconds.\n" + " The actual time interval depends on the previous execution but should not exceed twice this number.\n" + " Default value is 60000 (one minute)"); }
private void declareRoutes(ConstructDeclarer router, List<ExtensionParameter> routes) { routes.forEach(route -> { NestedRouteDeclarer routeDeclarer = router .withRoute(route.getAlias()) .describedAs(route.getDescription()) .withMinOccurs(route.isRequired() ? 1 : 0); route.getType().getDeclaringClass() .ifPresent(clazz -> routeDeclarer.withModelProperty(new ImplementingTypeModelProperty(clazz))); final List<FieldElement> parameters = route.getType().getAnnotatedFields(Parameter.class); loader.getFieldParametersLoader().declare(routeDeclarer, parameters, new ParameterDeclarationContext(CONSTRUCT, router.getDeclaration())); }); }
private void declareForEach(ExtensionDeclarer extensionDeclarer, ClassTypeLoader typeLoader) { ConstructDeclarer forEach = extensionDeclarer.withConstruct("foreach") .describedAs("The foreach Processor allows iterating over a collection payload, or any collection obtained by an expression," + " generating a message for each element."); forEach.withChain(); forEach.onDefaultParameterGroup() .withOptionalParameter("collection") .ofType(typeLoader.load(new TypeToken<Iterable<Object>>() { }.getType())) .defaultingTo("#[payload]") .withExpressionSupport(REQUIRED) .describedAs("An expression to that returns a java collection, object array, map or DOM nodes."); forEach.onDefaultParameterGroup() .withOptionalParameter("batchSize") .ofType(typeLoader.load(Integer.class)) .withExpressionSupport(NOT_SUPPORTED) .describedAs("An expression to that returns a java collection, object array, map or DOM nodes."); forEach.onDefaultParameterGroup() .withOptionalParameter("rootMessageVariableName") .ofType(typeLoader.load(String.class)) .defaultingTo("rootMessage") .withExpressionSupport(NOT_SUPPORTED) .describedAs("Property name where the parent message is stored."); forEach.onDefaultParameterGroup() .withOptionalParameter("counterVariableName") .ofType(typeLoader.load(String.class)) .defaultingTo("counter") .withExpressionSupport(NOT_SUPPORTED) .describedAs("Property name used to store the number of message being iterated."); }
router.withModelProperty(new ExtensionOperationDescriptorModelProperty(routerMethod)); Optional<Method> method = routerMethod.getMethod(); Optional<Class<?>> declaringClass = enclosingType.getDeclaringClass(); .withModelProperty(new ImplementingMethodModelProperty(method.get())) .withModelProperty(new ComponentExecutorModelProperty(new ReflectiveOperationExecutorFactory<>(declaringClass.get(), method.get()))); new ParameterDeclarationContext(CONSTRUCT, router.getDeclaration()));
private void declareRoundRobin(ExtensionDeclarer extensionDeclarer) { ConstructDeclarer roundRobin = extensionDeclarer.withConstruct("roundRobin") .describedAs("Send each message received to the next message processor in the circular list of targets."); roundRobin.withRoute("route").withChain(); }