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.impl.saga;
018
019import java.util.Map;
020import java.util.concurrent.CompletableFuture;
021import java.util.concurrent.ConcurrentHashMap;
022import java.util.concurrent.ScheduledExecutorService;
023
024import org.apache.camel.CamelContext;
025import org.apache.camel.saga.CamelSagaCoordinator;
026import org.apache.camel.saga.CamelSagaService;
027import org.apache.camel.saga.CamelSagaStep;
028import org.apache.camel.support.ServiceSupport;
029import org.apache.camel.util.ObjectHelper;
030
031/**
032 * A in-memory implementation of a saga service.
033 */
034public class InMemorySagaService extends ServiceSupport implements CamelSagaService {
035
036    public static final int DEFAULT_MAX_RETRY_ATTEMPTS = 5;
037
038    public static final long DEFAULT_RETRY_DELAY_IN_MILLISECONDS = 5000;
039
040    private CamelContext camelContext;
041
042    private Map<String, CamelSagaCoordinator> coordinators = new ConcurrentHashMap<>();
043
044    private ScheduledExecutorService executorService;
045
046    private int maxRetryAttempts = DEFAULT_MAX_RETRY_ATTEMPTS;
047
048    private long retryDelayInMilliseconds = DEFAULT_RETRY_DELAY_IN_MILLISECONDS;
049
050    @Override
051    public CompletableFuture<CamelSagaCoordinator> newSaga() {
052        ObjectHelper.notNull(camelContext, "camelContext");
053
054        String uuid = camelContext.getUuidGenerator().generateUuid();
055        CamelSagaCoordinator coordinator = new InMemorySagaCoordinator(camelContext, this, uuid);
056        coordinators.put(uuid, coordinator);
057
058        return CompletableFuture.completedFuture(coordinator);
059    }
060
061    @Override
062    public CompletableFuture<CamelSagaCoordinator> getSaga(String id) {
063        return CompletableFuture.completedFuture(coordinators.get(id));
064    }
065
066    @Override
067    public void registerStep(CamelSagaStep step) {
068        // do nothing
069    }
070
071    @Override
072    protected void doStart() throws Exception {
073        if (this.executorService == null) {
074            this.executorService = camelContext.getExecutorServiceManager()
075                    .newDefaultScheduledThreadPool(this, "saga");
076        }
077    }
078
079    @Override
080    protected void doStop() throws Exception {
081        if (this.executorService != null) {
082            camelContext.getExecutorServiceManager().shutdownGraceful(this.executorService);
083            this.executorService = null;
084        }
085    }
086
087    public ScheduledExecutorService getExecutorService() {
088        return executorService;
089    }
090
091    @Override
092    public void setCamelContext(CamelContext camelContext) {
093        this.camelContext = camelContext;
094    }
095
096    @Override
097    public CamelContext getCamelContext() {
098        return camelContext;
099    }
100
101    public int getMaxRetryAttempts() {
102        return maxRetryAttempts;
103    }
104
105    public void setMaxRetryAttempts(int maxRetryAttempts) {
106        this.maxRetryAttempts = maxRetryAttempts;
107    }
108
109    public long getRetryDelayInMilliseconds() {
110        return retryDelayInMilliseconds;
111    }
112
113    public void setRetryDelayInMilliseconds(long retryDelayInMilliseconds) {
114        this.retryDelayInMilliseconds = retryDelayInMilliseconds;
115    }
116
117}