All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.camel.main.MainSupport Maven / Gradle / Ivy

There is a newer version: 4.8.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.camel.main;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.camel.CamelContext;
import org.apache.camel.ExtendedCamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.spi.EventNotifier;
import org.apache.camel.support.service.ServiceHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Class for main implementations to allow starting up a JVM with Camel embedded.
 */
public abstract class MainSupport extends BaseMainSupport {

    protected static final Logger LOG = LoggerFactory.getLogger(MainSupport.class);

    protected static final int UNINITIALIZED_EXIT_CODE = Integer.MIN_VALUE;
    protected static final int DEFAULT_EXIT_CODE = 0;

    protected final AtomicInteger exitCode = new AtomicInteger(UNINITIALIZED_EXIT_CODE);
    protected MainShutdownStrategy shutdownStrategy;

    protected volatile ProducerTemplate camelTemplate;

    private int durationMaxIdleSeconds;
    private int durationMaxMessages;
    private long durationMaxSeconds;
    private int durationHitExitCode;

    protected MainSupport(Class... configurationClasses) {
        this();
        configure().addConfigurationClass(configurationClasses);
    }

    protected MainSupport() {
        this.shutdownStrategy = new DefaultMainShutdownStrategy(this);
    }

    /**
     * Runs this process with the given arguments, and will wait until completed, or the JVM terminates.
     */
    public void run() throws Exception {
        if (shutdownStrategy.isRunAllowed()) {
            init();
            internalBeforeStart();
            // if we have an issue starting then propagate the exception to caller
            beforeStart();
            start();
            try {
                afterStart();
                waitUntilCompleted();
                internalBeforeStop();
                beforeStop();
                stop();
                afterStop();
            } catch (Exception e) {
                // however while running then just log errors
                LOG.error("Failed: {}", e, e);
            }
        }
    }

