http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulClientConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulClientConfiguration.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulClientConfiguration.java new file mode 100644 index 0000000..fc92fc6 --- /dev/null +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulClientConfiguration.java @@ -0,0 +1,342 @@ +/** + * 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.component.consul; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.orbitz.consul.Consul; +import com.orbitz.consul.option.ConsistencyMode; +import org.apache.camel.CamelContext; +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.spi.UriParam; +import org.apache.camel.spi.UriParams; +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.jsse.SSLContextParameters; + +@UriParams +public class ConsulClientConfiguration implements Cloneable { + @UriParam + private String url; + @UriParam(label = "advanced") + private String datacenter; + @UriParam(label = "advanced") + private String nearNode; + @UriParam(label = "advanced") + private List<String> nodeMeta; + @UriParam(label = "advanced", defaultValue = "DEFAULT", enums = "DEFAULT,STALE,CONSISTENT") + private ConsistencyMode consistencyMode = ConsistencyMode.DEFAULT; + @UriParam(javaType = "java.lang.String") + private Set<String> tags; + + @UriParam(label = "security") + private SSLContextParameters sslContextParameters; + @UriParam(label = "security", secret = true) + private String aclToken; + @UriParam(label = "security", secret = true) + private String userName; + @UriParam(label = "security", secret = true) + private String password; + + @UriParam + private Long connectTimeoutMillis; + @UriParam + private Long readTimeoutMillis; + @UriParam + private Long writeTimeoutMillis; + @UriParam(defaultValue = "true") + private boolean pingInstance = true; + + @UriParam(label = "consumer,watch", defaultValue = "10") + private Integer blockSeconds = 10; + @UriParam(label = "consumer,watch", defaultValue = "0") + private long firstIndex; + @UriParam(label = "consumer,watch", defaultValue = "false") + private boolean recursive; + + public ConsulClientConfiguration() { + } + + public String getUrl() { + return url; + } + + /** + * The Consul agent URL + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * @deprecated replaced by {@link #getDatacenter()} ()} + */ + @Deprecated + public String getDc() { + return datacenter; + } + + /** + * The data center + * + * @deprecated replaced by {@link #setDatacenter(String)} ()} + */ + @Deprecated + public void setDc(String dc) { + this.datacenter = dc; + } + + public String getDatacenter() { + return datacenter; + } + + /** + * The data center + */ + public void setDatacenter(String datacenter) { + this.datacenter = datacenter; + } + + public String getNearNode() { + return nearNode; + } + + /** + * The near node to use for queries. + */ + public void setNearNode(String nearNode) { + this.nearNode = nearNode; + } + + public List<String> getNodeMeta() { + return nodeMeta; + } + + /** + * The note meta-data to use for queries. + */ + public void setNodeMeta(List<String> nodeMeta) { + this.nodeMeta = nodeMeta; + } + + public ConsistencyMode getConsistencyMode() { + return consistencyMode; + } + + /** + * The consistencyMode used for queries, default ConsistencyMode.DEFAULT + */ + public void setConsistencyMode(ConsistencyMode consistencyMode) { + this.consistencyMode = consistencyMode; + } + + public Set<String> getTags() { + return tags; + } + + /** + * Set tags. You can separate multiple tags by comma. + */ + public void setTags(Set<String> tags) { + this.tags = tags; + } + + /** + * Set tags. You can separate multiple tags by comma. + */ + public void setTags(String tagsAsString) { + this.tags = new HashSet<>(); + Collections.addAll(tags, tagsAsString.split(",")); + } + + public SSLContextParameters getSslContextParameters() { + return sslContextParameters; + } + + /** + * SSL configuration using an org.apache.camel.util.jsse.SSLContextParameters + * instance. + */ + public void setSslContextParameters(SSLContextParameters sslContextParameters) { + this.sslContextParameters = sslContextParameters; + } + + public String getAclToken() { + return aclToken; + } + + /** + * Sets the ACL token to be used with Consul + */ + public void setAclToken(String aclToken) { + this.aclToken = aclToken; + } + + public String getUserName() { + return userName; + } + + /** + * Sets the username to be used for basic authentication + */ + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + /** + * Sets the password to be used for basic authentication + */ + public void setPassword(String password) { + this.password = password; + } + + public boolean requiresBasicAuthentication() { + return ObjectHelper.isNotEmpty(userName) && ObjectHelper.isNotEmpty(password); + } + + public Long getConnectTimeoutMillis() { + return connectTimeoutMillis; + } + + /** + * Connect timeout for OkHttpClient + */ + public void setConnectTimeoutMillis(Long connectTimeoutMillis) { + this.connectTimeoutMillis = connectTimeoutMillis; + } + + public Long getReadTimeoutMillis() { + return readTimeoutMillis; + } + + /** + * Read timeout for OkHttpClient + */ + public void setReadTimeoutMillis(Long readTimeoutMillis) { + this.readTimeoutMillis = readTimeoutMillis; + } + + public Long getWriteTimeoutMillis() { + return writeTimeoutMillis; + } + + /** + * Write timeout for OkHttpClient + */ + public void setWriteTimeoutMillis(Long writeTimeoutMillis) { + this.writeTimeoutMillis = writeTimeoutMillis; + } + + public boolean isPingInstance() { + return pingInstance; + } + + /** + * Configure if the AgentClient should attempt a ping before returning the Consul instance + */ + public void setPingInstance(boolean pingInstance) { + this.pingInstance = pingInstance; + } + + public Integer getBlockSeconds() { + return blockSeconds; + } + + /** + * The second to wait for a watch event, default 10 seconds + */ + public void setBlockSeconds(Integer blockSeconds) { + this.blockSeconds = blockSeconds; + } + + public long getFirstIndex() { + return firstIndex; + } + + /** + * The first index for watch for, default 0 + */ + public void setFirstIndex(long firstIndex) { + this.firstIndex = firstIndex; + } + + public boolean isRecursive() { + return recursive; + } + + /** + * Recursively watch, default false + */ + public void setRecursive(boolean recursive) { + this.recursive = recursive; + } + + // **************************************** + // Create a client + // **************************************** + + public Consul createConsulClient() throws Exception { + return createConsulClient(null); + } + + public Consul createConsulClient(CamelContext camelContext) throws Exception { + Consul.Builder builder = Consul.builder(); + builder.withPing(pingInstance); + + if (ObjectHelper.isNotEmpty(url)) { + builder.withUrl(url); + } + if (ObjectHelper.isNotEmpty(camelContext) && ObjectHelper.isNotEmpty(sslContextParameters)) { + builder.withSslContext(sslContextParameters.createSSLContext(camelContext)); + } + if (ObjectHelper.isNotEmpty(aclToken)) { + builder.withAclToken(aclToken); + } + if (requiresBasicAuthentication()) { + builder.withBasicAuth(userName, password); + } + if (ObjectHelper.isNotEmpty(connectTimeoutMillis)) { + builder.withConnectTimeoutMillis(connectTimeoutMillis); + } + if (ObjectHelper.isNotEmpty(readTimeoutMillis)) { + builder.withReadTimeoutMillis(readTimeoutMillis); + } + if (ObjectHelper.isNotEmpty(writeTimeoutMillis)) { + builder.withWriteTimeoutMillis(writeTimeoutMillis); + } + + return builder.build(); + } + + // **************************************** + // Copy + // **************************************** + + public ConsulClientConfiguration copy() { + try { + return (ConsulClientConfiguration)super.clone(); + } catch (CloneNotSupportedException e) { + throw new RuntimeCamelException(e); + } + } +}
http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulComponent.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulComponent.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulComponent.java index f248527..11566f6 100644 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulComponent.java +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulComponent.java @@ -160,7 +160,6 @@ public class ConsulComponent extends DefaultComponent implements SSLContextParam @Override protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { ConsulConfiguration configuration = Optional.ofNullable(this.configuration).orElseGet(ConsulConfiguration::new).copy(); - configuration.setCamelContext(getCamelContext()); // using global ssl context parameters if set if (configuration.getSslContextParameters() == null) { http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulConfiguration.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulConfiguration.java index ceb1f20..80e665b 100644 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulConfiguration.java +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulConfiguration.java @@ -16,55 +16,12 @@ */ package org.apache.camel.component.consul; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import com.orbitz.consul.Consul; -import com.orbitz.consul.option.ConsistencyMode; - -import org.apache.camel.CamelContext; -import org.apache.camel.CamelContextAware; import org.apache.camel.RuntimeCamelException; import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriParams; -import org.apache.camel.util.ObjectHelper; -import org.apache.camel.util.jsse.SSLContextParameters; @UriParams -public class ConsulConfiguration implements CamelContextAware, Cloneable { - @UriParam - private String url; - @UriParam(label = "advanced") - private String datacenter; - @UriParam(label = "advanced") - private String nearNode; - @UriParam(label = "advanced") - private List<String> nodeMeta; - @UriParam(label = "advanced", defaultValue = "DEFAULT", enums = "DEFAULT,STALE,CONSISTENT") - private ConsistencyMode consistencyMode = ConsistencyMode.DEFAULT; - @UriParam(javaType = "java.lang.String") - private Set<String> tags; - - @UriParam(label = "security") - private SSLContextParameters sslContextParameters; - @UriParam(label = "security", secret = true) - private String aclToken; - @UriParam(label = "security", secret = true) - private String userName; - @UriParam(label = "security", secret = true) - private String password; - - @UriParam - private Long connectTimeoutMillis; - @UriParam - private Long readTimeoutMillis; - @UriParam - private Long writeTimeoutMillis; - @UriParam(defaultValue = "true") - private boolean pingInstance = true; - +public class ConsulConfiguration extends ConsulClientConfiguration { @UriParam private String key; @UriParam(label = "producer") @@ -72,222 +29,13 @@ public class ConsulConfiguration implements CamelContextAware, Cloneable { @UriParam(label = "producer", defaultValue = "false") private boolean valueAsString; - @UriParam(label = "consumer,watch", defaultValue = "10") - private Integer blockSeconds = 10; - @UriParam(label = "consumer,watch", defaultValue = "0") - private long firstIndex; - @UriParam(label = "consumer,watch", defaultValue = "false") - private boolean recursive; - - private CamelContext context; - public ConsulConfiguration() { - this.context = null; - } - - public ConsulConfiguration(CamelContext context) { - this.context = context; - } - - @Override - public void setCamelContext(CamelContext context) { - this.context = context; - } - - @Override - public CamelContext getCamelContext() { - return context; - } - - public String getUrl() { - return url; - } - - /** - * The Consul agent URL - */ - public void setUrl(String url) { - this.url = url; - } - - /** - * @deprecated replaced by {@link #getDatacenter()} ()} - */ - @Deprecated - public String getDc() { - return datacenter; - } - - /** - * The data center - * - * @deprecated replaced by {@link #setDatacenter(String)} ()} - */ - @Deprecated - public void setDc(String dc) { - this.datacenter = dc; - } - - public String getDatacenter() { - return datacenter; - } - - /** - * The data center - */ - public void setDatacenter(String datacenter) { - this.datacenter = datacenter; - } - - public String getNearNode() { - return nearNode; - } - - /** - * The near node to use for queries. - */ - public void setNearNode(String nearNode) { - this.nearNode = nearNode; - } - - public List<String> getNodeMeta() { - return nodeMeta; - } - - /** - * The note meta-data to use for queries. - */ - public void setNodeMeta(List<String> nodeMeta) { - this.nodeMeta = nodeMeta; - } - - public ConsistencyMode getConsistencyMode() { - return consistencyMode; - } - - /** - * The consistencyMode used for queries, default ConsistencyMode.DEFAULT - */ - public void setConsistencyMode(ConsistencyMode consistencyMode) { - this.consistencyMode = consistencyMode; - } - - public Set<String> getTags() { - return tags; - } - - /** - * Set tags. You can separate multiple tags by comma. - */ - public void setTags(Set<String> tags) { - this.tags = tags; - } - - /** - * Set tags. You can separate multiple tags by comma. - */ - public void setTags(String tagsAsString) { - this.tags = new HashSet<>(); - Collections.addAll(tags, tagsAsString.split(",")); - } - - public SSLContextParameters getSslContextParameters() { - return sslContextParameters; - } - - /** - * SSL configuration using an org.apache.camel.util.jsse.SSLContextParameters - * instance. - */ - public void setSslContextParameters(SSLContextParameters sslContextParameters) { - this.sslContextParameters = sslContextParameters; - } - - public String getAclToken() { - return aclToken; - } - - /** - * Sets the ACL token to be used with Consul - */ - public void setAclToken(String aclToken) { - this.aclToken = aclToken; } public String getAction() { return action; } - public String getUserName() { - return userName; - } - - /** - * Sets the username to be used for basic authentication - */ - public void setUserName(String userName) { - this.userName = userName; - } - - public String getPassword() { - return password; - } - - /** - * Sets the password to be used for basic authentication - */ - public void setPassword(String password) { - this.password = password; - } - - public boolean requiresBasicAuthentication() { - return ObjectHelper.isNotEmpty(userName) && ObjectHelper.isNotEmpty(password); - } - - public Long getConnectTimeoutMillis() { - return connectTimeoutMillis; - } - - /** - * Connect timeout for OkHttpClient - */ - public void setConnectTimeoutMillis(Long connectTimeoutMillis) { - this.connectTimeoutMillis = connectTimeoutMillis; - } - - public Long getReadTimeoutMillis() { - return readTimeoutMillis; - } - - /** - * Read timeout for OkHttpClient - */ - public void setReadTimeoutMillis(Long readTimeoutMillis) { - this.readTimeoutMillis = readTimeoutMillis; - } - - public Long getWriteTimeoutMillis() { - return writeTimeoutMillis; - } - - /** - * Write timeout for OkHttpClient - */ - public void setWriteTimeoutMillis(Long writeTimeoutMillis) { - this.writeTimeoutMillis = writeTimeoutMillis; - } - - public boolean isPingInstance() { - return pingInstance; - } - - /** - * Configure if the AgentClient should attempt a ping before returning the Consul instance - */ - public void setPingInstance(boolean pingInstance) { - this.pingInstance = pingInstance; - } - /** * The default action. Can be overridden by CamelConsulAction */ @@ -318,68 +66,11 @@ public class ConsulConfiguration implements CamelContextAware, Cloneable { this.key = key; } - public Integer getBlockSeconds() { - return blockSeconds; - } - - /** - * The second to wait for a watch event, default 10 seconds - */ - public void setBlockSeconds(Integer blockSeconds) { - this.blockSeconds = blockSeconds; - } - - public long getFirstIndex() { - return firstIndex; - } - - /** - * The first index for watch for, default 0 - */ - public void setFirstIndex(long firstIndex) { - this.firstIndex = firstIndex; - } - - public boolean isRecursive() { - return recursive; - } - - /** - * Recursively watch, default false - */ - public void setRecursive(boolean recursive) { - this.recursive = recursive; - } - - public Consul createConsulClient() throws Exception { - Consul.Builder builder = Consul.builder(); - builder.withPing(pingInstance); - - if (ObjectHelper.isNotEmpty(url)) { - builder.withUrl(url); - } - if (ObjectHelper.isNotEmpty(context) && ObjectHelper.isNotEmpty(sslContextParameters)) { - builder.withSslContext(sslContextParameters.createSSLContext(context)); - } - if (ObjectHelper.isNotEmpty(aclToken)) { - builder.withAclToken(aclToken); - } - if (requiresBasicAuthentication()) { - builder.withBasicAuth(userName, password); - } - if (ObjectHelper.isNotEmpty(connectTimeoutMillis)) { - builder.withConnectTimeoutMillis(connectTimeoutMillis); - } - if (ObjectHelper.isNotEmpty(readTimeoutMillis)) { - builder.withReadTimeoutMillis(readTimeoutMillis); - } - if (ObjectHelper.isNotEmpty(writeTimeoutMillis)) { - builder.withWriteTimeoutMillis(writeTimeoutMillis); - } - - return builder.build(); - } + // **************************************** + // Copy + // **************************************** + @Override public ConsulConfiguration copy() { try { return (ConsulConfiguration)super.clone(); http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulEndpoint.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulEndpoint.java index c9eaccf..c8d1c24 100644 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulEndpoint.java +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulEndpoint.java @@ -100,7 +100,7 @@ public class ConsulEndpoint extends DefaultEndpoint { public synchronized Consul getConsul() throws Exception { if (consul == null) { - consul = configuration.createConsulClient(); + consul = configuration.createConsulClient(getCamelContext()); } return consul; http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscovery.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscovery.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscovery.java index 8cfa854..e7cfd5f 100644 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscovery.java +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscovery.java @@ -27,7 +27,6 @@ import com.orbitz.consul.model.catalog.CatalogService; import com.orbitz.consul.model.health.ServiceHealth; import com.orbitz.consul.option.ImmutableQueryOptions; import com.orbitz.consul.option.QueryOptions; -import org.apache.camel.RuntimeCamelException; import org.apache.camel.cloud.ServiceDefinition; import org.apache.camel.component.consul.ConsulConfiguration; import org.apache.camel.impl.cloud.DefaultServiceDefinition; @@ -41,7 +40,10 @@ public final class ConsulServiceDiscovery extends DefaultServiceDiscovery { private final QueryOptions queryOptions; public ConsulServiceDiscovery(ConsulConfiguration configuration) throws Exception { - this.client = Suppliers.memorize(configuration::createConsulClient, this::rethrowAsRuntimeCamelException); + this.client = Suppliers.memorize( + () -> configuration.createConsulClient(getCamelContext()), + e -> ObjectHelper.wrapRuntimeCamelException(e) + ); ImmutableQueryOptions.Builder builder = ImmutableQueryOptions.builder(); ObjectHelper.ifNotEmpty(configuration.getDatacenter(), builder::datacenter); @@ -68,10 +70,6 @@ public final class ConsulServiceDiscovery extends DefaultServiceDiscovery { // Helpers // ************************* - private void rethrowAsRuntimeCamelException(Exception e) { - throw new RuntimeCamelException(e); - } - private boolean isHealthy(ServiceHealth serviceHealth) { return serviceHealth.getChecks().stream().allMatch( check -> ObjectHelper.equal(check.getStatus(), "passing", true) http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ha/ConsulClusterConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ha/ConsulClusterConfiguration.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ha/ConsulClusterConfiguration.java index f992487..535eec6 100644 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ha/ConsulClusterConfiguration.java +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ha/ConsulClusterConfiguration.java @@ -17,9 +17,9 @@ package org.apache.camel.component.consul.ha; import org.apache.camel.RuntimeCamelException; -import org.apache.camel.component.consul.ConsulConfiguration; +import org.apache.camel.component.consul.ConsulClientConfiguration; -public class ConsulClusterConfiguration extends ConsulConfiguration { +public class ConsulClusterConfiguration extends ConsulClientConfiguration { private int sessionTtl = 60; private int sessionLockDelay = 5; private int sessionRefreshInterval = 5; http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ha/ConsulClusterView.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ha/ConsulClusterView.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ha/ConsulClusterView.java index 1956d9e..4ec8be2 100644 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ha/ConsulClusterView.java +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ha/ConsulClusterView.java @@ -33,7 +33,6 @@ import com.orbitz.consul.model.kv.Value; import com.orbitz.consul.model.session.ImmutableSession; import com.orbitz.consul.model.session.SessionInfo; import com.orbitz.consul.option.QueryOptions; -import org.apache.camel.CamelContext; import org.apache.camel.ha.CamelClusterMember; import org.apache.camel.impl.ha.AbstractCamelClusterView; import org.slf4j.Logger; @@ -64,13 +63,6 @@ final class ConsulClusterView extends AbstractCamelClusterView { } @Override - public void setCamelContext(CamelContext camelContext) { - super.setCamelContext(camelContext); - - this.configuration.setCamelContext(camelContext); - } - - @Override public Optional<CamelClusterMember> getMaster() { if (keyValueClient == null) { return Optional.empty(); @@ -103,7 +95,7 @@ final class ConsulClusterView extends AbstractCamelClusterView { @Override protected void doStart() throws Exception { if (sessionId == null) { - client = configuration.createConsulClient(); + client = configuration.createConsulClient(getCamelContext()); sessionClient = client.sessionClient(); keyValueClient = client.keyValueClient(); http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-consul/src/main/java/org/apache/camel/component/consul/health/ConsulHealthCheckRepository.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/health/ConsulHealthCheckRepository.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/health/ConsulHealthCheckRepository.java new file mode 100644 index 0000000..e7ca18a --- /dev/null +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/health/ConsulHealthCheckRepository.java @@ -0,0 +1,230 @@ +/** + * 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.component.consul.health; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import com.orbitz.consul.Consul; +import org.apache.camel.CamelContext; +import org.apache.camel.CamelContextAware; +import org.apache.camel.health.HealthCheck; +import org.apache.camel.health.HealthCheckConfiguration; +import org.apache.camel.health.HealthCheckRepository; +import org.apache.camel.health.HealthCheckResultBuilder; +import org.apache.camel.impl.health.AbstractHealthCheck; +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.function.Suppliers; + +public class ConsulHealthCheckRepository implements HealthCheckRepository, CamelContextAware { + private final Supplier<Consul> client; + private final ConcurrentMap<String, HealthCheck> checks; + private ConsulHealthCheckRepositoryConfiguration configuration; + private CamelContext camelContext; + + public ConsulHealthCheckRepository() { + this(null); + } + + private ConsulHealthCheckRepository(ConsulHealthCheckRepositoryConfiguration configuration) { + this.checks = new ConcurrentHashMap<>(); + this.configuration = configuration; + this.client = Suppliers.memorize(this::createConsul, ObjectHelper::wrapRuntimeCamelException); + } + + // ************************************* + // + // ************************************* + + public ConsulHealthCheckRepositoryConfiguration getConfiguration() { + return configuration; + } + + public void setConfiguration(ConsulHealthCheckRepositoryConfiguration configuration) { + this.configuration = configuration; + } + + @Override + public void setCamelContext(CamelContext camelContext) { + this.camelContext = camelContext; + } + + @Override + public CamelContext getCamelContext() { + return camelContext; + } + + @Override + public Stream<HealthCheck> stream() { + final Set<String> ids = configuration.getChecks(); + + if (ObjectHelper.isNotEmpty(ids)) { + return ids.stream() + .map(checkId -> checks.computeIfAbsent(checkId, ConsulHealthCheck::new)) + .filter(check -> check.getConfiguration().isEnabled()); + } + + return Stream.empty(); + } + + // ************************************* + // + // ************************************* + + private Consul createConsul() throws Exception { + ConsulHealthCheckRepositoryConfiguration conf = configuration; + + if (conf == null) { + conf = new ConsulHealthCheckRepositoryConfiguration(); + } + + return conf.createConsulClient(camelContext); + } + + private class ConsulHealthCheck extends AbstractHealthCheck { + private final String checkId; + + ConsulHealthCheck(String checkId) { + super("consul-" + checkId.replaceAll(":", "-")); + + this.checkId = checkId; + + HealthCheckConfiguration conf = configuration.getConfigurations().get(getId()); + if (conf == null) { + conf = HealthCheckConfiguration.builder() + .complete(configuration.getDefaultConfiguration()) + .build(); + } + + setConfiguration(conf); + } + + @Override + protected void doCall(HealthCheckResultBuilder builder, Map<String, Object> options) { + builder.unknown(); + + com.orbitz.consul.model.health.HealthCheck check = client.get().agentClient().getChecks().get(checkId); + if (check != null) { + + // From Consul sources: + // https://github.com/hashicorp/consul/blob/master/api/health.go#L8-L16 + // + // States are: + // + // const ( + // HealthAny is special, and is used as a wild card, + // not as a specific state. + // HealthAny = "any" + // HealthPassing = "passing" + // HealthWarning = "warning" + // HealthCritical = "critical" + // HealthMaint = "maintenance" + // ) + if (ObjectHelper.equalIgnoreCase(check.getStatus(), "passing")) { + builder.up(); + } + if (ObjectHelper.equalIgnoreCase(check.getStatus(), "warning")) { + builder.down(); + } + if (ObjectHelper.equalIgnoreCase(check.getStatus(), "critical")) { + builder.down(); + } + + builder.detail("consul.service.name", check.getServiceName().orNull()); + builder.detail("consul.service.id", check.getServiceId().orNull()); + builder.detail("consul.check.status", check.getStatus()); + builder.detail("consul.check.id", check.getCheckId()); + } + } + } + + + + // **************************************** + // Builder + // **************************************** + + public static final class Builder implements org.apache.camel.Builder<ConsulHealthCheckRepository> { + private HealthCheckConfiguration defaultConfiguration; + private Set<String> checks; + private Map<String, HealthCheckConfiguration> configurations; + + public Builder configuration(HealthCheckConfiguration defaultConfiguration) { + this.defaultConfiguration = defaultConfiguration; + return this; + } + + public Builder configuration(String id, HealthCheckConfiguration configuration) { + if (this.configurations == null) { + this.configurations = new HashMap<>(); + } + + this.configurations.put(id, configuration); + + return this; + } + + public Builder configurations(Map<String, HealthCheckConfiguration> configurations) { + if (ObjectHelper.isNotEmpty(configurations)) { + configurations.forEach(this::configuration); + } + + return this; + } + + public Builder check(String id) { + if (ObjectHelper.isNotEmpty(id)) { + if (this.checks == null) { + this.checks = new HashSet<>(); + } + this.checks.add(id); + } + + return this; + } + + public Builder checks(Collection<String> ids) { + if (ObjectHelper.isNotEmpty(ids)) { + ids.forEach(this::check); + } + + return this; + } + + @Override + public ConsulHealthCheckRepository build() { + ConsulHealthCheckRepositoryConfiguration configuration = new ConsulHealthCheckRepositoryConfiguration(); + configuration.setDefaultConfiguration(defaultConfiguration); + + if (checks != null) { + checks.forEach(configuration::addCheck); + } + if (configurations != null) { + configurations.forEach(configuration::addConfiguration); + } + + return new ConsulHealthCheckRepository(configuration); + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-consul/src/main/java/org/apache/camel/component/consul/health/ConsulHealthCheckRepositoryConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/health/ConsulHealthCheckRepositoryConfiguration.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/health/ConsulHealthCheckRepositoryConfiguration.java new file mode 100644 index 0000000..1f3cde2 --- /dev/null +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/health/ConsulHealthCheckRepositoryConfiguration.java @@ -0,0 +1,93 @@ +/** + * 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.component.consul.health; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.component.consul.ConsulClientConfiguration; +import org.apache.camel.health.HealthCheckConfiguration; + +public class ConsulHealthCheckRepositoryConfiguration extends ConsulClientConfiguration { + /** + * Default configuration. + */ + private HealthCheckConfiguration defaultConfiguration; + + /** + * Define the checks to include. + */ + private Set<String> checks; + + /** + * Service configuration. + */ + private Map<String, HealthCheckConfiguration> configurations; + + public ConsulHealthCheckRepositoryConfiguration() { + this.checks = new HashSet<>(); + this.configurations = new HashMap<>(); + } + + // **************************************** + // Properties + // **************************************** + + public HealthCheckConfiguration getDefaultConfiguration() { + return defaultConfiguration; + } + + public void setDefaultConfiguration(HealthCheckConfiguration defaultConfiguration) { + this.defaultConfiguration = defaultConfiguration; + } + + public Set<String> getChecks() { + return checks; + } + + public void addCheck(String id) { + checks.add(id); + } + + public Map<String, HealthCheckConfiguration> getConfigurations() { + return configurations; + } + + public void addConfiguration(String id, HealthCheckConfiguration configuration) { + if (this.configurations == null) { + this.configurations = new HashMap<>(); + } + + this.configurations.put(id, configuration); + } + + // **************************************** + // Copy + // **************************************** + + @Override + public ConsulHealthCheckRepositoryConfiguration copy() { + try { + return (ConsulHealthCheckRepositoryConfiguration)super.clone(); + } catch (CloneNotSupportedException e) { + throw new RuntimeCamelException(e); + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-consul/src/main/java/org/apache/camel/component/consul/policy/ConsulRoutePolicy.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/policy/ConsulRoutePolicy.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/policy/ConsulRoutePolicy.java index a40fd20..c5ce6c1 100644 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/policy/ConsulRoutePolicy.java +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/policy/ConsulRoutePolicy.java @@ -83,7 +83,7 @@ public final class ConsulRoutePolicy extends RoutePolicySupport implements Camel public ConsulRoutePolicy(ConsulConfiguration configuration) throws Exception { this.consulUrl = configuration.getUrl(); - this.consul = configuration.createConsulClient(); + this.consul = configuration.createConsulClient(camelContext); } @Override http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscoveryTest.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscoveryTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscoveryTest.java index e63a39f..2523ad7 100644 --- a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscoveryTest.java +++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscoveryTest.java @@ -71,7 +71,7 @@ public class ConsulServiceDiscoveryTest { @Test public void testServiceDiscovery() throws Exception { - ConsulConfiguration configuration = new ConsulConfiguration(null); + ConsulConfiguration configuration = new ConsulConfiguration(); ServiceDiscovery discovery = new ConsulServiceDiscovery(configuration); List<ServiceDefinition> services = discovery.getServices("my-service"); http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java ---------------------------------------------------------------------- diff --git a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java index 7f134f3..8d0cb46 100644 --- a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java +++ b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java @@ -46,6 +46,9 @@ import org.apache.camel.component.properties.PropertiesLocation; import org.apache.camel.component.properties.PropertiesParser; import org.apache.camel.component.properties.PropertiesResolver; import org.apache.camel.ha.CamelClusterService; +import org.apache.camel.health.HealthCheckRegistry; +import org.apache.camel.health.HealthCheckRepository; +import org.apache.camel.health.HealthCheckService; import org.apache.camel.management.DefaultManagementAgent; import org.apache.camel.management.DefaultManagementLifecycleStrategy; import org.apache.camel.management.DefaultManagementStrategy; @@ -160,6 +163,7 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex return contextClassLoaderOnStart; } + //CHECKSTYLE:OFF public void afterPropertiesSet() throws Exception { if (ObjectHelper.isEmpty(getId())) { throw new IllegalArgumentException("Id must be set"); @@ -339,7 +343,29 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex getContext().addRoutePolicyFactory(factory); } } - + // Health check registry + HealthCheckRegistry healthCheckRegistry = getBeanForType(HealthCheckRegistry.class); + if (healthCheckRegistry != null) { + healthCheckRegistry.setCamelContext(getContext()); + LOG.info("Using HealthCheckRegistry: {}", healthCheckRegistry); + getContext().setHealthCheckRegistry(healthCheckRegistry); + } else { + healthCheckRegistry = getContext().getHealthCheckRegistry(); + healthCheckRegistry.setCamelContext(getContext()); + } + // Health check repository + Set<HealthCheckRepository> repositories = getContext().getRegistry().findByType(HealthCheckRepository.class); + if (ObjectHelper.isNotEmpty(repositories)) { + for (HealthCheckRepository repository: repositories) { + healthCheckRegistry.addRepository(repository); + } + } + // Health check service + HealthCheckService healthCheckService = getBeanForType(HealthCheckService.class); + if (healthCheckService != null) { + LOG.info("Using HealthCheckService: {}", healthCheckService); + getContext().addService(healthCheckService); + } // Route controller RouteController routeController = getBeanForType(RouteController.class); if (clusterService != null) { @@ -359,6 +385,7 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex // init stream caching strategy initStreamCachingStrategy(); } + //CHECKSTYLE:ON /** * Setup all the routes which must be done prior starting {@link CamelContext}. http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-servicenow/camel-servicenow-component/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-servicenow/camel-servicenow-component/pom.xml b/components/camel-servicenow/camel-servicenow-component/pom.xml index 4b9a720..6aa16a9 100644 --- a/components/camel-servicenow/camel-servicenow-component/pom.xml +++ b/components/camel-servicenow/camel-servicenow-component/pom.xml @@ -29,7 +29,7 @@ <artifactId>camel-servicenow</artifactId> <packaging>jar</packaging> - <name>Camel :: ServiceNow</name> + <name>Camel :: ServiceNow :: Component</name> <description>Camel ServiceNow support</description> <properties> http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-servicenow/camel-servicenow-component/src/main/docs/servicenow-component.adoc ---------------------------------------------------------------------- diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/docs/servicenow-component.adoc b/components/camel-servicenow/camel-servicenow-component/src/main/docs/servicenow-component.adoc index f0a177a..cf613d0 100644 --- a/components/camel-servicenow/camel-servicenow-component/src/main/docs/servicenow-component.adoc +++ b/components/camel-servicenow/camel-servicenow-component/src/main/docs/servicenow-component.adoc @@ -30,7 +30,7 @@ for this component: // component options: START -The ServiceNow component supports 10 options which are listed below. +The ServiceNow component supports 14 options which are listed below. @@ -45,6 +45,10 @@ The ServiceNow component supports 10 options which are listed below. | *oauthClientId* (security) | OAuth2 ClientID | | String | *oauthClientSecret* (security) | OAuth2 ClientSecret | | String | *oauthTokenUrl* (security) | OAuth token Url | | String +| *proxyHost* (advanced) | The proxy host name | | String +| *proxyPort* (advanced) | The proxy port number | | Integer +| *proxyUserName* (security) | Username for proxy authentication | | String +| *proxyPassword* (security) | Password for proxy authentication | | String | *useGlobalSslContext Parameters* (security) | Enable usage of global SSL context parameters. | false | boolean | *resolveProperty Placeholders* (advanced) | Whether the component should resolve property placeholders on itself when starting. Only properties which are of String type can use property placeholders. | true | boolean |=== http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowClient.java ---------------------------------------------------------------------- diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowClient.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowClient.java index 9fd7886..4e5668f 100644 --- a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowClient.java +++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowClient.java @@ -16,6 +16,8 @@ */ package org.apache.camel.component.servicenow; +import java.io.IOException; +import java.security.GeneralSecurityException; import java.util.Arrays; import java.util.Map; import java.util.function.Function; @@ -45,7 +47,7 @@ public final class ServiceNowClient { private final ServiceNowConfiguration configuration; private final WebClient client; - ServiceNowClient(CamelContext camelContext, ServiceNowConfiguration configuration) throws Exception { + public ServiceNowClient(CamelContext camelContext, ServiceNowConfiguration configuration) { this.camelContext = camelContext; this.configuration = configuration; this.client = WebClient.create( @@ -206,7 +208,7 @@ public final class ServiceNowClient { } private static void configureRequestContext( - CamelContext context, ServiceNowConfiguration configuration, WebClient client) throws Exception { + CamelContext context, ServiceNowConfiguration configuration, WebClient client) { WebClient.getConfig(client) .getRequestContext() @@ -214,7 +216,7 @@ public final class ServiceNowClient { } private static void configureTls( - CamelContext camelContext, ServiceNowConfiguration configuration, WebClient client) throws Exception { + CamelContext camelContext, ServiceNowConfiguration configuration, WebClient client) { SSLContextParameters sslContextParams = configuration.getSslContextParameters(); if (sslContextParams != null) { @@ -224,15 +226,19 @@ public final class ServiceNowClient { tlsClientParams = new TLSClientParameters(); } - SSLContext sslContext = sslContextParams.createSSLContext(camelContext); - tlsClientParams.setSSLSocketFactory(sslContext.getSocketFactory()); + try { + SSLContext sslContext = sslContextParams.createSSLContext(camelContext); + tlsClientParams.setSSLSocketFactory(sslContext.getSocketFactory()); - conduit.setTlsClientParameters(tlsClientParams); + conduit.setTlsClientParameters(tlsClientParams); + } catch (IOException | GeneralSecurityException e) { + throw ObjectHelper.wrapRuntimeCamelException(e); + } } } private static void configureHttpClientPolicy( - CamelContext context, ServiceNowConfiguration configuration, WebClient client) throws Exception { + CamelContext context, ServiceNowConfiguration configuration, WebClient client) { HTTPClientPolicy httpPolicy = configuration.getHttpClientPolicy(); if (httpPolicy == null) { @@ -252,7 +258,7 @@ public final class ServiceNowClient { } private static void configureProxyAuthorizationPolicy( - CamelContext context, ServiceNowConfiguration configuration, WebClient client) throws Exception { + CamelContext context, ServiceNowConfiguration configuration, WebClient client) { ProxyAuthorizationPolicy proxyPolicy = configuration.getProxyAuthorizationPolicy(); if (proxyPolicy == null) { http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponent.java ---------------------------------------------------------------------- diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponent.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponent.java index c9cbb89..e2cf354 100644 --- a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponent.java +++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponent.java @@ -16,8 +16,6 @@ */ package org.apache.camel.component.servicenow; -import java.util.Arrays; -import java.util.Collection; import java.util.Map; import org.apache.camel.CamelContext; @@ -25,9 +23,7 @@ import org.apache.camel.ComponentVerifier; import org.apache.camel.Endpoint; import org.apache.camel.SSLContextParametersAware; import org.apache.camel.VerifiableComponent; -import org.apache.camel.component.extension.ComponentExtension; import org.apache.camel.component.extension.ComponentVerifierExtension; -import org.apache.camel.component.extension.MetaDataExtension; import org.apache.camel.impl.DefaultComponent; import org.apache.camel.spi.Metadata; import org.apache.camel.util.EndpointHelper; @@ -39,8 +35,6 @@ import org.apache.camel.util.ObjectHelper; */ @Metadata(label = "verifiers", enums = "parameters,connectivity") public class ServiceNowComponent extends DefaultComponent implements VerifiableComponent, SSLContextParametersAware { - private static final Collection<Class<? extends ComponentExtension>> EXTENSIONS = Arrays.asList(ComponentVerifierExtension.class, MetaDataExtension.class); - @Metadata(label = "advanced") private String instanceName; @Metadata(label = "advanced") @@ -48,9 +42,6 @@ public class ServiceNowComponent extends DefaultComponent implements VerifiableC @Metadata(label = "security", defaultValue = "false") private boolean useGlobalSslContextParameters; - private ServiceNowComponentVerifierExtension verifierExtension; - private ServiceNowMetaDataExtension metaDataExtension; - public ServiceNowComponent() { this(null); } @@ -64,54 +55,9 @@ public class ServiceNowComponent extends DefaultComponent implements VerifiableC registerExtension(ServiceNowMetaDataExtension::new); } - @Override - protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { - final CamelContext context = getCamelContext(); - final ServiceNowConfiguration configuration = this.configuration.copy(); - - Map<String, Object> models = IntrospectionSupport.extractProperties(parameters, "model."); - for (Map.Entry<String, Object> entry : models.entrySet()) { - configuration.addModel( - entry.getKey(), - EndpointHelper.resolveParameter(context, (String)entry.getValue(), Class.class)); - } - - Map<String, Object> requestModels = IntrospectionSupport.extractProperties(parameters, "requestModel."); - for (Map.Entry<String, Object> entry : requestModels.entrySet()) { - configuration.addRequestModel( - entry.getKey(), - EndpointHelper.resolveParameter(context, (String)entry.getValue(), Class.class)); - } - - Map<String, Object> responseModels = IntrospectionSupport.extractProperties(parameters, "responseModel."); - for (Map.Entry<String, Object> entry : responseModels.entrySet()) { - configuration.addResponseModel( - entry.getKey(), - EndpointHelper.resolveParameter(context, (String)entry.getValue(), Class.class)); - } - - setProperties(configuration, parameters); - - if (ObjectHelper.isEmpty(remaining)) { - // If an instance is not set on the endpoint uri, use the one set on - // component. - remaining = instanceName; - } - - String instanceName = getCamelContext().resolvePropertyPlaceholders(remaining); - if (!configuration.hasApiUrl()) { - configuration.setApiUrl(String.format("https://%s.service-now.com/api", instanceName)); - } - if (!configuration.hasOauthTokenUrl()) { - configuration.setOauthTokenUrl(String.format("https://%s.service-now.com/oauth_token.do", instanceName)); - } - - if (configuration.getSslContextParameters() == null) { - configuration.setSslContextParameters(retrieveGlobalSslContextParameters()); - } - - return new ServiceNowEndpoint(uri, this, configuration, instanceName); - } + // **************************************** + // Properties + // **************************************** public String getInstanceName() { return instanceName; @@ -206,6 +152,58 @@ public class ServiceNowComponent extends DefaultComponent implements VerifiableC configuration.setOauthTokenUrl(oauthTokenUrl); } + public String getProxyHost() { + return configuration.getProxyHost(); + } + + /** + * The proxy host name + * @param proxyHost + */ + @Metadata(label = "advanced") + public void setProxyHost(String proxyHost) { + configuration.setProxyHost(proxyHost); + } + + public Integer getProxyPort() { + return configuration.getProxyPort(); + } + + /** + * The proxy port number + * @param proxyPort + */ + @Metadata(label = "advanced") + public void setProxyPort(Integer proxyPort) { + configuration.setProxyPort(proxyPort); + } + + public String getProxyUserName() { + return configuration.getProxyUserName(); + } + + /** + * Username for proxy authentication + * @param proxyUserName + */ + @Metadata(label = "advanced,security", secret = true) + public void setProxyUserName(String proxyUserName) { + configuration.setProxyUserName(proxyUserName); + } + + public String getProxyPassword() { + return configuration.getProxyPassword(); + } + + /** + * Password for proxy authentication + * @param proxyPassword + */ + @Metadata(label = "advanced,security", secret = true) + public void setProxyPassword(String proxyPassword) { + configuration.setProxyPassword(proxyPassword); + } + @Override public boolean isUseGlobalSslContextParameters() { return this.useGlobalSslContextParameters; @@ -223,4 +221,57 @@ public class ServiceNowComponent extends DefaultComponent implements VerifiableC public ComponentVerifier getVerifier() { return (scope, parameters) -> getExtension(ComponentVerifierExtension.class).orElseThrow(UnsupportedOperationException::new).verify(scope, parameters); } + + // **************************************** + // Component impl + // **************************************** + + @Override + protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { + final CamelContext context = getCamelContext(); + final ServiceNowConfiguration configuration = this.configuration.copy(); + + Map<String, Object> models = IntrospectionSupport.extractProperties(parameters, "model."); + for (Map.Entry<String, Object> entry : models.entrySet()) { + configuration.addModel( + entry.getKey(), + EndpointHelper.resolveParameter(context, (String)entry.getValue(), Class.class)); + } + + Map<String, Object> requestModels = IntrospectionSupport.extractProperties(parameters, "requestModel."); + for (Map.Entry<String, Object> entry : requestModels.entrySet()) { + configuration.addRequestModel( + entry.getKey(), + EndpointHelper.resolveParameter(context, (String)entry.getValue(), Class.class)); + } + + Map<String, Object> responseModels = IntrospectionSupport.extractProperties(parameters, "responseModel."); + for (Map.Entry<String, Object> entry : responseModels.entrySet()) { + configuration.addResponseModel( + entry.getKey(), + EndpointHelper.resolveParameter(context, (String)entry.getValue(), Class.class)); + } + + setProperties(configuration, parameters); + + if (ObjectHelper.isEmpty(remaining)) { + // If an instance is not set on the endpoint uri, use the one set on + // component. + remaining = instanceName; + } + + String instanceName = getCamelContext().resolvePropertyPlaceholders(remaining); + if (!configuration.hasApiUrl()) { + configuration.setApiUrl(String.format("https://%s.service-now.com/api", instanceName)); + } + if (!configuration.hasOauthTokenUrl()) { + configuration.setOauthTokenUrl(String.format("https://%s.service-now.com/oauth_token.do", instanceName)); + } + + if (configuration.getSslContextParameters() == null) { + configuration.setSslContextParameters(retrieveGlobalSslContextParameters()); + } + + return new ServiceNowEndpoint(uri, this, configuration, instanceName); + } } http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierExtension.java ---------------------------------------------------------------------- diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierExtension.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierExtension.java index 0422238..8a0222a 100644 --- a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierExtension.java +++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowComponentVerifierExtension.java @@ -24,6 +24,7 @@ import org.apache.camel.component.extension.verifier.DefaultComponentVerifierExt import org.apache.camel.component.extension.verifier.NoSuchOptionException; import org.apache.camel.component.extension.verifier.ResultBuilder; import org.apache.camel.component.extension.verifier.ResultErrorBuilder; +import org.apache.camel.util.ObjectHelper; final class ServiceNowComponentVerifierExtension extends DefaultComponentVerifierExtension { @@ -55,28 +56,18 @@ final class ServiceNowComponentVerifierExtension extends DefaultComponentVerifie ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.CONNECTIVITY); try { - // Load ServiceNow Configuration - ServiceNowConfiguration configuration = new ServiceNowConfiguration(); - setProperties(configuration, parameters); - - String instanceName = getMandatoryOption(parameters, "instanceName", String.class); - String tableName = configuration.getTable() != null ? configuration.getTable() : "incident"; - - // Configure Api and OAuthToken ULRs using instanceName - if (!configuration.hasApiUrl()) { - configuration.setApiUrl(String.format("https://%s.service-now.com/api", instanceName)); - } - if (!configuration.hasOauthTokenUrl()) { - configuration.setOauthTokenUrl(String.format("https://%s.service-now.com/oauth_token.do", instanceName)); - } + final ServiceNowConfiguration configuration = getServiceNowConfiguration(parameters); + final ServiceNowClient client = getServiceNowClient(configuration, parameters); + final String tableName = ObjectHelper.supplyIfEmpty(configuration.getTable(), () -> "incident"); - new ServiceNowClient(getCamelContext(), configuration) + client.reset() .types(MediaType.APPLICATION_JSON_TYPE) .path("now") .path(configuration.getApiVersion()) .path("table") .path(tableName) .query(ServiceNowParams.SYSPARM_LIMIT.getId(), 1L) + .query(ServiceNowParams.SYSPARM_FIELDS.getId(), "sys_id") .invoke(HttpMethod.GET); } catch (NoSuchOptionException e) { builder.error( @@ -106,4 +97,78 @@ final class ServiceNowComponentVerifierExtension extends DefaultComponentVerifie return builder.build(); } + + // ********************************* + // Helpers + // ********************************* + + private String getInstanceName(Map<String, Object> parameters) throws Exception { + String instanceName = (String)parameters.get("instanceName"); + if (ObjectHelper.isEmpty(instanceName) && ObjectHelper.isNotEmpty(getComponent())) { + instanceName = getComponent(ServiceNowComponent.class).getInstanceName(); + } + + if (ObjectHelper.isEmpty(instanceName)) { + throw new NoSuchOptionException("instanceName"); + } + + return instanceName; + } + + private ServiceNowClient getServiceNowClient(ServiceNowConfiguration configuration, Map<String, Object> parameters) throws Exception { + ServiceNowClient client = null; + + // check if a client has been supplied to the parameters map + for (Object value : parameters.values()) { + if (value instanceof ServiceNowClient) { + client = ServiceNowClient.class.cast(value); + break; + } + } + + // if no client is provided + if (ObjectHelper.isEmpty(client)) { + final String instanceName = getInstanceName(parameters); + + // Configure Api and OAuthToken ULRs using instanceName + if (!configuration.hasApiUrl()) { + configuration.setApiUrl(String.format("https://%s.service-now.com/api", instanceName)); + } + if (!configuration.hasOauthTokenUrl()) { + configuration.setOauthTokenUrl(String.format("https://%s.service-now.com/oauth_token.do", instanceName)); + } + + client = new ServiceNowClient(getCamelContext(), configuration); + } + + return client; + } + + private ServiceNowConfiguration getServiceNowConfiguration(Map<String, Object> parameters) throws Exception { + ServiceNowConfiguration configuration = null; + + // check if a configuration has been supplied to the parameters map + for (Object value : parameters.values()) { + if (value instanceof ServiceNowConfiguration) { + configuration = ServiceNowConfiguration.class.cast(value); + break; + } + } + + // if no configuration is provided + if (ObjectHelper.isEmpty(configuration)) { + if (ObjectHelper.isNotEmpty(getComponent())) { + configuration = getComponent(ServiceNowComponent.class).getConfiguration().copy(); + } else { + configuration = new ServiceNowConfiguration(); + } + + // bind parameters to ServiceNow Configuration only if configuration + // does not come from the parameters map as in that case we expect + // it to be pre-configured. + setProperties(configuration, parameters); + } + + return configuration; + } } http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowConstants.java ---------------------------------------------------------------------- diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowConstants.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowConstants.java index 955f389..fece6d6 100644 --- a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowConstants.java +++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/ServiceNowConstants.java @@ -17,6 +17,8 @@ package org.apache.camel.component.servicenow; public final class ServiceNowConstants { + public static final String COMPONENT_SCHEME = "servicenow"; + public static final String CAMEL_HEADER_PREFIX = "CamelServiceNow"; public static final String RESOURCE = "CamelServiceNowResource"; http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/auth/AuthenticationRequestFilter.java ---------------------------------------------------------------------- diff --git a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/auth/AuthenticationRequestFilter.java b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/auth/AuthenticationRequestFilter.java index 4689455..7f563f7 100644 --- a/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/auth/AuthenticationRequestFilter.java +++ b/components/camel-servicenow/camel-servicenow-component/src/main/java/org/apache/camel/component/servicenow/auth/AuthenticationRequestFilter.java @@ -35,7 +35,7 @@ public final class AuthenticationRequestFilter implements ClientRequestFilter { private final OAuthToken authToken; private final String authString; - public AuthenticationRequestFilter(ServiceNowConfiguration conf) throws IOException { + public AuthenticationRequestFilter(ServiceNowConfiguration conf) { this.authToken = conf.hasOAuthAuthentication() ? new OAuthToken(conf) : null; this.authString = conf.hasBasicAuthentication() ? getBasicAuthenticationString(conf) : null; } http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java index 2f99fca..fc6cde6 100644 --- a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java +++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java @@ -31,6 +31,9 @@ import org.apache.camel.TypeConverters; import org.apache.camel.component.properties.PropertiesComponent; import org.apache.camel.component.properties.PropertiesParser; import org.apache.camel.ha.CamelClusterService; +import org.apache.camel.health.HealthCheckRegistry; +import org.apache.camel.health.HealthCheckRepository; +import org.apache.camel.health.HealthCheckService; import org.apache.camel.impl.FileWatcherReloadStrategy; import org.apache.camel.processor.interceptor.BacklogTracer; import org.apache.camel.processor.interceptor.DefaultTraceFormatter; @@ -475,7 +478,29 @@ public class CamelAutoConfiguration { if (sslContextParametersSupplier != null) { camelContext.setSSLContextParameters(sslContextParametersSupplier.get()); } - + // Health check registry + HealthCheckRegistry healthCheckRegistry = getSingleBeanOfType(applicationContext, HealthCheckRegistry.class); + if (healthCheckRegistry != null) { + healthCheckRegistry.setCamelContext(camelContext); + LOG.info("Using HealthCheckRegistry: {}", healthCheckRegistry); + camelContext.setHealthCheckRegistry(healthCheckRegistry); + } else { + healthCheckRegistry = camelContext.getHealthCheckRegistry(); + healthCheckRegistry.setCamelContext(camelContext); + } + // Health check repository + Map<String, HealthCheckRepository> repositories = applicationContext.getBeansOfType(HealthCheckRepository.class); + if (ObjectHelper.isNotEmpty(repositories)) { + for (HealthCheckRepository repository: repositories.values()) { + healthCheckRegistry.addRepository(repository); + } + } + // Health check service + HealthCheckService healthCheckService = getSingleBeanOfType(applicationContext, HealthCheckService.class); + if (healthCheckService != null) { + LOG.info("Using HealthCheckService: {}", healthCheckService); + camelContext.addService(healthCheckService); + } // Route controller RouteController routeController = getSingleBeanOfType(applicationContext, RouteController.class); if (routeController != null) { http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/AbstractCamelEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/AbstractCamelEndpoint.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/AbstractCamelEndpoint.java new file mode 100644 index 0000000..532d0d6 --- /dev/null +++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/AbstractCamelEndpoint.java @@ -0,0 +1,42 @@ +/** + * 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.spring.boot.actuate.endpoint; + +import org.apache.camel.CamelContext; +import org.apache.camel.spi.HasCamelContext; +import org.springframework.boot.actuate.endpoint.AbstractEndpoint; +import org.springframework.boot.actuate.endpoint.Endpoint; + +/** + * Abstract camel {@link Endpoint}. + */ +abstract class AbstractCamelEndpoint<T> extends AbstractEndpoint<T> implements HasCamelContext { + private final CamelContext camelContext; + + protected AbstractCamelEndpoint(String id, CamelContext camelContext) { + super(id); + this.camelContext = camelContext; + + // is enabled by default + this.setEnabled(true); + } + + @Override + public CamelContext getCamelContext() { + return this.camelContext; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/AbstractCamelMvcEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/AbstractCamelMvcEndpoint.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/AbstractCamelMvcEndpoint.java new file mode 100644 index 0000000..991c508 --- /dev/null +++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/AbstractCamelMvcEndpoint.java @@ -0,0 +1,72 @@ +/** + * 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.spring.boot.actuate.endpoint; + +import java.util.function.Function; +import java.util.function.Supplier; + +import org.springframework.boot.actuate.endpoint.Endpoint; +import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter; +import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Adapter to expose {@link T} as an {@link MvcEndpoint}. + */ +abstract class AbstractCamelMvcEndpoint<T extends Endpoint> extends EndpointMvcAdapter { + private final T delegate; + + protected AbstractCamelMvcEndpoint(String path, T delegate) { + super(delegate); + this.delegate = delegate; + + setPath(path); + } + + // ******************************************** + // Helpers + // ******************************************** + + protected T delegate() { + return this.delegate; + } + + protected Object doIfEnabled(Supplier<Object> supplier) { + if (!delegate.isEnabled()) { + return getDisabledResponse(); + } + + return supplier.get(); + } + + protected Object doIfEnabled(Function<T, Object> supplier) { + if (!delegate.isEnabled()) { + return getDisabledResponse(); + } + + return supplier.apply(delegate); + } + + @SuppressWarnings("serial") + @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) + public static class GenericException extends RuntimeException { + public GenericException(String message, Throwable cause) { + super(message, cause); + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/00d1d70b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/CamelHealthCheckEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/CamelHealthCheckEndpoint.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/CamelHealthCheckEndpoint.java new file mode 100644 index 0000000..a55aca2 --- /dev/null +++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/endpoint/CamelHealthCheckEndpoint.java @@ -0,0 +1,180 @@ +/** + * 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.spring.boot.actuate.endpoint; + +import java.time.Duration; +import java.util.Collection; +import java.util.Map; +import java.util.Optional; + +import static java.util.stream.Collectors.toList; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.camel.CamelContext; +import org.apache.camel.health.HealthCheck; +import org.apache.camel.health.HealthCheckConfiguration; +import org.apache.camel.health.HealthCheckHelper; +import org.apache.camel.util.ObjectHelper; +import org.springframework.boot.actuate.endpoint.Endpoint; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * {@link Endpoint} to expose {@link org.apache.camel.health.HealthCheck} information. + */ +@ConfigurationProperties(prefix = "endpoints." + CamelHealthCheckEndpoint.ENDPOINT_ID) +public class CamelHealthCheckEndpoint extends AbstractCamelEndpoint<Collection<CamelHealthCheckEndpoint.HealthCheckResult>> { + public static final String ENDPOINT_ID = "camelhealthcheck"; + + public CamelHealthCheckEndpoint(CamelContext camelContext) { + super(ENDPOINT_ID, camelContext); + } + + @Override + public Collection<HealthCheckResult> invoke() { + return HealthCheckHelper.invoke(getCamelContext()).stream() + .map(result -> new HealthCheckResult(result, new Check(result))) + .collect(toList()); + } + + // **************************************** + // Used by CamelHealthCheckMvcEndpoint + // **************************************** + + Optional<HealthCheckResult> query(String id, Map<String, Object> options) { + return HealthCheckHelper.query(getCamelContext(), id, options) + .map(result -> new DetailedHealthCheckResult(result, new DetailedCheck(result))); + } + + Optional<HealthCheckResult> invoke(String id, Map<String, Object> options) { + return HealthCheckHelper.invoke(getCamelContext(), id, options) + .map(result -> new DetailedHealthCheckResult(result, new DetailedCheck(result))); + } + + // **************************************** + // Wrappers + // **************************************** + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + @JsonPropertyOrder({"enabled", "interval", "failureThreshold"}) + public static class CheckConfiguration { + protected final HealthCheckConfiguration configuration; + + public CheckConfiguration(HealthCheckConfiguration configuration) { + this.configuration = ObjectHelper.supplyIfEmpty(configuration, HealthCheckConfiguration::new); + } + + @JsonProperty("enabled") + public Boolean isEnabled() { + return configuration.isEnabled(); + } + + @JsonProperty("interval") + public String getDuration() { + Duration interval = configuration.getInterval(); + return interval != null ? interval.toString() : null; + } + + @JsonProperty("failureThreshold") + public Integer getFailureThreshold() { + return configuration.getFailureThreshold(); + } + } + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + @JsonPropertyOrder({"id", "group"}) + public static class Check { + protected final HealthCheck.Result result; + + public Check(HealthCheck.Result result) { + this.result = result; + } + + @JsonProperty("id") + public String getId() { + return result.getCheck().getId(); + } + + @JsonProperty("group") + public String getGroup() { + return result.getCheck().getGroup(); + } + } + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + @JsonPropertyOrder({"status", "message", "check"}) + public static class HealthCheckResult { + protected final HealthCheck.Result result; + protected final Check check; + + public HealthCheckResult(HealthCheck.Result result, Check check) { + this.result = result; + this.check = check; + } + + @JsonProperty("status") + public String getStatus() { + return result.getState().name(); + } + + @JsonProperty("message") + public String getMessage() { + return result.getMessage().orElse(null); + } + + @JsonProperty("check") + public Check getCheck() { + return this.check; + } + } + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + @JsonPropertyOrder({"id", "group", "metaData"}) + public static class DetailedCheck extends Check { + private CheckConfiguration configuration; + + public DetailedCheck(HealthCheck.Result result) { + super(result); + + this.configuration = new CheckConfiguration(result.getCheck().getConfiguration()); + } + + @JsonProperty("configuration") + public CheckConfiguration getConfiguration() { + return this.configuration; + } + + @JsonProperty("metaData") + public Map<String, Object> getMeta() { + return result.getCheck().getMetaData(); + } + } + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + @JsonPropertyOrder({"status", "message", "details", "check"}) + public static class DetailedHealthCheckResult extends HealthCheckResult { + public DetailedHealthCheckResult(HealthCheck.Result result, Check check) { + super(result, check); + } + + @JsonProperty("details") + public Map<String, Object> getDetails() { + return result.getDetails(); + } + } +}