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.SagaCompletionMode; 031import org.apache.camel.model.SagaDefinition; 032import org.apache.camel.model.SagaOptionDefinition; 033import org.apache.camel.model.SagaPropagation; 034import org.apache.camel.processor.saga.SagaProcessorBuilder; 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(ProcessorDefinition<?> definition) { 043 super((SagaDefinition)definition); 044 } 045 046 @Override 047 public Processor createProcessor(RouteContext routeContext) 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, Optional.ofNullable(definition.getTimeoutInMilliseconds())); 062 063 SagaPropagation propagation = definition.getPropagation(); 064 if (propagation == null) { 065 // default propagation mode 066 propagation = SagaPropagation.REQUIRED; 067 } 068 069 SagaCompletionMode completionMode = definition.getCompletionMode(); 070 if (completionMode == null) { 071 // default completion mode 072 completionMode = SagaCompletionMode.defaultCompletionMode(); 073 } 074 075 Processor childProcessor = this.createChildProcessor(routeContext, true); 076 CamelSagaService camelSagaService = findSagaService(routeContext.getCamelContext()); 077 078 camelSagaService.registerStep(step); 079 080 return new SagaProcessorBuilder().camelContext(routeContext.getCamelContext()).childProcessor(childProcessor).sagaService(camelSagaService).step(step) 081 .propagation(propagation(propagation)).completionMode(completionMode(completionMode)).build(); 082 } 083 084 private org.apache.camel.processor.saga.SagaCompletionMode completionMode(SagaCompletionMode completionMode) { 085 return org.apache.camel.processor.saga.SagaCompletionMode.valueOf(completionMode.name()); 086 } 087 088 private org.apache.camel.processor.saga.SagaPropagation propagation(SagaPropagation propagation) { 089 return org.apache.camel.processor.saga.SagaPropagation.valueOf(propagation.name()); 090 } 091 092 protected CamelSagaService findSagaService(CamelContext context) { 093 CamelSagaService sagaService = definition.getSagaService(); 094 if (sagaService != null) { 095 return sagaService; 096 } 097 098 sagaService = context.hasService(CamelSagaService.class); 099 if (sagaService != null) { 100 return sagaService; 101 } 102 103 sagaService = CamelContextHelper.findByType(context, CamelSagaService.class); 104 if (sagaService != null) { 105 return sagaService; 106 } 107 108 throw new RuntimeCamelException("Cannot find a CamelSagaService"); 109 } 110 111}