blob: 2586b8466171ba5d458d8c80d95786a6cb184985 [file] [log] [blame]
/*
* 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.k.main;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.k.Runtime;
import org.apache.camel.k.support.PropertiesSupport;
import org.apache.camel.main.BaseMainSupport;
import org.apache.camel.main.MainSupport;
import org.apache.camel.main.RoutesCollector;
import org.apache.camel.model.RoutesDefinition;
import org.apache.camel.model.rest.RestsDefinition;
import org.apache.camel.spi.HasId;
import org.apache.camel.util.function.ThrowingConsumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class ApplicationRuntime implements Runtime {
private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationRuntime.class);
private final MainSupport main;
private final DefaultCamelContext context;
private final Set<Runtime.Listener> listeners;
public ApplicationRuntime() {
this.listeners = new LinkedHashSet<>();
this.context = new DefaultCamelContext();
this.context.setName("camel-k");
this.main = new MainAdapter();
this.main.configure().setXmlRoutes("false");
this.main.configure().setXmlRests("false");
this.main.setRoutesCollector(new NoRoutesCollector());
this.main.addMainListener(new MainListenerAdapter());
}
@Override
public CamelContext getCamelContext() {
return this.context;
}
public void run() throws Exception {
this.main.run();
}
@Override
public void stop() throws Exception {
this.main.stop();
}
@Override
public void addRoutes(RoutesBuilder builder) {
this.main.addRoutesBuilder(builder);
}
@Override
public void addConfiguration(Object configuration) {
this.main.addConfiguration(configuration);
}
@Override
public void setInitialProperties(Properties properties) {
this.main.setInitialProperties(properties);
}
@Override
public void setProperties(Properties properties) {
this.main.setOverrideProperties(properties);
}
@Override
public void setPropertiesLocations(Collection<String> locations) {
this.main.setPropertyPlaceholderLocations(
locations.stream()
.map(location -> location.startsWith("file:") ? location : "file:" + location)
.distinct()
.sorted()
.collect(Collectors.joining(","))
);
}
public void addListeners(Iterable<Runtime.Listener> listeners) {
listeners.forEach(this::addListener);
}
public void addListener(Runtime.Listener listener) {
if (listener instanceof HasId) {
String id = ((HasId) listener).getId();
if (!id.endsWith(".")) {
id = id + ".";
}
PropertiesSupport.bindProperties(getCamelContext(), listener, id);
}
LOGGER.info("Add listener: {}", listener);
this.listeners.add(listener);
}
public void addListener(Phase phase, ThrowingConsumer<Runtime, Exception> consumer) {
addListener((p, runtime) -> {
if (p == phase) {
try {
consumer.accept(runtime);
return true;
} catch (Exception e) {
throw RuntimeCamelException.wrapRuntimeCamelException(e);
}
}
return false;
});
}
private final class MainListenerAdapter implements org.apache.camel.main.MainListener {
@Override
public void beforeStart(BaseMainSupport main) {
invokeListeners(Phase.Starting);
}
@Override
public void beforeConfigure(BaseMainSupport main) {
invokeListeners(Phase.ConfigureRoutes);
}
@Override
public void configure(CamelContext context) {
invokeListeners(Phase.ConfigureContext);
}
@Override
public void afterStart(BaseMainSupport main) {
invokeListeners(Phase.Started);
}
@Override
public void beforeStop(BaseMainSupport main) {
invokeListeners(Phase.Stopping);
}
@Override
public void afterStop(BaseMainSupport main) {
invokeListeners(Phase.Stopped);
}
private void invokeListeners(Phase phase) {
listeners.stream()
.sorted(Comparator.comparingInt(Listener::getOrder))
.forEach(l -> {
if (l.accept(phase, ApplicationRuntime.this)) {
LOGGER.info("Listener {} executed in phase {}", l, phase);
}
});
}
}
private final class MainAdapter extends MainSupport {
@Override
protected CamelContext createCamelContext() {
return ApplicationRuntime.this.context;
}
@Override
protected void doInit() throws Exception {
super.doInit();
initCamelContext();
}
@Override
protected void doStart() throws Exception {
super.doStart();
if (getCamelContext() != null) {
try {
// if we were veto started then mark as completed
getCamelContext().start();
} finally {
if (getCamelContext().isVetoStarted()) {
completed();
}
}
}
}
@Override
protected void doStop() throws Exception {
super.doStop();
if (getCamelContext() != null) {
getCamelContext().stop();
}
}
@Override
protected ProducerTemplate findOrCreateCamelTemplate() {
if (getCamelContext() != null) {
return getCamelContext().createProducerTemplate();
} else {
return null;
}
}
}
private static final class NoRoutesCollector implements RoutesCollector {
@Override
public List<RoutesBuilder> collectRoutesFromRegistry(CamelContext camelContext, String excludePattern, String includePattern) {
return Collections.emptyList();
}
@Override
public List<RoutesDefinition> collectXmlRoutesFromDirectory(CamelContext camelContext, String directory) throws Exception {
return Collections.emptyList();
}
@Override
public List<RestsDefinition> collectXmlRestsFromDirectory(CamelContext camelContext, String directory) throws Exception {
return Collections.emptyList();
}
}
}