    /**
     * Callback to run custom logic before CamelContext is being started.
     * 

* It is recommended to use {@link org.apache.camel.main.MainListener} instead. */ protected void beforeStart() throws Exception { for (MainListener listener : listeners) { listener.beforeStart(this); } } /** * Callback to run custom logic after CamelContext has been started. *

* It is recommended to use {@link org.apache.camel.main.MainListener} instead. */ protected void afterStart() throws Exception { for (MainListener listener : listeners) { listener.afterStart(this); } } /** * Tasks to run before start() is called. */ protected void internalBeforeStart() { // used while waiting to be done durationMaxIdleSeconds = mainConfigurationProperties.getDurationMaxIdleSeconds(); durationMaxMessages = mainConfigurationProperties.getDurationMaxMessages(); durationMaxSeconds = mainConfigurationProperties.getDurationMaxSeconds(); durationHitExitCode = mainConfigurationProperties.getDurationHitExitCode(); // register main as bootstrap registerMainBootstrap(); } /** * Callback to run custom logic before CamelContext is being stopped. *

* It is recommended to use {@link org.apache.camel.main.MainListener} instead. */ protected void beforeStop() throws Exception { for (MainListener listener : listeners) { listener.beforeStop(this); } } /** * Callback to run custom logic after CamelContext has been stopped. *

* It is recommended to use {@link org.apache.camel.main.MainListener} instead. */ protected void afterStop() throws Exception { for (MainListener listener : listeners) { listener.afterStop(this); } } private void internalBeforeStop() { try { if (camelTemplate != null) { ServiceHelper.stopService(camelTemplate); camelTemplate = null; } } catch (Exception e) { LOG.debug("Error stopping camelTemplate due " + e.getMessage() + ". This exception is ignored.", e); } } /** * Marks this process as being completed. */ public void completed() { shutdownStrategy.shutdown(); exitCode.compareAndSet(UNINITIALIZED_EXIT_CODE, DEFAULT_EXIT_CODE); } /** * Gets the complete task which allows to trigger this on demand. */ public Runnable getCompleteTask() { return this::completed; } /** * Registers {@link MainBootstrapCloseable} with the CamelContext. */ protected void registerMainBootstrap() { CamelContext context = getCamelContext(); if (context != null) { context.adapt(ExtendedCamelContext.class).addBootstrap(new MainBootstrapCloseable(this)); } } @Deprecated public int getDuration() { return mainConfigurationProperties.getDurationMaxSeconds(); } /** * Sets the duration (in seconds) to run the application until it should be terminated. Defaults to -1. Any value <= * 0 will run forever. * * @deprecated use {@link #configure()} */ @Deprecated public void setDuration(int duration) { mainConfigurationProperties.setDurationMaxSeconds(duration); } @Deprecated public int getDurationIdle() { return mainConfigurationProperties.getDurationMaxIdleSeconds(); } /** * Sets the maximum idle duration (in seconds) when running the application, and if there has been no message * processed after being idle for more than this duration then the application should be terminated. Defaults to -1. * Any value <= 0 will run forever. * * @deprecated use {@link #configure()} */ @Deprecated public void setDurationIdle(int durationIdle) { mainConfigurationProperties.setDurationMaxIdleSeconds(durationIdle); } @Deprecated public int getDurationMaxMessages() { return mainConfigurationProperties.getDurationMaxMessages(); } /** * Sets the duration to run the application to process at most max messages until it should be terminated. Defaults * to -1. Any value <= 0 will run forever. * * @deprecated use {@link #configure()} */ @Deprecated public void setDurationMaxMessages(int durationMaxMessages) { mainConfigurationProperties.setDurationMaxMessages(durationMaxMessages); } /** * Sets the exit code for the application if duration was hit * * @deprecated use {@link #configure()} */ @Deprecated public void setDurationHitExitCode(int durationHitExitCode) { mainConfigurationProperties.setDurationHitExitCode(durationHitExitCode); } @Deprecated public int getDurationHitExitCode() { return mainConfigurationProperties.getDurationHitExitCode(); } public int getExitCode() { return exitCode.get(); } public boolean isTrace() { return mainConfigurationProperties.isTracing(); } public void enableTrace() { mainConfigurationProperties.setTracing(true); } public MainShutdownStrategy getShutdownStrategy() { return shutdownStrategy; } /** * Set the {@link MainShutdownStrategy} used to properly shut-down the main instance. By default a * {@link DefaultMainShutdownStrategy} will be used. * * @param shutdownStrategy the shutdown strategy */ public void setShutdownStrategy(MainShutdownStrategy shutdownStrategy) { this.shutdownStrategy = shutdownStrategy; } @Override protected void doStop() throws Exception { // call completed to properly stop as we count down the waiting latch completed(); } @Override protected void doStart() throws Exception { } @Override protected void configureLifecycle(CamelContext camelContext) throws Exception { if (mainConfigurationProperties.getDurationMaxMessages() > 0 || mainConfigurationProperties.getDurationMaxIdleSeconds() > 0) { // register lifecycle so we can trigger to shutdown the JVM when maximum number of messages has been processed EventNotifier notifier = new MainDurationEventNotifier( camelContext, mainConfigurationProperties.getDurationMaxMessages(), mainConfigurationProperties.getDurationMaxIdleSeconds(), shutdownStrategy, true); // register our event notifier ServiceHelper.startService(notifier); camelContext.getManagementStrategy().addEventNotifier(notifier); } // register lifecycle so we are notified in Camel is stopped from JMX or somewhere else camelContext.addLifecycleStrategy(new MainLifecycleStrategy(shutdownStrategy)); } protected void waitUntilCompleted() { while (shutdownStrategy.isRunAllowed()) { try { int idle = durationMaxIdleSeconds; int max = durationMaxMessages; long sec = durationMaxSeconds; int exit = durationHitExitCode; if (sec > 0) { LOG.info("Waiting until complete: Duration max {} seconds", sec); shutdownStrategy.await(sec, TimeUnit.SECONDS); exitCode.compareAndSet(UNINITIALIZED_EXIT_CODE, exit); shutdownStrategy.shutdown(); } else if (idle > 0 || max > 0) { if (idle > 0 && max > 0) { LOG.info("Waiting until complete: Duration idle {} seconds or max {} messages processed", idle, max); } else if (idle > 0) { LOG.info("Waiting until complete: Duration idle {} seconds", idle); } else { LOG.info("Waiting until complete: Duration max {} messages processed", max); } exitCode.compareAndSet(UNINITIALIZED_EXIT_CODE, exit); shutdownStrategy.await(); shutdownStrategy.shutdown(); } else { shutdownStrategy.await(); } } catch (InterruptedException e) { // okay something interrupted us so terminate shutdownStrategy.shutdown(); Thread.currentThread().interrupt(); } } } protected abstract ProducerTemplate findOrCreateCamelTemplate(); protected abstract CamelContext createCamelContext(); public ProducerTemplate getCamelTemplate() throws Exception { if (camelTemplate == null) { camelTemplate = findOrCreateCamelTemplate(); } return camelTemplate; } protected void initCamelContext() throws Exception { camelContext = createCamelContext(); if (camelContext == null) { throw new IllegalStateException("Created CamelContext is null"); } postProcessCamelContext(camelContext); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy