You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2021/12/30 12:04:25 UTC
[camel] 09/30: CAMEL-17384: Developer Console SPI
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch console
in repository https://gitbox.apache.org/repos/asf/camel.git
commit efa35d52edbf10c0e86ba8c0a5c5f611347ed143
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Dec 27 15:07:43 2021 +0100
CAMEL-17384: Developer Console SPI
---
.../apache/camel/console/DevConsoleRegistry.java | 113 ++++++++++++++
.../impl/console/DefaultDevConsoleRegistry.java | 163 +++++++++++++++++++++
2 files changed, 276 insertions(+)
diff --git a/core/camel-api/src/main/java/org/apache/camel/console/DevConsoleRegistry.java b/core/camel-api/src/main/java/org/apache/camel/console/DevConsoleRegistry.java
new file mode 100644
index 0000000..03ecf79
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/console/DevConsoleRegistry.java
@@ -0,0 +1,113 @@
+/*
+ * 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.console;
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.StaticService;
+import org.apache.camel.spi.IdAware;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * A registry for dev console.
+ */
+public interface DevConsoleRegistry extends CamelContextAware, StaticService, IdAware {
+
+ /**
+ * Service factory name.
+ */
+ String NAME = "default-registry";
+
+ /**
+ * Service factory key.
+ */
+ String FACTORY = "console/" + NAME;
+
+ /**
+ * Whether dev console is enabled globally
+ */
+ boolean isEnabled();
+
+ /**
+ * Whether dev console is enabled globally
+ */
+ void setEnabled(boolean enabled);
+
+ /**
+ * Resolves {@link DevConsole by id.
+ *
+ * Will first lookup in this {@link DevConsoleRegistry} and then {@link org.apache.camel.spi.Registry}, and lastly
+ * do classpath scanning via {@link org.apache.camel.spi.annotations.ServiceFactory}.
+ *
+ * @return either {@link DevConsole}, or <tt>null</tt> if none found.
+ */
+ Object resolveById(String id);
+
+ /**
+ * Registers a {@link DevConsole}.
+ */
+ boolean register(DevConsole console);
+
+ /**
+ * Unregisters a {@link DevConsole}.
+ */
+ boolean unregister(DevConsole console);
+
+ /**
+ * A collection of dev console IDs.
+ */
+ default Collection<String> getConsoleIDs() {
+ return stream()
+ .map(DevConsole::getId)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Returns the dev console identified by the given <code>id</code> if available.
+ */
+ default Optional<DevConsole> getConsole(String id) {
+ return stream()
+ .filter(r -> ObjectHelper.equal(r.getId(), id))
+ .findFirst();
+ }
+
+ /**
+ * Returns an optional {@link DevConsoleRegistry}, by default no registry is present, and it must be explicit
+ * activated. Components can register/unregister dev consoles in response to life-cycle events (i.e. start/stop).
+ *
+ * This registry is not used by the camel context, but it is up to the implementation to properly use it.
+ */
+ static DevConsoleRegistry get(CamelContext context) {
+ return context.getExtension(DevConsoleRegistry.class);
+ }
+
+ /**
+ * Returns a sequential {@code Stream} with the known {@link DevConsole} as its source.
+ */
+ Stream<DevConsole> stream();
+
+ /**
+ * Loads custom dev consoles by scanning classpath.
+ */
+ void loadDevConsoles();
+
+}
diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsoleRegistry.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsoleRegistry.java
new file mode 100644
index 0000000..2fde33f
--- /dev/null
+++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsoleRegistry.java
@@ -0,0 +1,163 @@
+/*
+ * 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.impl.console;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.DeferredContextBinding;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.console.DevConsole;
+import org.apache.camel.console.DevConsoleRegistry;
+import org.apache.camel.console.DevConsoleResolver;
+import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.util.StopWatch;
+import org.apache.camel.util.TimeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.stream.Stream;
+
+/**
+ * Default {@link org.apache.camel.console.DevConsoleRegistry}.
+ */
+@org.apache.camel.spi.annotations.DevConsole(DevConsoleRegistry.NAME)
+@DeferredContextBinding
+public class DefaultDevConsoleRegistry extends ServiceSupport implements DevConsoleRegistry {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultDevConsoleRegistry.class);
+
+ private String id = "camel-console";
+ private CamelContext camelContext;
+ private final Set<DevConsole> consoles;
+ private boolean enabled = true;
+ private volatile boolean loadDevConsolesDone;
+
+ public DefaultDevConsoleRegistry() {
+ this(null);
+ }
+
+ public DefaultDevConsoleRegistry(CamelContext camelContext) {
+ this.consoles = new CopyOnWriteArraySet<>();
+ setCamelContext(camelContext);
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ @Override
+ public CamelContext getCamelContext() {
+ return camelContext;
+ }
+
+ @Override
+ public void setCamelContext(CamelContext camelContext) {
+ this.camelContext = camelContext;
+ }
+
+ @Override
+ protected void doInit() throws Exception {
+ super.doInit();
+
+ for (DevConsole console : consoles) {
+ CamelContextAware.trySetCamelContext(console, camelContext);
+ }
+ }
+
+ @Override
+ public DevConsole resolveById(String id) {
+ DevConsole answer = consoles.stream().filter(h -> h.getId().equals(id)).findFirst()
+ .orElse(camelContext.getRegistry().findByTypeWithName(DevConsole.class).get(id));
+ if (answer == null) {
+ DevConsoleResolver resolver = camelContext.adapt(ExtendedCamelContext.class).getDevConsoleResolver();
+ answer = resolver.resolveDevConsole(id);
+ }
+
+ return answer;
+ }
+
+ @Override
+ public boolean register(DevConsole console) {
+ boolean result;
+ // do we have this already
+ if (getConsole(console.getId()).isPresent()) {
+ return false;
+ }
+ result = consoles.add(console);
+ if (result) {
+ CamelContextAware.trySetCamelContext(console, camelContext);
+ LOG.debug("DevConsole with id {} successfully registered", console.getId());
+ }
+ return result;
+ }
+
+ @Override
+ public boolean unregister(DevConsole console) {
+ boolean result;
+
+ result = consoles.remove(console);
+ if (result) {
+ LOG.debug("DevConsole with id {} successfully un-registered", console.getId());
+ }
+ return result;
+ }
+
+ @Override
+ public Stream<DevConsole> stream() {
+ if (enabled) {
+ return consoles.stream();
+ }
+ return Stream.empty();
+ }
+
+ @Override
+ public void loadDevConsoles() {
+ StopWatch watch = new StopWatch();
+
+ if (!loadDevConsolesDone) {
+ loadDevConsolesDone = true;
+
+ DefaultDevConsolesLoader loader = new DefaultDevConsolesLoader(camelContext);
+ Collection<DevConsole> col = loader.loadDevConsoles();
+
+ // report how many health checks we have loaded
+ if (col.size() > 0) {
+ String time = TimeUtils.printDuration(watch.taken());
+ LOG.info("Dev consoles (scanned: {}) loaded in {}", col.size(), time);
+ }
+ }
+ }
+}