001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.reifier; 018 019import java.util.Map; 020import java.util.Optional; 021import java.util.TreeMap; 022 023import org.apache.camel.CamelContext; 024import org.apache.camel.Endpoint; 025import org.apache.camel.Expression; 026import org.apache.camel.Processor; 027import org.apache.camel.RuntimeCamelException; 028import org.apache.camel.model.ProcessorDefinition; 029import org.apache.camel.model.SagaActionUriDefinition; 030import org.apache.camel.model.SagaDefinition; 031import org.apache.camel.model.SagaOptionDefinition; 032import org.apache.camel.processor.saga.SagaCompletionMode; 033import org.apache.camel.processor.saga.SagaProcessorBuilder; 034import org.apache.camel.processor.saga.SagaPropagation; 035import org.apache.camel.saga.CamelSagaService; 036import org.apache.camel.saga.CamelSagaStep; 037import org.apache.camel.spi.RouteContext; 038import org.apache.camel.support.CamelContextHelper; 039 040public class SagaReifier extends ProcessorReifier<SagaDefinition> { 041 042 public SagaReifier(RouteContext routeContext, ProcessorDefinition<?> definition) { 043 super(routeContext, (SagaDefinition)definition); 044 } 045 046 @Override 047 public Processor createProcessor() throws Exception { 048 Optional<Endpoint> compensationEndpoint = Optional.ofNullable(definition.getCompensation()).map(SagaActionUriDefinition::getUri).map(routeContext::resolveEndpoint); 049 050 Optional<Endpoint> completionEndpoint = Optional.ofNullable(definition.getCompletion()).map(SagaActionUriDefinition::getUri).map(routeContext::resolveEndpoint); 051 052 Map<String, Expression> optionsMap = new TreeMap<>(); 053 if (definition.getOptions() != null) { 054 for (SagaOptionDefinition optionDef : definition.getOptions()) { 055 String optionName = optionDef.getOptionName(); 056 Expression expr = optionDef.getExpression(); 057 optionsMap.put(optionName, expr); 058 } 059 } 060 061 CamelSagaStep step = new CamelSagaStep(compensationEndpoint, completionEndpoint, optionsMap, 062 Optional.ofNullable(parseLong(definition.getTimeoutInMilliseconds()))); 063 064 SagaPropagation propagation = parse(SagaPropagation.class, definition.getPropagation()); 065 if (propagation == null) { 066 // default propagation mode 067 propagation = SagaPropagation.REQUIRED; 068 } 069 070 SagaCompletionMode completionMode = parse(SagaCompletionMode.class, definition.getCompletionMode()); 071 if (completionMode == null) { 072 // default completion mode 073 completionMode = SagaCompletionMode.defaultCompletionMode(); 074 } 075 076 Processor childProcessor = this.createChildProcessor(true); 077 CamelSagaService camelSagaService = findSagaService(camelContext); 078 079 camelSagaService.registerStep(step); 080 081 return new SagaProcessorBuilder().camelContext(camelContext).childProcessor(childProcessor) 082 .sagaService(camelSagaService).step(step) 083 .propagation(propagation).completionMode(completionMode).build(); 084 } 085 086 protected CamelSagaService findSagaService(CamelContext context) { 087 CamelSagaService sagaService = definition.getSagaService(); 088 if (sagaService != null) { 089 return sagaService; 090 } 091 092 if (definition.getSagaServiceRef() != null) { 093 return CamelContextHelper.mandatoryLookup(context, parseString(definition.getSagaServiceRef()), CamelSagaService.class); 094 } 095 096 sagaService = context.hasService(CamelSagaService.class); 097 if (sagaService != null) { 098 return sagaService; 099 } 100 101 sagaService = CamelContextHelper.findByType(context, CamelSagaService.class); 102 if (sagaService != null) { 103 return sagaService; 104 } 105 106 throw new RuntimeCamelException("Cannot find a CamelSagaService"); 107 } 108 109}