From 71c0698e7755202f2da017e9e110b65a40fa0085 Mon Sep 17 00:00:00 2001 From: Florent CHAMFROY Date: Mon, 28 Mar 2022 11:48:19 +0200 Subject: [PATCH] style: update prettier plugin configuration & apply --- .prettierrc | 2 + .../java/io/gravitee/node/api/Monitoring.java | 194 +-- .../main/java/io/gravitee/node/api/Node.java | 66 +- .../io/gravitee/node/api/NodeDeployer.java | 2 +- .../node/api/NodeMetadataResolver.java | 2 +- .../node/api/NodeMonitoringRepository.java | 66 +- .../io/gravitee/node/api/cache/Cache.java | 24 +- .../node/api/cache/CacheConfiguration.java | 42 +- .../node/api/cache/CacheListener.java | 2 +- .../gravitee/node/api/cache/CacheManager.java | 9 +- .../gravitee/node/api/cache/EntryEvent.java | 82 +- .../node/api/cache/EntryEventType.java | 184 +-- .../api/certificate/CertificateManager.java | 2 +- .../api/certificate/CertificateOptions.java | 24 +- .../node/api/certificate/KeyStoreBundle.java | 70 +- .../node/api/certificate/KeyStoreLoader.java | 14 +- .../certificate/KeyStoreLoaderFactory.java | 4 +- .../certificate/KeyStoreLoaderOptions.java | 182 ++- .../node/api/cluster/ClusterManager.java | 20 +- .../io/gravitee/node/api/cluster/Member.java | 10 +- .../node/api/cluster/MemberListener.java | 6 +- .../node/api/configuration/Configuration.java | 10 +- .../node/api/healthcheck/HealthCheck.java | 78 +- .../gravitee/node/api/healthcheck/Probe.java | 10 +- .../node/api/healthcheck/ProbeManager.java | 6 +- .../gravitee/node/api/healthcheck/Result.java | 139 +- .../io/gravitee/node/api/heartbeat/Event.java | 70 +- .../node/api/heartbeat/EventType.java | 4 +- .../io/gravitee/node/api/infos/NodeInfos.java | 232 +-- .../gravitee/node/api/infos/NodeStatus.java | 4 +- .../gravitee/node/api/infos/PluginInfos.java | 106 +- .../io/gravitee/node/api/message/Message.java | 34 +- .../node/api/message/MessageConsumer.java | 2 +- .../node/api/message/MessageProducer.java | 2 +- .../io/gravitee/node/api/message/Topic.java | 6 +- .../io/gravitee/node/api/monitor/JvmInfo.java | 180 ++- .../io/gravitee/node/api/monitor/Monitor.java | 134 +- .../io/gravitee/node/api/monitor/OsInfo.java | 76 +- .../node/api/monitor/ProcessInfo.java | 38 +- .../api/notifier/NotificationAcknowledge.java | 146 +- .../NotificationAcknowledgeRepository.java | 24 +- .../api/notifier/NotificationCondition.java | 3 +- .../api/notifier/NotificationDefinition.java | 204 +-- .../node/api/notifier/NotifierService.java | 71 +- .../notifier/ResendNotificationCondition.java | 4 +- .../api/plugin/NodeDeploymentContext.java | 2 +- .../io/gravitee/node/api/tracing/Tracer.java | 2 +- .../io/gravitee/node/api/utils/NodeUtils.java | 26 +- .../cache/CacheManagerFactoriesLoader.java | 17 +- .../node/cache/hazelcast/HazelcastCache.java | 198 ++- .../hazelcast/HazelcastCacheManager.java | 139 +- .../cache/standalone/StandaloneCache.java | 305 ++-- .../standalone/StandaloneCacheManager.java | 36 +- .../cache/hazelcast/HazelcastCacheTest.java | 154 +- .../cache/standalone/StandaloneCacheTest.java | 95 +- .../certificates/BaseCertificateManager.java | 47 +- .../node/certificates/FileKeyStoreLoader.java | 327 ++--- .../FileKeyStoreLoaderFactory.java | 46 +- .../certificates/KeyStoreLoaderManager.java | 59 +- .../certificates/ReloadableKeyManager.java | 288 ++-- .../SelfSignedKeyStoreLoader.java | 57 +- .../SelfSignedKeyStoreLoaderFactory.java | 23 +- .../spring/NodeCertificatesConfiguration.java | 8 +- .../FileKeyStoreLoaderFactoryTest.java | 152 +- .../certificates/FileKeyStoreLoaderTest.java | 383 +++-- .../KeyStoreLoaderManagerTest.java | 74 +- .../ReloadableKeyManagerTest.java | 230 ++- .../SelfSignedKeyStoreLoaderFactoryTest.java | 76 +- .../SelfSignedKeyStoreLoaderTest.java | 43 +- .../gravitee/node/cluster/ClusterService.java | 28 +- .../hazelcast/HazelcastClusterManager.java | 170 +-- .../hazelcast/HazelcastMessageProducer.java | 14 +- .../cluster/hazelcast/HazelcastTopic.java | 37 +- .../node/cluster/member/NodeMember.java | 66 +- .../cluster/spring/ClusterConfiguration.java | 20 +- .../spring/HazelcastClusterConfiguration.java | 84 +- .../StandaloneClusterConfiguration.java | 47 +- .../standalone/StandaloneClusterManager.java | 70 +- .../standalone/StandaloneMessageProducer.java | 12 +- .../cluster/standalone/StandaloneTopic.java | 165 ++- .../node/container/AbstractContainer.java | 225 ++- .../gravitee/node/container/AbstractNode.java | 354 ++--- .../io/gravitee/node/container/Container.java | 2 +- .../NodeDeployerFactoriesLoader.java | 17 +- .../gravitee/node/container/NodeFactory.java | 79 +- .../plugin/NodeDeploymentContextFactory.java | 15 +- .../container/spring/NodeConfiguration.java | 16 +- .../spring/SpringBasedContainer.java | 106 +- .../SpringEnvironmentConfiguration.java | 64 +- .../env/AbstractGraviteePropertySource.java | 116 +- .../spring/env/EnvironmentConfiguration.java | 67 +- ...nvironmentPropertySourceBeanProcessor.java | 71 +- .../GraviteeEnvironmentPropertySource.java | 42 +- .../env/GraviteeYamlPropertySource.java | 18 +- .../spring/env/PropertiesConfiguration.java | 41 +- .../env/PropertySourceBeanProcessor.java | 62 +- .../node/jetty/JettyHttpConfiguration.java | 322 +++-- .../gravitee/node/jetty/JettyHttpServer.java | 75 +- .../node/jetty/JettyHttpServerFactory.java | 240 ++-- .../handler/NoContentOutputErrorHandler.java | 92 +- .../healthcheck/JettyHttpServerProbe.java | 58 +- .../gravitee/node/jetty/node/JettyNode.java | 12 +- .../spring/JettyContainerConfiguration.java | 16 +- .../AbstractKubernetesKeyStoreLoader.java | 171 +-- .../KubernetesConfigMapKeyStoreLoader.java | 239 ++-- .../KubernetesKeyStoreLoaderFactory.java | 35 +- .../KubernetesSecretKeyStoreLoader.java | 291 ++-- .../propertyresolver/CloudScheme.java | 16 +- .../KubernetesPropertyResolver.java | 229 ++- .../propertyresolver/PropertyResolver.java | 34 +- .../PropertyResolverFactoriesLoader.java | 17 +- .../spring/NodeKubernetesConfiguration.java | 20 +- ...KubernetesConfigMapKeyStoreLoaderTest.java | 183 ++- .../KubernetesKeyStoreLoaderFactoryTest.java | 212 ++- .../KubernetesSecretKeyStoreLoaderTest.java | 478 +++---- .../management/http/ManagementService.java | 61 +- .../configuration/ConfigurationEndpoint.java | 208 ++- .../http/endpoint/ManagementEndpoint.java | 12 +- .../endpoint/ManagementEndpointManager.java | 2 +- .../prometheus/PrometheusEndpoint.java | 27 +- .../management/http/node/NodeEndpoint.java | 155 +- .../http/spring/ManagementConfiguration.java | 48 +- .../http/vertx/auth/BasicAuthProvider.java | 48 +- .../HttpServerConfiguration.java | 286 ++-- .../ManagementEndpointManagerImpl.java | 99 +- .../spring/HttpServerSpringConfiguration.java | 190 ++- .../vertx/verticle/ManagementVerticle.java | 248 ++-- .../node/monitoring/MonitoringConstants.java | 22 +- .../NoOpNodeMonitoringRepository.java | 36 +- .../monitoring/NodeMonitoringService.java | 125 +- .../monitoring/eventbus/AbstractCodec.java | 124 +- .../monitoring/eventbus/HealthCheckCodec.java | 8 +- .../monitoring/eventbus/MonitorCodec.java | 8 +- .../monitoring/eventbus/NodeInfosCodec.java | 8 +- .../ClusteredNodeMonitoringEventHandler.java | 206 ++- .../handler/NodeMonitoringEventHandler.java | 201 ++- .../NodeHealthCheckManagementEndpoint.java | 130 +- .../healthcheck/NodeHealthCheckService.java | 97 +- .../healthcheck/NodeHealthCheckThread.java | 206 ++- .../healthcheck/ProbeManagerImpl.java | 44 +- .../NodeHealthCheckMicrometerHandler.java | 36 +- .../healthcheck/probe/CPUProbe.java | 48 +- .../healthcheck/probe/MemoryProbe.java | 48 +- .../monitoring/infos/NodeInfosService.java | 213 ++- .../NodeMonitorManagementEndpoint.java | 68 +- .../monitor/NodeMonitorService.java | 239 ++-- .../monitoring/monitor/NodeMonitorThread.java | 144 +- .../monitoring/monitor/probe/Constants.java | 46 +- .../monitoring/monitor/probe/JvmProbe.java | 263 ++-- .../monitoring/monitor/probe/OsProbe.java | 336 +++-- .../monitor/probe/ProcessProbe.java | 279 ++-- .../spring/MonitoringConfiguration.java | 128 +- .../monitoring/NodeMonitoringServiceTest.java | 190 ++- ...usteredNodeMonitoringEventHandlerTest.java | 135 +- .../NodeMonitoringEventHandlerTest.java | 236 ++- ...NodeHealthCheckManagementEndpointTest.java | 381 +++-- .../node/notifier/NotifierServiceImpl.java | 253 ++-- .../gravitee/node/notifier/NotifierUtils.java | 17 +- .../NotifierPluginConfigurationFactory.java | 5 +- .../plugin/NotifierPluginFactory.java | 2 +- ...otifierPluginConfigurationFactoryImpl.java | 45 +- .../impl/NotifierPluginFactoryImpl.java | 307 ++-- .../spring/NotifierConfiguration.java | 16 +- .../notifier/trigger/NotificationTrigger.java | 363 +++-- .../trigger/NotificationTriggerTest.java | 332 ++--- .../node/plugins/service/ServiceManager.java | 2 +- .../service/handler/ServicePluginHandler.java | 62 +- .../service/impl/ServiceManagerImpl.java | 135 +- .../service/spring/ServiceConfiguration.java | 8 +- .../service/impl/ServiceManagerImplTest.java | 124 +- .../node/reporter/ReporterManager.java | 2 +- .../node/reporter/ReporterService.java | 2 +- .../plugin/ReporterPluginHandler.java | 62 +- .../spring/ReporterConfiguration.java | 16 +- .../reporter/vertx/ReporterManagerImpl.java | 212 ++- .../eventbus/EventBusReporterWrapper.java | 113 +- .../eventbus/ReportableMessageCodec.java | 95 +- .../vertx/verticle/ReporterVerticle.java | 83 +- .../io/gravitee/node/tracing/LazyTracer.java | 24 +- .../io/gravitee/node/tracing/NoOpSpan.java | 54 +- .../gravitee/node/tracing/TracingService.java | 82 +- .../node/tracing/plugin/TracerPlugin.java | 2 +- .../tracing/plugin/TracingPluginHandler.java | 69 +- .../tracing/spring/TracingConfiguration.java | 30 +- .../node/tracing/vertx/LazyVertxTracer.java | 134 +- .../tracing/vertx/LazyVertxTracerFactory.java | 54 +- .../node/tracing/vertx/VertxTracer.java | 3 +- .../vertx/AbstractVertxHttpServerFactory.java | 293 ++-- .../ReactivexVertxHttpServerFactory.java | 49 +- .../io/gravitee/node/vertx/VertxFactory.java | 301 ++-- .../node/vertx/VertxHttpServerFactory.java | 51 +- .../node/vertx/VertxHttpServerProvider.java | 20 +- .../vertx/cert/VertxCertificateManager.java | 26 +- .../HttpServerConfiguration.java | 1265 +++++++---------- .../node/vertx/spring/VertxConfiguration.java | 28 +- .../factory/SpringVerticleFactory.java | 53 +- pom.xml | 4 +- 197 files changed, 9210 insertions(+), 11102 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..aa85a8f44 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,2 @@ +printWidth: 140 +tabWidth: 4 diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/Monitoring.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/Monitoring.java index 0c77b0309..5a90587c2 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/Monitoring.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/Monitoring.java @@ -23,101 +23,101 @@ */ public class Monitoring { - public static final String HEALTH_CHECK = "HEALTH_CHECK"; - public static final String MONITOR = "MONITOR"; - public static final String NODE_INFOS = "NODE_INFOS"; - - /** - * The unique identifier of the monitoring object. - */ - private String id; - - /** - * The identifier of the node the monitoring object depends on. - */ - private String nodeId; - - /** - * The type of monitoring object. - */ - private String type; - - /** - * The payload data. - * @see io.gravitee.node.api.healthcheck.HealthCheck - * @see io.gravitee.node.api.monitor.Monitor - * @see io.gravitee.node.api.infos.NodeInfos - */ - private String payload; - - /** - * The creation date. - */ - private Date createdAt; - - /** - * The date corresponding to the time where the monitoring data have been evaluated. - */ - private Date evaluatedAt; - - /** - * The last update date. - */ - private Date updatedAt; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getNodeId() { - return nodeId; - } - - public void setNodeId(String nodeId) { - this.nodeId = nodeId; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getPayload() { - return payload; - } - - public void setPayload(String payload) { - this.payload = payload; - } - - public Date getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - } - - public Date getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(Date updatedAt) { - this.updatedAt = updatedAt; - } - - public Date getEvaluatedAt() { - return evaluatedAt; - } - - public void setEvaluatedAt(Date evaluatedAt) { - this.evaluatedAt = evaluatedAt; - } + public static final String HEALTH_CHECK = "HEALTH_CHECK"; + public static final String MONITOR = "MONITOR"; + public static final String NODE_INFOS = "NODE_INFOS"; + + /** + * The unique identifier of the monitoring object. + */ + private String id; + + /** + * The identifier of the node the monitoring object depends on. + */ + private String nodeId; + + /** + * The type of monitoring object. + */ + private String type; + + /** + * The payload data. + * @see io.gravitee.node.api.healthcheck.HealthCheck + * @see io.gravitee.node.api.monitor.Monitor + * @see io.gravitee.node.api.infos.NodeInfos + */ + private String payload; + + /** + * The creation date. + */ + private Date createdAt; + + /** + * The date corresponding to the time where the monitoring data have been evaluated. + */ + private Date evaluatedAt; + + /** + * The last update date. + */ + private Date updatedAt; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + public Date getEvaluatedAt() { + return evaluatedAt; + } + + public void setEvaluatedAt(Date evaluatedAt) { + this.evaluatedAt = evaluatedAt; + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/Node.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/Node.java index db913d6b3..9635c2703 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/Node.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/Node.java @@ -26,44 +26,44 @@ * @author GraviteeSource Team */ public interface Node extends LifecycleComponent { - String META_INSTALLATION = "installation"; - String META_ORGANIZATIONS = "organizations"; - String META_ENVIRONMENTS = "environments"; + String META_INSTALLATION = "installation"; + String META_ORGANIZATIONS = "organizations"; + String META_ENVIRONMENTS = "environments"; - String ID = UUID.toString(UUID.random()); + String ID = UUID.toString(UUID.random()); - /** - * Returns the node name in a human format - * - * @return The node name in a human format - */ - String name(); + /** + * Returns the node name in a human format + * + * @return The node name in a human format + */ + String name(); - /** - * Returns the node name in a technical format - * - * @return The node name in a technical format - */ - String application(); + /** + * Returns the node name in a technical format + * + * @return The node name in a technical format + */ + String application(); - /** - * Returns the node id. - * - * @return The node id. - */ - default String id() { - return ID; - } + /** + * Returns the node id. + * + * @return The node id. + */ + default String id() { + return ID; + } - default List> components() { - return Collections.emptyList(); - } + default List> components() { + return Collections.emptyList(); + } - default String hostname() { - return ""; - } + default String hostname() { + return ""; + } - default Map metadata() { - return Collections.emptyMap(); - } + default Map metadata() { + return Collections.emptyMap(); + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/NodeDeployer.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/NodeDeployer.java index 773b03511..e23ba1d76 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/NodeDeployer.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/NodeDeployer.java @@ -20,5 +20,5 @@ * @author GraviteeSource Team */ public interface NodeDeployer { - Node deploy(Node node); + Node deploy(Node node); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/NodeMetadataResolver.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/NodeMetadataResolver.java index 55b1737b0..7288cbb52 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/NodeMetadataResolver.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/NodeMetadataResolver.java @@ -22,5 +22,5 @@ * @author GraviteeSource Team */ public interface NodeMetadataResolver { - public Map resolve(); + public Map resolve(); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/NodeMonitoringRepository.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/NodeMonitoringRepository.java index c0d67499d..68241d36e 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/NodeMonitoringRepository.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/NodeMonitoringRepository.java @@ -25,40 +25,40 @@ * @author GraviteeSource Team */ public interface NodeMonitoringRepository { - /** - * Returns the {@link Monitoring} object corresponding to the specified type for the specified node identifier. - * - * @param nodeId the node identifier. - * @param type the type of monitoring (MONITOR, HEALTH_CHECK, NODE_INFOS). - * - * @return the {@link Monitoring} found or none if no corresponding monitoring object has been found. - */ - Maybe findByNodeIdAndType(String nodeId, String type); + /** + * Returns the {@link Monitoring} object corresponding to the specified type for the specified node identifier. + * + * @param nodeId the node identifier. + * @param type the type of monitoring (MONITOR, HEALTH_CHECK, NODE_INFOS). + * + * @return the {@link Monitoring} found or none if no corresponding monitoring object has been found. + */ + Maybe findByNodeIdAndType(String nodeId, String type); - /** - * Creates a {@link Monitoring} object. - * @param monitoring the monitoring object to create. - * - * @return the created {@link Monitoring} object. - */ - Single create(Monitoring monitoring); + /** + * Creates a {@link Monitoring} object. + * @param monitoring the monitoring object to create. + * + * @return the created {@link Monitoring} object. + */ + Single create(Monitoring monitoring); - /** - * Updates a {@link Monitoring} object. - * @param monitoring the monitoring object to update. - * - * @return the updated {@link Monitoring} object. - */ - Single update(Monitoring monitoring); + /** + * Updates a {@link Monitoring} object. + * @param monitoring the monitoring object to update. + * + * @return the updated {@link Monitoring} object. + */ + Single update(Monitoring monitoring); - /** - * Returns all the {@link Monitoring} objects corresponding to the specified type for the specified time frame. - * - * @param type the type of monitoring (MONITOR, HEALTH_CHECK, NODE_INFOS). - * @param from the beginning of the timeframe. - * @param to the end of the timeframe. - * - * @return the {@link Monitoring} found or none if no corresponding monitoring object has been found. - */ - Flowable findByTypeAndTimeFrame(String type, long from, long to); + /** + * Returns all the {@link Monitoring} objects corresponding to the specified type for the specified time frame. + * + * @param type the type of monitoring (MONITOR, HEALTH_CHECK, NODE_INFOS). + * @param from the beginning of the timeframe. + * @param to the end of the timeframe. + * + * @return the {@link Monitoring} found or none if no corresponding monitoring object has been found. + */ + Flowable findByTypeAndTimeFrame(String type, long from, long to); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/Cache.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/Cache.java index 2f8594268..2f0d2f441 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/Cache.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/Cache.java @@ -24,27 +24,27 @@ * @author GraviteeSource Team */ public interface Cache { - String getName(); + String getName(); - int size(); + int size(); - boolean isEmpty(); + boolean isEmpty(); - Collection values(); + Collection values(); - V get(K key); + V get(K key); - V put(K key, V value); + V put(K key, V value); - V put(K key, V value, long ttl, TimeUnit ttlUnit); + V put(K key, V value, long ttl, TimeUnit ttlUnit); - void putAll(Map m); + void putAll(Map m); - V evict(K key); + V evict(K key); - void clear(); + void clear(); - void addCacheListener(CacheListener listener); + void addCacheListener(CacheListener listener); - boolean removeCacheListener(CacheListener listener); + boolean removeCacheListener(CacheListener listener); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/CacheConfiguration.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/CacheConfiguration.java index 0ef235a8b..5d4156d21 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/CacheConfiguration.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/CacheConfiguration.java @@ -21,33 +21,33 @@ */ public class CacheConfiguration { - private long maxSize = -1; + private long maxSize = -1; - private long timeToLiveSeconds = -1; + private long timeToLiveSeconds = -1; - private long timeToIdleSeconds = -1; + private long timeToIdleSeconds = -1; - public long getMaxSize() { - return maxSize; - } + public long getMaxSize() { + return maxSize; + } - public void setMaxSize(long maxSize) { - this.maxSize = maxSize; - } + public void setMaxSize(long maxSize) { + this.maxSize = maxSize; + } - public long getTimeToLiveSeconds() { - return timeToLiveSeconds; - } + public long getTimeToLiveSeconds() { + return timeToLiveSeconds; + } - public void setTimeToLiveSeconds(long timeToLiveSeconds) { - this.timeToLiveSeconds = timeToLiveSeconds; - } + public void setTimeToLiveSeconds(long timeToLiveSeconds) { + this.timeToLiveSeconds = timeToLiveSeconds; + } - public long getTimeToIdleSeconds() { - return timeToIdleSeconds; - } + public long getTimeToIdleSeconds() { + return timeToIdleSeconds; + } - public void setTimeToIdleSeconds(long timeToIdleSeconds) { - this.timeToIdleSeconds = timeToIdleSeconds; - } + public void setTimeToIdleSeconds(long timeToIdleSeconds) { + this.timeToIdleSeconds = timeToIdleSeconds; + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/CacheListener.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/CacheListener.java index d818d7c28..7814c2175 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/CacheListener.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/CacheListener.java @@ -20,5 +20,5 @@ * @author GraviteeSource Team */ public interface CacheListener { - void onEvent(EntryEvent event); + void onEvent(EntryEvent event); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/CacheManager.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/CacheManager.java index 09a6309b3..1a56bf0df 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/CacheManager.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/CacheManager.java @@ -20,12 +20,9 @@ * @author GraviteeSource Team */ public interface CacheManager { - Cache getOrCreateCache(String name); + Cache getOrCreateCache(String name); - Cache getOrCreateCache( - String name, - CacheConfiguration configuration - ); + Cache getOrCreateCache(String name, CacheConfiguration configuration); - void destroy(String name); + void destroy(String name); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/EntryEvent.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/EntryEvent.java index aa5dcb48d..81d607d5c 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/EntryEvent.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/EntryEvent.java @@ -23,56 +23,50 @@ */ public class EntryEvent extends EventObject { - private K key; - private V oldValue; - private V value; - private final EntryEventType eventType; + private K key; + private V oldValue; + private V value; + private final EntryEventType eventType; - /** - * Constructs a prototypical Event. - * - * @param source the object on which the Event initially occurred - * @throws IllegalArgumentException if source is null - */ - public EntryEvent( - Object source, - EntryEventType eventType, - K key, - V oldValue, - V value - ) { - super(source); - this.eventType = eventType; - this.key = key; - this.oldValue = oldValue; - this.value = value; - } + /** + * Constructs a prototypical Event. + * + * @param source the object on which the Event initially occurred + * @throws IllegalArgumentException if source is null + */ + public EntryEvent(Object source, EntryEventType eventType, K key, V oldValue, V value) { + super(source); + this.eventType = eventType; + this.key = key; + this.oldValue = oldValue; + this.value = value; + } - public K getKey() { - return key; - } + public K getKey() { + return key; + } - public void setKey(K key) { - this.key = key; - } + public void setKey(K key) { + this.key = key; + } - public V getOldValue() { - return oldValue; - } + public V getOldValue() { + return oldValue; + } - public void setOldValue(V oldValue) { - this.oldValue = oldValue; - } + public void setOldValue(V oldValue) { + this.oldValue = oldValue; + } - public V getValue() { - return value; - } + public V getValue() { + return value; + } - public void setValue(V value) { - this.value = value; - } + public void setValue(V value) { + this.value = value; + } - public EntryEventType getEventType() { - return eventType; - } + public EntryEventType getEventType() { + return eventType; + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/EntryEventType.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/EntryEventType.java index cf25e3a97..737075374 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/EntryEventType.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/cache/EntryEventType.java @@ -16,111 +16,111 @@ package io.gravitee.node.api.cache; public enum EntryEventType { - /** - * Fired if an entry is added. - */ - ADDED(TypeId.ADDED), + /** + * Fired if an entry is added. + */ + ADDED(TypeId.ADDED), - /** - * Fired if an entry is removed. - */ - REMOVED(TypeId.REMOVED), + /** + * Fired if an entry is removed. + */ + REMOVED(TypeId.REMOVED), - /** - * Fired if an entry is updated. - */ - UPDATED(TypeId.UPDATED), + /** + * Fired if an entry is updated. + */ + UPDATED(TypeId.UPDATED), - /** - * Fired if an entry is evicted. - */ - EVICTED(TypeId.EVICTED), + /** + * Fired if an entry is evicted. + */ + EVICTED(TypeId.EVICTED), - /** - * Fired if an entry is expired. - */ - EXPIRED(TypeId.EXPIRED), - /** - * Fired if all entries are evicted. - */ - EVICT_ALL(TypeId.EVICT_ALL), + /** + * Fired if an entry is expired. + */ + EXPIRED(TypeId.EXPIRED), + /** + * Fired if all entries are evicted. + */ + EVICT_ALL(TypeId.EVICT_ALL), - /** - * Fired if all entries are cleared. - */ - CLEAR_ALL(TypeId.CLEAR_ALL), + /** + * Fired if all entries are cleared. + */ + CLEAR_ALL(TypeId.CLEAR_ALL), - /** - * Fired if an entry is merged after a network partition. - */ - MERGED(TypeId.MERGED), + /** + * Fired if an entry is merged after a network partition. + */ + MERGED(TypeId.MERGED), - /** - * Fired if an entry is invalidated. - */ - INVALIDATION(TypeId.INVALIDATION), + /** + * Fired if an entry is invalidated. + */ + INVALIDATION(TypeId.INVALIDATION), - /** - * Fired if an entry is loaded. - */ - LOADED(TypeId.LOADED); + /** + * Fired if an entry is loaded. + */ + LOADED(TypeId.LOADED); - private int typeId; + private int typeId; - EntryEventType(final int typeId) { - this.typeId = typeId; - } + EntryEventType(final int typeId) { + this.typeId = typeId; + } - /** - * @return the event type ID - */ - public int getType() { - return typeId; - } + /** + * @return the event type ID + */ + public int getType() { + return typeId; + } - /** - * @return the matching EntryEventType for the supplied {@code typeId} - * or {@code null} if there is no match - */ - @SuppressWarnings("checkstyle:returncount") - public static EntryEventType getByType(final int typeId) { - switch (typeId) { - case TypeId.ADDED: - return ADDED; - case TypeId.REMOVED: - return REMOVED; - case TypeId.UPDATED: - return UPDATED; - case TypeId.EVICTED: - return EVICTED; - case TypeId.EVICT_ALL: - return EVICT_ALL; - case TypeId.CLEAR_ALL: - return CLEAR_ALL; - case TypeId.MERGED: - return MERGED; - case TypeId.EXPIRED: - return EXPIRED; - case TypeId.INVALIDATION: - return INVALIDATION; - case TypeId.LOADED: - return LOADED; - default: - return null; + /** + * @return the matching EntryEventType for the supplied {@code typeId} + * or {@code null} if there is no match + */ + @SuppressWarnings("checkstyle:returncount") + public static EntryEventType getByType(final int typeId) { + switch (typeId) { + case TypeId.ADDED: + return ADDED; + case TypeId.REMOVED: + return REMOVED; + case TypeId.UPDATED: + return UPDATED; + case TypeId.EVICTED: + return EVICTED; + case TypeId.EVICT_ALL: + return EVICT_ALL; + case TypeId.CLEAR_ALL: + return CLEAR_ALL; + case TypeId.MERGED: + return MERGED; + case TypeId.EXPIRED: + return EXPIRED; + case TypeId.INVALIDATION: + return INVALIDATION; + case TypeId.LOADED: + return LOADED; + default: + return null; + } } - } - private static class TypeId { + private static class TypeId { - private static final int ADDED = 1; - private static final int REMOVED = 1 << 1; - private static final int UPDATED = 1 << 2; - private static final int EVICTED = 1 << 3; - private static final int EXPIRED = 1 << 4; - private static final int EVICT_ALL = 1 << 5; - private static final int CLEAR_ALL = 1 << 6; - private static final int MERGED = 1 << 7; - private static final int INVALIDATION = 1 << 8; - private static final int LOADED = 1 << 9; - } + private static final int ADDED = 1; + private static final int REMOVED = 1 << 1; + private static final int UPDATED = 1 << 2; + private static final int EVICTED = 1 << 3; + private static final int EXPIRED = 1 << 4; + private static final int EVICT_ALL = 1 << 5; + private static final int CLEAR_ALL = 1 << 6; + private static final int MERGED = 1 << 7; + private static final int INVALIDATION = 1 << 8; + private static final int LOADED = 1 << 9; + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/CertificateManager.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/CertificateManager.java index 8844a5a80..d6f2a3525 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/CertificateManager.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/CertificateManager.java @@ -22,5 +22,5 @@ * @author GraviteeSource Team */ public interface CertificateManager { - void registerLoader(KeyStoreLoader loader); + void registerLoader(KeyStoreLoader loader); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/CertificateOptions.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/CertificateOptions.java index 541e5c46e..2926fcaea 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/CertificateOptions.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/CertificateOptions.java @@ -17,19 +17,19 @@ public class CertificateOptions { - private final String certificate; - private final String privateKey; + private final String certificate; + private final String privateKey; - public CertificateOptions(String certificate, String privateKey) { - this.certificate = certificate; - this.privateKey = privateKey; - } + public CertificateOptions(String certificate, String privateKey) { + this.certificate = certificate; + this.privateKey = privateKey; + } - public String getCertificate() { - return certificate; - } + public String getCertificate() { + return certificate; + } - public String getPrivateKey() { - return privateKey; - } + public String getPrivateKey() { + return privateKey; + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreBundle.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreBundle.java index 305ddacce..b256ab8e8 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreBundle.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreBundle.java @@ -23,41 +23,37 @@ */ public class KeyStoreBundle { - private KeyStore keyStore; - private String password; - private String defaultAlias; - - public KeyStoreBundle( - KeyStore keyStore, - String password, - String defaultAlias - ) { - this.keyStore = keyStore; - this.password = password; - this.defaultAlias = defaultAlias; - } - - public KeyStore getKeyStore() { - return keyStore; - } - - public void setKeyStore(KeyStore keyStore) { - this.keyStore = keyStore; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getDefaultAlias() { - return defaultAlias; - } - - public void setDefaultAlias(String defaultAlias) { - this.defaultAlias = defaultAlias; - } + private KeyStore keyStore; + private String password; + private String defaultAlias; + + public KeyStoreBundle(KeyStore keyStore, String password, String defaultAlias) { + this.keyStore = keyStore; + this.password = password; + this.defaultAlias = defaultAlias; + } + + public KeyStore getKeyStore() { + return keyStore; + } + + public void setKeyStore(KeyStore keyStore) { + this.keyStore = keyStore; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getDefaultAlias() { + return defaultAlias; + } + + public void setDefaultAlias(String defaultAlias) { + this.defaultAlias = defaultAlias; + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreLoader.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreLoader.java index 1e37d1035..ed6e4dd25 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreLoader.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreLoader.java @@ -22,14 +22,14 @@ * @author GraviteeSource Team */ public interface KeyStoreLoader { - String CERTIFICATE_FORMAT_JKS = "JKS"; - String CERTIFICATE_FORMAT_PEM = "PEM"; - String CERTIFICATE_FORMAT_PKCS12 = "PKCS12"; - String CERTIFICATE_FORMAT_SELF_SIGNED = "SELF-SIGNED"; + String CERTIFICATE_FORMAT_JKS = "JKS"; + String CERTIFICATE_FORMAT_PEM = "PEM"; + String CERTIFICATE_FORMAT_PKCS12 = "PKCS12"; + String CERTIFICATE_FORMAT_SELF_SIGNED = "SELF-SIGNED"; - void start(); + void start(); - void stop(); + void stop(); - void addListener(Consumer listener); + void addListener(Consumer listener); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreLoaderFactory.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreLoaderFactory.java index 90df868da..a0bd6f76d 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreLoaderFactory.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreLoaderFactory.java @@ -20,7 +20,7 @@ * @author GraviteeSource Team */ public interface KeyStoreLoaderFactory { - boolean canHandle(KeyStoreLoaderOptions options); + boolean canHandle(KeyStoreLoaderOptions options); - KeyStoreLoader create(KeyStoreLoaderOptions options); + KeyStoreLoader create(KeyStoreLoaderOptions options); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreLoaderOptions.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreLoaderOptions.java index b3487e115..2efe4a935 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreLoaderOptions.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/certificate/KeyStoreLoaderOptions.java @@ -23,123 +23,119 @@ */ public class KeyStoreLoaderOptions { - private String keyStorePath; - private String keyStorePassword; - private String keyStoreType; - private List kubernetesLocations; - private List keyStoreCertificates; - private boolean watch = true; - private String defaultAlias = null; - - public String getKeyStorePath() { - return keyStorePath; - } + private String keyStorePath; + private String keyStorePassword; + private String keyStoreType; + private List kubernetesLocations; + private List keyStoreCertificates; + private boolean watch = true; + private String defaultAlias = null; + + public String getKeyStorePath() { + return keyStorePath; + } - public void setKeyStorePath(String keyStorePath) { - this.keyStorePath = keyStorePath; - } + public void setKeyStorePath(String keyStorePath) { + this.keyStorePath = keyStorePath; + } - public String getKeyStorePassword() { - return keyStorePassword; - } + public String getKeyStorePassword() { + return keyStorePassword; + } - public void setKeyStorePassword(String keyStorePassword) { - this.keyStorePassword = keyStorePassword; - } + public void setKeyStorePassword(String keyStorePassword) { + this.keyStorePassword = keyStorePassword; + } - public String getKeyStoreType() { - return keyStoreType; - } + public String getKeyStoreType() { + return keyStoreType; + } - public void setKeyStoreType(String keyStoreType) { - this.keyStoreType = keyStoreType; - } + public void setKeyStoreType(String keyStoreType) { + this.keyStoreType = keyStoreType; + } - public List getKeyStoreCertificates() { - return keyStoreCertificates; - } + public List getKeyStoreCertificates() { + return keyStoreCertificates; + } - public void setKeyStoreCertificates( - List keyStoreCertificates - ) { - this.keyStoreCertificates = keyStoreCertificates; - } + public void setKeyStoreCertificates(List keyStoreCertificates) { + this.keyStoreCertificates = keyStoreCertificates; + } - public List getKubernetesLocations() { - return kubernetesLocations; - } + public List getKubernetesLocations() { + return kubernetesLocations; + } - public void setKubernetesLocations(List kubernetesLocations) { - this.kubernetesLocations = kubernetesLocations; - } + public void setKubernetesLocations(List kubernetesLocations) { + this.kubernetesLocations = kubernetesLocations; + } - public boolean isWatch() { - return watch; - } + public boolean isWatch() { + return watch; + } - public void setWatch(boolean watch) { - this.watch = watch; - } + public void setWatch(boolean watch) { + this.watch = watch; + } - public String getDefaultAlias() { - return defaultAlias; - } + public String getDefaultAlias() { + return defaultAlias; + } - public void setDefaultAlias(String defaultAlias) { - this.defaultAlias = defaultAlias; - } + public void setDefaultAlias(String defaultAlias) { + this.defaultAlias = defaultAlias; + } - public static Builder builder() { - return new Builder(); - } + public static Builder builder() { + return new Builder(); + } - public static final class Builder { + public static final class Builder { - private KeyStoreLoaderOptions keyStoreLoaderOptions; + private KeyStoreLoaderOptions keyStoreLoaderOptions; - private Builder() { - keyStoreLoaderOptions = new KeyStoreLoaderOptions(); - } + private Builder() { + keyStoreLoaderOptions = new KeyStoreLoaderOptions(); + } - public Builder withKeyStorePath(String keyStorePath) { - keyStoreLoaderOptions.setKeyStorePath(keyStorePath); - return this; - } + public Builder withKeyStorePath(String keyStorePath) { + keyStoreLoaderOptions.setKeyStorePath(keyStorePath); + return this; + } - public Builder withKeyStorePassword(String keyStorePassword) { - keyStoreLoaderOptions.setKeyStorePassword(keyStorePassword); - return this; - } + public Builder withKeyStorePassword(String keyStorePassword) { + keyStoreLoaderOptions.setKeyStorePassword(keyStorePassword); + return this; + } - public Builder withKeyStoreType(String keyStoreType) { - keyStoreLoaderOptions.setKeyStoreType(keyStoreType); - return this; - } + public Builder withKeyStoreType(String keyStoreType) { + keyStoreLoaderOptions.setKeyStoreType(keyStoreType); + return this; + } - public Builder withKubernetesLocations(List kubernetesLocations) { - keyStoreLoaderOptions.setKubernetesLocations(kubernetesLocations); - return this; - } + public Builder withKubernetesLocations(List kubernetesLocations) { + keyStoreLoaderOptions.setKubernetesLocations(kubernetesLocations); + return this; + } - public Builder withKeyStoreCertificates( - List keyStoreCertificates - ) { - keyStoreLoaderOptions.setKeyStoreCertificates(keyStoreCertificates); - return this; - } + public Builder withKeyStoreCertificates(List keyStoreCertificates) { + keyStoreLoaderOptions.setKeyStoreCertificates(keyStoreCertificates); + return this; + } - public Builder withWatch(boolean watch) { - keyStoreLoaderOptions.setWatch(watch); - return this; - } + public Builder withWatch(boolean watch) { + keyStoreLoaderOptions.setWatch(watch); + return this; + } - public Builder withDefaultAlias(String defaultAlias) { - keyStoreLoaderOptions.setDefaultAlias(defaultAlias); - return this; - } + public Builder withDefaultAlias(String defaultAlias) { + keyStoreLoaderOptions.setDefaultAlias(defaultAlias); + return this; + } - public KeyStoreLoaderOptions build() { - return keyStoreLoaderOptions; + public KeyStoreLoaderOptions build() { + return keyStoreLoaderOptions; + } } - } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/cluster/ClusterManager.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/cluster/ClusterManager.java index 10e14dfc5..bacfc0253 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/cluster/ClusterManager.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/cluster/ClusterManager.java @@ -22,18 +22,18 @@ * @author GraviteeSource Team */ public interface ClusterManager { - Collection getMembers(); + Collection getMembers(); - Member getLocalMember(); + Member getLocalMember(); - /** - * Indicates if the local node is the master node of the cluster - * - * @return Local node is master node? - */ - boolean isMasterNode(); + /** + * Indicates if the local node is the master node of the cluster + * + * @return Local node is master node? + */ + boolean isMasterNode(); - void addMemberListener(MemberListener listener); + void addMemberListener(MemberListener listener); - void stop(); + void stop(); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/cluster/Member.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/cluster/Member.java index 043579c6d..a82c306f3 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/cluster/Member.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/cluster/Member.java @@ -22,13 +22,13 @@ * @author GraviteeSource Team */ public interface Member { - String uuid(); + String uuid(); - boolean master(); + boolean master(); - String host(); + String host(); - Map attributes(); + Map attributes(); - Member attribute(String key, String value); + Member attribute(String key, String value); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/cluster/MemberListener.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/cluster/MemberListener.java index 9ac01ce65..787df5fbd 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/cluster/MemberListener.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/cluster/MemberListener.java @@ -20,9 +20,9 @@ * @author GraviteeSource Team */ public interface MemberListener { - void memberAdded(Member member); + void memberAdded(Member member); - void memberRemoved(Member member); + void memberRemoved(Member member); - void memberChanged(Member member); + void memberChanged(Member member); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/configuration/Configuration.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/configuration/Configuration.java index ff9a42cbc..33a258c7c 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/configuration/Configuration.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/configuration/Configuration.java @@ -19,13 +19,13 @@ * The {@link Configuration} maintains the state of the node's configuration. */ public interface Configuration { - boolean containsProperty(String key); + boolean containsProperty(String key); - String getProperty(String key); + String getProperty(String key); - String getProperty(String key, String defaultValue); + String getProperty(String key, String defaultValue); - T getProperty(String key, Class targetType); + T getProperty(String key, Class targetType); - T getProperty(String key, Class targetType, T defaultValue); + T getProperty(String key, Class targetType, T defaultValue); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/HealthCheck.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/HealthCheck.java index 966585dda..48ce09d90 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/HealthCheck.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/HealthCheck.java @@ -24,53 +24,53 @@ */ public class HealthCheck implements Serializable { - /** - * Flag indicating if the global status of health check is healthy or not. - * It is basically based on the healthiness of all the health check probes. - */ - private boolean isHealthy; + /** + * Flag indicating if the global status of health check is healthy or not. + * It is basically based on the healthiness of all the health check probes. + */ + private boolean isHealthy; - /** - * The date on which the health check has been performed. - */ - private long evaluatedAt; + /** + * The date on which the health check has been performed. + */ + private long evaluatedAt; - /** - * Map of probe and associated result. - */ - private Map results; + /** + * Map of probe and associated result. + */ + private Map results; - public HealthCheck() { - super(); - } + public HealthCheck() { + super(); + } - public HealthCheck(long evaluatedAt, Map results) { - this.evaluatedAt = evaluatedAt; - this.results = results; - this.isHealthy = this.results.values().stream().allMatch(Result::isHealthy); - } + public HealthCheck(long evaluatedAt, Map results) { + this.evaluatedAt = evaluatedAt; + this.results = results; + this.isHealthy = this.results.values().stream().allMatch(Result::isHealthy); + } - public Map getResults() { - return results; - } + public Map getResults() { + return results; + } - public boolean isHealthy() { - return isHealthy; - } + public boolean isHealthy() { + return isHealthy; + } - public void setHealthy(boolean healthy) { - isHealthy = healthy; - } + public void setHealthy(boolean healthy) { + isHealthy = healthy; + } - public void setResults(Map results) { - this.results = results; - } + public void setResults(Map results) { + this.results = results; + } - public long getEvaluatedAt() { - return evaluatedAt; - } + public long getEvaluatedAt() { + return evaluatedAt; + } - public void setEvaluatedAt(long evaluatedAt) { - this.evaluatedAt = evaluatedAt; - } + public void setEvaluatedAt(long evaluatedAt) { + this.evaluatedAt = evaluatedAt; + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/Probe.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/Probe.java index 496bd6480..9c8f87461 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/Probe.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/Probe.java @@ -22,11 +22,11 @@ * @author GraviteeSource Team */ public interface Probe { - String id(); + String id(); - CompletionStage check(); + CompletionStage check(); - default boolean isVisibleByDefault() { - return true; - } + default boolean isVisibleByDefault() { + return true; + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/ProbeManager.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/ProbeManager.java index 12b015f73..e6a3ac592 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/ProbeManager.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/ProbeManager.java @@ -22,9 +22,9 @@ * @author GraviteeSource Team */ public interface ProbeManager { - List getProbes(); + List getProbes(); - void register(Probe probe); + void register(Probe probe); - void unregister(Probe probe); + void unregister(Probe probe); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/Result.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/Result.java index 5ce856db2..d94827020 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/Result.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/healthcheck/Result.java @@ -23,94 +23,87 @@ */ public class Result implements Serializable { - private static final Result HEALTHY = new Result(true, null); - private static final Result NOT_READY = new Result(false, "not ready"); + private static final Result HEALTHY = new Result(true, null); + private static final Result NOT_READY = new Result(false, "not ready"); - private static final int PRIME = 31; + private static final int PRIME = 31; - private final boolean healthy; - private final String message; + private final boolean healthy; + private final String message; - public Result() { - this.healthy = true; - this.message = null; - } + public Result() { + this.healthy = true; + this.message = null; + } - protected Result(boolean isHealthy, String message) { - this.healthy = isHealthy; - this.message = message; - } + protected Result(boolean isHealthy, String message) { + this.healthy = isHealthy; + this.message = message; + } - public static Result unhealthy(Throwable error) { - return new Result(false, error.getMessage()); - } + public static Result unhealthy(Throwable error) { + return new Result(false, error.getMessage()); + } - public static Result unhealthy(String message) { - return new Result(false, message); - } + public static Result unhealthy(String message) { + return new Result(false, message); + } - public static Result unhealthy(String message, Object... args) { - return unhealthy(String.format(message, args)); - } + public static Result unhealthy(String message, Object... args) { + return unhealthy(String.format(message, args)); + } - public static Result healthy(String message, Object... args) { - return healthy(String.format(message, args)); - } + public static Result healthy(String message, Object... args) { + return healthy(String.format(message, args)); + } - public static Result healthy(String message) { - return new Result(true, message); - } + public static Result healthy(String message) { + return new Result(true, message); + } - public static Result healthy() { - return HEALTHY; - } + public static Result healthy() { + return HEALTHY; + } - public boolean isHealthy() { - return healthy; - } + public boolean isHealthy() { + return healthy; + } - public static Result notReady() { - return NOT_READY; - } + public static Result notReady() { + return NOT_READY; + } - public String getMessage() { - return message; - } + public String getMessage() { + return message; + } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Result result = (Result) o; + return (healthy == result.healthy && !(message != null ? !message.equals(result.message) : result.message != null)); } - if (o == null || getClass() != o.getClass()) { - return false; + + @Override + public int hashCode() { + int result = (healthy ? 1 : 0); + result = PRIME * result + (message != null ? message.hashCode() : 0); + return result; } - final Result result = (Result) o; - return ( - healthy == result.healthy && - !( - message != null - ? !message.equals(result.message) - : result.message != null - ) - ); - } - - @Override - public int hashCode() { - int result = (healthy ? 1 : 0); - result = PRIME * result + (message != null ? message.hashCode() : 0); - return result; - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder("Result{isHealthy="); - builder.append(healthy); - if (message != null) { - builder.append(", message=").append(message); + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder("Result{isHealthy="); + builder.append(healthy); + if (message != null) { + builder.append(", message=").append(message); + } + builder.append('}'); + return builder.toString(); } - builder.append('}'); - return builder.toString(); - } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/heartbeat/Event.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/heartbeat/Event.java index 59aa3b1f1..d4d29c17f 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/heartbeat/Event.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/heartbeat/Event.java @@ -23,49 +23,49 @@ */ public class Event { - private String id; - private EventType type; - private String payload; - private Date createdAt; - private Date updatedAt; + private String id; + private EventType type; + private String payload; + private Date createdAt; + private Date updatedAt; - public String getId() { - return id; - } + public String getId() { + return id; + } - public void setId(String id) { - this.id = id; - } + public void setId(String id) { + this.id = id; + } - public EventType getType() { - return type; - } + public EventType getType() { + return type; + } - public void setType(EventType type) { - this.type = type; - } + public void setType(EventType type) { + this.type = type; + } - public String getPayload() { - return payload; - } + public String getPayload() { + return payload; + } - public void setPayload(String payload) { - this.payload = payload; - } + public void setPayload(String payload) { + this.payload = payload; + } - public Date getCreatedAt() { - return createdAt; - } + public Date getCreatedAt() { + return createdAt; + } - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - } + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } - public Date getUpdatedAt() { - return updatedAt; - } + public Date getUpdatedAt() { + return updatedAt; + } - public void setUpdatedAt(Date updatedAt) { - this.updatedAt = updatedAt; - } + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/heartbeat/EventType.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/heartbeat/EventType.java index ca39078cd..60821765b 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/heartbeat/EventType.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/heartbeat/EventType.java @@ -16,6 +16,6 @@ package io.gravitee.node.api.heartbeat; public enum EventType { - NODE_STARTED, - NODE_STOPPED, + NODE_STARTED, + NODE_STOPPED, } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/infos/NodeInfos.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/infos/NodeInfos.java index ba66df407..5540cf3e5 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/infos/NodeInfos.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/infos/NodeInfos.java @@ -26,121 +26,121 @@ */ public class NodeInfos implements Serializable { - private String id; - private String name; - private String application; - private long evaluatedAt; - private NodeStatus status; - private String version; - private String jdkVersion; - private List tags; - private String hostname; - private String ip; - private int port; - private String tenant; - private Set pluginInfos; - - public String getHostname() { - return hostname; - } - - public void setHostname(String hostname) { - this.hostname = hostname; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getIp() { - return ip; - } - - public void setIp(String ip) { - this.ip = ip; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public List getTags() { - return tags; - } - - public void setTags(List tags) { - this.tags = tags; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public Set getPluginInfos() { - return pluginInfos; - } - - public void setPluginInfos(Set pluginInfos) { - this.pluginInfos = pluginInfos; - } - - public String getTenant() { - return tenant; - } - - public void setTenant(String tenant) { - this.tenant = tenant; - } - - public NodeStatus getStatus() { - return status; - } - - public void setStatus(NodeStatus status) { - this.status = status; - } - - public String getJdkVersion() { - return jdkVersion; - } - - public void setJdkVersion(String jdkVersion) { - this.jdkVersion = jdkVersion; - } - - public long getEvaluatedAt() { - return evaluatedAt; - } - - public void setEvaluatedAt(long evaluatedAt) { - this.evaluatedAt = evaluatedAt; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getApplication() { - return application; - } + private String id; + private String name; + private String application; + private long evaluatedAt; + private NodeStatus status; + private String version; + private String jdkVersion; + private List tags; + private String hostname; + private String ip; + private int port; + private String tenant; + private Set pluginInfos; + + public String getHostname() { + return hostname; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public Set getPluginInfos() { + return pluginInfos; + } + + public void setPluginInfos(Set pluginInfos) { + this.pluginInfos = pluginInfos; + } + + public String getTenant() { + return tenant; + } + + public void setTenant(String tenant) { + this.tenant = tenant; + } + + public NodeStatus getStatus() { + return status; + } + + public void setStatus(NodeStatus status) { + this.status = status; + } + + public String getJdkVersion() { + return jdkVersion; + } + + public void setJdkVersion(String jdkVersion) { + this.jdkVersion = jdkVersion; + } + + public long getEvaluatedAt() { + return evaluatedAt; + } + + public void setEvaluatedAt(long evaluatedAt) { + this.evaluatedAt = evaluatedAt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getApplication() { + return application; + } - public void setApplication(String application) { - this.application = application; - } + public void setApplication(String application) { + this.application = application; + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/infos/NodeStatus.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/infos/NodeStatus.java index 4cd395937..74910a3f5 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/infos/NodeStatus.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/infos/NodeStatus.java @@ -20,6 +20,6 @@ * @author GraviteeSource Team */ public enum NodeStatus { - STARTED, - STOPPED, + STARTED, + STOPPED, } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/infos/PluginInfos.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/infos/PluginInfos.java index 47b2e565b..eb304da54 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/infos/PluginInfos.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/infos/PluginInfos.java @@ -25,76 +25,76 @@ */ public class PluginInfos implements Serializable { - private String id; + private String id; - private String name; + private String name; - private String description; + private String description; - private String version; + private String version; - private String plugin; + private String plugin; - private String type; + private String type; - public String getDescription() { - return description; - } + public String getDescription() { + return description; + } - public void setDescription(String description) { - this.description = description; - } + public void setDescription(String description) { + this.description = description; + } - public String getId() { - return id; - } + public String getId() { + return id; + } - public void setId(String id) { - this.id = id; - } + public void setId(String id) { + this.id = id; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - public String getPlugin() { - return plugin; - } + public String getPlugin() { + return plugin; + } - public void setPlugin(String plugin) { - this.plugin = plugin; - } + public void setPlugin(String plugin) { + this.plugin = plugin; + } - public String getType() { - return type; - } + public String getType() { + return type; + } - public void setType(String type) { - this.type = type; - } + public void setType(String type) { + this.type = type; + } - public String getVersion() { - return version; - } + public String getVersion() { + return version; + } - public void setVersion(String version) { - this.version = version; - } + public void setVersion(String version) { + this.version = version; + } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PluginInfos plugin = (PluginInfos) o; - return Objects.equals(id, plugin.id) && Objects.equals(type, plugin.type); - } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PluginInfos plugin = (PluginInfos) o; + return Objects.equals(id, plugin.id) && Objects.equals(type, plugin.type); + } - @Override - public int hashCode() { - return Objects.hash(id, type); - } + @Override + public int hashCode() { + return Objects.hash(id, type); + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/message/Message.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/message/Message.java index d691baf2f..a95ff974e 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/message/Message.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/message/Message.java @@ -23,24 +23,24 @@ */ public class Message extends EventObject { - private T messageObject; + private T messageObject; - /** - * Constructs a prototypical Event. - * - * @param topicName the object on which the Event initially occurred - * @throws IllegalArgumentException if source is null - */ - public Message(String topicName, T messageObject) { - super(topicName); - this.messageObject = messageObject; - } + /** + * Constructs a prototypical Event. + * + * @param topicName the object on which the Event initially occurred + * @throws IllegalArgumentException if source is null + */ + public Message(String topicName, T messageObject) { + super(topicName); + this.messageObject = messageObject; + } - public T getMessageObject() { - return messageObject; - } + public T getMessageObject() { + return messageObject; + } - public void setMessageObject(T messageObject) { - this.messageObject = messageObject; - } + public void setMessageObject(T messageObject) { + this.messageObject = messageObject; + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/message/MessageConsumer.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/message/MessageConsumer.java index 068bcab02..8d2345e40 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/message/MessageConsumer.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/message/MessageConsumer.java @@ -20,5 +20,5 @@ * @author GraviteeSource Team */ public interface MessageConsumer { - void onMessage(Message message); + void onMessage(Message message); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/message/MessageProducer.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/message/MessageProducer.java index ef45564d0..33e414a80 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/message/MessageProducer.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/message/MessageProducer.java @@ -20,5 +20,5 @@ * @author GraviteeSource Team */ public interface MessageProducer { - Topic getTopic(String name); + Topic getTopic(String name); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/message/Topic.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/message/Topic.java index 053e2e9e1..a781e8bb3 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/message/Topic.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/message/Topic.java @@ -22,7 +22,7 @@ * @author GraviteeSource Team */ public interface Topic { - void publish(T event); - UUID addMessageConsumer(MessageConsumer messageConsumer); - boolean removeMessageConsumer(UUID uuid); + void publish(T event); + UUID addMessageConsumer(MessageConsumer messageConsumer); + boolean removeMessageConsumer(UUID uuid); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/JvmInfo.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/JvmInfo.java index 5e272f0c7..4c552f50b 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/JvmInfo.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/JvmInfo.java @@ -23,118 +23,112 @@ */ public final class JvmInfo implements Serializable { - public long timestamp = -1; - public long uptime; - public Mem mem; - public Threads threads; - public GarbageCollectors gc; - - protected JvmInfo() {} - - public JvmInfo(long timestamp, long uptime) { - this.timestamp = timestamp; - this.uptime = uptime; - } - - public static class Mem implements Serializable { - - public long heapCommitted; - public long heapUsed; - public long heapMax; - public long nonHeapCommitted; - public long nonHeapUsed; - - public MemoryPool[] pools = new MemoryPool[0]; - - public short getHeapUsedPercent() { - if (heapMax == 0) { - return -1; - } - return (short) (heapUsed * 100 / heapMax); - } - } - - public static class MemoryPool implements Serializable { - - public String name; - public long used; - public long max; - - public long peakUsed; - public long peakMax; - - protected MemoryPool() {} - - public MemoryPool( - String name, - long used, - long max, - long peakUsed, - long peakMax - ) { - this.name = name; - this.used = used; - this.max = max; - this.peakUsed = peakUsed; - this.peakMax = peakMax; - } + public long timestamp = -1; + public long uptime; + public Mem mem; + public Threads threads; + public GarbageCollectors gc; - public String getName() { - return this.name; - } + protected JvmInfo() {} - public long getUsed() { - return used; + public JvmInfo(long timestamp, long uptime) { + this.timestamp = timestamp; + this.uptime = uptime; } - public long getMax() { - return max; - } + public static class Mem implements Serializable { - public long getPeakUsed() { - return peakUsed; - } + public long heapCommitted; + public long heapUsed; + public long heapMax; + public long nonHeapCommitted; + public long nonHeapUsed; - public long getPeakMax() { - return peakMax; + public MemoryPool[] pools = new MemoryPool[0]; + + public short getHeapUsedPercent() { + if (heapMax == 0) { + return -1; + } + return (short) (heapUsed * 100 / heapMax); + } } - } - public static class Threads implements Serializable { + public static class MemoryPool implements Serializable { - public int count; - public int peakCount; + public String name; + public long used; + public long max; - public int getCount() { - return count; - } + public long peakUsed; + public long peakMax; - public int getPeakCount() { - return peakCount; - } - } + protected MemoryPool() {} - public static class GarbageCollectors implements Serializable { + public MemoryPool(String name, long used, long max, long peakUsed, long peakMax) { + this.name = name; + this.used = used; + this.max = max; + this.peakUsed = peakUsed; + this.peakMax = peakMax; + } - public GarbageCollector[] collectors; - } + public String getName() { + return this.name; + } - public static class GarbageCollector implements Serializable { + public long getUsed() { + return used; + } - public String name; - public long collectionCount; - public long collectionTime; + public long getMax() { + return max; + } - public String getName() { - return this.name; + public long getPeakUsed() { + return peakUsed; + } + + public long getPeakMax() { + return peakMax; + } } - public long getCollectionTime() { - return collectionTime; + public static class Threads implements Serializable { + + public int count; + public int peakCount; + + public int getCount() { + return count; + } + + public int getPeakCount() { + return peakCount; + } + } + + public static class GarbageCollectors implements Serializable { + + public GarbageCollector[] collectors; } - public long getCollectionCount() { - return this.collectionCount; + public static class GarbageCollector implements Serializable { + + public String name; + public long collectionCount; + public long collectionTime; + + public String getName() { + return this.name; + } + + public long getCollectionTime() { + return collectionTime; + } + + public long getCollectionCount() { + return this.collectionCount; + } } - } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/Monitor.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/Monitor.java index 5fdbe1d88..1ac8db5bc 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/Monitor.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/Monitor.java @@ -26,88 +26,88 @@ // TODO: This class is a duplicate of the one coming from gravitee-reporter-api and will soon completely replace it. public class Monitor implements Serializable, Reportable { - private String nodeId; - private long timestamp; - - JvmInfo jvm; - OsInfo os; - ProcessInfo process; - - protected Monitor() {} - - public Monitor(String nodeId, final long timestamp) { - this.nodeId = nodeId; - this.timestamp = timestamp; - } - - @Override - public Instant timestamp() { - return Instant.ofEpochMilli(timestamp); - } - - public JvmInfo getJvm() { - return jvm; - } - - public OsInfo getOs() { - return os; - } - - public ProcessInfo getProcess() { - return process; - } + private String nodeId; + private long timestamp; - public long getTimestamp() { - return timestamp; - } + JvmInfo jvm; + OsInfo os; + ProcessInfo process; - public String getNodeId() { - return nodeId; - } + protected Monitor() {} - public static Builder on(String nodeId) { - return new Builder().on(nodeId); - } + public Monitor(String nodeId, final long timestamp) { + this.nodeId = nodeId; + this.timestamp = timestamp; + } - public static class Builder { + @Override + public Instant timestamp() { + return Instant.ofEpochMilli(timestamp); + } - private String nodeId; - private long timestamp; - private OsInfo os; - private JvmInfo jvm; - private ProcessInfo process; + public JvmInfo getJvm() { + return jvm; + } - public Builder on(String nodeId) { - this.nodeId = nodeId; - return this; + public OsInfo getOs() { + return os; } - public Builder at(long timestamp) { - this.timestamp = timestamp; - return this; + public ProcessInfo getProcess() { + return process; } - public Builder os(OsInfo os) { - this.os = os; - return this; + public long getTimestamp() { + return timestamp; } - public Builder jvm(JvmInfo jvm) { - this.jvm = jvm; - return this; + public String getNodeId() { + return nodeId; } - public Builder process(ProcessInfo process) { - this.process = process; - return this; + public static Builder on(String nodeId) { + return new Builder().on(nodeId); } - public Monitor build() { - Monitor metrics = new Monitor(nodeId, timestamp); - metrics.os = os; - metrics.jvm = jvm; - metrics.process = process; - return metrics; + public static class Builder { + + private String nodeId; + private long timestamp; + private OsInfo os; + private JvmInfo jvm; + private ProcessInfo process; + + public Builder on(String nodeId) { + this.nodeId = nodeId; + return this; + } + + public Builder at(long timestamp) { + this.timestamp = timestamp; + return this; + } + + public Builder os(OsInfo os) { + this.os = os; + return this; + } + + public Builder jvm(JvmInfo jvm) { + this.jvm = jvm; + return this; + } + + public Builder process(ProcessInfo process) { + this.process = process; + return this; + } + + public Monitor build() { + Monitor metrics = new Monitor(nodeId, timestamp); + metrics.os = os; + metrics.jvm = jvm; + metrics.process = process; + return metrics; + } } - } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/OsInfo.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/OsInfo.java index c55772c28..6dec664ae 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/OsInfo.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/OsInfo.java @@ -23,61 +23,61 @@ */ public class OsInfo implements Serializable { - public long timestamp; + public long timestamp; - public Cpu cpu = null; + public Cpu cpu = null; - public Mem mem = null; + public Mem mem = null; - public Swap swap = null; + public Swap swap = null; - public static class Cpu implements Serializable { + public static class Cpu implements Serializable { - public short percent = -1; - public double[] loadAverage = null; + public short percent = -1; + public double[] loadAverage = null; - public short getPercent() { - return percent; - } + public short getPercent() { + return percent; + } - public double[] getLoadAverage() { - return loadAverage; + public double[] getLoadAverage() { + return loadAverage; + } } - } - public static class Mem implements Serializable { + public static class Mem implements Serializable { - public long total = -1; - public long free = -1; + public long total = -1; + public long free = -1; - public long getTotal() { - return total; - } + public long getTotal() { + return total; + } - public long getUsed() { - return total - free; - } + public long getUsed() { + return total - free; + } - public short getUsedPercent() { - return calculatePercentage(getUsed(), getTotal()); - } + public short getUsedPercent() { + return calculatePercentage(getUsed(), getTotal()); + } - public long getFree() { - return free; - } + public long getFree() { + return free; + } - public short getFreePercent() { - return calculatePercentage(getFree(), getTotal()); + public short getFreePercent() { + return calculatePercentage(getFree(), getTotal()); + } } - } - public static class Swap implements Serializable { + public static class Swap implements Serializable { - public long total = -1; - public long free = -1; - } + public long total = -1; + public long free = -1; + } - private static short calculatePercentage(long used, long max) { - return max <= 0 ? 0 : (short) (Math.round((100d * used) / max)); - } + private static short calculatePercentage(long used, long max) { + return max <= 0 ? 0 : (short) (Math.round((100d * used) / max)); + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/ProcessInfo.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/ProcessInfo.java index dfebb1e65..ba272baa5 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/ProcessInfo.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/monitor/ProcessInfo.java @@ -23,34 +23,34 @@ */ public class ProcessInfo implements Serializable { - public long timestamp = -1; + public long timestamp = -1; - public long openFileDescriptors = -1; - public long maxFileDescriptors = -1; + public long openFileDescriptors = -1; + public long maxFileDescriptors = -1; - public Cpu cpu = null; - public Mem mem = null; + public Cpu cpu = null; + public Mem mem = null; - public static class Cpu implements Serializable { + public static class Cpu implements Serializable { - public short percent = -1; - public long total = -1; + public short percent = -1; + public long total = -1; - public short getPercent() { - return percent; - } + public short getPercent() { + return percent; + } - public long getTotal() { - return total; + public long getTotal() { + return total; + } } - } - public static class Mem implements Serializable { + public static class Mem implements Serializable { - public long totalVirtual = -1; + public long totalVirtual = -1; - public long getTotalVirtual() { - return totalVirtual; + public long getTotalVirtual() { + return totalVirtual; + } } - } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationAcknowledge.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationAcknowledge.java index 78429820b..be7ff3091 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationAcknowledge.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationAcknowledge.java @@ -23,104 +23,104 @@ */ public class NotificationAcknowledge { - private String id; + private String id; - private Date createdAt; + private Date createdAt; - private Date updatedAt; + private Date updatedAt; - private String resourceId; + private String resourceId; - private String resourceType; + private String resourceType; - private String type; + private String type; - private String audienceId; + private String audienceId; - private int counter = 1; + private int counter = 1; - public NotificationAcknowledge() { - this.createdAt = new Date(); - this.updatedAt = this.createdAt; - } + public NotificationAcknowledge() { + this.createdAt = new Date(); + this.updatedAt = this.createdAt; + } - public NotificationAcknowledge(NotificationAcknowledge other) { - this.id = other.id; - this.type = other.type; - this.counter = other.counter; - this.createdAt = other.createdAt; - this.audienceId = other.audienceId; - this.resourceId = other.resourceId; - this.resourceType = other.resourceType; + public NotificationAcknowledge(NotificationAcknowledge other) { + this.id = other.id; + this.type = other.type; + this.counter = other.counter; + this.createdAt = other.createdAt; + this.audienceId = other.audienceId; + this.resourceId = other.resourceId; + this.resourceType = other.resourceType; - this.updatedAt = new Date(); - } + this.updatedAt = new Date(); + } - public String getId() { - return id; - } + public String getId() { + return id; + } - public void setId(String id) { - this.id = id; - } + public void setId(String id) { + this.id = id; + } - public Date getCreatedAt() { - return createdAt; - } + public Date getCreatedAt() { + return createdAt; + } - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - } + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } - public String getResourceId() { - return resourceId; - } + public String getResourceId() { + return resourceId; + } - public void setResourceId(String resourceId) { - this.resourceId = resourceId; - } + public void setResourceId(String resourceId) { + this.resourceId = resourceId; + } - public String getResourceType() { - return resourceType; - } + public String getResourceType() { + return resourceType; + } - public void setResourceType(String resourceType) { - this.resourceType = resourceType; - } + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } - public String getType() { - return type; - } + public String getType() { + return type; + } - public Date getUpdatedAt() { - return updatedAt; - } + public Date getUpdatedAt() { + return updatedAt; + } - public void setUpdatedAt(Date updatedAt) { - this.updatedAt = updatedAt; - } + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } - public int getCounter() { - return counter; - } + public int getCounter() { + return counter; + } - public void setCounter(int counter) { - this.counter = counter; - } + public void setCounter(int counter) { + this.counter = counter; + } - public void incrementCounter() { - this.counter++; - } + public void incrementCounter() { + this.counter++; + } - public void setType(String type) { - this.type = type; - } + public void setType(String type) { + this.type = type; + } - public String getAudienceId() { - return audienceId; - } + public String getAudienceId() { + return audienceId; + } - public void setAudienceId(String audienceId) { - this.audienceId = audienceId; - } + public void setAudienceId(String audienceId) { + this.audienceId = audienceId; + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationAcknowledgeRepository.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationAcknowledgeRepository.java index cde060426..a13b828fc 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationAcknowledgeRepository.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationAcknowledgeRepository.java @@ -24,22 +24,18 @@ * @author GraviteeSource Team */ public interface NotificationAcknowledgeRepository { - Maybe findById(String id); + Maybe findById(String id); - Maybe findByResourceIdAndTypeAndAudienceId( - String resourceId, - String resourceType, - String type, - String audienceId - ); + Maybe findByResourceIdAndTypeAndAudienceId( + String resourceId, + String resourceType, + String type, + String audienceId + ); - Single create( - NotificationAcknowledge notificationAcknowledge - ); + Single create(NotificationAcknowledge notificationAcknowledge); - Single update( - NotificationAcknowledge notificationAcknowledge - ); + Single update(NotificationAcknowledge notificationAcknowledge); - Completable deleteByResourceId(String resourceId, String resourceType); + Completable deleteByResourceId(String resourceId, String resourceType); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationCondition.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationCondition.java index bf3625e0a..6dec2cb52 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationCondition.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationCondition.java @@ -21,5 +21,4 @@ * @author Eric LELEU (eric.leleu at graviteesource.com) * @author GraviteeSource Team */ -public interface NotificationCondition - extends Predicate {} +public interface NotificationCondition extends Predicate {} diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationDefinition.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationDefinition.java index 14814ff6d..861d4fa3f 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationDefinition.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotificationDefinition.java @@ -24,106 +24,106 @@ */ public class NotificationDefinition { - /** - * Resource concerned by the definition - */ - private String resourceId; - /** - * Resource Type concerned by the definition - */ - private String resourceType; - /** - * UserId targeted by the notification - */ - private String audienceId; - /** - * Plugin Notifier configuration - */ - private String configuration; - /** - * Type of notifier (plugin id) - */ - private String type; - /** - * Cron expression used to evaluate the rule - */ - private String cron; - /** - * Context used to evaluate the rule - */ - private Map data; - - public String getResourceId() { - return resourceId; - } - - public void setResourceId(String resourceId) { - this.resourceId = resourceId; - } - - public String getResourceType() { - return resourceType; - } - - public void setResourceType(String resourceType) { - this.resourceType = resourceType; - } - - public String getAudienceId() { - return audienceId; - } - - public void setAudienceId(String audienceId) { - this.audienceId = audienceId; - } - - public String getConfiguration() { - return configuration; - } - - public void setConfiguration(String configuration) { - this.configuration = configuration; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getCron() { - return cron; - } - - public void setCron(String cron) { - this.cron = cron; - } - - public Map getData() { - return data; - } - - public void setData(Map data) { - this.data = data; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof NotificationDefinition)) return false; - NotificationDefinition that = (NotificationDefinition) o; - return ( - Objects.equals(resourceId, that.resourceId) && - Objects.equals(resourceType, that.resourceType) && - Objects.equals(audienceId, that.audienceId) && - Objects.equals(type, that.type) - ); - } - - @Override - public int hashCode() { - return Objects.hash(resourceId, resourceType, audienceId, type); - } + /** + * Resource concerned by the definition + */ + private String resourceId; + /** + * Resource Type concerned by the definition + */ + private String resourceType; + /** + * UserId targeted by the notification + */ + private String audienceId; + /** + * Plugin Notifier configuration + */ + private String configuration; + /** + * Type of notifier (plugin id) + */ + private String type; + /** + * Cron expression used to evaluate the rule + */ + private String cron; + /** + * Context used to evaluate the rule + */ + private Map data; + + public String getResourceId() { + return resourceId; + } + + public void setResourceId(String resourceId) { + this.resourceId = resourceId; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public String getAudienceId() { + return audienceId; + } + + public void setAudienceId(String audienceId) { + this.audienceId = audienceId; + } + + public String getConfiguration() { + return configuration; + } + + public void setConfiguration(String configuration) { + this.configuration = configuration; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getCron() { + return cron; + } + + public void setCron(String cron) { + this.cron = cron; + } + + public Map getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof NotificationDefinition)) return false; + NotificationDefinition that = (NotificationDefinition) o; + return ( + Objects.equals(resourceId, that.resourceId) && + Objects.equals(resourceType, that.resourceType) && + Objects.equals(audienceId, that.audienceId) && + Objects.equals(type, that.type) + ); + } + + @Override + public int hashCode() { + return Objects.hash(resourceId, resourceType, audienceId, type); + } } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotifierService.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotifierService.java index efdf94944..f1861d1bf 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotifierService.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/NotifierService.java @@ -31,47 +31,38 @@ * @author GraviteeSource Team */ public interface NotifierService { - /** - * Register a notification in memory. - * - * @param definition Bean that contains all the settings to instantiate the notifier - * @param condition Rule evaluate to determine if the notification has to be triggered for the first time - * @param resendCondition Rule evaluate to determine if the notification has to be triggered another time - */ - void register( - NotificationDefinition definition, - NotificationCondition condition, - ResendNotificationCondition resendCondition - ); + /** + * Register a notification in memory. + * + * @param definition Bean that contains all the settings to instantiate the notifier + * @param condition Rule evaluate to determine if the notification has to be triggered for the first time + * @param resendCondition Rule evaluate to determine if the notification has to be triggered another time + */ + void register(NotificationDefinition definition, NotificationCondition condition, ResendNotificationCondition resendCondition); - /** - * Remove the notification trigger identified by the given parameters - * - * @param resourceId resourceId for which the notification has been created - * @param resourceType the type of resource - * @param type the type of notification (ex: email, mebhook...) - * @param audienceId the identifier of the notification audience. - */ - void unregister( - String resourceId, - String resourceType, - String type, - String audienceId - ); + /** + * Remove the notification trigger identified by the given parameters + * + * @param resourceId resourceId for which the notification has been created + * @param resourceType the type of resource + * @param type the type of notification (ex: email, mebhook...) + * @param audienceId the identifier of the notification audience. + */ + void unregister(String resourceId, String resourceType, String type, String audienceId); - /** - * Remove all the triggers for a given resource - * - * @param resourceId resourceId for which the notification has been created - * @param resourceType the type of resource - */ - void unregisterAll(String resourceId, String resourceType); + /** + * Remove all the triggers for a given resource + * + * @param resourceId resourceId for which the notification has been created + * @param resourceType the type of resource + */ + void unregisterAll(String resourceId, String resourceType); - /** - * Remove all acknowledge entries for the given resource. - * @param resourceId - * @param resourceType - * @return - */ - Completable deleteAcknowledge(String resourceId, String resourceType); + /** + * Remove all acknowledge entries for the given resource. + * @param resourceId + * @param resourceType + * @return + */ + Completable deleteAcknowledge(String resourceId, String resourceType); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/ResendNotificationCondition.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/ResendNotificationCondition.java index 1866d4b85..28dea2bd2 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/ResendNotificationCondition.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/notifier/ResendNotificationCondition.java @@ -21,6 +21,4 @@ * @author Eric LELEU (eric.leleu at graviteesource.com) * @author GraviteeSource Team */ -public interface ResendNotificationCondition - extends - BiFunction {} +public interface ResendNotificationCondition extends BiFunction {} diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/plugin/NodeDeploymentContext.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/plugin/NodeDeploymentContext.java index 64657ec8d..439388f0c 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/plugin/NodeDeploymentContext.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/plugin/NodeDeploymentContext.java @@ -23,5 +23,5 @@ * @author GraviteeSource Team */ public interface NodeDeploymentContext extends DeploymentContext { - Node node(); + Node node(); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/tracing/Tracer.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/tracing/Tracer.java index f308a4e77..eb2526c0e 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/tracing/Tracer.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/tracing/Tracer.java @@ -23,5 +23,5 @@ * @author GraviteeSource Team */ public interface Tracer extends LifecycleComponent { - Span trace(String spanName); + Span trace(String spanName); } diff --git a/gravitee-node-api/src/main/java/io/gravitee/node/api/utils/NodeUtils.java b/gravitee-node-api/src/main/java/io/gravitee/node/api/utils/NodeUtils.java index d5df8efa1..d7080b134 100644 --- a/gravitee-node-api/src/main/java/io/gravitee/node/api/utils/NodeUtils.java +++ b/gravitee-node-api/src/main/java/io/gravitee/node/api/utils/NodeUtils.java @@ -20,17 +20,17 @@ public class NodeUtils { - public static String userAgent(Node node) { - return node == null - ? null - : "Gravitee.io/" + - Version.RUNTIME_VERSION.MAJOR_VERSION + - " (" + - node.application() + - "; " + - node.name() + - "; " + - node.id() + - ")"; - } + public static String userAgent(Node node) { + return node == null + ? null + : "Gravitee.io/" + + Version.RUNTIME_VERSION.MAJOR_VERSION + + " (" + + node.application() + + "; " + + node.name() + + "; " + + node.id() + + ")"; + } } diff --git a/gravitee-node-cache/src/main/java/io/gravitee/node/cache/CacheManagerFactoriesLoader.java b/gravitee-node-cache/src/main/java/io/gravitee/node/cache/CacheManagerFactoriesLoader.java index feb88c054..63d50461a 100644 --- a/gravitee-node-cache/src/main/java/io/gravitee/node/cache/CacheManagerFactoriesLoader.java +++ b/gravitee-node-cache/src/main/java/io/gravitee/node/cache/CacheManagerFactoriesLoader.java @@ -24,15 +24,14 @@ * @author Kamiel Ahmadpour (kamiel.ahmadpour at graviteesource.com) * @author GraviteeSource Team */ -public class CacheManagerFactoriesLoader - extends SpringFactoriesLoader { +public class CacheManagerFactoriesLoader extends SpringFactoriesLoader { - @Override - protected Class getObjectType() { - return CacheManager.class; - } + @Override + protected Class getObjectType() { + return CacheManager.class; + } - public List getCacheManagers() { - return new ArrayList<>(getFactoriesInstances()); - } + public List getCacheManagers() { + return new ArrayList<>(getFactoriesInstances()); + } } diff --git a/gravitee-node-cache/src/main/java/io/gravitee/node/cache/hazelcast/HazelcastCache.java b/gravitee-node-cache/src/main/java/io/gravitee/node/cache/hazelcast/HazelcastCache.java index 89c0e76af..d7b1eb89b 100644 --- a/gravitee-node-cache/src/main/java/io/gravitee/node/cache/hazelcast/HazelcastCache.java +++ b/gravitee-node-cache/src/main/java/io/gravitee/node/cache/hazelcast/HazelcastCache.java @@ -34,108 +34,106 @@ */ public class HazelcastCache implements Cache { - private final IMap cache; - private final Map, UUID> listeners = new HashMap<>(); - private final long timeToLiveMillis; - - public HazelcastCache(IMap cache, CacheConfiguration configuration) { - this.cache = cache; - this.timeToLiveMillis = configuration.getTimeToLiveSeconds(); - } - - @Override - public String getName() { - return cache.getName(); - } - - @Override - public int size() { - return this.cache.size(); - } - - @Override - public boolean isEmpty() { - return this.cache.isEmpty(); - } - - @Override - public Collection values() { - return this.cache.values(); - } - - @Override - public V get(K key) { - return this.cache.get(key); - } - - @Override - public V put(K key, V value) { - return this.cache.put(key, value); - } - - @Override - public V put(K key, V value, long ttl, TimeUnit ttlUnit) { - long ttlMillis = TimeUnit.MILLISECONDS.convert(ttl, ttlUnit); - - if (timeToLiveMillis > 0 && ttlMillis > timeToLiveMillis) { - throw new RuntimeException( - "single ttl can't be bigger than ttl defined in the configuration" - ); + private final IMap cache; + private final Map, UUID> listeners = new HashMap<>(); + private final long timeToLiveMillis; + + public HazelcastCache(IMap cache, CacheConfiguration configuration) { + this.cache = cache; + this.timeToLiveMillis = configuration.getTimeToLiveSeconds(); + } + + @Override + public String getName() { + return cache.getName(); + } + + @Override + public int size() { + return this.cache.size(); + } + + @Override + public boolean isEmpty() { + return this.cache.isEmpty(); } - return this.cache.put(key, value, ttlMillis, TimeUnit.MILLISECONDS); - } - - @Override - public void putAll(Map m) { - this.cache.putAll(m); - } - - @Override - public V evict(K key) { - V v = cache.get(key); - cache.remove(key); - - return v; - } - - @Override - public void clear() { - cache.clear(); - } - - @Override - public void addCacheListener(CacheListener cacheListener) { - UUID id = - this.cache.addEntryListener( - new MapListenerAdapter() { - @Override - public void onEntryEvent(EntryEvent event) { - cacheListener.onEvent( - new io.gravitee.node.api.cache.EntryEvent<>( - event.getSource(), - EntryEventType.getByType(event.getEventType().getType()), - event.getKey(), - event.getOldValue(), - event.getValue() - ) - ); - } - }, - true - ); - - listeners.put(cacheListener, id); - } - - @Override - public boolean removeCacheListener(CacheListener cacheListener) { - UUID id = listeners.remove(cacheListener); - - if (id != null) { - return this.cache.removeEntryListener(id); + @Override + public Collection values() { + return this.cache.values(); } - return false; - } + @Override + public V get(K key) { + return this.cache.get(key); + } + + @Override + public V put(K key, V value) { + return this.cache.put(key, value); + } + + @Override + public V put(K key, V value, long ttl, TimeUnit ttlUnit) { + long ttlMillis = TimeUnit.MILLISECONDS.convert(ttl, ttlUnit); + + if (timeToLiveMillis > 0 && ttlMillis > timeToLiveMillis) { + throw new RuntimeException("single ttl can't be bigger than ttl defined in the configuration"); + } + + return this.cache.put(key, value, ttlMillis, TimeUnit.MILLISECONDS); + } + + @Override + public void putAll(Map m) { + this.cache.putAll(m); + } + + @Override + public V evict(K key) { + V v = cache.get(key); + cache.remove(key); + + return v; + } + + @Override + public void clear() { + cache.clear(); + } + + @Override + public void addCacheListener(CacheListener cacheListener) { + UUID id = + this.cache.addEntryListener( + new MapListenerAdapter() { + @Override + public void onEntryEvent(EntryEvent event) { + cacheListener.onEvent( + new io.gravitee.node.api.cache.EntryEvent<>( + event.getSource(), + EntryEventType.getByType(event.getEventType().getType()), + event.getKey(), + event.getOldValue(), + event.getValue() + ) + ); + } + }, + true + ); + + listeners.put(cacheListener, id); + } + + @Override + public boolean removeCacheListener(CacheListener cacheListener) { + UUID id = listeners.remove(cacheListener); + + if (id != null) { + return this.cache.removeEntryListener(id); + } + + return false; + } } diff --git a/gravitee-node-cache/src/main/java/io/gravitee/node/cache/hazelcast/HazelcastCacheManager.java b/gravitee-node-cache/src/main/java/io/gravitee/node/cache/hazelcast/HazelcastCacheManager.java index 7d79a0fe0..9bc99fda6 100644 --- a/gravitee-node-cache/src/main/java/io/gravitee/node/cache/hazelcast/HazelcastCacheManager.java +++ b/gravitee-node-cache/src/main/java/io/gravitee/node/cache/hazelcast/HazelcastCacheManager.java @@ -31,88 +31,69 @@ */ public class HazelcastCacheManager implements CacheManager { - private final ConcurrentMap caches = new ConcurrentHashMap<>(); - - private final HazelcastInstance hazelcastInstance; - - public HazelcastCacheManager(HazelcastInstance hazelcastInstance) { - this.hazelcastInstance = hazelcastInstance; - } - - @Override - public Cache getOrCreateCache(String name) { - return getOrCreateCache(name, new CacheConfiguration()); - } - - @Override - public Cache getOrCreateCache( - String name, - CacheConfiguration configuration - ) { - return caches.computeIfAbsent( - name, - s -> { - // First, configure the cache using Hazelcast config - configureCache(s, configuration); - - // Then create the cache entity - return new HazelcastCache<>( - hazelcastInstance.getMap(name), - configuration - ); - } - ); - } - - @Override - public void destroy(String name) { - Cache cache = caches.remove(name); - if (cache != null) { - cache.clear(); + private final ConcurrentMap caches = new ConcurrentHashMap<>(); + + private final HazelcastInstance hazelcastInstance; + + public HazelcastCacheManager(HazelcastInstance hazelcastInstance) { + this.hazelcastInstance = hazelcastInstance; } - } - - private void configureCache(String name, CacheConfiguration configuration) { - Config config = hazelcastInstance.getConfig(); - - if (config != null && !config.getMapConfigs().containsKey(name)) { - MapConfig resourceConfig = new MapConfig(name); - - // Cache is standalone, no backup wanted. - resourceConfig.setAsyncBackupCount(0); - resourceConfig.setBackupCount(0); - - if (configuration.getMaxSize() > 0) { - resourceConfig - .getEvictionConfig() - .setSize((int) configuration.getMaxSize()); - } - - if ( - resourceConfig - .getEvictionConfig() - .getEvictionPolicy() - .equals(EvictionPolicy.NONE) - ) { - // Set "Least Recently Used" eviction policy if not have eviction configured - resourceConfig - .getEvictionConfig() - .setEvictionPolicy(EvictionPolicy.LRU); - } - - if (configuration.getTimeToIdleSeconds() > 0) { - resourceConfig.setMaxIdleSeconds( - (int) configuration.getTimeToIdleSeconds() - ); - } - if (configuration.getTimeToLiveSeconds() > 0) { - resourceConfig.setTimeToLiveSeconds( - (int) configuration.getTimeToLiveSeconds() + @Override + public Cache getOrCreateCache(String name) { + return getOrCreateCache(name, new CacheConfiguration()); + } + + @Override + public Cache getOrCreateCache(String name, CacheConfiguration configuration) { + return caches.computeIfAbsent( + name, + s -> { + // First, configure the cache using Hazelcast config + configureCache(s, configuration); + + // Then create the cache entity + return new HazelcastCache<>(hazelcastInstance.getMap(name), configuration); + } ); - } + } + + @Override + public void destroy(String name) { + Cache cache = caches.remove(name); + if (cache != null) { + cache.clear(); + } + } + + private void configureCache(String name, CacheConfiguration configuration) { + Config config = hazelcastInstance.getConfig(); + + if (config != null && !config.getMapConfigs().containsKey(name)) { + MapConfig resourceConfig = new MapConfig(name); + + // Cache is standalone, no backup wanted. + resourceConfig.setAsyncBackupCount(0); + resourceConfig.setBackupCount(0); + + if (configuration.getMaxSize() > 0) { + resourceConfig.getEvictionConfig().setSize((int) configuration.getMaxSize()); + } + + if (resourceConfig.getEvictionConfig().getEvictionPolicy().equals(EvictionPolicy.NONE)) { + // Set "Least Recently Used" eviction policy if not have eviction configured + resourceConfig.getEvictionConfig().setEvictionPolicy(EvictionPolicy.LRU); + } + + if (configuration.getTimeToIdleSeconds() > 0) { + resourceConfig.setMaxIdleSeconds((int) configuration.getTimeToIdleSeconds()); + } + + if (configuration.getTimeToLiveSeconds() > 0) { + resourceConfig.setTimeToLiveSeconds((int) configuration.getTimeToLiveSeconds()); + } - config.addMapConfig(resourceConfig); + config.addMapConfig(resourceConfig); + } } - } } diff --git a/gravitee-node-cache/src/main/java/io/gravitee/node/cache/standalone/StandaloneCache.java b/gravitee-node-cache/src/main/java/io/gravitee/node/cache/standalone/StandaloneCache.java index 5b4c9dad3..f642190c0 100644 --- a/gravitee-node-cache/src/main/java/io/gravitee/node/cache/standalone/StandaloneCache.java +++ b/gravitee-node-cache/src/main/java/io/gravitee/node/cache/standalone/StandaloneCache.java @@ -35,181 +35,134 @@ */ public class StandaloneCache implements Cache { - private final String name; - private final CacheConfiguration configuration; - private final AtomicInteger counter = new AtomicInteger(); - private final com.google.common.cache.Cache> internalCache; - private final Set> cacheListeners = new HashSet<>(); - private static final ExecutorService executorService = Executors.newSingleThreadExecutor( - r -> new Thread(r, "gio-standalone-cache") - ); - - public StandaloneCache(String name, CacheConfiguration configuration) { - this.name = name; - this.configuration = configuration; + private final String name; + private final CacheConfiguration configuration; + private final AtomicInteger counter = new AtomicInteger(); + private final com.google.common.cache.Cache> internalCache; + private final Set> cacheListeners = new HashSet<>(); + private static final ExecutorService executorService = Executors.newSingleThreadExecutor(r -> new Thread(r, "gio-standalone-cache")); + + public StandaloneCache(String name, CacheConfiguration configuration) { + this.name = name; + this.configuration = configuration; + + CacheBuilder cacheBuilder = CacheBuilder.newBuilder(); + if (configuration.getMaxSize() > 0) { + cacheBuilder.maximumSize(configuration.getMaxSize()); + } + if (configuration.getTimeToIdleSeconds() > 0) { + cacheBuilder.expireAfterAccess(configuration.getTimeToIdleSeconds(), TimeUnit.SECONDS); + } + if (configuration.getTimeToLiveSeconds() > 0) { + cacheBuilder.expireAfterWrite(configuration.getTimeToLiveSeconds(), TimeUnit.SECONDS); + } - CacheBuilder cacheBuilder = CacheBuilder.newBuilder(); - if (configuration.getMaxSize() > 0) { - cacheBuilder.maximumSize(configuration.getMaxSize()); - } - if (configuration.getTimeToIdleSeconds() > 0) { - cacheBuilder.expireAfterAccess( - configuration.getTimeToIdleSeconds(), - TimeUnit.SECONDS - ); - } - if (configuration.getTimeToLiveSeconds() > 0) { - cacheBuilder.expireAfterWrite( - configuration.getTimeToLiveSeconds(), - TimeUnit.SECONDS - ); + cacheBuilder.removalListener((RemovalListener) notification -> counter.decrementAndGet()); + internalCache = cacheBuilder.build(); } - cacheBuilder.removalListener( - (RemovalListener) notification -> counter.decrementAndGet() - ); - internalCache = cacheBuilder.build(); - } - - @Override - public String getName() { - return name; - } - - @Override - public int size() { - return counter.get(); - } - - @Override - public boolean isEmpty() { - return this.size() == 0; - } + @Override + public String getName() { + return name; + } - @Override - public Collection values() { - return this.internalCache.asMap() - .values() - .stream() - .filter( - e -> - e.expirationTimeMillis == 0 || - System.currentTimeMillis() <= e.expirationTimeMillis - ) - .map(vValueWrapper -> vValueWrapper.value) - .collect(Collectors.toList()); - } + @Override + public int size() { + return counter.get(); + } - @Override - public V get(K key) { - ValueWrapper vw = internalCache.getIfPresent(key); - if (vw != null) { - if (vw.expirationTimeMillis == 0) { - return vw.value; - } else if (System.currentTimeMillis() <= vw.expirationTimeMillis) { - vw.expirationTimeMillis = - System.currentTimeMillis() + vw.timeToLiveMillis; - return vw.value; - } else { - this.internalCache.invalidate(key); - return null; - } - } else { - return null; + @Override + public boolean isEmpty() { + return this.size() == 0; } - } - @Override - public V put(K key, V value) { - return this.put(key, value, 0, TimeUnit.MILLISECONDS); - } + @Override + public Collection values() { + return this.internalCache.asMap() + .values() + .stream() + .filter(e -> e.expirationTimeMillis == 0 || System.currentTimeMillis() <= e.expirationTimeMillis) + .map(vValueWrapper -> vValueWrapper.value) + .collect(Collectors.toList()); + } - @Override - public V put(K key, V value, long ttl, TimeUnit ttlUnit) { - if (this.configuration.getTimeToLiveSeconds() > 0) { - Verify.verify( - TimeUnit.MILLISECONDS.convert(ttl, ttlUnit) <= - TimeUnit.MILLISECONDS.convert( - this.configuration.getTimeToLiveSeconds(), - TimeUnit.SECONDS - ), - "single ttl can't be bigger than ttl defined in the configuration" - ); + @Override + public V get(K key) { + ValueWrapper vw = internalCache.getIfPresent(key); + if (vw != null) { + if (vw.expirationTimeMillis == 0) { + return vw.value; + } else if (System.currentTimeMillis() <= vw.expirationTimeMillis) { + vw.expirationTimeMillis = System.currentTimeMillis() + vw.timeToLiveMillis; + return vw.value; + } else { + this.internalCache.invalidate(key); + return null; + } + } else { + return null; + } } - V currentValue = this.get(key); - long ttlMillis = TimeUnit.MILLISECONDS.convert(ttl, ttlUnit); - long expirationTimeMillis = ttlMillis != 0 - ? System.currentTimeMillis() + ttlMillis - : 0; - counter.incrementAndGet(); - this.internalCache.put( - key, - new ValueWrapper<>(value, ttlMillis, expirationTimeMillis) - ); + @Override + public V put(K key, V value) { + return this.put(key, value, 0, TimeUnit.MILLISECONDS); + } - executorService.execute( - () -> { - if (currentValue == null) { - cacheListeners.forEach( - listener -> - new EntryEvent<>(name, EntryEventType.ADDED, key, null, value) - ); - } else { - cacheListeners.forEach( - listener -> - new EntryEvent<>( - name, - EntryEventType.UPDATED, - key, - currentValue, - value - ) - ); + @Override + public V put(K key, V value, long ttl, TimeUnit ttlUnit) { + if (this.configuration.getTimeToLiveSeconds() > 0) { + Verify.verify( + TimeUnit.MILLISECONDS.convert(ttl, ttlUnit) <= + TimeUnit.MILLISECONDS.convert(this.configuration.getTimeToLiveSeconds(), TimeUnit.SECONDS), + "single ttl can't be bigger than ttl defined in the configuration" + ); } - } - ); - return currentValue; - } + V currentValue = this.get(key); + long ttlMillis = TimeUnit.MILLISECONDS.convert(ttl, ttlUnit); + long expirationTimeMillis = ttlMillis != 0 ? System.currentTimeMillis() + ttlMillis : 0; + counter.incrementAndGet(); + this.internalCache.put(key, new ValueWrapper<>(value, ttlMillis, expirationTimeMillis)); + + executorService.execute(() -> { + if (currentValue == null) { + cacheListeners.forEach(listener -> new EntryEvent<>(name, EntryEventType.ADDED, key, null, value)); + } else { + cacheListeners.forEach(listener -> new EntryEvent<>(name, EntryEventType.UPDATED, key, currentValue, value)); + } + }); + + return currentValue; + } - @Override - public void putAll(Map m) { - Map> wrapperMap = m - .entrySet() - .stream() - .collect( - Collectors.toMap( - Map.Entry::getKey, - e -> new ValueWrapper<>(e.getValue(), 0, 0) - ) - ); + @Override + public void putAll(Map m) { + Map> wrapperMap = m + .entrySet() + .stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> new ValueWrapper<>(e.getValue(), 0, 0))); - counter.addAndGet(wrapperMap.size()); - this.internalCache.putAll(wrapperMap); - } + counter.addAndGet(wrapperMap.size()); + this.internalCache.putAll(wrapperMap); + } - @Override - public V evict(K key) { - V v = this.get(key); - this.internalCache.invalidate(key); + @Override + public V evict(K key) { + V v = this.get(key); + this.internalCache.invalidate(key); - executorService.execute( - () -> - cacheListeners.forEach( - cacheListener -> - new EntryEvent<>(name, EntryEventType.REMOVED, key, v, null) - ) - ); + executorService.execute(() -> cacheListeners.forEach(cacheListener -> new EntryEvent<>(name, EntryEventType.REMOVED, key, v, null)) + ); - return v; - } + return v; + } - @Override - public void clear() { - this.internalCache.invalidateAll(); - //TODO: do we want to notify listeners on a clear ? - /* + @Override + public void clear() { + this.internalCache.invalidateAll(); + //TODO: do we want to notify listeners on a clear ? + /* getNativeCache() .forEach( (key, value) -> @@ -228,32 +181,28 @@ public void clear() { ) ); */ - } + } - @Override - public void addCacheListener(CacheListener listener) { - cacheListeners.add(listener); - } + @Override + public void addCacheListener(CacheListener listener) { + cacheListeners.add(listener); + } - @Override - public boolean removeCacheListener(CacheListener listener) { - return cacheListeners.remove(listener); - } + @Override + public boolean removeCacheListener(CacheListener listener) { + return cacheListeners.remove(listener); + } - private static class ValueWrapper { + private static class ValueWrapper { - private final T value; - private final long timeToLiveMillis; - private long expirationTimeMillis; + private final T value; + private final long timeToLiveMillis; + private long expirationTimeMillis; - public ValueWrapper( - T value, - long timeToLiveMillis, - long expirationTimeMillis - ) { - this.value = value; - this.timeToLiveMillis = timeToLiveMillis; - this.expirationTimeMillis = expirationTimeMillis; + public ValueWrapper(T value, long timeToLiveMillis, long expirationTimeMillis) { + this.value = value; + this.timeToLiveMillis = timeToLiveMillis; + this.expirationTimeMillis = expirationTimeMillis; + } } - } } diff --git a/gravitee-node-cache/src/main/java/io/gravitee/node/cache/standalone/StandaloneCacheManager.java b/gravitee-node-cache/src/main/java/io/gravitee/node/cache/standalone/StandaloneCacheManager.java index 0e2ce4cd5..53ede1ace 100644 --- a/gravitee-node-cache/src/main/java/io/gravitee/node/cache/standalone/StandaloneCacheManager.java +++ b/gravitee-node-cache/src/main/java/io/gravitee/node/cache/standalone/StandaloneCacheManager.java @@ -27,29 +27,23 @@ */ public class StandaloneCacheManager implements CacheManager { - private final ConcurrentMap caches = new ConcurrentHashMap<>(); + private final ConcurrentMap caches = new ConcurrentHashMap<>(); - @Override - public Cache getOrCreateCache(String name) { - return getOrCreateCache(name, new CacheConfiguration()); - } + @Override + public Cache getOrCreateCache(String name) { + return getOrCreateCache(name, new CacheConfiguration()); + } - @Override - public Cache getOrCreateCache( - String name, - CacheConfiguration configuration - ) { - return caches.computeIfAbsent( - name, - s -> new StandaloneCache<>(name, configuration) - ); - } + @Override + public Cache getOrCreateCache(String name, CacheConfiguration configuration) { + return caches.computeIfAbsent(name, s -> new StandaloneCache<>(name, configuration)); + } - @Override - public void destroy(String name) { - Cache cache = caches.remove(name); - if (cache != null) { - cache.clear(); + @Override + public void destroy(String name) { + Cache cache = caches.remove(name); + if (cache != null) { + cache.clear(); + } } - } } diff --git a/gravitee-node-cache/src/test/java/io/gravitee/node/cache/hazelcast/HazelcastCacheTest.java b/gravitee-node-cache/src/test/java/io/gravitee/node/cache/hazelcast/HazelcastCacheTest.java index e6160c05a..1582a79cf 100644 --- a/gravitee-node-cache/src/test/java/io/gravitee/node/cache/hazelcast/HazelcastCacheTest.java +++ b/gravitee-node-cache/src/test/java/io/gravitee/node/cache/hazelcast/HazelcastCacheTest.java @@ -44,87 +44,75 @@ @RunWith(MockitoJUnitRunner.class) public class HazelcastCacheTest { - private static final String CACHE_NAME = "HazelcastCacheTest"; - private static final Long TIME_TO_LIVE = 60L; - private static final String TEST_KEY = "foobar"; - private static final String TEST_VALUE = "value"; - - Config config; - - @Mock - HazelcastInstance hazelcastInstance; - - @Mock - IMap map; - - @Mock - ApplicationContext applicationContext; - - @InjectMocks - HazelcastCacheManager cacheManager; - - @Before - public void setup() throws Exception { - config = new Config(); - when(hazelcastInstance.getMap(anyString())).thenReturn(map); - - MapConfig mapConfig = new MapConfig(); - mapConfig.setName("cache_*"); - mapConfig.setTimeToLiveSeconds(600); - mapConfig.setMaxIdleSeconds(600); - EvictionConfig evictionConfig = new EvictionConfig(); - evictionConfig.setMaxSizePolicy(MaxSizePolicy.PER_NODE); - evictionConfig.setSize(200); - mapConfig.setEvictionConfig(evictionConfig); - - config.addMapConfig(mapConfig); - } - - @Test - public void shouldPutToCache() { - CacheConfiguration configuration = new CacheConfiguration(); - configuration.setTimeToLiveSeconds(60); - Cache cache = cacheManager.getOrCreateCache( - CACHE_NAME, - configuration - ); - cache.put(TEST_KEY, TEST_VALUE, 30, TimeUnit.MILLISECONDS); - - verify(hazelcastInstance, times(1)) - .getMap(argThat(cacheName -> cacheName.startsWith(CACHE_NAME))); - verify(map, times(1)).put(TEST_KEY, TEST_VALUE, 30, TimeUnit.MILLISECONDS); - } - - @Test - public void shouldPutToCacheWithTtl() { - CacheConfiguration configuration = new CacheConfiguration(); - configuration.setTimeToLiveSeconds(60); - Cache cache = cacheManager.getOrCreateCache( - CACHE_NAME, - configuration - ); - cache.put(TEST_KEY, TEST_VALUE, 30, TimeUnit.MILLISECONDS); - - verify(hazelcastInstance, times(1)) - .getMap(argThat(cacheName -> cacheName.startsWith(CACHE_NAME))); - verify(map, times(1)).put(TEST_KEY, TEST_VALUE, 30, TimeUnit.MILLISECONDS); - } - - @Test - public void shouldDestroyCache() throws Exception { - CacheConfiguration configuration = new CacheConfiguration(); - configuration.setTimeToLiveSeconds(60); - final Cache cache = cacheManager.getOrCreateCache( - CACHE_NAME, - configuration - ); - assertNotNull(cache); - cache.put(TEST_KEY, TEST_VALUE, 30, TimeUnit.MILLISECONDS); - - verify(hazelcastInstance, times(1)) - .getMap(argThat(cacheName -> cacheName.startsWith(CACHE_NAME))); - verify(map, times(1)).put(TEST_KEY, TEST_VALUE, 30, TimeUnit.MILLISECONDS); - - cache.clear(); - } + private static final String CACHE_NAME = "HazelcastCacheTest"; + private static final Long TIME_TO_LIVE = 60L; + private static final String TEST_KEY = "foobar"; + private static final String TEST_VALUE = "value"; + + Config config; + + @Mock + HazelcastInstance hazelcastInstance; + + @Mock + IMap map; + + @Mock + ApplicationContext applicationContext; + + @InjectMocks + HazelcastCacheManager cacheManager; + + @Before + public void setup() throws Exception { + config = new Config(); + when(hazelcastInstance.getMap(anyString())).thenReturn(map); + + MapConfig mapConfig = new MapConfig(); + mapConfig.setName("cache_*"); + mapConfig.setTimeToLiveSeconds(600); + mapConfig.setMaxIdleSeconds(600); + EvictionConfig evictionConfig = new EvictionConfig(); + evictionConfig.setMaxSizePolicy(MaxSizePolicy.PER_NODE); + evictionConfig.setSize(200); + mapConfig.setEvictionConfig(evictionConfig); + + config.addMapConfig(mapConfig); + } + + @Test + public void shouldPutToCache() { + CacheConfiguration configuration = new CacheConfiguration(); + configuration.setTimeToLiveSeconds(60); + Cache cache = cacheManager.getOrCreateCache(CACHE_NAME, configuration); + cache.put(TEST_KEY, TEST_VALUE, 30, TimeUnit.MILLISECONDS); + + verify(hazelcastInstance, times(1)).getMap(argThat(cacheName -> cacheName.startsWith(CACHE_NAME))); + verify(map, times(1)).put(TEST_KEY, TEST_VALUE, 30, TimeUnit.MILLISECONDS); + } + + @Test + public void shouldPutToCacheWithTtl() { + CacheConfiguration configuration = new CacheConfiguration(); + configuration.setTimeToLiveSeconds(60); + Cache cache = cacheManager.getOrCreateCache(CACHE_NAME, configuration); + cache.put(TEST_KEY, TEST_VALUE, 30, TimeUnit.MILLISECONDS); + + verify(hazelcastInstance, times(1)).getMap(argThat(cacheName -> cacheName.startsWith(CACHE_NAME))); + verify(map, times(1)).put(TEST_KEY, TEST_VALUE, 30, TimeUnit.MILLISECONDS); + } + + @Test + public void shouldDestroyCache() throws Exception { + CacheConfiguration configuration = new CacheConfiguration(); + configuration.setTimeToLiveSeconds(60); + final Cache cache = cacheManager.getOrCreateCache(CACHE_NAME, configuration); + assertNotNull(cache); + cache.put(TEST_KEY, TEST_VALUE, 30, TimeUnit.MILLISECONDS); + + verify(hazelcastInstance, times(1)).getMap(argThat(cacheName -> cacheName.startsWith(CACHE_NAME))); + verify(map, times(1)).put(TEST_KEY, TEST_VALUE, 30, TimeUnit.MILLISECONDS); + + cache.clear(); + } } diff --git a/gravitee-node-cache/src/test/java/io/gravitee/node/cache/standalone/StandaloneCacheTest.java b/gravitee-node-cache/src/test/java/io/gravitee/node/cache/standalone/StandaloneCacheTest.java index d17f84d64..d9815c641 100644 --- a/gravitee-node-cache/src/test/java/io/gravitee/node/cache/standalone/StandaloneCacheTest.java +++ b/gravitee-node-cache/src/test/java/io/gravitee/node/cache/standalone/StandaloneCacheTest.java @@ -32,65 +32,56 @@ @RunWith(MockitoJUnitRunner.class) public class StandaloneCacheTest { - private static final String CACHE_NAME = "StandaloneCacheTest"; - private static final Long TIME_TO_LIVE = 1L; - private static final String TEST_KEY = "foobar"; - private static final String TEST_VALUE = "value"; + private static final String CACHE_NAME = "StandaloneCacheTest"; + private static final Long TIME_TO_LIVE = 1L; + private static final String TEST_KEY = "foobar"; + private static final String TEST_VALUE = "value"; - @InjectMocks - StandaloneCacheManager cacheManager; + @InjectMocks + StandaloneCacheManager cacheManager; - @Test - public void shouldPutToCache() throws InterruptedException { - CacheConfiguration configuration = new CacheConfiguration(); - configuration.setTimeToLiveSeconds(2); - Cache cache = cacheManager.getOrCreateCache( - CACHE_NAME, - configuration - ); - cache.put(TEST_KEY, TEST_VALUE, 1, TimeUnit.MILLISECONDS); - cache.put(TEST_KEY + 2, TEST_VALUE, 2000, TimeUnit.MILLISECONDS); + @Test + public void shouldPutToCache() throws InterruptedException { + CacheConfiguration configuration = new CacheConfiguration(); + configuration.setTimeToLiveSeconds(2); + Cache cache = cacheManager.getOrCreateCache(CACHE_NAME, configuration); + cache.put(TEST_KEY, TEST_VALUE, 1, TimeUnit.MILLISECONDS); + cache.put(TEST_KEY + 2, TEST_VALUE, 2000, TimeUnit.MILLISECONDS); - assertNotNull(cache.get(TEST_KEY)); - assertEquals(2, cache.size()); - assertFalse(cache.isEmpty()); + assertNotNull(cache.get(TEST_KEY)); + assertEquals(2, cache.size()); + assertFalse(cache.isEmpty()); - Thread.sleep(1000L); - assertNotNull(cache.get(TEST_KEY + 2)); - // assertEquals(1, cache.size()); - assertFalse(cache.isEmpty()); - } + Thread.sleep(1000L); + assertNotNull(cache.get(TEST_KEY + 2)); + // assertEquals(1, cache.size()); + assertFalse(cache.isEmpty()); + } - @Test - public void shouldBeCleanedUpFromCache() throws InterruptedException { - CacheConfiguration configuration = new CacheConfiguration(); - configuration.setTimeToLiveSeconds(100); - Cache cache = cacheManager.getOrCreateCache( - CACHE_NAME, - configuration - ); + @Test + public void shouldBeCleanedUpFromCache() throws InterruptedException { + CacheConfiguration configuration = new CacheConfiguration(); + configuration.setTimeToLiveSeconds(100); + Cache cache = cacheManager.getOrCreateCache(CACHE_NAME, configuration); - cache.put(TEST_KEY, TEST_VALUE, 10, TimeUnit.MILLISECONDS); + cache.put(TEST_KEY, TEST_VALUE, 10, TimeUnit.MILLISECONDS); - Thread.sleep(12L); - assertNull(cache.get(TEST_KEY)); - } + Thread.sleep(12L); + assertNull(cache.get(TEST_KEY)); + } - @Test - public void shouldBeRenewed() throws InterruptedException { - CacheConfiguration configuration = new CacheConfiguration(); - configuration.setTimeToLiveSeconds(100); - Cache cache = cacheManager.getOrCreateCache( - CACHE_NAME, - configuration - ); - cache.put(TEST_KEY, TEST_VALUE, 40, TimeUnit.MILLISECONDS); - Thread.sleep(30L); - cache.get(TEST_KEY); - Thread.sleep(30L); + @Test + public void shouldBeRenewed() throws InterruptedException { + CacheConfiguration configuration = new CacheConfiguration(); + configuration.setTimeToLiveSeconds(100); + Cache cache = cacheManager.getOrCreateCache(CACHE_NAME, configuration); + cache.put(TEST_KEY, TEST_VALUE, 40, TimeUnit.MILLISECONDS); + Thread.sleep(30L); + cache.get(TEST_KEY); + Thread.sleep(30L); - assertNotNull(cache.get(TEST_KEY)); - assertEquals(1, cache.size()); - assertFalse(cache.isEmpty()); - } + assertNotNull(cache.get(TEST_KEY)); + assertEquals(1, cache.size()); + assertFalse(cache.isEmpty()); + } } diff --git a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/BaseCertificateManager.java b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/BaseCertificateManager.java index 6160ca84f..93cb56824 100644 --- a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/BaseCertificateManager.java +++ b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/BaseCertificateManager.java @@ -30,33 +30,26 @@ */ public class BaseCertificateManager implements CertificateManager { - protected boolean enableSni; - protected final ReloadableKeyManager keyManager; - protected final List keyStoreLoaders; + protected boolean enableSni; + protected final ReloadableKeyManager keyManager; + protected final List keyStoreLoaders; - public BaseCertificateManager(boolean enableSni) { - this.enableSni = enableSni; - this.keyManager = new ReloadableKeyManager(); - this.keyStoreLoaders = new ArrayList<>(); - } + public BaseCertificateManager(boolean enableSni) { + this.enableSni = enableSni; + this.keyManager = new ReloadableKeyManager(); + this.keyStoreLoaders = new ArrayList<>(); + } - @Override - public void registerLoader(KeyStoreLoader keyStoreLoader) { - Objects.requireNonNull(keyStoreLoader, "KeyStoreLoader cannot be null"); - this.keyStoreLoaders.add(keyStoreLoader); - keyStoreLoader.addListener( - keyStoreBundle -> { - try { - keyManager.load( - keyStoreBundle.getDefaultAlias(), - keyStoreBundle.getKeyStore(), - keyStoreBundle.getPassword(), - enableSni - ); - } catch (Exception e) { - throw new IllegalArgumentException("Unable to load the keystore", e); - } - } - ); - } + @Override + public void registerLoader(KeyStoreLoader keyStoreLoader) { + Objects.requireNonNull(keyStoreLoader, "KeyStoreLoader cannot be null"); + this.keyStoreLoaders.add(keyStoreLoader); + keyStoreLoader.addListener(keyStoreBundle -> { + try { + keyManager.load(keyStoreBundle.getDefaultAlias(), keyStoreBundle.getKeyStore(), keyStoreBundle.getPassword(), enableSni); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to load the keystore", e); + } + }); + } } diff --git a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/FileKeyStoreLoader.java b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/FileKeyStoreLoader.java index 8076b262f..e17c6d06d 100644 --- a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/FileKeyStoreLoader.java +++ b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/FileKeyStoreLoader.java @@ -42,215 +42,168 @@ */ public class FileKeyStoreLoader implements KeyStoreLoader { - private static final Logger logger = LoggerFactory.getLogger( - FileKeyStoreLoader.class - ); - - private final KeyStoreLoaderOptions options; - private final List> listeners; - private final ExecutorService executor; - private KeyStoreBundle keyStoreBundle; - private List filesToWatch; - private boolean started; - private boolean watching; - - public FileKeyStoreLoader(KeyStoreLoaderOptions options) { - this.options = options; - this.listeners = new ArrayList<>(); - this.executor = - Executors.newSingleThreadExecutor( - r -> new Thread(r, "gio.file-cert-watcher") - ); - this.filesToWatch = new ArrayList<>(); - } - - @Override - public void start() { - logger.debug("Initializing file keystore certificates."); - - load(); - - started = true; - - if (options.isWatch()) { - startWatch(); + private static final Logger logger = LoggerFactory.getLogger(FileKeyStoreLoader.class); + + private final KeyStoreLoaderOptions options; + private final List> listeners; + private final ExecutorService executor; + private KeyStoreBundle keyStoreBundle; + private List filesToWatch; + private boolean started; + private boolean watching; + + public FileKeyStoreLoader(KeyStoreLoaderOptions options) { + this.options = options; + this.listeners = new ArrayList<>(); + this.executor = Executors.newSingleThreadExecutor(r -> new Thread(r, "gio.file-cert-watcher")); + this.filesToWatch = new ArrayList<>(); } - } - @Override - public void stop() { - started = false; + @Override + public void start() { + logger.debug("Initializing file keystore certificates."); - executor.shutdown(); - } + load(); - private void load() { - if ( - options.getKeyStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_JKS) || - options.getKeyStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_PKCS12) - ) { - filesToWatch = loadFromKeyStore(); - } else if ( - options.getKeyStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_PEM) - ) { - filesToWatch = loadFromPems(); - } else if ( - options.getKeyStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_SELF_SIGNED) - ) { - filesToWatch = loadFromSelfSigned(); - } else { - throw new IllegalArgumentException( - String.format( - "Unsupported keystore format (%s).", - options.getKeyStoreType() - ) - ); - } + started = true; - if (keyStoreBundle != null) { - notifyListeners(keyStoreBundle); + if (options.isWatch()) { + startWatch(); + } } - } - private List loadFromKeyStore() { - final List paths = new ArrayList<>(); + @Override + public void stop() { + started = false; - if ( - options.getKeyStorePath() != null && !options.getKeyStorePath().isEmpty() - ) { - final KeyStore keyStore = KeyStoreUtils.initFromPath( - options.getKeyStoreType(), - options.getKeyStorePath(), - options.getKeyStorePassword() - ); - keyStoreBundle = - new KeyStoreBundle( - keyStore, - options.getKeyStorePassword(), - options.getDefaultAlias() - ); - paths.add(FileSystems.getDefault().getPath(options.getKeyStorePath())); - } else { - throw new IllegalArgumentException( - "A JKS/PKCS12 Keystore is missing. Unable to configure TLS." - ); + executor.shutdown(); } - return paths; - } - - private List loadFromPems() { - final List paths = new ArrayList<>(); - if ( - options.getKeyStoreCertificates() != null && - !options.getKeyStoreCertificates().isEmpty() - ) { - final List certs = options - .getKeyStoreCertificates() - .stream() - .map(CertificateOptions::getCertificate) - .collect(Collectors.toList()); - final List keys = options - .getKeyStoreCertificates() - .stream() - .map(CertificateOptions::getPrivateKey) - .collect(Collectors.toList()); - final KeyStore keyStore = KeyStoreUtils.initFromPems( - certs, - keys, - options.getKeyStorePassword() - ); - - // No default alias can be provided when loading keystore from pems / keys. - keyStoreBundle = - new KeyStoreBundle(keyStore, options.getKeyStorePassword(), null); + private void load() { + if ( + options.getKeyStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_JKS) || + options.getKeyStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_PKCS12) + ) { + filesToWatch = loadFromKeyStore(); + } else if (options.getKeyStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_PEM)) { + filesToWatch = loadFromPems(); + } else if (options.getKeyStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_SELF_SIGNED)) { + filesToWatch = loadFromSelfSigned(); + } else { + throw new IllegalArgumentException(String.format("Unsupported keystore format (%s).", options.getKeyStoreType())); + } - certs.forEach(cert -> paths.add(FileSystems.getDefault().getPath(cert))); - keys.forEach(key -> paths.add(FileSystems.getDefault().getPath(key))); - } else { - throw new IllegalArgumentException( - "A PEM Keystore is missing. Unable to configure TLS." - ); + if (keyStoreBundle != null) { + notifyListeners(keyStoreBundle); + } } - return paths; - } - private List loadFromSelfSigned() { - keyStoreBundle = null; - return new ArrayList<>(); - } + private List loadFromKeyStore() { + final List paths = new ArrayList<>(); - @Override - public void addListener(Consumer listener) { - listeners.add(listener); - } + if (options.getKeyStorePath() != null && !options.getKeyStorePath().isEmpty()) { + final KeyStore keyStore = KeyStoreUtils.initFromPath( + options.getKeyStoreType(), + options.getKeyStorePath(), + options.getKeyStorePassword() + ); + keyStoreBundle = new KeyStoreBundle(keyStore, options.getKeyStorePassword(), options.getDefaultAlias()); + paths.add(FileSystems.getDefault().getPath(options.getKeyStorePath())); + } else { + throw new IllegalArgumentException("A JKS/PKCS12 Keystore is missing. Unable to configure TLS."); + } + return paths; + } - private void startWatch() { - executor.execute( - () -> { - try { - WatchService watcherService = FileSystems - .getDefault() - .newWatchService(); + private List loadFromPems() { + final List paths = new ArrayList<>(); - // Extract the list of path to watch from the list of files to watch (note: we can only watch folder, not files directly). - final List watchedPaths = filesToWatch - .stream() - .map(Path::getParent) - .distinct() - .collect(Collectors.toList()); + if (options.getKeyStoreCertificates() != null && !options.getKeyStoreCertificates().isEmpty()) { + final List certs = options + .getKeyStoreCertificates() + .stream() + .map(CertificateOptions::getCertificate) + .collect(Collectors.toList()); + final List keys = options + .getKeyStoreCertificates() + .stream() + .map(CertificateOptions::getPrivateKey) + .collect(Collectors.toList()); + final KeyStore keyStore = KeyStoreUtils.initFromPems(certs, keys, options.getKeyStorePassword()); - for (Path path : watchedPaths) { - path.register( - watcherService, - new WatchEvent.Kind[] { StandardWatchEventKinds.ENTRY_MODIFY }, - SensitivityWatchEventModifier.HIGH - ); - } + // No default alias can be provided when loading keystore from pems / keys. + keyStoreBundle = new KeyStoreBundle(keyStore, options.getKeyStorePassword(), null); - watching = true; + certs.forEach(cert -> paths.add(FileSystems.getDefault().getPath(cert))); + keys.forEach(key -> paths.add(FileSystems.getDefault().getPath(key))); + } else { + throw new IllegalArgumentException("A PEM Keystore is missing. Unable to configure TLS."); + } + return paths; + } - WatchKey watchKey; - while (started) { - watchKey = watcherService.poll(200, TimeUnit.MILLISECONDS); - if (watchKey != null) { - final Optional optionalPath = watchKey - .pollEvents() - .stream() - .map(watchEvent -> ((WatchEvent) watchEvent).context()) - .filter( - file -> - filesToWatch - .stream() - .map(Path::getFileName) - .anyMatch(file::equals) - ) - .findFirst(); + private List loadFromSelfSigned() { + keyStoreBundle = null; + return new ArrayList<>(); + } - if (optionalPath.isPresent()) { - // In case of any changes, just reload the complete keystore. - load(); - } + @Override + public void addListener(Consumer listener) { + listeners.add(listener); + } - if (!watchKey.reset()) { - break; - } + private void startWatch() { + executor.execute(() -> { + try { + WatchService watcherService = FileSystems.getDefault().newWatchService(); + + // Extract the list of path to watch from the list of files to watch (note: we can only watch folder, not files directly). + final List watchedPaths = filesToWatch.stream().map(Path::getParent).distinct().collect(Collectors.toList()); + + for (Path path : watchedPaths) { + path.register( + watcherService, + new WatchEvent.Kind[] { StandardWatchEventKinds.ENTRY_MODIFY }, + SensitivityWatchEventModifier.HIGH + ); + } + + watching = true; + + WatchKey watchKey; + while (started) { + watchKey = watcherService.poll(200, TimeUnit.MILLISECONDS); + if (watchKey != null) { + final Optional optionalPath = watchKey + .pollEvents() + .stream() + .map(watchEvent -> ((WatchEvent) watchEvent).context()) + .filter(file -> filesToWatch.stream().map(Path::getFileName).anyMatch(file::equals)) + .findFirst(); + + if (optionalPath.isPresent()) { + // In case of any changes, just reload the complete keystore. + load(); + } + + if (!watchKey.reset()) { + break; + } + } + } + } catch (InterruptedException ie) { + logger.info("Watch for keystore files has been stopped."); + } catch (Exception e) { + logger.error("Unable to watch the keystore files.", e); } - } - } catch (InterruptedException ie) { - logger.info("Watch for keystore files has been stopped."); - } catch (Exception e) { - logger.error("Unable to watch the keystore files.", e); - } - } - ); - } + }); + } - private void notifyListeners(KeyStoreBundle keyStoreBundle) { - listeners.forEach(consumer -> consumer.accept(keyStoreBundle)); - } + private void notifyListeners(KeyStoreBundle keyStoreBundle) { + listeners.forEach(consumer -> consumer.accept(keyStoreBundle)); + } - public boolean isWatching() { - return watching; - } + public boolean isWatching() { + return watching; + } } diff --git a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/FileKeyStoreLoaderFactory.java b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/FileKeyStoreLoaderFactory.java index cc5da0a06..af7bd8713 100644 --- a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/FileKeyStoreLoaderFactory.java +++ b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/FileKeyStoreLoaderFactory.java @@ -29,32 +29,26 @@ */ public class FileKeyStoreLoaderFactory implements KeyStoreLoaderFactory { - private static final List SUPPORTED_TYPES = Arrays.asList( - KeyStoreLoader.CERTIFICATE_FORMAT_JKS.toLowerCase(), - KeyStoreLoader.CERTIFICATE_FORMAT_PEM.toLowerCase(), - KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12.toLowerCase() - ); - - @Override - public boolean canHandle(KeyStoreLoaderOptions options) { - return ( - options.getKeyStoreType() != null && - SUPPORTED_TYPES.contains(options.getKeyStoreType().toLowerCase()) && - ( - ( - options.getKeyStorePath() != null && - !options.getKeyStorePath().isEmpty() - ) || - ( - options.getKeyStoreCertificates() != null && - !options.getKeyStoreCertificates().isEmpty() - ) - ) + private static final List SUPPORTED_TYPES = Arrays.asList( + KeyStoreLoader.CERTIFICATE_FORMAT_JKS.toLowerCase(), + KeyStoreLoader.CERTIFICATE_FORMAT_PEM.toLowerCase(), + KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12.toLowerCase() ); - } - @Override - public KeyStoreLoader create(KeyStoreLoaderOptions options) { - return new FileKeyStoreLoader(options); - } + @Override + public boolean canHandle(KeyStoreLoaderOptions options) { + return ( + options.getKeyStoreType() != null && + SUPPORTED_TYPES.contains(options.getKeyStoreType().toLowerCase()) && + ( + (options.getKeyStorePath() != null && !options.getKeyStorePath().isEmpty()) || + (options.getKeyStoreCertificates() != null && !options.getKeyStoreCertificates().isEmpty()) + ) + ); + } + + @Override + public KeyStoreLoader create(KeyStoreLoaderOptions options) { + return new FileKeyStoreLoader(options); + } } diff --git a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/KeyStoreLoaderManager.java b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/KeyStoreLoaderManager.java index ab40ca701..3c5e800ff 100644 --- a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/KeyStoreLoaderManager.java +++ b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/KeyStoreLoaderManager.java @@ -30,41 +30,40 @@ * @author Jeoffrey HAEYAERT (jeoffrey.haeyaert at graviteesource.com) * @author GraviteeSource Team */ -public class KeyStoreLoaderManager - extends AbstractService { +public class KeyStoreLoaderManager extends AbstractService { - private final Set loaderFactories; - private final Set loaders; + private final Set loaderFactories; + private final Set loaders; - public KeyStoreLoaderManager() { - this.loaderFactories = new HashSet<>(); - this.loaders = new HashSet<>(); + public KeyStoreLoaderManager() { + this.loaderFactories = new HashSet<>(); + this.loaders = new HashSet<>(); - // Automatically register the file keystore nd self-signed loader factories. - this.registerFactory(new FileKeyStoreLoaderFactory()); - this.registerFactory(new SelfSignedKeyStoreLoaderFactory()); - } + // Automatically register the file keystore nd self-signed loader factories. + this.registerFactory(new FileKeyStoreLoaderFactory()); + this.registerFactory(new SelfSignedKeyStoreLoaderFactory()); + } - @Override - public KeyStoreLoaderManager preStop() throws Exception { - loaders.forEach(KeyStoreLoader::stop); - return this; - } + @Override + public KeyStoreLoaderManager preStop() throws Exception { + loaders.forEach(KeyStoreLoader::stop); + return this; + } - public void registerFactory(KeyStoreLoaderFactory keyStoreLoaderFactory) { - loaderFactories.add(keyStoreLoaderFactory); - } + public void registerFactory(KeyStoreLoaderFactory keyStoreLoaderFactory) { + loaderFactories.add(keyStoreLoaderFactory); + } - public Set getLoaderFactories() { - return loaderFactories; - } + public Set getLoaderFactories() { + return loaderFactories; + } - public KeyStoreLoader create(KeyStoreLoaderOptions options) { - return getLoaderFactories() - .stream() - .filter(keyStoreLoaderFactory -> keyStoreLoaderFactory.canHandle(options)) - .findFirst() - .map(keyStoreLoaderFactory -> keyStoreLoaderFactory.create(options)) - .orElse(null); - } + public KeyStoreLoader create(KeyStoreLoaderOptions options) { + return getLoaderFactories() + .stream() + .filter(keyStoreLoaderFactory -> keyStoreLoaderFactory.canHandle(options)) + .findFirst() + .map(keyStoreLoaderFactory -> keyStoreLoaderFactory.create(options)) + .orElse(null); + } } diff --git a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/ReloadableKeyManager.java b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/ReloadableKeyManager.java index 1ec6fb27d..b99475dbe 100644 --- a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/ReloadableKeyManager.java +++ b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/ReloadableKeyManager.java @@ -36,176 +36,134 @@ */ public class ReloadableKeyManager extends X509ExtendedKeyManager { - private static final Logger logger = LoggerFactory.getLogger( - ReloadableKeyManager.class - ); - - static final int MAX_SNI_DOMAINS = 10000; - - private String defaultAlias; - - private Map sniDomainAliases; - private volatile X509ExtendedKeyManager delegate; - private boolean enableSni; - - public void load( - String defaultAlias, - KeyStore keyStore, - String password, - boolean enableSni - ) { - try { - this.enableSni = enableSni; - - // If no alias is defined, get it from keystore. - if (defaultAlias == null) { - defaultAlias = KeyStoreUtils.getDefaultAlias(keyStore); - } else if (!keyStore.containsAlias(defaultAlias)) { - throw new IllegalArgumentException( - String.format( - "Unable to load keystore, default alias [%s] not present in the keystore.", - defaultAlias - ) - ); - } - - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance( - KeyManagerFactory.getDefaultAlgorithm() - ); - keyManagerFactory.init( - keyStore, - KeyStoreUtils.passwordToCharArray(password) - ); - - this.defaultAlias = defaultAlias; - - if (enableSni) { - // Try to pre-construct a list of domain -> alias to use for SNI. - this.sniDomainAliases = - new ConcurrentHashMap<>( - KeyStoreUtils.getCommonNamesByAlias(keyStore) - ); - } - this.delegate = - (X509ExtendedKeyManager) keyManagerFactory.getKeyManagers()[0]; - - logger.info( - "Key store has been (re)loaded with {} entries.", - keyStore.size() - ); - } catch (Exception e) { - throw new IllegalArgumentException("Unable to load keystore", e); - } - } - - @Override - public String chooseEngineServerAlias( - String keyType, - Principal[] issuers, - SSLEngine engine - ) { - if (!enableSni) { - return defaultAlias; + private static final Logger logger = LoggerFactory.getLogger(ReloadableKeyManager.class); + + static final int MAX_SNI_DOMAINS = 10000; + + private String defaultAlias; + + private Map sniDomainAliases; + private volatile X509ExtendedKeyManager delegate; + private boolean enableSni; + + public void load(String defaultAlias, KeyStore keyStore, String password, boolean enableSni) { + try { + this.enableSni = enableSni; + + // If no alias is defined, get it from keystore. + if (defaultAlias == null) { + defaultAlias = KeyStoreUtils.getDefaultAlias(keyStore); + } else if (!keyStore.containsAlias(defaultAlias)) { + throw new IllegalArgumentException( + String.format("Unable to load keystore, default alias [%s] not present in the keystore.", defaultAlias) + ); + } + + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + keyManagerFactory.init(keyStore, KeyStoreUtils.passwordToCharArray(password)); + + this.defaultAlias = defaultAlias; + + if (enableSni) { + // Try to pre-construct a list of domain -> alias to use for SNI. + this.sniDomainAliases = new ConcurrentHashMap<>(KeyStoreUtils.getCommonNamesByAlias(keyStore)); + } + this.delegate = (X509ExtendedKeyManager) keyManagerFactory.getKeyManagers()[0]; + + logger.info("Key store has been (re)loaded with {} entries.", keyStore.size()); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to load keystore", e); + } } - final ExtendedSSLSession session = (ExtendedSSLSession) engine.getHandshakeSession(); - final Optional optionalSNIServerName = session - .getRequestedServerNames() - .stream() - .filter(name -> name.getType() == SNI_HOST_NAME) - .map(name -> ((SNIHostName) name).getAsciiName()) - .findFirst(); - - if (optionalSNIServerName.isPresent()) { - final String hostname = optionalSNIServerName.get(); - - if (this.sniDomainAliases.containsKey(hostname)) { - return this.sniDomainAliases.get(hostname); - } - - // Try to find by wildcard. - final Optional> optCN = sniDomainAliases - .entrySet() - .stream() - .filter(e -> e.getKey().startsWith("*.")) - .filter(e -> hostname.endsWith(e.getKey().substring(2))) - .findFirst(); - - if (optCN.isPresent()) { - final String alias = optCN.get().getValue(); - cacheSniDomainAlias(hostname, alias); - return alias; - } else { - // Add the hostname to avoid future resolutions. - cacheSniDomainAlias(hostname, defaultAlias); + @Override + public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) { + if (!enableSni) { + return defaultAlias; + } + + final ExtendedSSLSession session = (ExtendedSSLSession) engine.getHandshakeSession(); + final Optional optionalSNIServerName = session + .getRequestedServerNames() + .stream() + .filter(name -> name.getType() == SNI_HOST_NAME) + .map(name -> ((SNIHostName) name).getAsciiName()) + .findFirst(); + + if (optionalSNIServerName.isPresent()) { + final String hostname = optionalSNIServerName.get(); + + if (this.sniDomainAliases.containsKey(hostname)) { + return this.sniDomainAliases.get(hostname); + } + + // Try to find by wildcard. + final Optional> optCN = sniDomainAliases + .entrySet() + .stream() + .filter(e -> e.getKey().startsWith("*.")) + .filter(e -> hostname.endsWith(e.getKey().substring(2))) + .findFirst(); + + if (optCN.isPresent()) { + final String alias = optCN.get().getValue(); + cacheSniDomainAlias(hostname, alias); + return alias; + } else { + // Add the hostname to avoid future resolutions. + cacheSniDomainAlias(hostname, defaultAlias); + return defaultAlias; + } + } + return defaultAlias; - } } - return defaultAlias; - } + /** + * Cache the mapping between domain name and certificate alias. + * If the map is full, the cache put is ignored. This avoid to full the memory in case of dos attack on a lot of non unknown domain names. + */ + private void cacheSniDomainAlias(String hostname, String alias) { + if (sniDomainAliases.size() < MAX_SNI_DOMAINS) { + this.sniDomainAliases.put(hostname, alias); + } + } + + @Override + public String[] getServerAliases(String keyType, Principal[] issuers) { + return delegate != null ? delegate.getServerAliases(keyType, issuers) : null; + } + + @Override + public X509Certificate[] getCertificateChain(String alias) { + return delegate != null ? delegate.getCertificateChain(alias) : null; + } + + @Override + public PrivateKey getPrivateKey(String alias) { + return delegate != null ? delegate.getPrivateKey(alias) : null; + } + + @Override + public String[] getClientAliases(String keyType, Principal[] issuers) { + return delegate != null ? delegate.getClientAliases(keyType, issuers) : null; + } + + @Override + public String chooseClientAlias(String[] aliases, Principal[] issuers, Socket socket) { + return delegate != null ? delegate.chooseClientAlias(aliases, issuers, socket) : null; + } + + @Override + public String chooseServerAlias(String alias, Principal[] issuers, Socket socket) { + return delegate != null ? delegate.chooseServerAlias(alias, issuers, socket) : null; + } + + Map getSniDomainAliases() { + return sniDomainAliases; + } - /** - * Cache the mapping between domain name and certificate alias. - * If the map is full, the cache put is ignored. This avoid to full the memory in case of dos attack on a lot of non unknown domain names. - */ - private void cacheSniDomainAlias(String hostname, String alias) { - if (sniDomainAliases.size() < MAX_SNI_DOMAINS) { - this.sniDomainAliases.put(hostname, alias); + void setSniDomainAliases(Map sniDomainAliases) { + this.sniDomainAliases = sniDomainAliases; } - } - - @Override - public String[] getServerAliases(String keyType, Principal[] issuers) { - return delegate != null - ? delegate.getServerAliases(keyType, issuers) - : null; - } - - @Override - public X509Certificate[] getCertificateChain(String alias) { - return delegate != null ? delegate.getCertificateChain(alias) : null; - } - - @Override - public PrivateKey getPrivateKey(String alias) { - return delegate != null ? delegate.getPrivateKey(alias) : null; - } - - @Override - public String[] getClientAliases(String keyType, Principal[] issuers) { - return delegate != null - ? delegate.getClientAliases(keyType, issuers) - : null; - } - - @Override - public String chooseClientAlias( - String[] aliases, - Principal[] issuers, - Socket socket - ) { - return delegate != null - ? delegate.chooseClientAlias(aliases, issuers, socket) - : null; - } - - @Override - public String chooseServerAlias( - String alias, - Principal[] issuers, - Socket socket - ) { - return delegate != null - ? delegate.chooseServerAlias(alias, issuers, socket) - : null; - } - - Map getSniDomainAliases() { - return sniDomainAliases; - } - - void setSniDomainAliases(Map sniDomainAliases) { - this.sniDomainAliases = sniDomainAliases; - } } diff --git a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoader.java b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoader.java index 436906187..a249f62a6 100644 --- a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoader.java +++ b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoader.java @@ -33,44 +33,35 @@ */ public class SelfSignedKeyStoreLoader implements KeyStoreLoader { - private static final Logger logger = LoggerFactory.getLogger( - SelfSignedKeyStoreLoader.class - ); + private static final Logger logger = LoggerFactory.getLogger(SelfSignedKeyStoreLoader.class); - private final List> listeners; - private final KeyStoreLoaderOptions options; + private final List> listeners; + private final KeyStoreLoaderOptions options; - public SelfSignedKeyStoreLoader(KeyStoreLoaderOptions options) { - this.options = options; - this.listeners = new ArrayList<>(); - } + public SelfSignedKeyStoreLoader(KeyStoreLoaderOptions options) { + this.options = options; + this.listeners = new ArrayList<>(); + } - @Override - public void start() { - logger.debug("Initializing self-signed keystore certificate."); - final String password = UUID.randomUUID().toString(); - final KeyStore keyStore = KeyStoreUtils.initSelfSigned( - "localhost", - password - ); - final KeyStoreBundle keyStoreBundle = new KeyStoreBundle( - keyStore, - password, - options.getDefaultAlias() - ); + @Override + public void start() { + logger.debug("Initializing self-signed keystore certificate."); + final String password = UUID.randomUUID().toString(); + final KeyStore keyStore = KeyStoreUtils.initSelfSigned("localhost", password); + final KeyStoreBundle keyStoreBundle = new KeyStoreBundle(keyStore, password, options.getDefaultAlias()); - notifyListeners(keyStoreBundle); - } + notifyListeners(keyStoreBundle); + } - @Override - public void stop() {} + @Override + public void stop() {} - @Override - public void addListener(Consumer listener) { - listeners.add(listener); - } + @Override + public void addListener(Consumer listener) { + listeners.add(listener); + } - private void notifyListeners(KeyStoreBundle keyStoreBundle) { - listeners.forEach(consumer -> consumer.accept(keyStoreBundle)); - } + private void notifyListeners(KeyStoreBundle keyStoreBundle) { + listeners.forEach(consumer -> consumer.accept(keyStoreBundle)); + } } diff --git a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoaderFactory.java b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoaderFactory.java index 8ef76232a..6dc21ec8c 100644 --- a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoaderFactory.java +++ b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoaderFactory.java @@ -25,18 +25,15 @@ */ public class SelfSignedKeyStoreLoaderFactory implements KeyStoreLoaderFactory { - @Override - public boolean canHandle(KeyStoreLoaderOptions options) { - return ( - options.getKeyStoreType() != null && - options - .getKeyStoreType() - .equalsIgnoreCase(KeyStoreLoader.CERTIFICATE_FORMAT_SELF_SIGNED) - ); - } + @Override + public boolean canHandle(KeyStoreLoaderOptions options) { + return ( + options.getKeyStoreType() != null && options.getKeyStoreType().equalsIgnoreCase(KeyStoreLoader.CERTIFICATE_FORMAT_SELF_SIGNED) + ); + } - @Override - public KeyStoreLoader create(KeyStoreLoaderOptions options) { - return new SelfSignedKeyStoreLoader(options); - } + @Override + public KeyStoreLoader create(KeyStoreLoaderOptions options) { + return new SelfSignedKeyStoreLoader(options); + } } diff --git a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/spring/NodeCertificatesConfiguration.java b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/spring/NodeCertificatesConfiguration.java index d036623af..608458362 100644 --- a/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/spring/NodeCertificatesConfiguration.java +++ b/gravitee-node-certificates/src/main/java/io/gravitee/node/certificates/spring/NodeCertificatesConfiguration.java @@ -26,8 +26,8 @@ @Configuration public class NodeCertificatesConfiguration { - @Bean - public KeyStoreLoaderManager keyStoreLoaderFactoryManager() { - return new KeyStoreLoaderManager(); - } + @Bean + public KeyStoreLoaderManager keyStoreLoaderFactoryManager() { + return new KeyStoreLoaderManager(); + } } diff --git a/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/FileKeyStoreLoaderFactoryTest.java b/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/FileKeyStoreLoaderFactoryTest.java index 45903f001..31d704023 100644 --- a/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/FileKeyStoreLoaderFactoryTest.java +++ b/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/FileKeyStoreLoaderFactoryTest.java @@ -28,80 +28,80 @@ */ public class FileKeyStoreLoaderFactoryTest { - private FileKeyStoreLoaderFactory cut; - - @Before - public void before() { - cut = new FileKeyStoreLoaderFactory(); - } - - @Test - public void shouldHandleOptionsWithPKCS12() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKeyStorePath(getPath("localhost.p12")) - .build(); - - assertTrue(cut.canHandle(options)); - } - - @Test - public void shouldNotHandleOptionsWithPKCS12WithoutPath() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKeyStorePath(null) - .build(); - - assertFalse(cut.canHandle(options)); - } - - @Test - public void shouldHandleOptionsWithJKS() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_JKS) - .withKeyStorePath(getPath("localhost.jks")) - .build(); - - assertTrue(cut.canHandle(options)); - } - - @Test - public void shouldNotHandleOptionsWithJKSWithoutPath() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_JKS) - .withKeyStorePath(null) - .build(); - - assertFalse(cut.canHandle(options)); - } - - @Test - public void shouldHandleOptionsWithPEM() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_JKS) - .withKeyStorePath(getPath("localhost.jks")) - .build(); - - assertTrue(cut.canHandle(options)); - } - - @Test - public void shouldNotHandleOptionsWithSelfSigned() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_SELF_SIGNED) - .withKeyStorePath(null) - .build(); - - assertFalse(cut.canHandle(options)); - } - - private String getPath(String resource) { - return this.getClass().getResource("/keystores/" + resource).getPath(); - } + private FileKeyStoreLoaderFactory cut; + + @Before + public void before() { + cut = new FileKeyStoreLoaderFactory(); + } + + @Test + public void shouldHandleOptionsWithPKCS12() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKeyStorePath(getPath("localhost.p12")) + .build(); + + assertTrue(cut.canHandle(options)); + } + + @Test + public void shouldNotHandleOptionsWithPKCS12WithoutPath() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKeyStorePath(null) + .build(); + + assertFalse(cut.canHandle(options)); + } + + @Test + public void shouldHandleOptionsWithJKS() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_JKS) + .withKeyStorePath(getPath("localhost.jks")) + .build(); + + assertTrue(cut.canHandle(options)); + } + + @Test + public void shouldNotHandleOptionsWithJKSWithoutPath() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_JKS) + .withKeyStorePath(null) + .build(); + + assertFalse(cut.canHandle(options)); + } + + @Test + public void shouldHandleOptionsWithPEM() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_JKS) + .withKeyStorePath(getPath("localhost.jks")) + .build(); + + assertTrue(cut.canHandle(options)); + } + + @Test + public void shouldNotHandleOptionsWithSelfSigned() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_SELF_SIGNED) + .withKeyStorePath(null) + .build(); + + assertFalse(cut.canHandle(options)); + } + + private String getPath(String resource) { + return this.getClass().getResource("/keystores/" + resource).getPath(); + } } diff --git a/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/FileKeyStoreLoaderTest.java b/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/FileKeyStoreLoaderTest.java index 560feb9fc..33fcbfa7e 100644 --- a/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/FileKeyStoreLoaderTest.java +++ b/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/FileKeyStoreLoaderTest.java @@ -39,217 +39,188 @@ */ public class FileKeyStoreLoaderTest { - private FileKeyStoreLoader cut; - - @After - public void after() { - cut.stop(); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldNotStartOnMissingFile() { - // Make sure an exception is thrown in case of missing file. - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKeyStorePath("/path-to-unknown.p12") - .withKeyStorePassword("secret") - .withDefaultAlias("localhost") - .withWatch(false) - .build(); - - cut = new FileKeyStoreLoader(options); - cut.start(); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldNotStartOnInvalidKeyStore() throws IOException { - // Make sure an exception is thrown in case of invalid keystore. - final File tempKeyStore = File.createTempFile("gio", ".p12"); - FileCopyUtils.copy(new byte[0], tempKeyStore); - - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKeyStorePath(tempKeyStore.getAbsolutePath()) - .withKeyStorePassword("secret") - .withDefaultAlias("localhost") - .withWatch(false) - .build(); - - cut = new FileKeyStoreLoader(options); - cut.start(); - } - - @Test - public void shouldLoadPKCS12() throws KeyStoreException { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKeyStorePath(getPath("all-in-one.p12")) - .withKeyStorePassword("secret") - .withDefaultAlias("localhost") - .withWatch(false) - .build(); - - cut = new FileKeyStoreLoader(options); - - final AtomicReference bundleRef = new AtomicReference<>( - null - ); - cut.addListener(bundleRef::set); - - cut.start(); - - assertNotNull(bundleRef.get()); - - final KeyStoreBundle keyStoreBundle = bundleRef.get(); - assertNotNull(keyStoreBundle); - assertNotNull(keyStoreBundle.getKeyStore()); - assertEquals(4, keyStoreBundle.getKeyStore().size()); - assertEquals("localhost", keyStoreBundle.getDefaultAlias()); - assertEquals("secret", keyStoreBundle.getPassword()); - } - - @Test - public void shouldLoadJKS() throws KeyStoreException { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_JKS) - .withKeyStorePath(getPath("all-in-one.jks")) - .withKeyStorePassword("secret") - .withDefaultAlias("localhost") - .withWatch(false) - .build(); - - cut = new FileKeyStoreLoader(options); - - final AtomicReference bundleRef = new AtomicReference<>( - null - ); - cut.addListener(bundleRef::set); - - cut.start(); - - final KeyStoreBundle keyStoreBundle = bundleRef.get(); - assertNotNull(keyStoreBundle); - assertNotNull(keyStoreBundle.getKeyStore()); - assertEquals(4, keyStoreBundle.getKeyStore().size()); - assertEquals("localhost", keyStoreBundle.getDefaultAlias()); - assertEquals("secret", keyStoreBundle.getPassword()); - } - - @Test - public void shouldLoadPEMs() throws KeyStoreException { - final ArrayList certificates = new ArrayList<>(); - - certificates.add( - new CertificateOptions(getPath("localhost.cer"), getPath("localhost.key")) - ); - certificates.add( - new CertificateOptions( - getPath("localhost2.cer"), - getPath("localhost2.key") - ) - ); - certificates.add( - new CertificateOptions( - getPath("localhost3.cer"), - getPath("localhost3.key") - ) - ); - certificates.add( - new CertificateOptions(getPath("wildcard.cer"), getPath("wildcard.key")) - ); - - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) - .withKeyStoreCertificates(certificates) - .withKeyStorePassword("secret") - .withDefaultAlias("localhost") - .withWatch(false) - .build(); - - cut = new FileKeyStoreLoader(options); - - final AtomicReference bundleRef = new AtomicReference<>( - null - ); - cut.addListener(bundleRef::set); - - cut.start(); - - final KeyStoreBundle keyStoreBundle = bundleRef.get(); - assertNotNull(keyStoreBundle); - assertNotNull(keyStoreBundle.getKeyStore()); - assertEquals(4, keyStoreBundle.getKeyStore().size()); - assertNull(keyStoreBundle.getDefaultAlias()); // Alias can't be defined for pem. - assertEquals("secret", keyStoreBundle.getPassword()); - } - - @Test - public void shouldWatchFileAndDetectChanges() - throws IOException, InterruptedException { - final File tempKeyStore = File.createTempFile("gio", ".p12"); - FileCopyUtils.copy(new File(getPath("localhost.p12")), tempKeyStore); - - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_JKS) - .withKeyStorePath(tempKeyStore.getAbsolutePath()) - .withKeyStorePassword("secret") - .withWatch(true) - .build(); - - cut = new FileKeyStoreLoader(options); - - final AtomicReference bundleRef = new AtomicReference<>( - null - ); - cut.addListener(bundleRef::set); - - cut.start(); - - KeyStoreBundle bundle = bundleRef.get(); - - // Check the initial keystore has been properly loaded. - assertNotNull(bundle); - assertEquals( - "localhost", - KeyStoreUtils.getDefaultAlias(bundle.getKeyStore()) - ); - - // Register a listener to trap the reload event. - CountDownLatch latch = new CountDownLatch(1); - cut.addListener(kb -> latch.countDown()); - - long started = System.currentTimeMillis(); - - // Wait the watcher to be started started before making changes on the file keystore. - while (!cut.isWatching()) { - Thread.sleep(50); - if (System.currentTimeMillis() - started > 10000) { - fail("Watcher time to start exceed 10s"); - } + private FileKeyStoreLoader cut; + + @After + public void after() { + cut.stop(); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldNotStartOnMissingFile() { + // Make sure an exception is thrown in case of missing file. + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKeyStorePath("/path-to-unknown.p12") + .withKeyStorePassword("secret") + .withDefaultAlias("localhost") + .withWatch(false) + .build(); + + cut = new FileKeyStoreLoader(options); + cut.start(); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldNotStartOnInvalidKeyStore() throws IOException { + // Make sure an exception is thrown in case of invalid keystore. + final File tempKeyStore = File.createTempFile("gio", ".p12"); + FileCopyUtils.copy(new byte[0], tempKeyStore); + + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKeyStorePath(tempKeyStore.getAbsolutePath()) + .withKeyStorePassword("secret") + .withDefaultAlias("localhost") + .withWatch(false) + .build(); + + cut = new FileKeyStoreLoader(options); + cut.start(); + } + + @Test + public void shouldLoadPKCS12() throws KeyStoreException { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKeyStorePath(getPath("all-in-one.p12")) + .withKeyStorePassword("secret") + .withDefaultAlias("localhost") + .withWatch(false) + .build(); + + cut = new FileKeyStoreLoader(options); + + final AtomicReference bundleRef = new AtomicReference<>(null); + cut.addListener(bundleRef::set); + + cut.start(); + + assertNotNull(bundleRef.get()); + + final KeyStoreBundle keyStoreBundle = bundleRef.get(); + assertNotNull(keyStoreBundle); + assertNotNull(keyStoreBundle.getKeyStore()); + assertEquals(4, keyStoreBundle.getKeyStore().size()); + assertEquals("localhost", keyStoreBundle.getDefaultAlias()); + assertEquals("secret", keyStoreBundle.getPassword()); + } + + @Test + public void shouldLoadJKS() throws KeyStoreException { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_JKS) + .withKeyStorePath(getPath("all-in-one.jks")) + .withKeyStorePassword("secret") + .withDefaultAlias("localhost") + .withWatch(false) + .build(); + + cut = new FileKeyStoreLoader(options); + + final AtomicReference bundleRef = new AtomicReference<>(null); + cut.addListener(bundleRef::set); + + cut.start(); + + final KeyStoreBundle keyStoreBundle = bundleRef.get(); + assertNotNull(keyStoreBundle); + assertNotNull(keyStoreBundle.getKeyStore()); + assertEquals(4, keyStoreBundle.getKeyStore().size()); + assertEquals("localhost", keyStoreBundle.getDefaultAlias()); + assertEquals("secret", keyStoreBundle.getPassword()); } - FileCopyUtils.copy(new File(getPath("localhost2.p12")), tempKeyStore); + @Test + public void shouldLoadPEMs() throws KeyStoreException { + final ArrayList certificates = new ArrayList<>(); + + certificates.add(new CertificateOptions(getPath("localhost.cer"), getPath("localhost.key"))); + certificates.add(new CertificateOptions(getPath("localhost2.cer"), getPath("localhost2.key"))); + certificates.add(new CertificateOptions(getPath("localhost3.cer"), getPath("localhost3.key"))); + certificates.add(new CertificateOptions(getPath("wildcard.cer"), getPath("wildcard.key"))); + + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) + .withKeyStoreCertificates(certificates) + .withKeyStorePassword("secret") + .withDefaultAlias("localhost") + .withWatch(false) + .build(); + + cut = new FileKeyStoreLoader(options); + + final AtomicReference bundleRef = new AtomicReference<>(null); + cut.addListener(bundleRef::set); + + cut.start(); + + final KeyStoreBundle keyStoreBundle = bundleRef.get(); + assertNotNull(keyStoreBundle); + assertNotNull(keyStoreBundle.getKeyStore()); + assertEquals(4, keyStoreBundle.getKeyStore().size()); + assertNull(keyStoreBundle.getDefaultAlias()); // Alias can't be defined for pem. + assertEquals("secret", keyStoreBundle.getPassword()); + } + + @Test + public void shouldWatchFileAndDetectChanges() throws IOException, InterruptedException { + final File tempKeyStore = File.createTempFile("gio", ".p12"); + FileCopyUtils.copy(new File(getPath("localhost.p12")), tempKeyStore); + + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_JKS) + .withKeyStorePath(tempKeyStore.getAbsolutePath()) + .withKeyStorePassword("secret") + .withWatch(true) + .build(); + + cut = new FileKeyStoreLoader(options); + + final AtomicReference bundleRef = new AtomicReference<>(null); + cut.addListener(bundleRef::set); + + cut.start(); + + KeyStoreBundle bundle = bundleRef.get(); - assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); + // Check the initial keystore has been properly loaded. + assertNotNull(bundle); + assertEquals("localhost", KeyStoreUtils.getDefaultAlias(bundle.getKeyStore())); - bundle = bundleRef.get(); + // Register a listener to trap the reload event. + CountDownLatch latch = new CountDownLatch(1); + cut.addListener(kb -> latch.countDown()); - assertNotNull(bundle); - assertEquals( - "localhost2", - KeyStoreUtils.getDefaultAlias(bundle.getKeyStore()) - ); + long started = System.currentTimeMillis(); - cut.stop(); - } + // Wait the watcher to be started started before making changes on the file keystore. + while (!cut.isWatching()) { + Thread.sleep(50); + if (System.currentTimeMillis() - started > 10000) { + fail("Watcher time to start exceed 10s"); + } + } - private String getPath(String resource) { - return this.getClass().getResource("/keystores/" + resource).getPath(); - } + FileCopyUtils.copy(new File(getPath("localhost2.p12")), tempKeyStore); + + assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); + + bundle = bundleRef.get(); + + assertNotNull(bundle); + assertEquals("localhost2", KeyStoreUtils.getDefaultAlias(bundle.getKeyStore())); + + cut.stop(); + } + + private String getPath(String resource) { + return this.getClass().getResource("/keystores/" + resource).getPath(); + } } diff --git a/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/KeyStoreLoaderManagerTest.java b/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/KeyStoreLoaderManagerTest.java index 73fe4b323..df5e96cef 100644 --- a/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/KeyStoreLoaderManagerTest.java +++ b/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/KeyStoreLoaderManagerTest.java @@ -32,55 +32,43 @@ */ public class KeyStoreLoaderManagerTest { - private KeyStoreLoaderManager cut; + private KeyStoreLoaderManager cut; - @Before - public void before() { - cut = new KeyStoreLoaderManager(); - } + @Before + public void before() { + cut = new KeyStoreLoaderManager(); + } - @Test - public void shouldHaveDefaultLoaders() { - assertEquals(2, cut.getLoaderFactories().size()); - assertTrue( - cut - .getLoaderFactories() - .stream() - .allMatch( - l -> - l instanceof FileKeyStoreLoaderFactory || - l instanceof SelfSignedKeyStoreLoaderFactory - ) - ); - } + @Test + public void shouldHaveDefaultLoaders() { + assertEquals(2, cut.getLoaderFactories().size()); + assertTrue( + cut + .getLoaderFactories() + .stream() + .allMatch(l -> l instanceof FileKeyStoreLoaderFactory || l instanceof SelfSignedKeyStoreLoaderFactory) + ); + } - @Test - public void shouldRegisterFactory() { - final KeyStoreLoaderFactory loaderFactory = mock( - KeyStoreLoaderFactory.class - ); - cut.registerFactory(loaderFactory); + @Test + public void shouldRegisterFactory() { + final KeyStoreLoaderFactory loaderFactory = mock(KeyStoreLoaderFactory.class); + cut.registerFactory(loaderFactory); - assertTrue(cut.getLoaderFactories().contains(loaderFactory)); - } + assertTrue(cut.getLoaderFactories().contains(loaderFactory)); + } - @Test - public void shouldCreateUsingAppropriateFactory() { - final KeyStoreLoaderFactory loaderFactory = mock( - KeyStoreLoaderFactory.class - ); - final KeyStoreLoader keyStoreLoader = mock(KeyStoreLoader.class); + @Test + public void shouldCreateUsingAppropriateFactory() { + final KeyStoreLoaderFactory loaderFactory = mock(KeyStoreLoaderFactory.class); + final KeyStoreLoader keyStoreLoader = mock(KeyStoreLoader.class); - when(loaderFactory.canHandle(any(KeyStoreLoaderOptions.class))) - .thenReturn(true); - when(loaderFactory.create(any(KeyStoreLoaderOptions.class))) - .thenReturn(keyStoreLoader); + when(loaderFactory.canHandle(any(KeyStoreLoaderOptions.class))).thenReturn(true); + when(loaderFactory.create(any(KeyStoreLoaderOptions.class))).thenReturn(keyStoreLoader); - cut.registerFactory(loaderFactory); - final KeyStoreLoader createdLoader = cut.create( - KeyStoreLoaderOptions.builder().build() - ); + cut.registerFactory(loaderFactory); + final KeyStoreLoader createdLoader = cut.create(KeyStoreLoaderOptions.builder().build()); - assertEquals(keyStoreLoader, createdLoader); - } + assertEquals(keyStoreLoader, createdLoader); + } } diff --git a/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/ReloadableKeyManagerTest.java b/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/ReloadableKeyManagerTest.java index 39e5e053e..46aeb668b 100644 --- a/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/ReloadableKeyManagerTest.java +++ b/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/ReloadableKeyManagerTest.java @@ -41,147 +41,101 @@ @RunWith(MockitoJUnitRunner.class) public class ReloadableKeyManagerTest { - @Mock - private SSLEngine sslEngine; - - @Mock - private ExtendedSSLSession sslSession; - - private ReloadableKeyManager cut; - - @Before - public void before() { - cut = new ReloadableKeyManager(); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldNotLoadIfAliasUnknown() { - final KeyStore keyStore = KeyStoreUtils.initFromPath( - CERTIFICATE_FORMAT_PKCS12, - getPath("all-in-one.p12"), - "secret" - ); - - cut.load("unknown", keyStore, "secret", false); - } - - @Test - public void shouldChooseDefaultAliasWhenNoSNI() { - final KeyStore keyStore = KeyStoreUtils.initFromPath( - CERTIFICATE_FORMAT_PKCS12, - getPath("all-in-one.p12"), - "secret" - ); - - cut.load("localhost", keyStore, "secret", false); - - // No SNI, default alias is returned. - assertEquals( - "localhost", - cut.chooseEngineServerAlias("void", null, sslEngine) - ); - } - - @Test - public void shouldChooseWildcard() { - final KeyStore keyStore = KeyStoreUtils.initFromPath( - CERTIFICATE_FORMAT_PKCS12, - getPath("all-in-one.p12"), - "secret" - ); - - cut.load("localhost", keyStore, "secret", true); - - when(sslEngine.getHandshakeSession()).thenReturn(sslSession); - when(sslSession.getRequestedServerNames()) - .thenReturn( - Collections.singletonList(new SNIHostName("test.localhost.com")) - ); - - assertEquals( - "wildcard", - cut.chooseEngineServerAlias("void", null, sslEngine) - ); - - assertTrue(cut.getSniDomainAliases().containsKey("test.localhost.com")); - } - - @Test - public void shouldFallbackToDefaultAliasIfUnknown() { - final KeyStore keyStore = KeyStoreUtils.initFromPath( - CERTIFICATE_FORMAT_PKCS12, - getPath("all-in-one.p12"), - "secret" - ); - - cut.load("localhost", keyStore, "secret", true); - - when(sslEngine.getHandshakeSession()).thenReturn(sslSession); - when(sslSession.getRequestedServerNames()) - .thenReturn(Collections.singletonList(new SNIHostName("unknown.com"))); - - assertEquals( - "localhost", - cut.chooseEngineServerAlias("void", null, sslEngine) - ); - } - - @Test - public void shouldFallbackToDefaultAliasIfNoServerName() { - final KeyStore keyStore = KeyStoreUtils.initFromPath( - CERTIFICATE_FORMAT_PKCS12, - getPath("all-in-one.p12"), - "secret" - ); - - cut.load("localhost", keyStore, "secret", true); - - when(sslEngine.getHandshakeSession()).thenReturn(sslSession); - when(sslSession.getRequestedServerNames()) - .thenReturn(Collections.emptyList()); - - assertEquals( - "localhost", - cut.chooseEngineServerAlias("void", null, sslEngine) - ); - } - - @Test - public void shouldStopCacheWhenCacheIsFull() { - final KeyStore keyStore = KeyStoreUtils.initFromPath( - CERTIFICATE_FORMAT_PKCS12, - getPath("all-in-one.p12"), - "secret" - ); - - cut.load("localhost", keyStore, "secret", true); - - AtomicInteger counter = new AtomicInteger(0); - - when(sslEngine.getHandshakeSession()).thenReturn(sslSession); - when(sslSession.getRequestedServerNames()) - .thenAnswer( - i -> - Collections.singletonList( - new SNIHostName("unknown" + counter.getAndIncrement() + ".com") - ) - ); - - // Populate the cache up to max size. - int numToFake = MAX_SNI_DOMAINS - cut.getSniDomainAliases().size(); - for (int i = 0; i < numToFake; i++) { - cut.getSniDomainAliases().put("fake" + i, "fake"); + @Mock + private SSLEngine sslEngine; + + @Mock + private ExtendedSSLSession sslSession; + + private ReloadableKeyManager cut; + + @Before + public void before() { + cut = new ReloadableKeyManager(); } - assertEquals(MAX_SNI_DOMAINS, cut.getSniDomainAliases().size()); + @Test(expected = IllegalArgumentException.class) + public void shouldNotLoadIfAliasUnknown() { + final KeyStore keyStore = KeyStoreUtils.initFromPath(CERTIFICATE_FORMAT_PKCS12, getPath("all-in-one.p12"), "secret"); + + cut.load("unknown", keyStore, "secret", false); + } + + @Test + public void shouldChooseDefaultAliasWhenNoSNI() { + final KeyStore keyStore = KeyStoreUtils.initFromPath(CERTIFICATE_FORMAT_PKCS12, getPath("all-in-one.p12"), "secret"); + + cut.load("localhost", keyStore, "secret", false); + + // No SNI, default alias is returned. + assertEquals("localhost", cut.chooseEngineServerAlias("void", null, sslEngine)); + } - // Try a new call - cut.chooseEngineServerAlias("void", null, sslEngine); + @Test + public void shouldChooseWildcard() { + final KeyStore keyStore = KeyStoreUtils.initFromPath(CERTIFICATE_FORMAT_PKCS12, getPath("all-in-one.p12"), "secret"); - assertEquals(MAX_SNI_DOMAINS, cut.getSniDomainAliases().size()); - } + cut.load("localhost", keyStore, "secret", true); - private String getPath(String resource) { - return this.getClass().getResource("/keystores/" + resource).getPath(); - } + when(sslEngine.getHandshakeSession()).thenReturn(sslSession); + when(sslSession.getRequestedServerNames()).thenReturn(Collections.singletonList(new SNIHostName("test.localhost.com"))); + + assertEquals("wildcard", cut.chooseEngineServerAlias("void", null, sslEngine)); + + assertTrue(cut.getSniDomainAliases().containsKey("test.localhost.com")); + } + + @Test + public void shouldFallbackToDefaultAliasIfUnknown() { + final KeyStore keyStore = KeyStoreUtils.initFromPath(CERTIFICATE_FORMAT_PKCS12, getPath("all-in-one.p12"), "secret"); + + cut.load("localhost", keyStore, "secret", true); + + when(sslEngine.getHandshakeSession()).thenReturn(sslSession); + when(sslSession.getRequestedServerNames()).thenReturn(Collections.singletonList(new SNIHostName("unknown.com"))); + + assertEquals("localhost", cut.chooseEngineServerAlias("void", null, sslEngine)); + } + + @Test + public void shouldFallbackToDefaultAliasIfNoServerName() { + final KeyStore keyStore = KeyStoreUtils.initFromPath(CERTIFICATE_FORMAT_PKCS12, getPath("all-in-one.p12"), "secret"); + + cut.load("localhost", keyStore, "secret", true); + + when(sslEngine.getHandshakeSession()).thenReturn(sslSession); + when(sslSession.getRequestedServerNames()).thenReturn(Collections.emptyList()); + + assertEquals("localhost", cut.chooseEngineServerAlias("void", null, sslEngine)); + } + + @Test + public void shouldStopCacheWhenCacheIsFull() { + final KeyStore keyStore = KeyStoreUtils.initFromPath(CERTIFICATE_FORMAT_PKCS12, getPath("all-in-one.p12"), "secret"); + + cut.load("localhost", keyStore, "secret", true); + + AtomicInteger counter = new AtomicInteger(0); + + when(sslEngine.getHandshakeSession()).thenReturn(sslSession); + when(sslSession.getRequestedServerNames()) + .thenAnswer(i -> Collections.singletonList(new SNIHostName("unknown" + counter.getAndIncrement() + ".com"))); + + // Populate the cache up to max size. + int numToFake = MAX_SNI_DOMAINS - cut.getSniDomainAliases().size(); + for (int i = 0; i < numToFake; i++) { + cut.getSniDomainAliases().put("fake" + i, "fake"); + } + + assertEquals(MAX_SNI_DOMAINS, cut.getSniDomainAliases().size()); + + // Try a new call + cut.chooseEngineServerAlias("void", null, sslEngine); + + assertEquals(MAX_SNI_DOMAINS, cut.getSniDomainAliases().size()); + } + + private String getPath(String resource) { + return this.getClass().getResource("/keystores/" + resource).getPath(); + } } diff --git a/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoaderFactoryTest.java b/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoaderFactoryTest.java index c247d2506..eb44704af 100644 --- a/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoaderFactoryTest.java +++ b/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoaderFactoryTest.java @@ -28,51 +28,51 @@ */ public class SelfSignedKeyStoreLoaderFactoryTest { - private SelfSignedKeyStoreLoaderFactory cut; + private SelfSignedKeyStoreLoaderFactory cut; - @Before - public void before() { - cut = new SelfSignedKeyStoreLoaderFactory(); - } + @Before + public void before() { + cut = new SelfSignedKeyStoreLoaderFactory(); + } - @Test - public void shouldHandleOptionsWithSelfSigned() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_SELF_SIGNED) - .withKeyStorePath(null) - .build(); + @Test + public void shouldHandleOptionsWithSelfSigned() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_SELF_SIGNED) + .withKeyStorePath(null) + .build(); - assertTrue(cut.canHandle(options)); - } + assertTrue(cut.canHandle(options)); + } - @Test - public void shouldNotHandleOptionsWithPKCS12() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .build(); + @Test + public void shouldNotHandleOptionsWithPKCS12() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .build(); - assertFalse(cut.canHandle(options)); - } + assertFalse(cut.canHandle(options)); + } - @Test - public void shouldNotHandleOptionsWithJKS() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_JKS) - .build(); + @Test + public void shouldNotHandleOptionsWithJKS() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_JKS) + .build(); - assertFalse(cut.canHandle(options)); - } + assertFalse(cut.canHandle(options)); + } - @Test - public void shouldNotHandleOptionsWithPEM() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) - .build(); + @Test + public void shouldNotHandleOptionsWithPEM() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) + .build(); - assertFalse(cut.canHandle(options)); - } + assertFalse(cut.canHandle(options)); + } } diff --git a/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoaderTest.java b/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoaderTest.java index 7b418093e..a4f5f7d78 100644 --- a/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoaderTest.java +++ b/gravitee-node-certificates/src/test/java/io/gravitee/node/certificates/SelfSignedKeyStoreLoaderTest.java @@ -33,34 +33,29 @@ */ public class SelfSignedKeyStoreLoaderTest { - private SelfSignedKeyStoreLoader cut; + private SelfSignedKeyStoreLoader cut; - @Before - public void before() { - cut = - new SelfSignedKeyStoreLoader( - KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_SELF_SIGNED) - .build() - ); - } + @Before + public void before() { + cut = + new SelfSignedKeyStoreLoader( + KeyStoreLoaderOptions.builder().withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_SELF_SIGNED).build() + ); + } - @Test - public void shouldGenerateSelfSignedCertificate() throws KeyStoreException { - final AtomicReference bundleRef = new AtomicReference<>( - null - ); + @Test + public void shouldGenerateSelfSignedCertificate() throws KeyStoreException { + final AtomicReference bundleRef = new AtomicReference<>(null); - cut.addListener(bundleRef::set); + cut.addListener(bundleRef::set); - cut.start(); + cut.start(); - final KeyStoreBundle bundle = bundleRef.get(); + final KeyStoreBundle bundle = bundleRef.get(); - assertNotNull(bundle); - assertNotNull(bundle.getKeyStore()); - assertEquals(1, bundle.getKeyStore().size()); - assertNotNull(bundle.getKeyStore().getCertificate(DEFAULT_ALIAS)); - } + assertNotNull(bundle); + assertNotNull(bundle.getKeyStore()); + assertEquals(1, bundle.getKeyStore().size()); + assertNotNull(bundle.getKeyStore().getCertificate(DEFAULT_ALIAS)); + } } diff --git a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/ClusterService.java b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/ClusterService.java index 4ba37b11e..b46c0ca76 100644 --- a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/ClusterService.java +++ b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/ClusterService.java @@ -22,22 +22,22 @@ public class ClusterService extends AbstractService { - @Autowired - private ClusterManager clusterManager; + @Autowired + private ClusterManager clusterManager; - @Autowired - private Node node; + @Autowired + private Node node; - @Override - public ClusterService postStart() throws Exception { - node.metadata().put("node.id", node.id()); - node.metadata().put("node.hostname", node.hostname()); + @Override + public ClusterService postStart() throws Exception { + node.metadata().put("node.id", node.id()); + node.metadata().put("node.hostname", node.hostname()); - return this; - } + return this; + } - @Override - protected void doStop() throws Exception { - clusterManager.stop(); - } + @Override + protected void doStop() throws Exception { + clusterManager.stop(); + } } diff --git a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/hazelcast/HazelcastClusterManager.java b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/hazelcast/HazelcastClusterManager.java index b849f5ab0..fa13bb6d2 100644 --- a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/hazelcast/HazelcastClusterManager.java +++ b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/hazelcast/HazelcastClusterManager.java @@ -36,101 +36,77 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class HazelcastClusterManager - implements InitializingBean, ClusterManager, MembershipListener { - - private final Logger LOGGER = LoggerFactory.getLogger( - HazelcastClusterManager.class - ); - - @Autowired - private HazelcastInstance hazelcastInstance; - - private final Set memberListeners = new HashSet<>(); - - @Override - public void afterPropertiesSet() throws Exception { - hazelcastInstance.getCluster().addMembershipListener(this); - } - - private boolean isMaster(com.hazelcast.cluster.Member member) { - com.hazelcast.cluster.Member master = hazelcastInstance - .getCluster() - .getMembers() - .iterator() - .next(); - return member.equals(master); - } - - @Override - public Collection getMembers() { - return hazelcastInstance - .getCluster() - .getMembers() - .stream() - .map( - new Function() { - @Override - public Member apply(com.hazelcast.cluster.Member member) { - return new NodeMember(member, isMaster(member)); - } - } - ) - .collect(Collectors.toSet()); - } - - @Override - public Member getLocalMember() { - return new NodeMember( - hazelcastInstance.getCluster().getLocalMember(), - isMaster(hazelcastInstance.getCluster().getLocalMember()) - ); - } - - @Override - public boolean isMasterNode() { - return isMaster(hazelcastInstance.getCluster().getLocalMember()); - } - - @Override - public void addMemberListener(MemberListener listener) { - memberListeners.add(listener); - } - - @Override - public void stop() { - hazelcastInstance.shutdown(); - } - - @Override - public void memberAdded(MembershipEvent event) { - LOGGER.info("A node join the cluster: {}", event); - com.hazelcast.cluster.Member master = hazelcastInstance - .getCluster() - .getMembers() - .iterator() - .next(); - Member newMember = new NodeMember( - event.getMember(), - master.equals(event.getMember()) - ); - - memberListeners.forEach(listener -> listener.memberAdded(newMember)); - } - - @Override - public void memberRemoved(MembershipEvent event) { - LOGGER.info("A node leave the cluster: {}", event); - com.hazelcast.cluster.Member master = hazelcastInstance - .getCluster() - .getMembers() - .iterator() - .next(); - Member newMember = new NodeMember( - event.getMember(), - master.equals(event.getMember()) - ); - - memberListeners.forEach(listener -> listener.memberRemoved(newMember)); - } +public class HazelcastClusterManager implements InitializingBean, ClusterManager, MembershipListener { + + private final Logger LOGGER = LoggerFactory.getLogger(HazelcastClusterManager.class); + + @Autowired + private HazelcastInstance hazelcastInstance; + + private final Set memberListeners = new HashSet<>(); + + @Override + public void afterPropertiesSet() throws Exception { + hazelcastInstance.getCluster().addMembershipListener(this); + } + + private boolean isMaster(com.hazelcast.cluster.Member member) { + com.hazelcast.cluster.Member master = hazelcastInstance.getCluster().getMembers().iterator().next(); + return member.equals(master); + } + + @Override + public Collection getMembers() { + return hazelcastInstance + .getCluster() + .getMembers() + .stream() + .map( + new Function() { + @Override + public Member apply(com.hazelcast.cluster.Member member) { + return new NodeMember(member, isMaster(member)); + } + } + ) + .collect(Collectors.toSet()); + } + + @Override + public Member getLocalMember() { + return new NodeMember(hazelcastInstance.getCluster().getLocalMember(), isMaster(hazelcastInstance.getCluster().getLocalMember())); + } + + @Override + public boolean isMasterNode() { + return isMaster(hazelcastInstance.getCluster().getLocalMember()); + } + + @Override + public void addMemberListener(MemberListener listener) { + memberListeners.add(listener); + } + + @Override + public void stop() { + hazelcastInstance.shutdown(); + } + + @Override + public void memberAdded(MembershipEvent event) { + LOGGER.info("A node join the cluster: {}", event); + com.hazelcast.cluster.Member master = hazelcastInstance.getCluster().getMembers().iterator().next(); + Member newMember = new NodeMember(event.getMember(), master.equals(event.getMember())); + + memberListeners.forEach(listener -> listener.memberAdded(newMember)); + } + + @Override + public void memberRemoved(MembershipEvent event) { + LOGGER.info("A node leave the cluster: {}", event); + com.hazelcast.cluster.Member master = hazelcastInstance.getCluster().getMembers().iterator().next(); + Member newMember = new NodeMember(event.getMember(), master.equals(event.getMember())); + + memberListeners.forEach(listener -> listener.memberRemoved(newMember)); + } } diff --git a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/hazelcast/HazelcastMessageProducer.java b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/hazelcast/HazelcastMessageProducer.java index 30ca4f412..37d9a1f6b 100644 --- a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/hazelcast/HazelcastMessageProducer.java +++ b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/hazelcast/HazelcastMessageProducer.java @@ -27,12 +27,12 @@ */ public class HazelcastMessageProducer implements MessageProducer { - @Autowired - private HazelcastInstance hazelcastInstance; + @Autowired + private HazelcastInstance hazelcastInstance; - @Override - public Topic getTopic(String name) { - ITopic iTopic = hazelcastInstance.getTopic(name); - return new HazelcastTopic<>(iTopic); - } + @Override + public Topic getTopic(String name) { + ITopic iTopic = hazelcastInstance.getTopic(name); + return new HazelcastTopic<>(iTopic); + } } diff --git a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/hazelcast/HazelcastTopic.java b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/hazelcast/HazelcastTopic.java index 148eb6e17..4257f03a0 100644 --- a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/hazelcast/HazelcastTopic.java +++ b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/hazelcast/HazelcastTopic.java @@ -27,29 +27,24 @@ */ public class HazelcastTopic implements Topic { - private final ITopic iTopic; + private final ITopic iTopic; - public HazelcastTopic(ITopic iTopic) { - this.iTopic = iTopic; - } + public HazelcastTopic(ITopic iTopic) { + this.iTopic = iTopic; + } - @Override - public void publish(T event) { - iTopic.publish(event); - } + @Override + public void publish(T event) { + iTopic.publish(event); + } - @Override - public UUID addMessageConsumer(MessageConsumer messageConsumer) { - return iTopic.addMessageListener( - message -> - messageConsumer.onMessage( - new Message<>(iTopic.getName(), message.getMessageObject()) - ) - ); - } + @Override + public UUID addMessageConsumer(MessageConsumer messageConsumer) { + return iTopic.addMessageListener(message -> messageConsumer.onMessage(new Message<>(iTopic.getName(), message.getMessageObject()))); + } - @Override - public boolean removeMessageConsumer(UUID uuid) { - return iTopic.removeMessageListener(uuid); - } + @Override + public boolean removeMessageConsumer(UUID uuid) { + return iTopic.removeMessageListener(uuid); + } } diff --git a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/member/NodeMember.java b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/member/NodeMember.java index e7987241d..975b1adeb 100644 --- a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/member/NodeMember.java +++ b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/member/NodeMember.java @@ -24,37 +24,37 @@ */ public class NodeMember implements Member { - private final com.hazelcast.cluster.Member member; - private final boolean master; - - public NodeMember(com.hazelcast.cluster.Member member, boolean master) { - this.member = member; - this.master = master; - } - - @Override - public String uuid() { - return member.getUuid().toString(); - } - - @Override - public boolean master() { - return master; - } - - @Override - public String host() { - return member.getAddress().getHost(); - } - - @Override - public Map attributes() { - return member.getAttributes(); - } - - @Override - public Member attribute(String key, String value) { - member.getAttributes().put(key, value); - return this; - } + private final com.hazelcast.cluster.Member member; + private final boolean master; + + public NodeMember(com.hazelcast.cluster.Member member, boolean master) { + this.member = member; + this.master = master; + } + + @Override + public String uuid() { + return member.getUuid().toString(); + } + + @Override + public boolean master() { + return master; + } + + @Override + public String host() { + return member.getAddress().getHost(); + } + + @Override + public Map attributes() { + return member.getAttributes(); + } + + @Override + public Member attribute(String key, String value) { + member.getAttributes().put(key, value); + return this; + } } diff --git a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/spring/ClusterConfiguration.java b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/spring/ClusterConfiguration.java index 108430ffd..c5475b172 100644 --- a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/spring/ClusterConfiguration.java +++ b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/spring/ClusterConfiguration.java @@ -26,18 +26,16 @@ * @author GraviteeSource Team */ @Configuration -@Import( - { HazelcastClusterConfiguration.class, StandaloneClusterConfiguration.class } -) +@Import({ HazelcastClusterConfiguration.class, StandaloneClusterConfiguration.class }) public class ClusterConfiguration { - @Bean - public ClusterService clusterService() { - return new ClusterService(); - } + @Bean + public ClusterService clusterService() { + return new ClusterService(); + } - @Bean - CacheManagerFactoriesLoader cacheManagerFactoriesLoader() { - return new CacheManagerFactoriesLoader(); - } + @Bean + CacheManagerFactoriesLoader cacheManagerFactoriesLoader() { + return new CacheManagerFactoriesLoader(); + } } diff --git a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/spring/HazelcastClusterConfiguration.java b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/spring/HazelcastClusterConfiguration.java index d4bd0047f..a27a413a2 100644 --- a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/spring/HazelcastClusterConfiguration.java +++ b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/spring/HazelcastClusterConfiguration.java @@ -37,66 +37,50 @@ @Conditional(HazelcastClusterConfiguration.ClusterModeEnabled.class) public class HazelcastClusterConfiguration { - @Value( - "${cluster.hazelcast.config.path:${gravitee.home}/config/hazelcast.xml}" - ) - private String hazelcastConfigFilePath; + @Value("${cluster.hazelcast.config.path:${gravitee.home}/config/hazelcast.xml}") + private String hazelcastConfigFilePath; - @Bean - public HazelcastInstance distributedHazelcastInstance() throws Exception { - // Force Hazelcast to use SLF4J before loading any HZ classes - System.setProperty(ClusterProperty.LOGGING_TYPE.getName(), "slf4j"); - System.setProperty(ClusterProperty.SHUTDOWNHOOK_ENABLED.getName(), "false"); + @Bean + public HazelcastInstance distributedHazelcastInstance() throws Exception { + // Force Hazelcast to use SLF4J before loading any HZ classes + System.setProperty(ClusterProperty.LOGGING_TYPE.getName(), "slf4j"); + System.setProperty(ClusterProperty.SHUTDOWNHOOK_ENABLED.getName(), "false"); - FileSystemXmlConfig config = new FileSystemXmlConfig( - hazelcastConfigFilePath - ); + FileSystemXmlConfig config = new FileSystemXmlConfig(hazelcastConfigFilePath); - // Force the classloader used by Hazelcast to the container's classloader. - config.setClassLoader(ClusterConfiguration.class.getClassLoader()); + // Force the classloader used by Hazelcast to the container's classloader. + config.setClassLoader(ClusterConfiguration.class.getClassLoader()); - config.setProperty( - ClusterProperty.HEALTH_MONITORING_LEVEL.getName(), - "OFF" - ); + config.setProperty(ClusterProperty.HEALTH_MONITORING_LEVEL.getName(), "OFF"); - return Hazelcast.newHazelcastInstance( - new FileSystemXmlConfig(hazelcastConfigFilePath) - ); - } + return Hazelcast.newHazelcastInstance(new FileSystemXmlConfig(hazelcastConfigFilePath)); + } - @Bean("hazelcastClusterManager") - public ClusterManager hazelcastClusterManager() { - return new HazelcastClusterManager(); - } + @Bean("hazelcastClusterManager") + public ClusterManager hazelcastClusterManager() { + return new HazelcastClusterManager(); + } - @Bean("hazelcastCacheManager") - public CacheManager hazelcastCacheManager( - HazelcastInstance hazelcastInstance - ) { - return new HazelcastCacheManager(hazelcastInstance); - } + @Bean("hazelcastCacheManager") + public CacheManager hazelcastCacheManager(HazelcastInstance hazelcastInstance) { + return new HazelcastCacheManager(hazelcastInstance); + } - @Bean("hazelcastMessageProducer") - public MessageProducer hazelcastMessageProducer() { - return new HazelcastMessageProducer(); - } + @Bean("hazelcastMessageProducer") + public MessageProducer hazelcastMessageProducer() { + return new HazelcastMessageProducer(); + } - public static class ClusterModeEnabled implements ConfigurationCondition { + public static class ClusterModeEnabled implements ConfigurationCondition { - @Override - public boolean matches( - ConditionContext conditionContext, - AnnotatedTypeMetadata annotatedTypeMetadata - ) { - return conditionContext - .getEnvironment() - .getProperty("gravitee.cluster.enabled", Boolean.class, false); - } + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { + return conditionContext.getEnvironment().getProperty("gravitee.cluster.enabled", Boolean.class, false); + } - @Override - public ConfigurationPhase getConfigurationPhase() { - return ConfigurationPhase.REGISTER_BEAN; + @Override + public ConfigurationPhase getConfigurationPhase() { + return ConfigurationPhase.REGISTER_BEAN; + } } - } } diff --git a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/spring/StandaloneClusterConfiguration.java b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/spring/StandaloneClusterConfiguration.java index 5c2bc726f..4cf72126c 100644 --- a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/spring/StandaloneClusterConfiguration.java +++ b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/spring/StandaloneClusterConfiguration.java @@ -32,36 +32,31 @@ @Conditional(StandaloneClusterConfiguration.StandaloneModeEnabled.class) public class StandaloneClusterConfiguration { - @Bean("standaloneClusterManager") - public ClusterManager standaloneClusterManager() { - return new StandaloneClusterManager(); - } + @Bean("standaloneClusterManager") + public ClusterManager standaloneClusterManager() { + return new StandaloneClusterManager(); + } - @Bean("standaloneCacheManager") - public CacheManager standaloneCacheManager() { - return new StandaloneCacheManager(); - } + @Bean("standaloneCacheManager") + public CacheManager standaloneCacheManager() { + return new StandaloneCacheManager(); + } - @Bean("standaloneMessageProducer") - public MessageProducer standaloneMessageProducer() { - return new StandaloneMessageProducer(); - } + @Bean("standaloneMessageProducer") + public MessageProducer standaloneMessageProducer() { + return new StandaloneMessageProducer(); + } - public static class StandaloneModeEnabled implements ConfigurationCondition { + public static class StandaloneModeEnabled implements ConfigurationCondition { - @Override - public boolean matches( - ConditionContext conditionContext, - AnnotatedTypeMetadata annotatedTypeMetadata - ) { - return !conditionContext - .getEnvironment() - .getProperty("gravitee.cluster.enabled", Boolean.class, false); - } + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { + return !conditionContext.getEnvironment().getProperty("gravitee.cluster.enabled", Boolean.class, false); + } - @Override - public ConfigurationPhase getConfigurationPhase() { - return ConfigurationPhase.REGISTER_BEAN; + @Override + public ConfigurationPhase getConfigurationPhase() { + return ConfigurationPhase.REGISTER_BEAN; + } } - } } diff --git a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/standalone/StandaloneClusterManager.java b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/standalone/StandaloneClusterManager.java index f0a6e6c06..bf647b8a4 100644 --- a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/standalone/StandaloneClusterManager.java +++ b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/standalone/StandaloneClusterManager.java @@ -29,51 +29,51 @@ */ public class StandaloneClusterManager implements ClusterManager { - private static final Member localMember = new Member() { - @Override - public String uuid() { - return UUID.random().toString(); - } + private static final Member localMember = new Member() { + @Override + public String uuid() { + return UUID.random().toString(); + } - @Override - public boolean master() { - return true; - } + @Override + public boolean master() { + return true; + } + + @Override + public String host() { + return "localhost"; + } + + @Override + public Map attributes() { + return Collections.emptyMap(); + } + + @Override + public Member attribute(String key, String value) { + return null; + } + }; @Override - public String host() { - return "localhost"; + public Collection getMembers() { + return Collections.singleton(localMember); } @Override - public Map attributes() { - return Collections.emptyMap(); + public Member getLocalMember() { + return localMember; } @Override - public Member attribute(String key, String value) { - return null; + public boolean isMasterNode() { + return true; } - }; - - @Override - public Collection getMembers() { - return Collections.singleton(localMember); - } - - @Override - public Member getLocalMember() { - return localMember; - } - @Override - public boolean isMasterNode() { - return true; - } - - @Override - public void addMemberListener(MemberListener listener) {} + @Override + public void addMemberListener(MemberListener listener) {} - @Override - public void stop() {} + @Override + public void stop() {} } diff --git a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/standalone/StandaloneMessageProducer.java b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/standalone/StandaloneMessageProducer.java index b9ef55235..09004cdc7 100644 --- a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/standalone/StandaloneMessageProducer.java +++ b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/standalone/StandaloneMessageProducer.java @@ -26,11 +26,11 @@ */ public class StandaloneMessageProducer implements MessageProducer { - @Autowired - private Vertx vertx; + @Autowired + private Vertx vertx; - @Override - public Topic getTopic(String name) { - return new StandaloneTopic<>(vertx, name); - } + @Override + public Topic getTopic(String name) { + return new StandaloneTopic<>(vertx, name); + } } diff --git a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/standalone/StandaloneTopic.java b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/standalone/StandaloneTopic.java index 8b2bbd5a7..8f5df887c 100644 --- a/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/standalone/StandaloneTopic.java +++ b/gravitee-node-cluster/src/main/java/io/gravitee/node/cluster/standalone/StandaloneTopic.java @@ -37,94 +37,91 @@ */ public class StandaloneTopic implements Topic { - private final Vertx vertx; - private final String topicName; - Map> consumerMap = new ConcurrentHashMap<>(); - private static final List messageCodecs = new ArrayList<>(); - - public StandaloneTopic(Vertx vertx, String topicName) { - this.vertx = vertx; - this.topicName = topicName; - - if (!messageCodecs.contains(topicName)) { - messageCodecs.add(topicName); - - vertx - .eventBus() - .registerCodec( - new MessageCodec() { - // Will not be used for local transformations - @Override - public void encodeToWire(Buffer buffer, T o) {} - - // Will not be used for local transformations - @Override - public T decodeFromWire(int pos, Buffer buffer) { - return null; - } + private final Vertx vertx; + private final String topicName; + Map> consumerMap = new ConcurrentHashMap<>(); + private static final List messageCodecs = new ArrayList<>(); + + public StandaloneTopic(Vertx vertx, String topicName) { + this.vertx = vertx; + this.topicName = topicName; + + if (!messageCodecs.contains(topicName)) { + messageCodecs.add(topicName); + + vertx + .eventBus() + .registerCodec( + new MessageCodec() { + // Will not be used for local transformations + @Override + public void encodeToWire(Buffer buffer, T o) {} + + // Will not be used for local transformations + @Override + public T decodeFromWire(int pos, Buffer buffer) { + return null; + } + + @Override + public T transform(T o) { + return o; + } + + @Override + public String name() { + return topicName; + } + + @Override + public byte systemCodecID() { + return -1; + } + } + ); + } + } - @Override - public T transform(T o) { - return o; - } + @Override + public void publish(T event) { + DeliveryOptions deliveryOptions = new DeliveryOptions(); + deliveryOptions.setCodecName(topicName); - @Override - public String name() { - return topicName; - } + vertx.eventBus().publish(topicName, event, deliveryOptions); + } - @Override - public byte systemCodecID() { - return -1; - } - } + @Override + public UUID addMessageConsumer(io.gravitee.node.api.message.MessageConsumer messageConsumer) { + UUID uuid = io.gravitee.common.utils.UUID.random(); + + MessageConsumer vertxConsumer = vertx.eventBus().consumer(topicName); + consumerMap.put(uuid, vertxConsumer); + + vertxConsumer.handler(event -> + vertx.executeBlocking( + (Handler>) promise -> { + messageConsumer.onMessage(new Message<>(topicName, event.body())); + promise.handle(null); + } + ) ); + + return uuid; } - } - - @Override - public void publish(T event) { - DeliveryOptions deliveryOptions = new DeliveryOptions(); - deliveryOptions.setCodecName(topicName); - - vertx.eventBus().publish(topicName, event, deliveryOptions); - } - - @Override - public UUID addMessageConsumer( - io.gravitee.node.api.message.MessageConsumer messageConsumer - ) { - UUID uuid = io.gravitee.common.utils.UUID.random(); - - MessageConsumer vertxConsumer = vertx.eventBus().consumer(topicName); - consumerMap.put(uuid, vertxConsumer); - - vertxConsumer.handler( - event -> - vertx.executeBlocking( - (Handler>) promise -> { - messageConsumer.onMessage(new Message<>(topicName, event.body())); - promise.handle(null); - } - ) - ); - - return uuid; - } - - @Override - public boolean removeMessageConsumer(UUID uuid) { - if (!consumerMap.containsKey(uuid)) { - return false; - } else { - Future unregister = consumerMap.get(uuid).unregister(); - - if (unregister.succeeded()) { - consumerMap.remove(uuid); - return true; - } else { - return false; - } + + @Override + public boolean removeMessageConsumer(UUID uuid) { + if (!consumerMap.containsKey(uuid)) { + return false; + } else { + Future unregister = consumerMap.get(uuid).unregister(); + + if (unregister.succeeded()) { + consumerMap.remove(uuid); + return true; + } else { + return false; + } + } } - } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/AbstractContainer.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/AbstractContainer.java index 04710887f..8a9115550 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/AbstractContainer.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/AbstractContainer.java @@ -29,142 +29,115 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public abstract class AbstractContainer - extends AbstractService - implements Container { - - private static final String GRAVITEE_HOME_PROPERTY = "gravitee.home"; - private static final String GRAVITEE_CONFIGURATION_PROPERTY = "gravitee.conf"; - - protected boolean stopped = false; - - public AbstractContainer() { - initialize(); - } - - protected void initialize() { - initializeEnvironment(); - initializeLogging(); - } - - protected void initializeEnvironment() { - // Set system properties if needed - String graviteeConfiguration = System.getProperty( - GRAVITEE_CONFIGURATION_PROPERTY - ); - if (graviteeConfiguration == null || graviteeConfiguration.isEmpty()) { - String graviteeHome = System.getProperty(GRAVITEE_HOME_PROPERTY); - System.setProperty( - GRAVITEE_CONFIGURATION_PROPERTY, - graviteeHome + - File.separator + - "config" + - File.separator + - "gravitee.yml" - ); - } - } - - protected void initializeLogging() { - String graviteeHome = System.getProperty(GRAVITEE_HOME_PROPERTY); - String logbackConfiguration = - graviteeHome + File.separator + "config" + File.separator + "logback.xml"; - File logbackConfigurationfile = new File(logbackConfiguration); - - // If logback configuration available, load it, else, load default logback configuration - if (logbackConfigurationfile.exists()) { - System.setProperty( - "logback.configurationFile", - logbackConfigurationfile.getAbsolutePath() - ); - StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton(); - LoggerContext loggerContext = (LoggerContext) loggerBinder.getLoggerFactory(); - loggerContext.reset(); - JoranConfigurator configurator = new JoranConfigurator(); - configurator.setContext(loggerContext); - try { - configurator.doConfigure(logbackConfigurationfile); - } catch (JoranException e) { - LoggerFactory - .getLogger(this.getClass()) - .error("An error occurs while initializing logging system", e); - } - - // Internal status data is printed in case of warnings or errors. - StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext); +public abstract class AbstractContainer extends AbstractService implements Container { + + private static final String GRAVITEE_HOME_PROPERTY = "gravitee.home"; + private static final String GRAVITEE_CONFIGURATION_PROPERTY = "gravitee.conf"; + + protected boolean stopped = false; + + public AbstractContainer() { + initialize(); } - } - - @Override - protected void doStart() throws Exception { - LoggerFactory - .getLogger(AbstractContainer.class) - .info("Starting {}...", name()); - - try { - final Node node = node(); - node.start(); - - // Register shutdown hook - Thread shutdownHook = new ContainerShutdownHook(node); - shutdownHook.setName("graviteeio-finalizer"); - Runtime.getRuntime().addShutdownHook(shutdownHook); - } catch (Exception ex) { - LoggerFactory - .getLogger(this.getClass()) - .error("An unexpected error occurs while starting {}", name(), ex); - stop(); + + protected void initialize() { + initializeEnvironment(); + initializeLogging(); } - } - - @Override - public Container preStop() throws Exception { - if (!stopped) { - LoggerFactory - .getLogger(this.getClass()) - .info("Preparing {} for shutting-down...", name()); - node().preStop(); + + protected void initializeEnvironment() { + // Set system properties if needed + String graviteeConfiguration = System.getProperty(GRAVITEE_CONFIGURATION_PROPERTY); + if (graviteeConfiguration == null || graviteeConfiguration.isEmpty()) { + String graviteeHome = System.getProperty(GRAVITEE_HOME_PROPERTY); + System.setProperty(GRAVITEE_CONFIGURATION_PROPERTY, graviteeHome + File.separator + "config" + File.separator + "gravitee.yml"); + } } - return this; - } - - @Override - protected void doStop() throws Exception { - if (!stopped) { - LoggerFactory - .getLogger(this.getClass()) - .info("Shutting-down {}...", name()); - - try { - node().stop(); - } catch (Exception ex) { - LoggerFactory.getLogger(this.getClass()).error("Unexpected error", ex); - } finally { - stopped = true; - } + + protected void initializeLogging() { + String graviteeHome = System.getProperty(GRAVITEE_HOME_PROPERTY); + String logbackConfiguration = graviteeHome + File.separator + "config" + File.separator + "logback.xml"; + File logbackConfigurationfile = new File(logbackConfiguration); + + // If logback configuration available, load it, else, load default logback configuration + if (logbackConfigurationfile.exists()) { + System.setProperty("logback.configurationFile", logbackConfigurationfile.getAbsolutePath()); + StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton(); + LoggerContext loggerContext = (LoggerContext) loggerBinder.getLoggerFactory(); + loggerContext.reset(); + JoranConfigurator configurator = new JoranConfigurator(); + configurator.setContext(loggerContext); + try { + configurator.doConfigure(logbackConfigurationfile); + } catch (JoranException e) { + LoggerFactory.getLogger(this.getClass()).error("An error occurs while initializing logging system", e); + } + + // Internal status data is printed in case of warnings or errors. + StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext); + } } - } - private class ContainerShutdownHook extends Thread { + @Override + protected void doStart() throws Exception { + LoggerFactory.getLogger(AbstractContainer.class).info("Starting {}...", name()); + + try { + final Node node = node(); + node.start(); - private final Node node; + // Register shutdown hook + Thread shutdownHook = new ContainerShutdownHook(node); + shutdownHook.setName("graviteeio-finalizer"); + Runtime.getRuntime().addShutdownHook(shutdownHook); + } catch (Exception ex) { + LoggerFactory.getLogger(this.getClass()).error("An unexpected error occurs while starting {}", name(), ex); + stop(); + } + } - private ContainerShutdownHook(Node node) { - this.node = node; + @Override + public Container preStop() throws Exception { + if (!stopped) { + LoggerFactory.getLogger(this.getClass()).info("Preparing {} for shutting-down...", name()); + node().preStop(); + } + return this; } @Override - public void run() { - if (node != null) { - try { - AbstractContainer.this.preStop(); - AbstractContainer.this.stop(); - } catch (Exception ex) { - LoggerFactory - .getLogger(this.getClass()) - .error("Unexpected error while stopping {}", name(), ex); + protected void doStop() throws Exception { + if (!stopped) { + LoggerFactory.getLogger(this.getClass()).info("Shutting-down {}...", name()); + + try { + node().stop(); + } catch (Exception ex) { + LoggerFactory.getLogger(this.getClass()).error("Unexpected error", ex); + } finally { + stopped = true; + } + } + } + + private class ContainerShutdownHook extends Thread { + + private final Node node; + + private ContainerShutdownHook(Node node) { + this.node = node; + } + + @Override + public void run() { + if (node != null) { + try { + AbstractContainer.this.preStop(); + AbstractContainer.this.stop(); + } catch (Exception ex) { + LoggerFactory.getLogger(this.getClass()).error("Unexpected error while stopping {}", name(), ex); + } + } } - } } - } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/AbstractNode.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/AbstractNode.java index 4a5aaecc7..066e146ed 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/AbstractNode.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/AbstractNode.java @@ -49,255 +49,181 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public abstract class AbstractNode - extends AbstractService - implements Node, ApplicationContextAware { +public abstract class AbstractNode extends AbstractService implements Node, ApplicationContextAware { - protected final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); + protected final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); - protected ApplicationContext applicationContext; + protected ApplicationContext applicationContext; - private String hostname; + private String hostname; - public AbstractNode() { - try { - hostname = InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException uhe) { - LOGGER.warn("Could not get hostname / IP", uhe); + public AbstractNode() { + try { + hostname = InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException uhe) { + LOGGER.warn("Could not get hostname / IP", uhe); + } } - } - protected void doStart() throws Exception { - this.LOGGER.info("{} is now starting...", this.name()); - long startTime = System.currentTimeMillis(); - List> components = this.components(); + protected void doStart() throws Exception { + this.LOGGER.info("{} is now starting...", this.name()); + long startTime = System.currentTimeMillis(); + List> components = this.components(); - preStartComponents(components); - startComponents(components); - postStartComponents(components); + preStartComponents(components); + startComponents(components); + postStartComponents(components); - long endTime = System.currentTimeMillis(); - String processId = ManagementFactory.getRuntimeMXBean().getName(); - if (processId.contains("@")) { - processId = processId.split("@")[0]; - } + long endTime = System.currentTimeMillis(); + String processId = ManagementFactory.getRuntimeMXBean().getName(); + if (processId.contains("@")) { + processId = processId.split("@")[0]; + } - this.LOGGER.info( - "{} id[{}] version[{}] pid[{}] build[{}#{}] jvm[{}/{}/{}] started in {} ms.", - this.name(), - this.id(), - Version.RUNTIME_VERSION.MAJOR_VERSION, - processId, - Version.RUNTIME_VERSION.BUILD_NUMBER, - Version.RUNTIME_VERSION.REVISION, - ManagementFactory.getRuntimeMXBean().getVmVendor(), - ManagementFactory.getRuntimeMXBean().getVmName(), - ManagementFactory.getRuntimeMXBean().getVmVersion(), - endTime - startTime - ); - } + this.LOGGER.info( + "{} id[{}] version[{}] pid[{}] build[{}#{}] jvm[{}/{}/{}] started in {} ms.", + this.name(), + this.id(), + Version.RUNTIME_VERSION.MAJOR_VERSION, + processId, + Version.RUNTIME_VERSION.BUILD_NUMBER, + Version.RUNTIME_VERSION.REVISION, + ManagementFactory.getRuntimeMXBean().getVmVendor(), + ManagementFactory.getRuntimeMXBean().getVmName(), + ManagementFactory.getRuntimeMXBean().getVmVersion(), + endTime - startTime + ); + } - @Override - public Node preStop() throws Exception { - super.preStop(); + @Override + public Node preStop() throws Exception { + super.preStop(); - final Environment environment = - this.applicationContext.getBean(Environment.class); - final Integer shutdownDelay = environment.getProperty( - "gracefulShutdown.delay", - Integer.class, - 0 - ); - final TimeUnit shutdownUnit = TimeUnit.valueOf( - environment.getProperty( - "gracefulShutdown.unit", - String.class, - "MILLISECONDS" - ) - ); + final Environment environment = this.applicationContext.getBean(Environment.class); + final Integer shutdownDelay = environment.getProperty("gracefulShutdown.delay", Integer.class, 0); + final TimeUnit shutdownUnit = TimeUnit.valueOf(environment.getProperty("gracefulShutdown.unit", String.class, "MILLISECONDS")); - LOGGER.info( - "Applying graceful shutdown delay {} {}", - shutdownDelay, - shutdownUnit - ); - Thread.sleep( - Duration.ofMillis(shutdownUnit.toMillis(shutdownDelay)).toMillis() - ); - LOGGER.info("Graceful shutdown delay exhausted"); + LOGGER.info("Applying graceful shutdown delay {} {}", shutdownDelay, shutdownUnit); + Thread.sleep(Duration.ofMillis(shutdownUnit.toMillis(shutdownDelay)).toMillis()); + LOGGER.info("Graceful shutdown delay exhausted"); - return this; - } + return this; + } - protected void doStop() throws Exception { - this.LOGGER.info("{} is stopping", this.name()); + protected void doStop() throws Exception { + this.LOGGER.info("{} is stopping", this.name()); - final List> components = - this.components(); + final List> components = this.components(); - preStopComponents(new ListReverser(components)); - stopComponents(new ListReverser(components)); - postStopComponents(new ListReverser(components)); + preStopComponents(new ListReverser(components)); + stopComponents(new ListReverser(components)); + postStopComponents(new ListReverser(components)); - this.LOGGER.info("{} stopped", this.name()); - } + this.LOGGER.info("{} stopped", this.name()); + } - @Override - public String hostname() { - return hostname; - } + @Override + public String hostname() { + return hostname; + } - public abstract String name(); + public abstract String name(); - @Override - public List> components() { - List> components = new ArrayList<>(); + @Override + public List> components() { + List> components = new ArrayList<>(); - components.add(PluginEventListener.class); - components.add(PluginRegistry.class); - components.add(ServiceManager.class); - components.add(ManagementService.class); - components.add(NodeMonitoringEventHandler.class); - components.add(NodeInfosService.class); - components.add(NodeHealthCheckService.class); - components.add(NodeMonitorService.class); - components.add(ReporterManager.class); - components.add(KeyStoreLoaderManager.class); + components.add(PluginEventListener.class); + components.add(PluginRegistry.class); + components.add(ServiceManager.class); + components.add(ManagementService.class); + components.add(NodeMonitoringEventHandler.class); + components.add(NodeInfosService.class); + components.add(NodeHealthCheckService.class); + components.add(NodeMonitorService.class); + components.add(ReporterManager.class); + components.add(KeyStoreLoaderManager.class); - return components; - } + return components; + } - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { - this.applicationContext = applicationContext; - } + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } - private void preStartComponents( - Iterable> components - ) throws Exception { - for (Class componentClass : components) { - try { - LOGGER.debug( - "\tPre-starting component: {}", - componentClass.getSimpleName() - ); - this.applicationContext.getBean(componentClass).preStart(); - } catch (Exception e) { - this.LOGGER.error( - "An error occurred while pre-starting component {}", - componentClass, - e - ); - throw e; - } + private void preStartComponents(Iterable> components) throws Exception { + for (Class componentClass : components) { + try { + LOGGER.debug("\tPre-starting component: {}", componentClass.getSimpleName()); + this.applicationContext.getBean(componentClass).preStart(); + } catch (Exception e) { + this.LOGGER.error("An error occurred while pre-starting component {}", componentClass, e); + throw e; + } + } } - } - private void startComponents( - Iterable> components - ) throws Exception { - for (Class componentClass : components) { - try { - LOGGER.info("\tStarting component: {}", componentClass.getSimpleName()); - this.applicationContext.getBean(componentClass).start(); - } catch (Exception e) { - this.LOGGER.error( - "An error occurred while starting component {}", - componentClass, - e - ); - throw e; - } + private void startComponents(Iterable> components) throws Exception { + for (Class componentClass : components) { + try { + LOGGER.info("\tStarting component: {}", componentClass.getSimpleName()); + this.applicationContext.getBean(componentClass).start(); + } catch (Exception e) { + this.LOGGER.error("An error occurred while starting component {}", componentClass, e); + throw e; + } + } } - } - private void postStartComponents( - Iterable> components - ) throws Exception { - for (Class componentClass : components) { - try { - LOGGER.debug( - "\tPost-starting component: {}", - componentClass.getSimpleName() - ); - this.applicationContext.getBean(componentClass).postStart(); - } catch (Exception e) { - this.LOGGER.error( - "An error occurred while post-starting component {}", - componentClass, - e - ); - throw e; - } + private void postStartComponents(Iterable> components) throws Exception { + for (Class componentClass : components) { + try { + LOGGER.debug("\tPost-starting component: {}", componentClass.getSimpleName()); + this.applicationContext.getBean(componentClass).postStart(); + } catch (Exception e) { + this.LOGGER.error("An error occurred while post-starting component {}", componentClass, e); + throw e; + } + } } - } - private void preStopComponents( - Iterable> components - ) { - for (Class componentClass : components) { - try { - LifecycleComponent lifecycleComponent = - this.applicationContext.getBean(componentClass); - if (lifecycleComponent.lifecycleState() != Lifecycle.State.STOPPING) { - this.LOGGER.debug( - "\tPre-stopping component: {}", - componentClass.getSimpleName() - ); - lifecycleComponent.preStop(); + private void preStopComponents(Iterable> components) { + for (Class componentClass : components) { + try { + LifecycleComponent lifecycleComponent = this.applicationContext.getBean(componentClass); + if (lifecycleComponent.lifecycleState() != Lifecycle.State.STOPPING) { + this.LOGGER.debug("\tPre-stopping component: {}", componentClass.getSimpleName()); + lifecycleComponent.preStop(); + } + } catch (Exception e) { + this.LOGGER.error("An error occurred while pre-stopping component {}", componentClass.getSimpleName(), e); + } } - } catch (Exception e) { - this.LOGGER.error( - "An error occurred while pre-stopping component {}", - componentClass.getSimpleName(), - e - ); - } } - } - private void stopComponents( - Iterable> components - ) { - for (Class componentClass : components) { - try { - LifecycleComponent lifecycleComponent = - this.applicationContext.getBean(componentClass); - if (lifecycleComponent.lifecycleState() != Lifecycle.State.STOPPED) { - this.LOGGER.info( - "\tStopping component: {}", - componentClass.getSimpleName() - ); - lifecycleComponent.stop(); + private void stopComponents(Iterable> components) { + for (Class componentClass : components) { + try { + LifecycleComponent lifecycleComponent = this.applicationContext.getBean(componentClass); + if (lifecycleComponent.lifecycleState() != Lifecycle.State.STOPPED) { + this.LOGGER.info("\tStopping component: {}", componentClass.getSimpleName()); + lifecycleComponent.stop(); + } + } catch (Exception e) { + this.LOGGER.error("An error occurred while stopping component {}", componentClass.getSimpleName(), e); + } } - } catch (Exception e) { - this.LOGGER.error( - "An error occurred while stopping component {}", - componentClass.getSimpleName(), - e - ); - } } - } - private void postStopComponents( - Iterable> components - ) throws Exception { - for (Class componentClass : components) { - try { - LOGGER.debug( - "\tPost-stopping component: {}", - componentClass.getSimpleName() - ); - this.applicationContext.getBean(componentClass).postStop(); - } catch (Exception e) { - this.LOGGER.error( - "An error occurred while post-stopping component {}", - componentClass, - e - ); - throw e; - } + private void postStopComponents(Iterable> components) throws Exception { + for (Class componentClass : components) { + try { + LOGGER.debug("\tPost-stopping component: {}", componentClass.getSimpleName()); + this.applicationContext.getBean(componentClass).postStop(); + } catch (Exception e) { + this.LOGGER.error("An error occurred while post-stopping component {}", componentClass, e); + throw e; + } + } } - } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/Container.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/Container.java index 1fe5b51b0..c523a055a 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/Container.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/Container.java @@ -23,5 +23,5 @@ * @author GraviteeSource Team */ public interface Container extends LifecycleComponent { - Node node(); + Node node(); } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/NodeDeployerFactoriesLoader.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/NodeDeployerFactoriesLoader.java index 1bb8ec228..2b89ef56a 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/NodeDeployerFactoriesLoader.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/NodeDeployerFactoriesLoader.java @@ -24,15 +24,14 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class NodeDeployerFactoriesLoader - extends SpringFactoriesLoader { +public class NodeDeployerFactoriesLoader extends SpringFactoriesLoader { - @Override - protected Class getObjectType() { - return NodeDeployer.class; - } + @Override + protected Class getObjectType() { + return NodeDeployer.class; + } - List getNodeDeployers() { - return new ArrayList<>(getFactoriesInstances()); - } + List getNodeDeployers() { + return new ArrayList<>(getFactoriesInstances()); + } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/NodeFactory.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/NodeFactory.java index 9fe1a1ce5..f3e2ed92a 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/NodeFactory.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/NodeFactory.java @@ -28,59 +28,54 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class NodeFactory - extends AbstractFactoryBean - implements ApplicationContextAware { +public class NodeFactory extends AbstractFactoryBean implements ApplicationContextAware { - @Autowired - private NodeDeployerFactoriesLoader nodeDeployerFactoriesLoader; + @Autowired + private NodeDeployerFactoriesLoader nodeDeployerFactoriesLoader; - private ApplicationContext applicationContext; + private ApplicationContext applicationContext; - private final Class nodeClass; + private final Class nodeClass; - public NodeFactory(Class nodeClass) { - this.nodeClass = nodeClass; - } + public NodeFactory(Class nodeClass) { + this.nodeClass = nodeClass; + } - @Override - public Class getObjectType() { - return Node.class; - } + @Override + public Class getObjectType() { + return Node.class; + } - @Override - protected Node createInstance() throws Exception { - Node node = nodeClass.newInstance(); - autowire(node); + @Override + protected Node createInstance() throws Exception { + Node node = nodeClass.newInstance(); + autowire(node); - List deployers = nodeDeployerFactoriesLoader.getNodeDeployers(); + List deployers = nodeDeployerFactoriesLoader.getNodeDeployers(); - for (NodeDeployer deployer : deployers) { - node = deployer.deploy(node); - autowire(node); - } + for (NodeDeployer deployer : deployers) { + node = deployer.deploy(node); + autowire(node); + } - return node; - } + return node; + } - private void autowire(Node node) throws Exception { - if (node != null) { - this.applicationContext.getAutowireCapableBeanFactory() - .autowireBean(node); - if (node instanceof ApplicationContextAware) { - ((ApplicationContextAware) node).setApplicationContext( - this.applicationContext - ); - } + private void autowire(Node node) throws Exception { + if (node != null) { + this.applicationContext.getAutowireCapableBeanFactory().autowireBean(node); + if (node instanceof ApplicationContextAware) { + ((ApplicationContextAware) node).setApplicationContext(this.applicationContext); + } - if (node instanceof InitializingBean) { - ((InitializingBean) node).afterPropertiesSet(); - } + if (node instanceof InitializingBean) { + ((InitializingBean) node).afterPropertiesSet(); + } + } } - } - @Override - public void setApplicationContext(ApplicationContext applicationContext) { - this.applicationContext = applicationContext; - } + @Override + public void setApplicationContext(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/plugin/NodeDeploymentContextFactory.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/plugin/NodeDeploymentContextFactory.java index 1c1adfd2e..2475deb06 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/plugin/NodeDeploymentContextFactory.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/plugin/NodeDeploymentContextFactory.java @@ -24,14 +24,13 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class NodeDeploymentContextFactory - implements DeploymentContextFactory { +public class NodeDeploymentContextFactory implements DeploymentContextFactory { - @Autowired - private Node node; + @Autowired + private Node node; - @Override - public NodeDeploymentContext create() { - return () -> node; - } + @Override + public NodeDeploymentContext create() { + return () -> node; + } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/NodeConfiguration.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/NodeConfiguration.java index 1f415e5ad..429738098 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/NodeConfiguration.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/NodeConfiguration.java @@ -25,13 +25,13 @@ */ public class NodeConfiguration { - @Bean - public NodeDeployerFactoriesLoader nodeDeployerFactoriesLoader() { - return new NodeDeployerFactoriesLoader(); - } + @Bean + public NodeDeployerFactoriesLoader nodeDeployerFactoriesLoader() { + return new NodeDeployerFactoriesLoader(); + } - @Bean - public NodeDeploymentContextFactory nodeDeploymentContextFactory() { - return new NodeDeploymentContextFactory(); - } + @Bean + public NodeDeploymentContextFactory nodeDeploymentContextFactory() { + return new NodeDeploymentContextFactory(); + } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/SpringBasedContainer.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/SpringBasedContainer.java index e4b8709a8..359c49d5e 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/SpringBasedContainer.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/SpringBasedContainer.java @@ -38,76 +38,72 @@ */ public abstract class SpringBasedContainer extends AbstractContainer { - private ConfigurableApplicationContext ctx; + private ConfigurableApplicationContext ctx; - public SpringBasedContainer() { - super(); - } - - @Override - protected void initialize() { - super.initialize(); + public SpringBasedContainer() { + super(); + } - this.initializeContext(); - } + @Override + protected void initialize() { + super.initialize(); - protected void initializeContext() { - ctx = new AnnotationConfigApplicationContext(); + this.initializeContext(); + } - List> classes = annotatedClasses(); - classes.forEach( - aClass -> ((AnnotationConfigApplicationContext) ctx).register(aClass) - ); + protected void initializeContext() { + ctx = new AnnotationConfigApplicationContext(); - // Finally refresh the context - ctx.refresh(); - } + List> classes = annotatedClasses(); + classes.forEach(aClass -> ((AnnotationConfigApplicationContext) ctx).register(aClass)); - protected List> annotatedClasses() { - List> classes = new ArrayList<>(); + // Finally refresh the context + ctx.refresh(); + } - classes.add(EnvironmentConfiguration.class); - classes.add(PropertiesConfiguration.class); + protected List> annotatedClasses() { + List> classes = new ArrayList<>(); - classes.add(PluginConfiguration.class); - classes.add(ServiceConfiguration.class); + classes.add(EnvironmentConfiguration.class); + classes.add(PropertiesConfiguration.class); - classes.add(ManagementConfiguration.class); - classes.add(ReporterConfiguration.class); + classes.add(PluginConfiguration.class); + classes.add(ServiceConfiguration.class); - classes.add(MonitoringConfiguration.class); - classes.add(KubernetesClientConfiguration.class); + classes.add(ManagementConfiguration.class); + classes.add(ReporterConfiguration.class); - classes.add(NodeConfiguration.class); + classes.add(MonitoringConfiguration.class); + classes.add(KubernetesClientConfiguration.class); - return classes; - } + classes.add(NodeConfiguration.class); - @Override - protected void doStop() throws Exception { - if (!stopped) { - LoggerFactory - .getLogger(this.getClass()) - .info("Shutting-down {}...", name()); + return classes; + } - try { - node().stop(); - } catch (Exception ex) { - LoggerFactory.getLogger(this.getClass()).error("Unexpected error", ex); - } finally { - ctx.close(); - stopped = true; - } + @Override + protected void doStop() throws Exception { + if (!stopped) { + LoggerFactory.getLogger(this.getClass()).info("Shutting-down {}...", name()); + + try { + node().stop(); + } catch (Exception ex) { + LoggerFactory.getLogger(this.getClass()).error("Unexpected error", ex); + } finally { + ctx.close(); + stopped = true; + } + } } - } - @Override - public Node node() { - // Get a reference to the node - return ctx.getBean(Node.class); - } + @Override + public Node node() { + // Get a reference to the node + return ctx.getBean(Node.class); + } - public ApplicationContext applicationContext() { - return ctx; - } + public ApplicationContext applicationContext() { + return ctx; + } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/SpringEnvironmentConfiguration.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/SpringEnvironmentConfiguration.java index 5c3f558c2..d17d42049 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/SpringEnvironmentConfiguration.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/SpringEnvironmentConfiguration.java @@ -21,36 +21,36 @@ public class SpringEnvironmentConfiguration implements Configuration { - private final Environment environment; - - public SpringEnvironmentConfiguration(Environment environment) { - this.environment = environment; - } - - @Override - public boolean containsProperty(String key) { - return environment.containsProperty(key); - } - - @Override - @Nullable - public String getProperty(String key) { - return environment.getProperty(key); - } - - @Override - public String getProperty(String key, String defaultValue) { - return environment.getProperty(key, defaultValue); - } - - @Override - @Nullable - public T getProperty(String key, Class targetType) { - return environment.getProperty(key, targetType); - } - - @Override - public T getProperty(String key, Class targetType, T defaultValue) { - return environment.getProperty(key, targetType, defaultValue); - } + private final Environment environment; + + public SpringEnvironmentConfiguration(Environment environment) { + this.environment = environment; + } + + @Override + public boolean containsProperty(String key) { + return environment.containsProperty(key); + } + + @Override + @Nullable + public String getProperty(String key) { + return environment.getProperty(key); + } + + @Override + public String getProperty(String key, String defaultValue) { + return environment.getProperty(key, defaultValue); + } + + @Override + @Nullable + public T getProperty(String key, Class targetType) { + return environment.getProperty(key, targetType); + } + + @Override + public T getProperty(String key, Class targetType, T defaultValue) { + return environment.getProperty(key, targetType, defaultValue); + } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/AbstractGraviteePropertySource.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/AbstractGraviteePropertySource.java index 2a8556d97..33d5ef8b3 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/AbstractGraviteePropertySource.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/AbstractGraviteePropertySource.java @@ -30,84 +30,70 @@ * @author Kamiel Ahmadpour (kamiel.ahmadpour at graviteesource.com) * @author GraviteeSource Team */ -public abstract class AbstractGraviteePropertySource - extends EnumerablePropertySource> { +public abstract class AbstractGraviteePropertySource extends EnumerablePropertySource> { - private static final Logger LOGGER = LoggerFactory.getLogger( - AbstractGraviteePropertySource.class - ); - private final PropertyResolverFactoriesLoader propertyResolverLoader; + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractGraviteePropertySource.class); + private final PropertyResolverFactoriesLoader propertyResolverLoader; - protected AbstractGraviteePropertySource( - String name, - Map source, - ApplicationContext applicationContext - ) { - super(name, source); - this.propertyResolverLoader = - applicationContext.getBean(PropertyResolverFactoriesLoader.class); - } + protected AbstractGraviteePropertySource(String name, Map source, ApplicationContext applicationContext) { + super(name, source); + this.propertyResolverLoader = applicationContext.getBean(PropertyResolverFactoriesLoader.class); + } - @Override - public String[] getPropertyNames() { - return source.keySet().toArray(new String[0]); - } + @Override + public String[] getPropertyNames() { + return source.keySet().toArray(new String[0]); + } - @Override - public Object getProperty(String name) { - Assert.notNull(name, "Property name can not be null."); - Object value = source.getOrDefault(name, getValue(name)); + @Override + public Object getProperty(String name) { + Assert.notNull(name, "Property name can not be null."); + Object value = source.getOrDefault(name, getValue(name)); - if (value == null) { - return null; - } + if (value == null) { + return null; + } - if (isCloudBased(value)) { - for (PropertyResolver propertyResolver : propertyResolverLoader.getPropertyResolvers()) { - if (propertyResolver.supports(value.toString())) { - Object resolvedValue = propertyResolver - .resolve(value.toString()) - .doOnError( - t -> { - LOGGER.error("Unable to resolve property {}", name, t); - source.put(name, null); - } - ) - .blockingGet(); // property must be resolved before continuing with the rest of the code - source.put(name, resolvedValue); // to avoid resolving this property again + if (isCloudBased(value)) { + for (PropertyResolver propertyResolver : propertyResolverLoader.getPropertyResolvers()) { + if (propertyResolver.supports(value.toString())) { + Object resolvedValue = propertyResolver + .resolve(value.toString()) + .doOnError(t -> { + LOGGER.error("Unable to resolve property {}", name, t); + source.put(name, null); + }) + .blockingGet(); // property must be resolved before continuing with the rest of the code + source.put(name, resolvedValue); // to avoid resolving this property again - watchProperty(propertyResolver, name, value); + watchProperty(propertyResolver, name, value); - break; + break; + } + } } - } + + return getValue(name); } - return getValue(name); - } + protected abstract Object getValue(String key); - protected abstract Object getValue(String key); + private boolean isCloudBased(Object value) { + for (CloudScheme cloudScheme : CloudScheme.values()) { + if (value.toString().startsWith(cloudScheme.value())) { + return true; + } + } - private boolean isCloudBased(Object value) { - for (CloudScheme cloudScheme : CloudScheme.values()) { - if (value.toString().startsWith(cloudScheme.value())) { - return true; - } + return false; } - return false; - } - - private void watchProperty( - PropertyResolver propertyResolver, - String name, - Object value - ) { - propertyResolver - .watch(value.toString()) - .doOnNext(newValue -> source.put(name, newValue)) - .doOnError(t -> LOGGER.error("Unable to update property {}", name, t)) - .doOnComplete(() -> watchProperty(propertyResolver, name, value)) - .subscribe(); - } + private void watchProperty(PropertyResolver propertyResolver, String name, Object value) { + propertyResolver + .watch(value.toString()) + .doOnNext(newValue -> source.put(name, newValue)) + .doOnError(t -> LOGGER.error("Unable to update property {}", name, t)) + .doOnComplete(() -> watchProperty(propertyResolver, name, value)) + .subscribe(); + } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/EnvironmentConfiguration.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/EnvironmentConfiguration.java index 1f820d4b2..f13ef1678 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/EnvironmentConfiguration.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/EnvironmentConfiguration.java @@ -33,48 +33,35 @@ @Import({ PropertiesConfiguration.class }) public class EnvironmentConfiguration { - @Bean - public static PropertySourcesPlaceholderConfigurer properties( - @Qualifier("graviteeProperties") Properties graviteeProperties - ) { - PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer(); - propertySourcesPlaceholderConfigurer.setProperties(graviteeProperties); - propertySourcesPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders( - true - ); + @Bean + public static PropertySourcesPlaceholderConfigurer properties(@Qualifier("graviteeProperties") Properties graviteeProperties) { + PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer(); + propertySourcesPlaceholderConfigurer.setProperties(graviteeProperties); + propertySourcesPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(true); - return propertySourcesPlaceholderConfigurer; - } + return propertySourcesPlaceholderConfigurer; + } - @Bean - public static PropertySourceBeanProcessor propertySourceBeanProcessor( - @Qualifier("graviteeProperties") Properties graviteeProperties, - Environment environment, - ApplicationContext applicationContext - ) { - // Using this we are now able to use {@link org.springframework.core.env.Environment} in Spring beans - return new PropertySourceBeanProcessor( - graviteeProperties, - environment, - applicationContext - ); - } + @Bean + public static PropertySourceBeanProcessor propertySourceBeanProcessor( + @Qualifier("graviteeProperties") Properties graviteeProperties, + Environment environment, + ApplicationContext applicationContext + ) { + // Using this we are now able to use {@link org.springframework.core.env.Environment} in Spring beans + return new PropertySourceBeanProcessor(graviteeProperties, environment, applicationContext); + } - @Bean - public static EnvironmentPropertySourceBeanProcessor environmentBeanFactoryPostProcessor( - Environment environment, - ApplicationContext applicationContext - ) { - return new EnvironmentPropertySourceBeanProcessor( - environment, - applicationContext - ); - } + @Bean + public static EnvironmentPropertySourceBeanProcessor environmentBeanFactoryPostProcessor( + Environment environment, + ApplicationContext applicationContext + ) { + return new EnvironmentPropertySourceBeanProcessor(environment, applicationContext); + } - @Bean - public static io.gravitee.node.api.configuration.Configuration graviteeEnvironment( - Environment environment - ) { - return new SpringEnvironmentConfiguration(environment); - } + @Bean + public static io.gravitee.node.api.configuration.Configuration graviteeEnvironment(Environment environment) { + return new SpringEnvironmentConfiguration(environment); + } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/EnvironmentPropertySourceBeanProcessor.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/EnvironmentPropertySourceBeanProcessor.java index d968b99b2..469c7708c 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/EnvironmentPropertySourceBeanProcessor.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/EnvironmentPropertySourceBeanProcessor.java @@ -29,54 +29,35 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class EnvironmentPropertySourceBeanProcessor - implements BeanFactoryPostProcessor, Ordered { +public class EnvironmentPropertySourceBeanProcessor implements BeanFactoryPostProcessor, Ordered { - private static final String[] PROPERTY_PREFIXES = new String[] { - "gravitee.", - "gravitee_", - "GRAVITEE.", - "GRAVITEE_", - }; - private final Environment environment; - private final ApplicationContext applicationContext; + private static final String[] PROPERTY_PREFIXES = new String[] { "gravitee.", "gravitee_", "GRAVITEE.", "GRAVITEE_" }; + private final Environment environment; + private final ApplicationContext applicationContext; - EnvironmentPropertySourceBeanProcessor( - Environment environment, - ApplicationContext applicationContext - ) { - this.environment = environment; - this.applicationContext = applicationContext; - } + EnvironmentPropertySourceBeanProcessor(Environment environment, ApplicationContext applicationContext) { + this.environment = environment; + this.applicationContext = applicationContext; + } - @Override - public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE; - } + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } - @Override - public void postProcessBeanFactory( - ConfigurableListableBeanFactory beanFactory - ) { - Map source = new ConcurrentHashMap<>(); - ((StandardEnvironment) environment).getSystemEnvironment() - .forEach( - (key, value) -> { - for (String propertyPrefix : PROPERTY_PREFIXES) { - if (key.startsWith(propertyPrefix)) { - source.put(key.substring(propertyPrefix.length()), value); - } - } - } - ); + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { + Map source = new ConcurrentHashMap<>(); + ((StandardEnvironment) environment).getSystemEnvironment() + .forEach((key, value) -> { + for (String propertyPrefix : PROPERTY_PREFIXES) { + if (key.startsWith(propertyPrefix)) { + source.put(key.substring(propertyPrefix.length()), value); + } + } + }); - ((ConfigurableEnvironment) environment).getPropertySources() - .addFirst( - new GraviteeEnvironmentPropertySource( - "graviteeEnvironmentPropertySource", - source, - applicationContext - ) - ); - } + ((ConfigurableEnvironment) environment).getPropertySources() + .addFirst(new GraviteeEnvironmentPropertySource("graviteeEnvironmentPropertySource", source, applicationContext)); + } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/GraviteeEnvironmentPropertySource.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/GraviteeEnvironmentPropertySource.java index 733c7e998..bc82fc66f 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/GraviteeEnvironmentPropertySource.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/GraviteeEnvironmentPropertySource.java @@ -23,33 +23,27 @@ * @author Kamiel Ahmadpour (kamiel.ahmadpour at graviteesource.com) * @author GraviteeSource Team */ -public class GraviteeEnvironmentPropertySource - extends AbstractGraviteePropertySource { +public class GraviteeEnvironmentPropertySource extends AbstractGraviteePropertySource { - private final RelaxedPropertySource relaxedPropertySource; + private final RelaxedPropertySource relaxedPropertySource; - public GraviteeEnvironmentPropertySource( - String name, - Map source, - ApplicationContext applicationContext - ) { - super(name, source, applicationContext); - this.relaxedPropertySource = - new RelaxedPropertySource("envVariables", source); - } + public GraviteeEnvironmentPropertySource(String name, Map source, ApplicationContext applicationContext) { + super(name, source, applicationContext); + this.relaxedPropertySource = new RelaxedPropertySource("envVariables", source); + } - @Override - protected Object getValue(String key) { - return relaxedPropertySource.getProperty(key); - } + @Override + protected Object getValue(String key) { + return relaxedPropertySource.getProperty(key); + } - @Override - public boolean containsProperty(String name) { - return relaxedPropertySource.containsProperty(name); - } + @Override + public boolean containsProperty(String name) { + return relaxedPropertySource.containsProperty(name); + } - @Override - public String[] getPropertyNames() { - return relaxedPropertySource.getPropertyNames(); - } + @Override + public String[] getPropertyNames() { + return relaxedPropertySource.getPropertyNames(); + } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/GraviteeYamlPropertySource.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/GraviteeYamlPropertySource.java index c7136f8da..69cdb263f 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/GraviteeYamlPropertySource.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/GraviteeYamlPropertySource.java @@ -25,16 +25,12 @@ */ public class GraviteeYamlPropertySource extends AbstractGraviteePropertySource { - public GraviteeYamlPropertySource( - String name, - Map source, - ApplicationContext applicationContext - ) { - super(name, source, applicationContext); - } + public GraviteeYamlPropertySource(String name, Map source, ApplicationContext applicationContext) { + super(name, source, applicationContext); + } - @Override - protected Object getValue(String key) { - return source.get(key); - } + @Override + protected Object getValue(String key) { + return source.get(key); + } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/PropertiesConfiguration.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/PropertiesConfiguration.java index ed0db27a8..197dfc8c4 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/PropertiesConfiguration.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/PropertiesConfiguration.java @@ -33,35 +33,30 @@ @Configuration public class PropertiesConfiguration { - private static final Logger LOGGER = LoggerFactory.getLogger( - PropertiesConfiguration.class - ); + private static final Logger LOGGER = LoggerFactory.getLogger(PropertiesConfiguration.class); - public static final String GRAVITEE_CONFIGURATION = "gravitee.conf"; + public static final String GRAVITEE_CONFIGURATION = "gravitee.conf"; - @Bean(name = "graviteeProperties") - public static Properties graviteeProperties() throws IOException { - LOGGER.info("Loading Gravitee configuration."); + @Bean(name = "graviteeProperties") + public static Properties graviteeProperties() throws IOException { + LOGGER.info("Loading Gravitee configuration."); - YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean(); + YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean(); - String yamlConfiguration = System.getProperty(GRAVITEE_CONFIGURATION); - Resource yamlResource = new FileSystemResource(yamlConfiguration); + String yamlConfiguration = System.getProperty(GRAVITEE_CONFIGURATION); + Resource yamlResource = new FileSystemResource(yamlConfiguration); - LOGGER.info( - "\tGravitee configuration loaded from {}", - yamlResource.getURL().getPath() - ); + LOGGER.info("\tGravitee configuration loaded from {}", yamlResource.getURL().getPath()); - yaml.setResources(yamlResource); - Properties properties = yaml.getObject(); - LOGGER.info("Loading Gravitee configuration. DONE"); + yaml.setResources(yamlResource); + Properties properties = yaml.getObject(); + LOGGER.info("Loading Gravitee configuration. DONE"); - return properties; - } + return properties; + } - @Bean - public static PropertyResolverFactoriesLoader propertyResolverFactoriesLoader() { - return new PropertyResolverFactoriesLoader(); - } + @Bean + public static PropertyResolverFactoriesLoader propertyResolverFactoriesLoader() { + return new PropertyResolverFactoriesLoader(); + } } diff --git a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/PropertySourceBeanProcessor.java b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/PropertySourceBeanProcessor.java index 2f4f958cc..c02f189a2 100644 --- a/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/PropertySourceBeanProcessor.java +++ b/gravitee-node-container/src/main/java/io/gravitee/node/container/spring/env/PropertySourceBeanProcessor.java @@ -29,49 +29,31 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class PropertySourceBeanProcessor - implements BeanFactoryPostProcessor, Ordered { +public class PropertySourceBeanProcessor implements BeanFactoryPostProcessor, Ordered { - private final ApplicationContext applicationContext; - private final Environment environment; - private final Properties properties; + private final ApplicationContext applicationContext; + private final Environment environment; + private final Properties properties; - PropertySourceBeanProcessor( - Properties properties, - Environment environment, - ApplicationContext applicationContext - ) { - this.properties = properties; - this.environment = environment; - this.applicationContext = applicationContext; - } + PropertySourceBeanProcessor(Properties properties, Environment environment, ApplicationContext applicationContext) { + this.properties = properties; + this.environment = environment; + this.applicationContext = applicationContext; + } - @Override - public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE + 10; - } + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE + 10; + } - @Override - public void postProcessBeanFactory( - ConfigurableListableBeanFactory beanFactory - ) { - Map source = properties - .entrySet() - .stream() - .collect( - Collectors.toMap( - entry -> entry.getKey().toString(), - Map.Entry::getValue - ) - ); + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { + Map source = properties + .entrySet() + .stream() + .collect(Collectors.toMap(entry -> entry.getKey().toString(), Map.Entry::getValue)); - ((ConfigurableEnvironment) environment).getPropertySources() - .addLast( - new GraviteeYamlPropertySource( - "graviteeYamlConfiguration", - source, - applicationContext - ) - ); - } + ((ConfigurableEnvironment) environment).getPropertySources() + .addLast(new GraviteeYamlPropertySource("graviteeYamlConfiguration", source, applicationContext)); + } } diff --git a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/JettyHttpConfiguration.java b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/JettyHttpConfiguration.java index c035b462c..5359e5a06 100644 --- a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/JettyHttpConfiguration.java +++ b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/JettyHttpConfiguration.java @@ -25,225 +25,223 @@ @Configuration public class JettyHttpConfiguration { - @Value("${jetty.host:0.0.0.0}") - private String httpHost; + @Value("${jetty.host:0.0.0.0}") + private String httpHost; - @Value("${jetty.port:8093}") - private int httpPort; + @Value("${jetty.port:8093}") + private int httpPort; - @Value("${jetty.idleTimeout:30000}") - private int idleTimeout; + @Value("${jetty.idleTimeout:30000}") + private int idleTimeout; - @Value("${jetty.acceptors:-1}") - private int acceptors; + @Value("${jetty.acceptors:-1}") + private int acceptors; - @Value("${jetty.selectors:-1}") - private int selectors; + @Value("${jetty.selectors:-1}") + private int selectors; - @Value("${jetty.pool.minThreads:10}") - private int poolMinThreads; + @Value("${jetty.pool.minThreads:10}") + private int poolMinThreads; - @Value("${jetty.pool.maxThreads:200}") - private int poolMaxThreads; + @Value("${jetty.pool.maxThreads:200}") + private int poolMaxThreads; - @Value("${jetty.pool.idleTimeout:60000}") - private int poolIdleTimeout; + @Value("${jetty.pool.idleTimeout:60000}") + private int poolIdleTimeout; - @Value("${jetty.pool.queueSize:6000}") - private int poolQueueSize; + @Value("${jetty.pool.queueSize:6000}") + private int poolQueueSize; - @Value("${jetty.jmx:false}") - private boolean jmxEnabled; + @Value("${jetty.jmx:false}") + private boolean jmxEnabled; - @Value("${jetty.statistics:false}") - private boolean statisticsEnabled; + @Value("${jetty.statistics:false}") + private boolean statisticsEnabled; - @Value("${jetty.accesslog.enabled:true}") - private boolean accessLogEnabled; + @Value("${jetty.accesslog.enabled:true}") + private boolean accessLogEnabled; - @Value( - "${jetty.accesslog.path:${gravitee.home}/logs/gravitee_accesslog_yyyy_mm_dd.log}" - ) - private String accessLogPath; + @Value("${jetty.accesslog.path:${gravitee.home}/logs/gravitee_accesslog_yyyy_mm_dd.log}") + private String accessLogPath; - @Value("${jetty.secured:false}") - private boolean secured; + @Value("${jetty.secured:false}") + private boolean secured; - @Value("${jetty.ssl.keystore.path:#{null}}") - private String keyStorePath; + @Value("${jetty.ssl.keystore.path:#{null}}") + private String keyStorePath; - @Value("${jetty.ssl.keystore.password:#{null}}") - private String keyStorePassword; + @Value("${jetty.ssl.keystore.password:#{null}}") + private String keyStorePassword; - @Value("${jetty.ssl.keystore.type:#{null}}") - private String keyStoreType; + @Value("${jetty.ssl.keystore.type:#{null}}") + private String keyStoreType; - @Value("${jetty.ssl.truststore.path:#{null}}") - private String trustStorePath; + @Value("${jetty.ssl.truststore.path:#{null}}") + private String trustStorePath; - @Value("${jetty.ssl.truststore.password:#{null}}") - private String trustStorePassword; + @Value("${jetty.ssl.truststore.password:#{null}}") + private String trustStorePassword; - @Value("${jetty.ssl.truststore.type:#{null}}") - private String trustStoreType; + @Value("${jetty.ssl.truststore.type:#{null}}") + private String trustStoreType; - public int getHttpPort() { - return httpPort; - } + public int getHttpPort() { + return httpPort; + } - public void setHttpPort(int httpPort) { - this.httpPort = httpPort; - } + public void setHttpPort(int httpPort) { + this.httpPort = httpPort; + } - public int getAcceptors() { - return acceptors; - } + public int getAcceptors() { + return acceptors; + } - public void setAcceptors(int acceptors) { - this.acceptors = acceptors; - } + public void setAcceptors(int acceptors) { + this.acceptors = acceptors; + } - public int getSelectors() { - return selectors; - } + public int getSelectors() { + return selectors; + } - public void setSelectors(int selectors) { - this.selectors = selectors; - } + public void setSelectors(int selectors) { + this.selectors = selectors; + } - public int getPoolMinThreads() { - return poolMinThreads; - } + public int getPoolMinThreads() { + return poolMinThreads; + } - public void setPoolMinThreads(int poolMinThreads) { - this.poolMinThreads = poolMinThreads; - } + public void setPoolMinThreads(int poolMinThreads) { + this.poolMinThreads = poolMinThreads; + } - public int getPoolMaxThreads() { - return poolMaxThreads; - } + public int getPoolMaxThreads() { + return poolMaxThreads; + } - public void setPoolMaxThreads(int poolMaxThreads) { - this.poolMaxThreads = poolMaxThreads; - } + public void setPoolMaxThreads(int poolMaxThreads) { + this.poolMaxThreads = poolMaxThreads; + } - public boolean isJmxEnabled() { - return jmxEnabled; - } + public boolean isJmxEnabled() { + return jmxEnabled; + } - public void setJmxEnabled(boolean jmxEnabled) { - this.jmxEnabled = jmxEnabled; - } + public void setJmxEnabled(boolean jmxEnabled) { + this.jmxEnabled = jmxEnabled; + } - public int getIdleTimeout() { - return idleTimeout; - } + public int getIdleTimeout() { + return idleTimeout; + } - public void setIdleTimeout(int idleTimeout) { - this.idleTimeout = idleTimeout; - } + public void setIdleTimeout(int idleTimeout) { + this.idleTimeout = idleTimeout; + } - public boolean isStatisticsEnabled() { - return statisticsEnabled; - } + public boolean isStatisticsEnabled() { + return statisticsEnabled; + } - public void setStatisticsEnabled(boolean statisticsEnabled) { - this.statisticsEnabled = statisticsEnabled; - } + public void setStatisticsEnabled(boolean statisticsEnabled) { + this.statisticsEnabled = statisticsEnabled; + } - public int getPoolIdleTimeout() { - return poolIdleTimeout; - } + public int getPoolIdleTimeout() { + return poolIdleTimeout; + } - public void setPoolIdleTimeout(int poolIdleTimeout) { - this.poolIdleTimeout = poolIdleTimeout; - } + public void setPoolIdleTimeout(int poolIdleTimeout) { + this.poolIdleTimeout = poolIdleTimeout; + } - public int getPoolQueueSize() { - return poolQueueSize; - } + public int getPoolQueueSize() { + return poolQueueSize; + } - public void setPoolQueueSize(int poolQueueSize) { - this.poolQueueSize = poolQueueSize; - } + public void setPoolQueueSize(int poolQueueSize) { + this.poolQueueSize = poolQueueSize; + } - public boolean isAccessLogEnabled() { - return accessLogEnabled; - } + public boolean isAccessLogEnabled() { + return accessLogEnabled; + } - public void setAccessLogEnabled(boolean accessLogEnabled) { - this.accessLogEnabled = accessLogEnabled; - } + public void setAccessLogEnabled(boolean accessLogEnabled) { + this.accessLogEnabled = accessLogEnabled; + } - public String getAccessLogPath() { - return accessLogPath; - } + public String getAccessLogPath() { + return accessLogPath; + } - public void setAccessLogPath(String accessLogPath) { - this.accessLogPath = accessLogPath; - } + public void setAccessLogPath(String accessLogPath) { + this.accessLogPath = accessLogPath; + } - public String getHttpHost() { - return httpHost; - } + public String getHttpHost() { + return httpHost; + } - public void setHttpHost(String httpHost) { - this.httpHost = httpHost; - } + public void setHttpHost(String httpHost) { + this.httpHost = httpHost; + } - public boolean isSecured() { - return secured; - } + public boolean isSecured() { + return secured; + } - public void setSecured(boolean secured) { - this.secured = secured; - } + public void setSecured(boolean secured) { + this.secured = secured; + } - public String getKeyStorePath() { - return keyStorePath; - } + public String getKeyStorePath() { + return keyStorePath; + } - public void setKeyStorePath(String keyStorePath) { - this.keyStorePath = keyStorePath; - } + public void setKeyStorePath(String keyStorePath) { + this.keyStorePath = keyStorePath; + } - public String getKeyStorePassword() { - return keyStorePassword; - } + public String getKeyStorePassword() { + return keyStorePassword; + } - public void setKeyStorePassword(String keyStorePassword) { - this.keyStorePassword = keyStorePassword; - } + public void setKeyStorePassword(String keyStorePassword) { + this.keyStorePassword = keyStorePassword; + } - public String getTrustStorePath() { - return trustStorePath; - } + public String getTrustStorePath() { + return trustStorePath; + } - public void setTrustStorePath(String trustStorePath) { - this.trustStorePath = trustStorePath; - } + public void setTrustStorePath(String trustStorePath) { + this.trustStorePath = trustStorePath; + } - public String getTrustStorePassword() { - return trustStorePassword; - } + public String getTrustStorePassword() { + return trustStorePassword; + } - public void setTrustStorePassword(String trustStorePassword) { - this.trustStorePassword = trustStorePassword; - } + public void setTrustStorePassword(String trustStorePassword) { + this.trustStorePassword = trustStorePassword; + } - public String getKeyStoreType() { - return keyStoreType; - } + public String getKeyStoreType() { + return keyStoreType; + } - public void setKeyStoreType(String keyStoreType) { - this.keyStoreType = keyStoreType; - } + public void setKeyStoreType(String keyStoreType) { + this.keyStoreType = keyStoreType; + } - public String getTrustStoreType() { - return trustStoreType; - } + public String getTrustStoreType() { + return trustStoreType; + } - public void setTrustStoreType(String trustStoreType) { - this.trustStoreType = trustStoreType; - } + public void setTrustStoreType(String trustStoreType) { + this.trustStoreType = trustStoreType; + } } diff --git a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/JettyHttpServer.java b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/JettyHttpServer.java index 441591065..5d1adeba0 100644 --- a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/JettyHttpServer.java +++ b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/JettyHttpServer.java @@ -32,58 +32,51 @@ * @author GraviteeSource Team */ @Import({ JettyContainerConfiguration.class }) -public abstract class JettyHttpServer - extends AbstractLifecycleComponent { +public abstract class JettyHttpServer extends AbstractLifecycleComponent { - private final Logger logger = LoggerFactory.getLogger(JettyHttpServer.class); + private final Logger logger = LoggerFactory.getLogger(JettyHttpServer.class); - @Autowired - protected Server server; + @Autowired + protected Server server; - /** - * Allows to attach any handlers to the Jetty Http Server before it starts (ex : jaxrs with security configuration). - */ - protected abstract void attachHandlers(); + /** + * Allows to attach any handlers to the Jetty Http Server before it starts (ex : jaxrs with security configuration). + */ + protected abstract void attachHandlers(); - @Override - protected void doStart() throws Exception { - // This part is needed to avoid WARN while starting container. - this.attachNoContentHandler(); + @Override + protected void doStart() throws Exception { + // This part is needed to avoid WARN while starting container. + this.attachNoContentHandler(); - // Attach all custom handlers. - this.attachHandlers(); + // Attach all custom handlers. + this.attachHandlers(); - server.setStopAtShutdown(true); + server.setStopAtShutdown(true); - try { - server.join(); + try { + server.join(); - // Start HTTP server... - server.start(); + // Start HTTP server... + server.start(); - logger.info( - "HTTP Server is now started and listening on port {}", - ((ServerConnector) server.getConnectors()[0]).getPort() - ); - } catch (InterruptedException ex) { - logger.error( - "An error occurs while trying to initialize HTTP server", - ex - ); - throw ex; + logger.info("HTTP Server is now started and listening on port {}", ((ServerConnector) server.getConnectors()[0]).getPort()); + } catch (InterruptedException ex) { + logger.error("An error occurs while trying to initialize HTTP server", ex); + throw ex; + } } - } - @Override - protected void doStop() throws Exception { - server.stop(); - } + @Override + protected void doStop() throws Exception { + server.stop(); + } - private void attachNoContentHandler() { - AbstractHandler noContentHandler = new NoContentOutputErrorHandler(); + private void attachNoContentHandler() { + AbstractHandler noContentHandler = new NoContentOutputErrorHandler(); - // This part is needed to avoid WARN while starting container. - noContentHandler.setServer(server); - server.addBean(noContentHandler); - } + // This part is needed to avoid WARN while starting container. + noContentHandler.setServer(server); + server.addBean(noContentHandler); + } } diff --git a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/JettyHttpServerFactory.java b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/JettyHttpServerFactory.java index a51c1d63e..f8c2deee2 100644 --- a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/JettyHttpServerFactory.java +++ b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/JettyHttpServerFactory.java @@ -34,148 +34,122 @@ */ public class JettyHttpServerFactory implements FactoryBean { - private static final String KEYSTORE_TYPE_PKCS12 = "pkcs12"; - - @Autowired - private JettyHttpConfiguration jettyHttpConfiguration; - - @Override - public Server getObject() { - // Setup ThreadPool - QueuedThreadPool threadPool = new QueuedThreadPool( - jettyHttpConfiguration.getPoolMaxThreads(), - jettyHttpConfiguration.getPoolMinThreads(), - jettyHttpConfiguration.getPoolIdleTimeout(), - new ArrayBlockingQueue<>(jettyHttpConfiguration.getPoolQueueSize()) - ); - threadPool.setName("gravitee-listener"); - - Server server = new Server(threadPool); - - // Extra options - server.setDumpAfterStart(false); - server.setDumpBeforeStop(false); - server.setStopAtShutdown(true); - - // Setup JMX - if (jettyHttpConfiguration.isJmxEnabled()) { - MBeanContainer mbContainer = new MBeanContainer( - ManagementFactory.getPlatformMBeanServer() - ); - server.addBean(mbContainer); - } - - // HTTP Configuration - HttpConfiguration httpConfig = new HttpConfiguration(); - httpConfig.setOutputBufferSize(32768); - httpConfig.setRequestHeaderSize(8192); - httpConfig.setResponseHeaderSize(8192); - httpConfig.setSendServerVersion(false); - httpConfig.setSendDateHeader(false); - httpConfig.setRequestCookieCompliance(CookieCompliance.RFC2965); - httpConfig.setResponseCookieCompliance(CookieCompliance.RFC2965); - - // Setup Jetty HTTP or HTTPS Connector - if (jettyHttpConfiguration.isSecured()) { - httpConfig.setSecureScheme("https"); - httpConfig.setSecurePort(jettyHttpConfiguration.getHttpPort()); - - // SSL Context Factory - SslContextFactory sslContextFactory = new SslContextFactory.Server.Server(); - - if (jettyHttpConfiguration.getKeyStorePath() != null) { - sslContextFactory.setKeyStorePath( - jettyHttpConfiguration.getKeyStorePath() - ); - sslContextFactory.setKeyStorePassword( - jettyHttpConfiguration.getKeyStorePassword() + private static final String KEYSTORE_TYPE_PKCS12 = "pkcs12"; + + @Autowired + private JettyHttpConfiguration jettyHttpConfiguration; + + @Override + public Server getObject() { + // Setup ThreadPool + QueuedThreadPool threadPool = new QueuedThreadPool( + jettyHttpConfiguration.getPoolMaxThreads(), + jettyHttpConfiguration.getPoolMinThreads(), + jettyHttpConfiguration.getPoolIdleTimeout(), + new ArrayBlockingQueue<>(jettyHttpConfiguration.getPoolQueueSize()) ); + threadPool.setName("gravitee-listener"); + + Server server = new Server(threadPool); - if ( - KEYSTORE_TYPE_PKCS12.equalsIgnoreCase( - jettyHttpConfiguration.getKeyStoreType() - ) - ) { - sslContextFactory.setKeyStoreType(KEYSTORE_TYPE_PKCS12); + // Extra options + server.setDumpAfterStart(false); + server.setDumpBeforeStop(false); + server.setStopAtShutdown(true); + + // Setup JMX + if (jettyHttpConfiguration.isJmxEnabled()) { + MBeanContainer mbContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer()); + server.addBean(mbContainer); } - } - if (jettyHttpConfiguration.getTrustStorePath() != null) { - sslContextFactory.setTrustStorePath( - jettyHttpConfiguration.getTrustStorePath() - ); - sslContextFactory.setTrustStorePassword( - jettyHttpConfiguration.getTrustStorePassword() - ); + // HTTP Configuration + HttpConfiguration httpConfig = new HttpConfiguration(); + httpConfig.setOutputBufferSize(32768); + httpConfig.setRequestHeaderSize(8192); + httpConfig.setResponseHeaderSize(8192); + httpConfig.setSendServerVersion(false); + httpConfig.setSendDateHeader(false); + httpConfig.setRequestCookieCompliance(CookieCompliance.RFC2965); + httpConfig.setResponseCookieCompliance(CookieCompliance.RFC2965); + + // Setup Jetty HTTP or HTTPS Connector + if (jettyHttpConfiguration.isSecured()) { + httpConfig.setSecureScheme("https"); + httpConfig.setSecurePort(jettyHttpConfiguration.getHttpPort()); + + // SSL Context Factory + SslContextFactory sslContextFactory = new SslContextFactory.Server.Server(); + + if (jettyHttpConfiguration.getKeyStorePath() != null) { + sslContextFactory.setKeyStorePath(jettyHttpConfiguration.getKeyStorePath()); + sslContextFactory.setKeyStorePassword(jettyHttpConfiguration.getKeyStorePassword()); + + if (KEYSTORE_TYPE_PKCS12.equalsIgnoreCase(jettyHttpConfiguration.getKeyStoreType())) { + sslContextFactory.setKeyStoreType(KEYSTORE_TYPE_PKCS12); + } + } + + if (jettyHttpConfiguration.getTrustStorePath() != null) { + sslContextFactory.setTrustStorePath(jettyHttpConfiguration.getTrustStorePath()); + sslContextFactory.setTrustStorePassword(jettyHttpConfiguration.getTrustStorePassword()); + + if (KEYSTORE_TYPE_PKCS12.equalsIgnoreCase(jettyHttpConfiguration.getTrustStoreType())) { + sslContextFactory.setTrustStoreType(KEYSTORE_TYPE_PKCS12); + } + } + + HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig); + httpsConfig.addCustomizer(new SecureRequestCustomizer()); + + ServerConnector https = new ServerConnector( + server, + new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()), + new HttpConnectionFactory(httpsConfig) + ); + https.setHost(jettyHttpConfiguration.getHttpHost()); + https.setPort(jettyHttpConfiguration.getHttpPort()); + server.addConnector(https); + } else { + ServerConnector http = new ServerConnector( + server, + jettyHttpConfiguration.getAcceptors(), + jettyHttpConfiguration.getSelectors(), + new HttpConnectionFactory(httpConfig) + ); + http.setHost(jettyHttpConfiguration.getHttpHost()); + http.setPort(jettyHttpConfiguration.getHttpPort()); + http.setIdleTimeout(jettyHttpConfiguration.getIdleTimeout()); + + server.addConnector(http); + } - if ( - KEYSTORE_TYPE_PKCS12.equalsIgnoreCase( - jettyHttpConfiguration.getTrustStoreType() - ) - ) { - sslContextFactory.setTrustStoreType(KEYSTORE_TYPE_PKCS12); + // Setup Jetty statistics + if (jettyHttpConfiguration.isStatisticsEnabled()) { + StatisticsHandler stats = new StatisticsHandler(); + stats.setHandler(server.getHandler()); + server.setHandler(stats); } - } - - HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig); - httpsConfig.addCustomizer(new SecureRequestCustomizer()); - - ServerConnector https = new ServerConnector( - server, - new SslConnectionFactory( - sslContextFactory, - HttpVersion.HTTP_1_1.asString() - ), - new HttpConnectionFactory(httpsConfig) - ); - https.setHost(jettyHttpConfiguration.getHttpHost()); - https.setPort(jettyHttpConfiguration.getHttpPort()); - server.addConnector(https); - } else { - ServerConnector http = new ServerConnector( - server, - jettyHttpConfiguration.getAcceptors(), - jettyHttpConfiguration.getSelectors(), - new HttpConnectionFactory(httpConfig) - ); - http.setHost(jettyHttpConfiguration.getHttpHost()); - http.setPort(jettyHttpConfiguration.getHttpPort()); - http.setIdleTimeout(jettyHttpConfiguration.getIdleTimeout()); - - server.addConnector(http); - } - // Setup Jetty statistics - if (jettyHttpConfiguration.isStatisticsEnabled()) { - StatisticsHandler stats = new StatisticsHandler(); - stats.setHandler(server.getHandler()); - server.setHandler(stats); - } + if (jettyHttpConfiguration.isAccessLogEnabled()) { + RequestLogWriter requestLogWriter = new AsyncRequestLogWriter(jettyHttpConfiguration.getAccessLogPath()); + requestLogWriter.setRetainDays(90); + requestLogWriter.setTimeZone("GMT"); - if (jettyHttpConfiguration.isAccessLogEnabled()) { - RequestLogWriter requestLogWriter = new AsyncRequestLogWriter( - jettyHttpConfiguration.getAccessLogPath() - ); - requestLogWriter.setRetainDays(90); - requestLogWriter.setTimeZone("GMT"); - - CustomRequestLog requestLog = new CustomRequestLog( - requestLogWriter, - CustomRequestLog.EXTENDED_NCSA_FORMAT - ); - server.setRequestLog(requestLog); - } + CustomRequestLog requestLog = new CustomRequestLog(requestLogWriter, CustomRequestLog.EXTENDED_NCSA_FORMAT); + server.setRequestLog(requestLog); + } - return server; - } + return server; + } - @Override - public Class getObjectType() { - return Server.class; - } + @Override + public Class getObjectType() { + return Server.class; + } - @Override - public boolean isSingleton() { - return true; - } + @Override + public boolean isSingleton() { + return true; + } } diff --git a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/handler/NoContentOutputErrorHandler.java b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/handler/NoContentOutputErrorHandler.java index 9b4a95dd7..884b00567 100644 --- a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/handler/NoContentOutputErrorHandler.java +++ b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/handler/NoContentOutputErrorHandler.java @@ -27,64 +27,36 @@ */ public class NoContentOutputErrorHandler extends ErrorHandler { - @Override - protected void handleErrorPage( - HttpServletRequest request, - Writer writer, - int code, - String message - ) throws IOException { - writeErrorPage(request, writer, code, message, false); - } - - @Override - protected void writeErrorPageStacks( - HttpServletRequest request, - Writer writer - ) throws IOException { - // We do not want to put stacks in response - } - - @Override - protected void writeErrorPageMessage( - HttpServletRequest request, - Writer writer, - int code, - String message, - String uri - ) throws IOException { - // We do not want to put message in response - } - - @Override - protected void writeErrorPageBody( - HttpServletRequest request, - Writer writer, - int code, - String message, - boolean showStacks - ) throws IOException { - // We do not want to put body in response - } - - @Override - protected void writeErrorPageHead( - HttpServletRequest request, - Writer writer, - int code, - String message - ) throws IOException { - // We do not want to put head in response - } - - @Override - protected void writeErrorPage( - HttpServletRequest request, - Writer writer, - int code, - String message, - boolean showStacks - ) throws IOException { - // No error page - } + @Override + protected void handleErrorPage(HttpServletRequest request, Writer writer, int code, String message) throws IOException { + writeErrorPage(request, writer, code, message, false); + } + + @Override + protected void writeErrorPageStacks(HttpServletRequest request, Writer writer) throws IOException { + // We do not want to put stacks in response + } + + @Override + protected void writeErrorPageMessage(HttpServletRequest request, Writer writer, int code, String message, String uri) + throws IOException { + // We do not want to put message in response + } + + @Override + protected void writeErrorPageBody(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks) + throws IOException { + // We do not want to put body in response + } + + @Override + protected void writeErrorPageHead(HttpServletRequest request, Writer writer, int code, String message) throws IOException { + // We do not want to put head in response + } + + @Override + protected void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks) + throws IOException { + // No error page + } } diff --git a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/healthcheck/JettyHttpServerProbe.java b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/healthcheck/JettyHttpServerProbe.java index 579878e4b..21c312d80 100644 --- a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/healthcheck/JettyHttpServerProbe.java +++ b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/healthcheck/JettyHttpServerProbe.java @@ -34,41 +34,41 @@ */ public class JettyHttpServerProbe implements Probe { - @Value("${jetty.port:8093}") - private int port; + @Value("${jetty.port:8093}") + private int port; - @Value("${jetty.host:localhost}") - private String host; + @Value("${jetty.host:localhost}") + private String host; - @Autowired - private Vertx vertx; + @Autowired + private Vertx vertx; - @Override - public String id() { - return "jetty-http-server"; - } + @Override + public String id() { + return "jetty-http-server"; + } - @Override - public CompletionStage check() { - Promise promise = Promise.promise(); + @Override + public CompletionStage check() { + Promise promise = Promise.promise(); - NetClientOptions options = new NetClientOptions().setConnectTimeout(500); - NetClient client = vertx.createNetClient(options); + NetClientOptions options = new NetClientOptions().setConnectTimeout(500); + NetClient client = vertx.createNetClient(options); - client.connect( - port, - host, - res -> { - if (res.succeeded()) { - promise.complete(Result.healthy()); - } else { - promise.complete(Result.unhealthy(res.cause())); - } + client.connect( + port, + host, + res -> { + if (res.succeeded()) { + promise.complete(Result.healthy()); + } else { + promise.complete(Result.unhealthy(res.cause())); + } - client.close(); - } - ); + client.close(); + } + ); - return promise.future().toCompletionStage(); - } + return promise.future().toCompletionStage(); + } } diff --git a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/node/JettyNode.java b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/node/JettyNode.java index a1ec14a18..75cde7e85 100644 --- a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/node/JettyNode.java +++ b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/node/JettyNode.java @@ -26,11 +26,11 @@ */ public abstract class JettyNode extends AbstractNode { - @Override - public List> components() { - final List> components = super.components(); - components.add(JettyHttpServer.class); + @Override + public List> components() { + final List> components = super.components(); + components.add(JettyHttpServer.class); - return components; - } + return components; + } } diff --git a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/spring/JettyContainerConfiguration.java b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/spring/JettyContainerConfiguration.java index af9bf1828..b19e21f4a 100644 --- a/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/spring/JettyContainerConfiguration.java +++ b/gravitee-node-jetty/src/main/java/io/gravitee/node/jetty/spring/JettyContainerConfiguration.java @@ -28,13 +28,13 @@ @Configuration public class JettyContainerConfiguration { - @Bean - public JettyHttpConfiguration jettyConfiguration() { - return new JettyHttpConfiguration(); - } + @Bean + public JettyHttpConfiguration jettyConfiguration() { + return new JettyHttpConfiguration(); + } - @Bean - public JettyHttpServerFactory jettyServerFactory() { - return new JettyHttpServerFactory(); - } + @Bean + public JettyHttpServerFactory jettyServerFactory() { + return new JettyHttpServerFactory(); + } } diff --git a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/AbstractKubernetesKeyStoreLoader.java b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/AbstractKubernetesKeyStoreLoader.java index 4fb0a9770..52d7e844e 100644 --- a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/AbstractKubernetesKeyStoreLoader.java +++ b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/AbstractKubernetesKeyStoreLoader.java @@ -39,107 +39,78 @@ * @author Jeoffrey HAEYAERT (jeoffrey.haeyaert at graviteesource.com) * @author GraviteeSource Team */ -public abstract class AbstractKubernetesKeyStoreLoader - implements KeyStoreLoader { - - private static final Logger logger = LoggerFactory.getLogger( - AbstractKubernetesKeyStoreLoader.class - ); - private static final int WATCH_RETRY_DELAY = 000; - protected static final int RETRY_DELAY_MILLIS = 10000; - - protected final KeyStoreLoaderOptions options; - protected final KubernetesClient kubernetesClient; - protected final List> listeners; - protected final Map keyStoresByLocation; - protected final Map resources = new HashMap<>(); - protected KeyStoreBundle keyStoreBundle; - - private Disposable disposable; - - public AbstractKubernetesKeyStoreLoader( - KeyStoreLoaderOptions options, - KubernetesClient kubernetesClient - ) { - this.options = options; - this.kubernetesClient = kubernetesClient; - this.listeners = new ArrayList<>(); - this.keyStoresByLocation = new ConcurrentHashMap<>(); - } - - @Override - public void start() { - final Throwable throwable = init() - .doOnComplete( - () -> { - if (options.isWatch()) { - startWatch(); - } +public abstract class AbstractKubernetesKeyStoreLoader implements KeyStoreLoader { + + private static final Logger logger = LoggerFactory.getLogger(AbstractKubernetesKeyStoreLoader.class); + private static final int WATCH_RETRY_DELAY = 000; + protected static final int RETRY_DELAY_MILLIS = 10000; + + protected final KeyStoreLoaderOptions options; + protected final KubernetesClient kubernetesClient; + protected final List> listeners; + protected final Map keyStoresByLocation; + protected final Map resources = new HashMap<>(); + protected KeyStoreBundle keyStoreBundle; + + private Disposable disposable; + + public AbstractKubernetesKeyStoreLoader(KeyStoreLoaderOptions options, KubernetesClient kubernetesClient) { + this.options = options; + this.kubernetesClient = kubernetesClient; + this.listeners = new ArrayList<>(); + this.keyStoresByLocation = new ConcurrentHashMap<>(); + } + + @Override + public void start() { + final Throwable throwable = init() + .doOnComplete(() -> { + if (options.isWatch()) { + startWatch(); + } + }) + .blockingGet(); + + if (throwable != null) { + throw new IllegalArgumentException("An error occurred when trying to init certificates.", throwable); + } + } + + protected void startWatch() { + this.disposable = + watch() + .observeOn(Schedulers.computation()) + .flatMapCompletable(t -> loadKeyStore(t).andThen(Completable.fromRunnable(this::refreshKeyStoreBundle))) + .doOnError(throwable -> logger.error("An error occurred during keystore refresh. Restarting watch.", throwable)) + .retry() + .subscribe(); + } + + @Override + public void stop() { + if (disposable != null && !disposable.isDisposed()) { + disposable.dispose(); } - ) - .blockingGet(); - - if (throwable != null) { - throw new IllegalArgumentException( - "An error occurred when trying to init certificates.", - throwable - ); } - } - - protected void startWatch() { - this.disposable = - watch() - .observeOn(Schedulers.computation()) - .flatMapCompletable( - t -> - loadKeyStore(t) - .andThen(Completable.fromRunnable(this::refreshKeyStoreBundle)) - ) - .doOnError( - throwable -> - logger.error( - "An error occurred during keystore refresh. Restarting watch.", - throwable - ) - ) - .retry() - .subscribe(); - } - - @Override - public void stop() { - if (disposable != null && !disposable.isDisposed()) { - disposable.dispose(); + + protected abstract Flowable watch(); + + protected abstract Completable init(); + + protected abstract Completable loadKeyStore(T elt); + + @Override + public void addListener(Consumer listener) { + listeners.add(listener); + } + + protected void refreshKeyStoreBundle() { + final KeyStore keyStore = KeyStoreUtils.merge(new ArrayList<>(keyStoresByLocation.values()), options.getKeyStorePassword()); + this.keyStoreBundle = new KeyStoreBundle(keyStore, options.getKeyStorePassword(), options.getDefaultAlias()); + this.notifyListeners(); + } + + protected void notifyListeners() { + listeners.forEach(consumer -> consumer.accept(keyStoreBundle)); } - } - - protected abstract Flowable watch(); - - protected abstract Completable init(); - - protected abstract Completable loadKeyStore(T elt); - - @Override - public void addListener(Consumer listener) { - listeners.add(listener); - } - - protected void refreshKeyStoreBundle() { - final KeyStore keyStore = KeyStoreUtils.merge( - new ArrayList<>(keyStoresByLocation.values()), - options.getKeyStorePassword() - ); - this.keyStoreBundle = - new KeyStoreBundle( - keyStore, - options.getKeyStorePassword(), - options.getDefaultAlias() - ); - this.notifyListeners(); - } - - protected void notifyListeners() { - listeners.forEach(consumer -> consumer.accept(keyStoreBundle)); - } } diff --git a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesConfigMapKeyStoreLoader.java b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesConfigMapKeyStoreLoader.java index f15bfc139..a7079b964 100644 --- a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesConfigMapKeyStoreLoader.java +++ b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesConfigMapKeyStoreLoader.java @@ -37,150 +37,115 @@ * @author Jeoffrey HAEYAERT (jeoffrey.haeyaert at graviteesource.com) * @author GraviteeSource Team */ -public class KubernetesConfigMapKeyStoreLoader - extends AbstractKubernetesKeyStoreLoader { - - private static final List SUPPORTED_TYPES = Arrays.asList( - KeyStoreLoader.CERTIFICATE_FORMAT_JKS.toLowerCase(), - KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12.toLowerCase() - ); - - private static final Pattern CONFIGMAP_PATTERN = Pattern.compile( - "^(.*/configmaps/.*)/.*$" - ); - - public KubernetesConfigMapKeyStoreLoader( - KeyStoreLoaderOptions options, - KubernetesClient kubernetesClient - ) { - super(options, kubernetesClient); - prepareLocations(); - } - - private void prepareLocations() { - this.options.getKubernetesLocations() - .forEach( - location -> { - final Matcher matcher = CONFIGMAP_PATTERN.matcher(location); - if (matcher.matches()) { - this.resources.put( - matcher.group(1), - new KubernetesResource(location) - ); - } else { - throw new IllegalArgumentException( - "You must specify a data when using configmap (ex: /my-namespace/configmaps/my-configmap/my-keystore)." - ); - } - } - ); - } - - public static boolean canHandle(KeyStoreLoaderOptions options) { - final List kubernetesLocations = options.getKubernetesLocations(); - - return ( - kubernetesLocations != null && - !kubernetesLocations.isEmpty() && - SUPPORTED_TYPES.contains(options.getKeyStoreType().toLowerCase()) && - kubernetesLocations - .stream() - .allMatch(location -> CONFIGMAP_PATTERN.matcher(location).matches()) +public class KubernetesConfigMapKeyStoreLoader extends AbstractKubernetesKeyStoreLoader { + + private static final List SUPPORTED_TYPES = Arrays.asList( + KeyStoreLoader.CERTIFICATE_FORMAT_JKS.toLowerCase(), + KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12.toLowerCase() ); - } - - @Override - protected Completable init() { - final List locationObs = resources - .keySet() - .stream() - .map( - location -> - kubernetesClient - .get(location, ConfigMap.class) - .observeOn(Schedulers.computation()) - .flatMapCompletable(this::loadKeyStore) - ) - .collect(Collectors.toList()); - - return Completable - .merge(locationObs) - .observeOn(Schedulers.computation()) - .andThen(Completable.fromRunnable(this::refreshKeyStoreBundle)); - } - - @Override - protected Flowable watch() { - final List> toWatch = resources - .keySet() - .stream() - .map( - location -> - kubernetesClient - .watch(location, ConfigMapEvent.class) - .observeOn(Schedulers.computation()) - .repeat() - .retryWhen( - errors -> errors.delay(RETRY_DELAY_MILLIS, TimeUnit.MILLISECONDS) - ) - ) - .collect(Collectors.toList()); - - return Flowable - .merge(toWatch) - .filter(event -> event.getType().equalsIgnoreCase("MODIFIED")) - .map(ConfigMapEvent::getObject); - } - - @Override - protected Completable loadKeyStore(ConfigMap configMap) { - final Optional optResource = resources - .values() - .stream() - .filter( - r -> - r - .getNamespace() - .equalsIgnoreCase(configMap.getMetadata().getNamespace()) && - r.getName().equalsIgnoreCase(configMap.getMetadata().getName()) - ) - .findFirst(); - - if (optResource.isEmpty()) { - return Completable.error( - new IllegalArgumentException("Unable to load keystore: unknown secret.") - ); + + private static final Pattern CONFIGMAP_PATTERN = Pattern.compile("^(.*/configmaps/.*)/.*$"); + + public KubernetesConfigMapKeyStoreLoader(KeyStoreLoaderOptions options, KubernetesClient kubernetesClient) { + super(options, kubernetesClient); + prepareLocations(); } - Map data = configMap.getBinaryData() == null - ? configMap.getData() - : configMap.getBinaryData(); + private void prepareLocations() { + this.options.getKubernetesLocations() + .forEach(location -> { + final Matcher matcher = CONFIGMAP_PATTERN.matcher(location); + if (matcher.matches()) { + this.resources.put(matcher.group(1), new KubernetesResource(location)); + } else { + throw new IllegalArgumentException( + "You must specify a data when using configmap (ex: /my-namespace/configmaps/my-configmap/my-keystore)." + ); + } + }); + } + + public static boolean canHandle(KeyStoreLoaderOptions options) { + final List kubernetesLocations = options.getKubernetesLocations(); - if (configMap.getBinaryData() != null) { - data = configMap.getBinaryData(); - } else if (configMap.getData() != null) { - data = configMap.getData(); + return ( + kubernetesLocations != null && + !kubernetesLocations.isEmpty() && + SUPPORTED_TYPES.contains(options.getKeyStoreType().toLowerCase()) && + kubernetesLocations.stream().allMatch(location -> CONFIGMAP_PATTERN.matcher(location).matches()) + ); } - final String dataKey = optResource.get().getKey(); - if (data == null || data.get(dataKey) == null) { - return Completable.error( - new IllegalArgumentException( - String.format( - "No data has been found in the configmap for the specified key [%s].", - dataKey - ) - ) - ); + @Override + protected Completable init() { + final List locationObs = resources + .keySet() + .stream() + .map(location -> + kubernetesClient.get(location, ConfigMap.class).observeOn(Schedulers.computation()).flatMapCompletable(this::loadKeyStore) + ) + .collect(Collectors.toList()); + + return Completable + .merge(locationObs) + .observeOn(Schedulers.computation()) + .andThen(Completable.fromRunnable(this::refreshKeyStoreBundle)); } - final KeyStore keyStore = KeyStoreUtils.initFromContent( - options.getKeyStoreType(), - data.get(dataKey), - options.getKeyStorePassword() - ); + @Override + protected Flowable watch() { + final List> toWatch = resources + .keySet() + .stream() + .map(location -> + kubernetesClient + .watch(location, ConfigMapEvent.class) + .observeOn(Schedulers.computation()) + .repeat() + .retryWhen(errors -> errors.delay(RETRY_DELAY_MILLIS, TimeUnit.MILLISECONDS)) + ) + .collect(Collectors.toList()); - keyStoresByLocation.put(configMap.getMetadata().getUid(), keyStore); - return Completable.complete(); - } + return Flowable.merge(toWatch).filter(event -> event.getType().equalsIgnoreCase("MODIFIED")).map(ConfigMapEvent::getObject); + } + + @Override + protected Completable loadKeyStore(ConfigMap configMap) { + final Optional optResource = resources + .values() + .stream() + .filter(r -> + r.getNamespace().equalsIgnoreCase(configMap.getMetadata().getNamespace()) && + r.getName().equalsIgnoreCase(configMap.getMetadata().getName()) + ) + .findFirst(); + + if (optResource.isEmpty()) { + return Completable.error(new IllegalArgumentException("Unable to load keystore: unknown secret.")); + } + + Map data = configMap.getBinaryData() == null ? configMap.getData() : configMap.getBinaryData(); + + if (configMap.getBinaryData() != null) { + data = configMap.getBinaryData(); + } else if (configMap.getData() != null) { + data = configMap.getData(); + } + + final String dataKey = optResource.get().getKey(); + if (data == null || data.get(dataKey) == null) { + return Completable.error( + new IllegalArgumentException(String.format("No data has been found in the configmap for the specified key [%s].", dataKey)) + ); + } + + final KeyStore keyStore = KeyStoreUtils.initFromContent( + options.getKeyStoreType(), + data.get(dataKey), + options.getKeyStorePassword() + ); + + keyStoresByLocation.put(configMap.getMetadata().getUid(), keyStore); + return Completable.complete(); + } } diff --git a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesKeyStoreLoaderFactory.java b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesKeyStoreLoaderFactory.java index 550ec5a61..13571bc0c 100644 --- a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesKeyStoreLoaderFactory.java +++ b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesKeyStoreLoaderFactory.java @@ -28,28 +28,23 @@ */ public class KubernetesKeyStoreLoaderFactory implements KeyStoreLoaderFactory { - private final KubernetesClient client; + private final KubernetesClient client; - public KubernetesKeyStoreLoaderFactory(KubernetesClient client) { - this.client = client; - } - - public boolean canHandle(KeyStoreLoaderOptions options) { - return ( - KubernetesConfigMapKeyStoreLoader.canHandle(options) || - KubernetesSecretKeyStoreLoader.canHandle(options) - ); - } + public KubernetesKeyStoreLoaderFactory(KubernetesClient client) { + this.client = client; + } - public KeyStoreLoader create(KeyStoreLoaderOptions options) { - if (KubernetesConfigMapKeyStoreLoader.canHandle(options)) { - return new KubernetesConfigMapKeyStoreLoader(options, client); - } else if (KubernetesSecretKeyStoreLoader.canHandle(options)) { - return new KubernetesSecretKeyStoreLoader(options, client); + public boolean canHandle(KeyStoreLoaderOptions options) { + return (KubernetesConfigMapKeyStoreLoader.canHandle(options) || KubernetesSecretKeyStoreLoader.canHandle(options)); } - throw new IllegalArgumentException( - "Cannot found appropriate KubernetesKeyStoreLoaderFactory." - ); - } + public KeyStoreLoader create(KeyStoreLoaderOptions options) { + if (KubernetesConfigMapKeyStoreLoader.canHandle(options)) { + return new KubernetesConfigMapKeyStoreLoader(options, client); + } else if (KubernetesSecretKeyStoreLoader.canHandle(options)) { + return new KubernetesSecretKeyStoreLoader(options, client); + } + + throw new IllegalArgumentException("Cannot found appropriate KubernetesKeyStoreLoaderFactory."); + } } diff --git a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesSecretKeyStoreLoader.java b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesSecretKeyStoreLoader.java index 9032a03f1..e7df7fc0f 100644 --- a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesSecretKeyStoreLoader.java +++ b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesSecretKeyStoreLoader.java @@ -38,177 +38,136 @@ * @author Jeoffrey HAEYAERT (jeoffrey.haeyaert at graviteesource.com) * @author GraviteeSource Team */ -public class KubernetesSecretKeyStoreLoader - extends AbstractKubernetesKeyStoreLoader { - - private static final List SUPPORTED_TYPES = Arrays.asList( - KeyStoreLoader.CERTIFICATE_FORMAT_JKS.toLowerCase(), - KeyStoreLoader.CERTIFICATE_FORMAT_PEM.toLowerCase(), - KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12.toLowerCase() - ); - - private static final Pattern SECRET_PATTERN = Pattern.compile( - "^(.*)/secrets/(.*)$" - ); - private static final Pattern SECRET_OPAQUE_PATTERN = Pattern.compile( - "^(.*/secrets/[^/]*)/.*$" - ); - protected static final String KUBERNETES_TLS_SECRET = "kubernetes.io/tls"; - protected static final String KUBERNETES_OPAQUE_SECRET = "Opaque"; - protected static final String KUBERNETES_TLS_CRT = "tls.crt"; - protected static final String KUBERNETES_TLS_KEY = "tls.key"; - - public KubernetesSecretKeyStoreLoader( - KeyStoreLoaderOptions options, - KubernetesClient kubernetesClient - ) { - super(options, kubernetesClient); - prepareLocations(); - } - - private void prepareLocations() { - this.options.getKubernetesLocations() - .forEach( - location -> { - final Matcher matcher = SECRET_OPAQUE_PATTERN.matcher(location); - if (matcher.matches()) { - this.resources.put( - matcher.group(1), - new KubernetesResource(location) - ); - } else { - this.resources.put(location, new KubernetesResource(location)); - } - } - ); - } - - public static boolean canHandle(KeyStoreLoaderOptions options) { - final List kubernetesLocations = options.getKubernetesLocations(); - - return ( - kubernetesLocations != null && - !kubernetesLocations.isEmpty() && - SUPPORTED_TYPES.contains(options.getKeyStoreType().toLowerCase()) && - kubernetesLocations - .stream() - .allMatch(location -> SECRET_PATTERN.matcher(location).matches()) +public class KubernetesSecretKeyStoreLoader extends AbstractKubernetesKeyStoreLoader { + + private static final List SUPPORTED_TYPES = Arrays.asList( + KeyStoreLoader.CERTIFICATE_FORMAT_JKS.toLowerCase(), + KeyStoreLoader.CERTIFICATE_FORMAT_PEM.toLowerCase(), + KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12.toLowerCase() ); - } - - @Override - protected Completable init() { - final List locationObs = resources - .keySet() - .stream() - .map( - location -> - kubernetesClient - .get(location, Secret.class) - .observeOn(Schedulers.computation()) - .flatMapCompletable(this::loadKeyStore) - ) - .collect(Collectors.toList()); - - return Completable - .merge(locationObs) - .observeOn(Schedulers.computation()) - .andThen(Completable.fromRunnable(this::refreshKeyStoreBundle)); - } - - @Override - protected Flowable watch() { - final List> toWatch = resources - .keySet() - .stream() - .map( - location -> - kubernetesClient - .watch(location, SecretEvent.class) - .observeOn(Schedulers.computation()) - .repeat() - .retryWhen( - errors -> errors.delay(RETRY_DELAY_MILLIS, TimeUnit.MILLISECONDS) - ) - ) - .collect(Collectors.toList()); - - return Flowable - .merge(toWatch) - .filter(event -> event.getType().equalsIgnoreCase("MODIFIED")) - .map(SecretEvent::getObject); - } - - @Override - protected Completable loadKeyStore(Secret secret) { - final Map data = secret.getData(); - final KeyStore keyStore; - - if (secret.getType().equals(KUBERNETES_TLS_SECRET)) { - keyStore = - KeyStoreUtils.initFromPem( - new String(Base64.getDecoder().decode(data.get(KUBERNETES_TLS_CRT))), - new String(Base64.getDecoder().decode(data.get(KUBERNETES_TLS_KEY))), - options.getKeyStorePassword(), - secret.getMetadata().getName() - ); - } else if (secret.getType().equals(KUBERNETES_OPAQUE_SECRET)) { - if (options.getKeyStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_PEM)) { - return Completable.error( - new IllegalArgumentException( - "Pem format is not supported with opaque secret, use kubernetes tls secret instead." - ) + + private static final Pattern SECRET_PATTERN = Pattern.compile("^(.*)/secrets/(.*)$"); + private static final Pattern SECRET_OPAQUE_PATTERN = Pattern.compile("^(.*/secrets/[^/]*)/.*$"); + protected static final String KUBERNETES_TLS_SECRET = "kubernetes.io/tls"; + protected static final String KUBERNETES_OPAQUE_SECRET = "Opaque"; + protected static final String KUBERNETES_TLS_CRT = "tls.crt"; + protected static final String KUBERNETES_TLS_KEY = "tls.key"; + + public KubernetesSecretKeyStoreLoader(KeyStoreLoaderOptions options, KubernetesClient kubernetesClient) { + super(options, kubernetesClient); + prepareLocations(); + } + + private void prepareLocations() { + this.options.getKubernetesLocations() + .forEach(location -> { + final Matcher matcher = SECRET_OPAQUE_PATTERN.matcher(location); + if (matcher.matches()) { + this.resources.put(matcher.group(1), new KubernetesResource(location)); + } else { + this.resources.put(location, new KubernetesResource(location)); + } + }); + } + + public static boolean canHandle(KeyStoreLoaderOptions options) { + final List kubernetesLocations = options.getKubernetesLocations(); + + return ( + kubernetesLocations != null && + !kubernetesLocations.isEmpty() && + SUPPORTED_TYPES.contains(options.getKeyStoreType().toLowerCase()) && + kubernetesLocations.stream().allMatch(location -> SECRET_PATTERN.matcher(location).matches()) ); - } else { - final Optional optResource = resources - .values() - .stream() - .filter( - r -> - r - .getNamespace() - .equalsIgnoreCase(secret.getMetadata().getNamespace()) && - ( - secret.getType().equalsIgnoreCase(KUBERNETES_OPAQUE_SECRET) || - r.getType().value().equalsIgnoreCase(secret.getType()) - ) && - r.getName().equalsIgnoreCase(secret.getMetadata().getName()) - ) - .findFirst(); - - if (optResource.isEmpty()) { - return Completable.error( - new IllegalArgumentException( - "Unable to load keystore: unknown secret." + } + + @Override + protected Completable init() { + final List locationObs = resources + .keySet() + .stream() + .map(location -> + kubernetesClient.get(location, Secret.class).observeOn(Schedulers.computation()).flatMapCompletable(this::loadKeyStore) ) - ); - } else if ( - optResource.get().getKey() == null || - optResource.get().getKey().isEmpty() - ) { - return Completable.error( - new IllegalArgumentException( - "You must specify a data when using opaque secret (ex: /my-namespace/secrets/my-secret/my-keystore)." + .collect(Collectors.toList()); + + return Completable + .merge(locationObs) + .observeOn(Schedulers.computation()) + .andThen(Completable.fromRunnable(this::refreshKeyStoreBundle)); + } + + @Override + protected Flowable watch() { + final List> toWatch = resources + .keySet() + .stream() + .map(location -> + kubernetesClient + .watch(location, SecretEvent.class) + .observeOn(Schedulers.computation()) + .repeat() + .retryWhen(errors -> errors.delay(RETRY_DELAY_MILLIS, TimeUnit.MILLISECONDS)) ) - ); - } + .collect(Collectors.toList()); - keyStore = - KeyStoreUtils.initFromContent( - options.getKeyStoreType(), - data.get(optResource.get().getKey()), - options.getKeyStorePassword() - ); - } - } else { - return Completable.error( - new IllegalArgumentException( - String.format("Invalid secret type [%s]", secret.getType()) - ) - ); + return Flowable.merge(toWatch).filter(event -> event.getType().equalsIgnoreCase("MODIFIED")).map(SecretEvent::getObject); } - keyStoresByLocation.put(secret.getMetadata().getUid(), keyStore); - return Completable.complete(); - } + @Override + protected Completable loadKeyStore(Secret secret) { + final Map data = secret.getData(); + final KeyStore keyStore; + + if (secret.getType().equals(KUBERNETES_TLS_SECRET)) { + keyStore = + KeyStoreUtils.initFromPem( + new String(Base64.getDecoder().decode(data.get(KUBERNETES_TLS_CRT))), + new String(Base64.getDecoder().decode(data.get(KUBERNETES_TLS_KEY))), + options.getKeyStorePassword(), + secret.getMetadata().getName() + ); + } else if (secret.getType().equals(KUBERNETES_OPAQUE_SECRET)) { + if (options.getKeyStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_PEM)) { + return Completable.error( + new IllegalArgumentException("Pem format is not supported with opaque secret, use kubernetes tls secret instead.") + ); + } else { + final Optional optResource = resources + .values() + .stream() + .filter(r -> + r.getNamespace().equalsIgnoreCase(secret.getMetadata().getNamespace()) && + ( + secret.getType().equalsIgnoreCase(KUBERNETES_OPAQUE_SECRET) || + r.getType().value().equalsIgnoreCase(secret.getType()) + ) && + r.getName().equalsIgnoreCase(secret.getMetadata().getName()) + ) + .findFirst(); + + if (optResource.isEmpty()) { + return Completable.error(new IllegalArgumentException("Unable to load keystore: unknown secret.")); + } else if (optResource.get().getKey() == null || optResource.get().getKey().isEmpty()) { + return Completable.error( + new IllegalArgumentException( + "You must specify a data when using opaque secret (ex: /my-namespace/secrets/my-secret/my-keystore)." + ) + ); + } + + keyStore = + KeyStoreUtils.initFromContent( + options.getKeyStoreType(), + data.get(optResource.get().getKey()), + options.getKeyStorePassword() + ); + } + } else { + return Completable.error(new IllegalArgumentException(String.format("Invalid secret type [%s]", secret.getType()))); + } + + keyStoresByLocation.put(secret.getMetadata().getUid(), keyStore); + return Completable.complete(); + } } diff --git a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/CloudScheme.java b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/CloudScheme.java index 1c5396079..99bf3ee2f 100644 --- a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/CloudScheme.java +++ b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/CloudScheme.java @@ -21,15 +21,15 @@ * @since 3.9.11 */ public enum CloudScheme { - KUBERNETES("kubernetes://"); + KUBERNETES("kubernetes://"); - private final String scheme; + private final String scheme; - CloudScheme(String scheme) { - this.scheme = scheme; - } + CloudScheme(String scheme) { + this.scheme = scheme; + } - public String value() { - return scheme; - } + public String value() { + return scheme; + } } diff --git a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/KubernetesPropertyResolver.java b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/KubernetesPropertyResolver.java index 181663d09..1635a780d 100644 --- a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/KubernetesPropertyResolver.java +++ b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/KubernetesPropertyResolver.java @@ -34,150 +34,123 @@ */ public class KubernetesPropertyResolver implements PropertyResolver { - private static final Logger LOGGER = LoggerFactory.getLogger( - KubernetesPropertyResolver.class - ); + private static final Logger LOGGER = LoggerFactory.getLogger(KubernetesPropertyResolver.class); - @Autowired - private KubernetesClient kubernetesClient; + @Autowired + private KubernetesClient kubernetesClient; - @Override - public boolean supports(String currentValue) { - Assert.notNull(currentValue, "Current value can not be null"); + @Override + public boolean supports(String currentValue) { + Assert.notNull(currentValue, "Current value can not be null"); - return currentValue.startsWith(CloudScheme.KUBERNETES.value()); - } + return currentValue.startsWith(CloudScheme.KUBERNETES.value()); + } + + @Override + public Maybe resolve(String location) { + Assert.notNull(location, "Location can not be null"); + + String[] properties = parsePropertyName(location); // kubernetes://default/configmaps/gravitee-config/management.db.name + if (properties == null) { + return Maybe.empty(); + } - @Override - public Maybe resolve(String location) { - Assert.notNull(location, "Location can not be null"); + LOGGER.debug("Resolve location [{}]", location); - String[] properties = parsePropertyName(location); // kubernetes://default/configmaps/gravitee-config/management.db.name - if (properties == null) { - return Maybe.empty(); + if ("secrets".equals(properties[1])) { // type + return resolvePropertyFromSecret(generateLocation(properties)) + .map(encodeData -> new String(Base64.getDecoder().decode(encodeData))); + } else if ("configmaps".equals(properties[1])) { + return resolvePropertyFromConfigMap(generateLocation(properties)).map(String::strip); + } else { + return Maybe.error(new RuntimeException("Property type " + properties[1] + " is not supported")); + } } - LOGGER.debug("Resolve location [{}]", location); - - if ("secrets".equals(properties[1])) { // type - return resolvePropertyFromSecret(generateLocation(properties)) - .map(encodeData -> new String(Base64.getDecoder().decode(encodeData))); - } else if ("configmaps".equals(properties[1])) { - return resolvePropertyFromConfigMap(generateLocation(properties)) - .map(String::strip); - } else { - return Maybe.error( - new RuntimeException( - "Property type " + properties[1] + " is not supported" - ) - ); + @Override + public Flowable watch(String location) { + Assert.notNull(location, "Location can not be null"); + + String[] properties = parsePropertyName(location); // kubernetes://default/configmaps/gravitee-config/my_key + if (properties == null) { + return Flowable.empty(); + } + + LOGGER.debug("Start watching location [{}]", location); + + if ("secrets".equals(properties[1])) { // type + return kubernetesClient + .watch(generateLocation(properties), SecretEvent.class) + .filter(event -> + event.getType().equals(KubernetesEventType.MODIFIED.name()) || event.getType().equals(KubernetesEventType.ADDED.name()) + ) + .map(secretEvent -> { + String encodedData = secretEvent.getObject().getData().get(properties[3]); + return new String(Base64.getDecoder().decode(encodedData)); + }); + } else if ("configmaps".equals(properties[1])) { + return kubernetesClient + .watch(generateLocation(properties), ConfigMapEvent.class) + .filter(event -> + event.getType().equals(KubernetesEventType.MODIFIED.name()) || event.getType().equals(KubernetesEventType.ADDED.name()) + ) + .map(configMapEvent -> configMapEvent.getObject().getData().get(properties[3])); + } else { + return Flowable.error(new RuntimeException("Property type " + properties[1] + " is not supported")); + } } - } - @Override - public Flowable watch(String location) { - Assert.notNull(location, "Location can not be null"); + private String[] parsePropertyName(String currentValue) { + if (!supports(currentValue)) { + LOGGER.error("Does not support scheme {}", currentValue); + return null; + } - String[] properties = parsePropertyName(location); // kubernetes://default/configmaps/gravitee-config/my_key - if (properties == null) { - return Flowable.empty(); + String[] properties = currentValue.substring(13).split("/"); // eliminate initial kubernetes:// + + if (properties.length != 4) { + LOGGER.error( + "Wrong property value. A correct format looks like this \"kubernetes://{namespace}/configmaps/{configmap-name}/key\"" + ); + return null; + } + + return properties; } - LOGGER.debug("Start watching location [{}]", location); - - if ("secrets".equals(properties[1])) { // type - return kubernetesClient - .watch(generateLocation(properties), SecretEvent.class) - .filter( - event -> - event.getType().equals(KubernetesEventType.MODIFIED.name()) || - event.getType().equals(KubernetesEventType.ADDED.name()) - ) - .map( - secretEvent -> { - String encodedData = secretEvent - .getObject() - .getData() - .get(properties[3]); - return new String(Base64.getDecoder().decode(encodedData)); - } + private String generateLocation(String[] properties) { + return String.format( + "/%s/%s/%s/%s", + properties[0], // namespace + properties[1], // resource type + properties[2], // name + properties[3] // key ); - } else if ("configmaps".equals(properties[1])) { - return kubernetesClient - .watch(generateLocation(properties), ConfigMapEvent.class) - .filter( - event -> - event.getType().equals(KubernetesEventType.MODIFIED.name()) || - event.getType().equals(KubernetesEventType.ADDED.name()) - ) - .map( - configMapEvent -> - configMapEvent.getObject().getData().get(properties[3]) - ); - } else { - return Flowable.error( - new RuntimeException( - "Property type " + properties[1] + " is not supported" - ) - ); } - } - private String[] parsePropertyName(String currentValue) { - if (!supports(currentValue)) { - LOGGER.error("Does not support scheme {}", currentValue); - return null; + private Maybe resolvePropertyFromConfigMap(String location) { + return kubernetesClient + .get(location, String.class) + .flatMap(data -> { + if (data != null) { + return Maybe.just(data); + } else { + LOGGER.warn("Key not found in this location [{}]", location); + return Maybe.empty(); + } + }); } - String[] properties = currentValue.substring(13).split("/"); // eliminate initial kubernetes:// - - if (properties.length != 4) { - LOGGER.error( - "Wrong property value. A correct format looks like this \"kubernetes://{namespace}/configmaps/{configmap-name}/key\"" - ); - return null; + private Maybe resolvePropertyFromSecret(String location) { + return kubernetesClient + .get(location, String.class) + .flatMap(data -> { + if (data != null) { + return Maybe.just(data); + } else { + LOGGER.debug("Key not found in this location [{}]", location); + return Maybe.empty(); + } + }); } - - return properties; - } - - private String generateLocation(String[] properties) { - return String.format( - "/%s/%s/%s/%s", - properties[0], // namespace - properties[1], // resource type - properties[2], // name - properties[3] // key - ); - } - - private Maybe resolvePropertyFromConfigMap(String location) { - return kubernetesClient - .get(location, String.class) - .flatMap( - data -> { - if (data != null) { - return Maybe.just(data); - } else { - LOGGER.warn("Key not found in this location [{}]", location); - return Maybe.empty(); - } - } - ); - } - - private Maybe resolvePropertyFromSecret(String location) { - return kubernetesClient - .get(location, String.class) - .flatMap( - data -> { - if (data != null) { - return Maybe.just(data); - } else { - LOGGER.debug("Key not found in this location [{}]", location); - return Maybe.empty(); - } - } - ); - } } diff --git a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/PropertyResolver.java b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/PropertyResolver.java index 6b39869a5..8bd7da37b 100644 --- a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/PropertyResolver.java +++ b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/PropertyResolver.java @@ -24,23 +24,23 @@ * @since 3.9.11 */ public interface PropertyResolver { - /** - * Check if this property can be resolved - * @param currentValue - * @return - */ - boolean supports(String currentValue); + /** + * Check if this property can be resolved + * @param currentValue + * @return + */ + boolean supports(String currentValue); - /** - * @param location - * @return The values of the given property if exist - */ - Maybe resolve(String location); + /** + * @param location + * @return The values of the given property if exist + */ + Maybe resolve(String location); - /** - * Watch for any changes in the property and emmit the new values - * @param location - * @return last value - */ - Flowable watch(String location); + /** + * Watch for any changes in the property and emmit the new values + * @param location + * @return last value + */ + Flowable watch(String location); } diff --git a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/PropertyResolverFactoriesLoader.java b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/PropertyResolverFactoriesLoader.java index a13a25661..2a2436bf6 100644 --- a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/PropertyResolverFactoriesLoader.java +++ b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/propertyresolver/PropertyResolverFactoriesLoader.java @@ -24,15 +24,14 @@ * @author GraviteeSource Team * @since 3.9.11 */ -public class PropertyResolverFactoriesLoader - extends SpringFactoriesLoader { +public class PropertyResolverFactoriesLoader extends SpringFactoriesLoader { - @Override - protected Class getObjectType() { - return PropertyResolver.class; - } + @Override + protected Class getObjectType() { + return PropertyResolver.class; + } - public List getPropertyResolvers() { - return new ArrayList<>(getFactoriesInstances()); - } + public List getPropertyResolvers() { + return new ArrayList<>(getFactoriesInstances()); + } } diff --git a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/spring/NodeKubernetesConfiguration.java b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/spring/NodeKubernetesConfiguration.java index f4eed966c..8a9754ef4 100644 --- a/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/spring/NodeKubernetesConfiguration.java +++ b/gravitee-node-kubernetes/src/main/java/io/gravitee/node/kubernetes/spring/NodeKubernetesConfiguration.java @@ -28,15 +28,13 @@ @Configuration public class NodeKubernetesConfiguration { - @Bean - public KubernetesKeyStoreLoaderFactory kubernetesKeyStoreLoaderFactory( - KubernetesClient kubernetesClient, - KeyStoreLoaderManager keyStoreLoaderManager - ) { - final KubernetesKeyStoreLoaderFactory kubernetesKeyStoreLoaderFactory = new KubernetesKeyStoreLoaderFactory( - kubernetesClient - ); - keyStoreLoaderManager.registerFactory(kubernetesKeyStoreLoaderFactory); - return kubernetesKeyStoreLoaderFactory; - } + @Bean + public KubernetesKeyStoreLoaderFactory kubernetesKeyStoreLoaderFactory( + KubernetesClient kubernetesClient, + KeyStoreLoaderManager keyStoreLoaderManager + ) { + final KubernetesKeyStoreLoaderFactory kubernetesKeyStoreLoaderFactory = new KubernetesKeyStoreLoaderFactory(kubernetesClient); + keyStoreLoaderManager.registerFactory(kubernetesKeyStoreLoaderFactory); + return kubernetesKeyStoreLoaderFactory; + } } diff --git a/gravitee-node-kubernetes/src/test/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesConfigMapKeyStoreLoaderTest.java b/gravitee-node-kubernetes/src/test/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesConfigMapKeyStoreLoaderTest.java index eff4b5c5a..960da47e0 100644 --- a/gravitee-node-kubernetes/src/test/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesConfigMapKeyStoreLoaderTest.java +++ b/gravitee-node-kubernetes/src/test/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesConfigMapKeyStoreLoaderTest.java @@ -46,103 +46,88 @@ @RunWith(MockitoJUnitRunner.class) public class KubernetesConfigMapKeyStoreLoaderTest { - @Mock - private KubernetesClient kubernetesClient; - - private KubernetesConfigMapKeyStoreLoader cut; - - @Test - public void shouldLoadConfigMap() throws IOException, KeyStoreException { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKubernetesLocations( - Collections.singletonList("/gio/configmaps/my-configmap/keystore") - ) - .withKeyStorePassword("secret") - .withWatch(false) - .build(); - - cut = new KubernetesConfigMapKeyStoreLoader(options, kubernetesClient); - - final ConfigMap configMap = new ConfigMap(); - - final HashMap data = new HashMap<>(); - data.put("keystore", readContent("localhost.p12")); - configMap.setBinaryData(data); - - final ObjectMeta metadata = new ObjectMeta(); - metadata.setName("my-configmap"); - metadata.setUid("/namespaces/gio/configmaps/my-configmap"); - metadata.setNamespace("gio"); - configMap.setMetadata(metadata); - - Mockito - .when( - kubernetesClient.get("/gio/configmaps/my-configmap", ConfigMap.class) - ) - .thenReturn(Maybe.just(configMap)); - - AtomicReference bundleRef = new AtomicReference<>(null); - cut.addListener(bundleRef::set); - cut.start(); - - final KeyStoreBundle keyStoreBundle = bundleRef.get(); - - assertNotNull(keyStoreBundle); - assertEquals(1, keyStoreBundle.getKeyStore().size()); - } - - @Test - public void shouldLoadConfigMapFromData() - throws IOException, KeyStoreException { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKubernetesLocations( - Collections.singletonList("/gio/configmaps/my-configmap/keystore") - ) - .withKeyStorePassword("secret") - .withWatch(false) - .build(); - - cut = new KubernetesConfigMapKeyStoreLoader(options, kubernetesClient); - - final ConfigMap configMap = new ConfigMap(); - - final HashMap data = new HashMap<>(); - data.put("keystore", readContent("localhost.p12")); - configMap.setData(data); - - final ObjectMeta metadata = new ObjectMeta(); - metadata.setName("my-configmap"); - metadata.setUid("/namespaces/gio/configmaps/my-configmap"); - metadata.setNamespace("gio"); - configMap.setMetadata(metadata); - - Mockito - .when( - kubernetesClient.get("/gio/configmaps/my-configmap", ConfigMap.class) - ) - .thenReturn(Maybe.just(configMap)); - - AtomicReference bundleRef = new AtomicReference<>(null); - cut.addListener(bundleRef::set); - cut.start(); - - final KeyStoreBundle keyStoreBundle = bundleRef.get(); - - assertNotNull(keyStoreBundle); - assertEquals(1, keyStoreBundle.getKeyStore().size()); - } - - private String readContent(String resource) throws IOException { - return java.util.Base64 - .getEncoder() - .encodeToString(Files.readAllBytes(new File(getPath(resource)).toPath())); - } - - private String getPath(String resource) { - return this.getClass().getResource("/keystores/" + resource).getPath(); - } + @Mock + private KubernetesClient kubernetesClient; + + private KubernetesConfigMapKeyStoreLoader cut; + + @Test + public void shouldLoadConfigMap() throws IOException, KeyStoreException { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKubernetesLocations(Collections.singletonList("/gio/configmaps/my-configmap/keystore")) + .withKeyStorePassword("secret") + .withWatch(false) + .build(); + + cut = new KubernetesConfigMapKeyStoreLoader(options, kubernetesClient); + + final ConfigMap configMap = new ConfigMap(); + + final HashMap data = new HashMap<>(); + data.put("keystore", readContent("localhost.p12")); + configMap.setBinaryData(data); + + final ObjectMeta metadata = new ObjectMeta(); + metadata.setName("my-configmap"); + metadata.setUid("/namespaces/gio/configmaps/my-configmap"); + metadata.setNamespace("gio"); + configMap.setMetadata(metadata); + + Mockito.when(kubernetesClient.get("/gio/configmaps/my-configmap", ConfigMap.class)).thenReturn(Maybe.just(configMap)); + + AtomicReference bundleRef = new AtomicReference<>(null); + cut.addListener(bundleRef::set); + cut.start(); + + final KeyStoreBundle keyStoreBundle = bundleRef.get(); + + assertNotNull(keyStoreBundle); + assertEquals(1, keyStoreBundle.getKeyStore().size()); + } + + @Test + public void shouldLoadConfigMapFromData() throws IOException, KeyStoreException { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKubernetesLocations(Collections.singletonList("/gio/configmaps/my-configmap/keystore")) + .withKeyStorePassword("secret") + .withWatch(false) + .build(); + + cut = new KubernetesConfigMapKeyStoreLoader(options, kubernetesClient); + + final ConfigMap configMap = new ConfigMap(); + + final HashMap data = new HashMap<>(); + data.put("keystore", readContent("localhost.p12")); + configMap.setData(data); + + final ObjectMeta metadata = new ObjectMeta(); + metadata.setName("my-configmap"); + metadata.setUid("/namespaces/gio/configmaps/my-configmap"); + metadata.setNamespace("gio"); + configMap.setMetadata(metadata); + + Mockito.when(kubernetesClient.get("/gio/configmaps/my-configmap", ConfigMap.class)).thenReturn(Maybe.just(configMap)); + + AtomicReference bundleRef = new AtomicReference<>(null); + cut.addListener(bundleRef::set); + cut.start(); + + final KeyStoreBundle keyStoreBundle = bundleRef.get(); + + assertNotNull(keyStoreBundle); + assertEquals(1, keyStoreBundle.getKeyStore().size()); + } + + private String readContent(String resource) throws IOException { + return java.util.Base64.getEncoder().encodeToString(Files.readAllBytes(new File(getPath(resource)).toPath())); + } + + private String getPath(String resource) { + return this.getClass().getResource("/keystores/" + resource).getPath(); + } } diff --git a/gravitee-node-kubernetes/src/test/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesKeyStoreLoaderFactoryTest.java b/gravitee-node-kubernetes/src/test/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesKeyStoreLoaderFactoryTest.java index e52141ebc..6618d2624 100644 --- a/gravitee-node-kubernetes/src/test/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesKeyStoreLoaderFactoryTest.java +++ b/gravitee-node-kubernetes/src/test/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesKeyStoreLoaderFactoryTest.java @@ -34,119 +34,101 @@ @RunWith(MockitoJUnitRunner.class) public class KubernetesKeyStoreLoaderFactoryTest { - @Mock - private KubernetesClient kubernetesClient; - - private KubernetesKeyStoreLoaderFactory cut; - - @Before - public void before() { - cut = new KubernetesKeyStoreLoaderFactory(kubernetesClient); - } - - @Test - public void shouldHandleOptionsWithConfigMap() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKubernetesLocations( - Collections.singletonList("/gio/configmaps/my-configmap/keystore") - ) - .build(); - - assertTrue(cut.canHandle(options)); - } - - @Test - public void shouldNotHandleOptionsWithConfigMapAndPEMFormat() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) - .withKubernetesLocations( - Collections.singletonList("/gio/configmaps/my-configmap/keystore") - ) - .build(); - - assertFalse(cut.canHandle(options)); - } - - @Test - public void shouldHandleOptionsWithTlsSecret() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) - .withKubernetesLocations( - Collections.singletonList("/gio/secrets/my-secret") - ) - .build(); - - assertTrue(cut.canHandle(options)); - } - - @Test - public void shouldHandleOptionsWithOpaqueSecret() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKubernetesLocations( - Collections.singletonList("/gio/secrets/my-secret/keystore") - ) - .build(); - - assertTrue(cut.canHandle(options)); - } - - @Test - public void shouldCreateConfigMapLoader() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKubernetesLocations( - Collections.singletonList("/gio/configmaps/my-configmap/keystore") - ) - .build(); - - assertEquals( - KubernetesConfigMapKeyStoreLoader.class, - cut.create(options).getClass() - ); - } - - @Test - public void shouldCreateSecretLoader() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) - .withKubernetesLocations( - Collections.singletonList("/gio/secrets/my-secret") - ) - .build(); - - assertEquals( - KubernetesSecretKeyStoreLoader.class, - cut.create(options).getClass() - ); - } - - @Test - public void shouldNotHandleOptionsWithoutKubernetesLocations() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKubernetesLocations(Collections.emptyList()) - .build(); - - assertFalse(cut.canHandle(options)); - } - - @Test - public void shouldNotHandleOptionsWithoutUnsupportedLocation() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKubernetesLocations(Collections.singletonList("/gio/unknown")) - .build(); - - assertFalse(cut.canHandle(options)); - } + @Mock + private KubernetesClient kubernetesClient; + + private KubernetesKeyStoreLoaderFactory cut; + + @Before + public void before() { + cut = new KubernetesKeyStoreLoaderFactory(kubernetesClient); + } + + @Test + public void shouldHandleOptionsWithConfigMap() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKubernetesLocations(Collections.singletonList("/gio/configmaps/my-configmap/keystore")) + .build(); + + assertTrue(cut.canHandle(options)); + } + + @Test + public void shouldNotHandleOptionsWithConfigMapAndPEMFormat() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) + .withKubernetesLocations(Collections.singletonList("/gio/configmaps/my-configmap/keystore")) + .build(); + + assertFalse(cut.canHandle(options)); + } + + @Test + public void shouldHandleOptionsWithTlsSecret() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) + .withKubernetesLocations(Collections.singletonList("/gio/secrets/my-secret")) + .build(); + + assertTrue(cut.canHandle(options)); + } + + @Test + public void shouldHandleOptionsWithOpaqueSecret() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKubernetesLocations(Collections.singletonList("/gio/secrets/my-secret/keystore")) + .build(); + + assertTrue(cut.canHandle(options)); + } + + @Test + public void shouldCreateConfigMapLoader() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKubernetesLocations(Collections.singletonList("/gio/configmaps/my-configmap/keystore")) + .build(); + + assertEquals(KubernetesConfigMapKeyStoreLoader.class, cut.create(options).getClass()); + } + + @Test + public void shouldCreateSecretLoader() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) + .withKubernetesLocations(Collections.singletonList("/gio/secrets/my-secret")) + .build(); + + assertEquals(KubernetesSecretKeyStoreLoader.class, cut.create(options).getClass()); + } + + @Test + public void shouldNotHandleOptionsWithoutKubernetesLocations() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKubernetesLocations(Collections.emptyList()) + .build(); + + assertFalse(cut.canHandle(options)); + } + + @Test + public void shouldNotHandleOptionsWithoutUnsupportedLocation() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKubernetesLocations(Collections.singletonList("/gio/unknown")) + .build(); + + assertFalse(cut.canHandle(options)); + } } diff --git a/gravitee-node-kubernetes/src/test/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesSecretKeyStoreLoaderTest.java b/gravitee-node-kubernetes/src/test/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesSecretKeyStoreLoaderTest.java index 60ae1e15c..1df01a97a 100644 --- a/gravitee-node-kubernetes/src/test/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesSecretKeyStoreLoaderTest.java +++ b/gravitee-node-kubernetes/src/test/java/io/gravitee/node/kubernetes/keystoreloader/KubernetesSecretKeyStoreLoaderTest.java @@ -52,267 +52,219 @@ @RunWith(MockitoJUnitRunner.class) public class KubernetesSecretKeyStoreLoaderTest { - @Mock - private KubernetesClient kubernetesClient; - - private KubernetesSecretKeyStoreLoader cut; - - @Test - public void shouldLoadTlsSecret() throws IOException, KeyStoreException { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) - .withKubernetesLocations( - Collections.singletonList("/gio/secrets/my-tls-secret") - ) - .withWatch(false) - .build(); - - cut = new KubernetesSecretKeyStoreLoader(options, kubernetesClient); - - final Secret secret = new Secret(); - secret.setType(KUBERNETES_TLS_SECRET); - - final HashMap data = new HashMap<>(); - data.put(KUBERNETES_TLS_CRT, readContent("localhost.cer")); - data.put(KUBERNETES_TLS_KEY, readContent("localhost.key")); - secret.setData(data); - - final ObjectMeta metadata = new ObjectMeta(); - metadata.setName("my-tls-secret"); - metadata.setUid("/namespaces/gio/secrets/my-tls-secret"); - secret.setMetadata(metadata); - - Mockito - .when( - kubernetesClient.get( - options.getKubernetesLocations().get(0), - Secret.class - ) - ) - .thenReturn(Maybe.just(secret)); - - AtomicReference bundleRef = new AtomicReference<>(null); - cut.addListener(bundleRef::set); - cut.start(); - - final KeyStoreBundle keyStoreBundle = bundleRef.get(); - - assertNotNull(keyStoreBundle); - assertEquals(1, keyStoreBundle.getKeyStore().size()); - } - - @Test - public void shouldLoadOpaqueSecret() throws IOException, KeyStoreException { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKubernetesLocations( - Collections.singletonList("/gio/secrets/my-tls-secret/keystore") - ) - .withKeyStorePassword("secret") - .withWatch(false) - .build(); - - cut = new KubernetesSecretKeyStoreLoader(options, kubernetesClient); - - final Secret secret = new Secret(); - secret.setType(KUBERNETES_OPAQUE_SECRET); - - final HashMap data = new HashMap<>(); - data.put("keystore", readContent("localhost.p12")); - secret.setData(data); - - final ObjectMeta metadata = new ObjectMeta(); - metadata.setName("my-tls-secret"); - metadata.setNamespace("gio"); - metadata.setUid("/namespaces/gio/secrets/my-tls-secret"); - secret.setMetadata(metadata); - - Mockito - .when(kubernetesClient.get("/gio/secrets/my-tls-secret", Secret.class)) - .thenReturn(Maybe.just(secret)); - - AtomicReference bundleRef = new AtomicReference<>(null); - cut.addListener(bundleRef::set); - cut.start(); - - final KeyStoreBundle keyStoreBundle = bundleRef.get(); - - assertNotNull(keyStoreBundle); - assertEquals(1, keyStoreBundle.getKeyStore().size()); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldNotLoadOpaqueSecretPEM() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) - .withKubernetesLocations( - Collections.singletonList("/gio/secrets/my-tls-secret/pem") - ) - .withKeyStorePassword("secret") - .withWatch(false) - .build(); - - cut = new KubernetesSecretKeyStoreLoader(options, kubernetesClient); - - final Secret secret = new Secret(); - secret.setType(KUBERNETES_OPAQUE_SECRET); - - Mockito - .when(kubernetesClient.get("/gio/secrets/my-tls-secret", Secret.class)) - .thenReturn(Maybe.just(secret)); - - cut.start(); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldNotLoadOpaqueSecretWithNoDataKey() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKubernetesLocations( - Collections.singletonList("/gio/secrets/my-tls-secret") - ) - .withKeyStorePassword("secret") - .withWatch(false) - .build(); - - cut = new KubernetesSecretKeyStoreLoader(options, kubernetesClient); - - final Secret secret = new Secret(); - secret.setType(KUBERNETES_OPAQUE_SECRET); - - final ObjectMeta metadata = new ObjectMeta(); - metadata.setName("my-tls-secret"); - metadata.setUid("/namespaces/gio/secrets/my-tls-secret"); - secret.setMetadata(metadata); - - Mockito - .when(kubernetesClient.get("/gio/secrets/my-tls-secret", Secret.class)) - .thenReturn(Maybe.just(secret)); - - cut.start(); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldNotLoadWithInvalidSecretType() { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) - .withKubernetesLocations( - Collections.singletonList("/gio/secrets/my-tls-secret/invalid-keystore") - ) - .withKeyStorePassword("secret") - .withWatch(false) - .build(); - - cut = new KubernetesSecretKeyStoreLoader(options, kubernetesClient); - - final Secret secret = new Secret(); - secret.setType("Invalid"); - - Mockito - .when(kubernetesClient.get("/gio/secrets/my-tls-secret", Secret.class)) - .thenReturn(Maybe.just(secret)); - - cut.start(); - } - - @Test - public void shouldWatchSecret() - throws IOException, KeyStoreException, InterruptedException { - final KeyStoreLoaderOptions options = KeyStoreLoaderOptions - .builder() - .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) - .withKubernetesLocations( - Collections.singletonList("/gio/secrets/my-tls-secret") - ) - .withWatch(true) - .build(); - - cut = new KubernetesSecretKeyStoreLoader(options, kubernetesClient); - - final Secret secret = new Secret(); - secret.setType(KUBERNETES_TLS_SECRET); - - final HashMap data = new HashMap<>(); - data.put(KUBERNETES_TLS_CRT, readContent("localhost.cer")); - data.put(KUBERNETES_TLS_KEY, readContent("localhost.key")); - secret.setData(data); - - final ObjectMeta metadata = new ObjectMeta(); - metadata.setName("my-tls-secret"); - metadata.setUid("/namespaces/gio/secrets/my-tls-secret"); - secret.setMetadata(metadata); - - final Secret modifiedSecret = new Secret(); - modifiedSecret.setType(KUBERNETES_TLS_SECRET); - - final HashMap modifiedData = new HashMap<>(); - modifiedData.put(KUBERNETES_TLS_CRT, readContent("localhost2.cer")); - modifiedData.put(KUBERNETES_TLS_KEY, readContent("localhost2.key")); - modifiedSecret.setData(modifiedData); - - final ObjectMeta modifiedMetadata = new ObjectMeta(); - modifiedMetadata.setName("my-tls-secret"); - modifiedMetadata.setUid("/namespaces/gio/secrets/my-tls-secret"); - modifiedSecret.setMetadata(modifiedMetadata); - - final SecretEvent modifiedSecretEvent = new SecretEvent(); - modifiedSecretEvent.setType("MODIFIED"); - modifiedSecretEvent.setObject(modifiedSecret); - - Mockito - .when( - kubernetesClient.get( - options.getKubernetesLocations().get(0), - Secret.class - ) - ) - .thenReturn(Maybe.just(secret)); - Mockito - .when( - kubernetesClient.watch( - options.getKubernetesLocations().get(0), - SecretEvent.class - ) - ) - .thenReturn(Flowable.just(modifiedSecretEvent)); - - CountDownLatch latch = new CountDownLatch(2); - AtomicReference bundleRef = new AtomicReference<>(null); - cut.addListener( - bundle -> { - bundleRef.set(bundle); - latch.countDown(); - } - ); - - cut.start(); - - // Wait for the event to be processed. - latch.await(5000, TimeUnit.MILLISECONDS); - final KeyStoreBundle keyStoreBundle = bundleRef.get(); - - assertNotNull(keyStoreBundle); - assertEquals(1, keyStoreBundle.getKeyStore().size()); - // Make sure the kestore has been reloaded by checking the CN. - assertTrue( - KeyStoreUtils - .getCommonNamesByAlias(keyStoreBundle.getKeyStore()) - .containsKey("localhost2") - ); - } - - private String readContent(String resource) throws IOException { - return java.util.Base64 - .getEncoder() - .encodeToString(Files.readAllBytes(new File(getPath(resource)).toPath())); - } - - private String getPath(String resource) { - return this.getClass().getResource("/keystores/" + resource).getPath(); - } + @Mock + private KubernetesClient kubernetesClient; + + private KubernetesSecretKeyStoreLoader cut; + + @Test + public void shouldLoadTlsSecret() throws IOException, KeyStoreException { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) + .withKubernetesLocations(Collections.singletonList("/gio/secrets/my-tls-secret")) + .withWatch(false) + .build(); + + cut = new KubernetesSecretKeyStoreLoader(options, kubernetesClient); + + final Secret secret = new Secret(); + secret.setType(KUBERNETES_TLS_SECRET); + + final HashMap data = new HashMap<>(); + data.put(KUBERNETES_TLS_CRT, readContent("localhost.cer")); + data.put(KUBERNETES_TLS_KEY, readContent("localhost.key")); + secret.setData(data); + + final ObjectMeta metadata = new ObjectMeta(); + metadata.setName("my-tls-secret"); + metadata.setUid("/namespaces/gio/secrets/my-tls-secret"); + secret.setMetadata(metadata); + + Mockito.when(kubernetesClient.get(options.getKubernetesLocations().get(0), Secret.class)).thenReturn(Maybe.just(secret)); + + AtomicReference bundleRef = new AtomicReference<>(null); + cut.addListener(bundleRef::set); + cut.start(); + + final KeyStoreBundle keyStoreBundle = bundleRef.get(); + + assertNotNull(keyStoreBundle); + assertEquals(1, keyStoreBundle.getKeyStore().size()); + } + + @Test + public void shouldLoadOpaqueSecret() throws IOException, KeyStoreException { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKubernetesLocations(Collections.singletonList("/gio/secrets/my-tls-secret/keystore")) + .withKeyStorePassword("secret") + .withWatch(false) + .build(); + + cut = new KubernetesSecretKeyStoreLoader(options, kubernetesClient); + + final Secret secret = new Secret(); + secret.setType(KUBERNETES_OPAQUE_SECRET); + + final HashMap data = new HashMap<>(); + data.put("keystore", readContent("localhost.p12")); + secret.setData(data); + + final ObjectMeta metadata = new ObjectMeta(); + metadata.setName("my-tls-secret"); + metadata.setNamespace("gio"); + metadata.setUid("/namespaces/gio/secrets/my-tls-secret"); + secret.setMetadata(metadata); + + Mockito.when(kubernetesClient.get("/gio/secrets/my-tls-secret", Secret.class)).thenReturn(Maybe.just(secret)); + + AtomicReference bundleRef = new AtomicReference<>(null); + cut.addListener(bundleRef::set); + cut.start(); + + final KeyStoreBundle keyStoreBundle = bundleRef.get(); + + assertNotNull(keyStoreBundle); + assertEquals(1, keyStoreBundle.getKeyStore().size()); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldNotLoadOpaqueSecretPEM() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) + .withKubernetesLocations(Collections.singletonList("/gio/secrets/my-tls-secret/pem")) + .withKeyStorePassword("secret") + .withWatch(false) + .build(); + + cut = new KubernetesSecretKeyStoreLoader(options, kubernetesClient); + + final Secret secret = new Secret(); + secret.setType(KUBERNETES_OPAQUE_SECRET); + + Mockito.when(kubernetesClient.get("/gio/secrets/my-tls-secret", Secret.class)).thenReturn(Maybe.just(secret)); + + cut.start(); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldNotLoadOpaqueSecretWithNoDataKey() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKubernetesLocations(Collections.singletonList("/gio/secrets/my-tls-secret")) + .withKeyStorePassword("secret") + .withWatch(false) + .build(); + + cut = new KubernetesSecretKeyStoreLoader(options, kubernetesClient); + + final Secret secret = new Secret(); + secret.setType(KUBERNETES_OPAQUE_SECRET); + + final ObjectMeta metadata = new ObjectMeta(); + metadata.setName("my-tls-secret"); + metadata.setUid("/namespaces/gio/secrets/my-tls-secret"); + secret.setMetadata(metadata); + + Mockito.when(kubernetesClient.get("/gio/secrets/my-tls-secret", Secret.class)).thenReturn(Maybe.just(secret)); + + cut.start(); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldNotLoadWithInvalidSecretType() { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PKCS12) + .withKubernetesLocations(Collections.singletonList("/gio/secrets/my-tls-secret/invalid-keystore")) + .withKeyStorePassword("secret") + .withWatch(false) + .build(); + + cut = new KubernetesSecretKeyStoreLoader(options, kubernetesClient); + + final Secret secret = new Secret(); + secret.setType("Invalid"); + + Mockito.when(kubernetesClient.get("/gio/secrets/my-tls-secret", Secret.class)).thenReturn(Maybe.just(secret)); + + cut.start(); + } + + @Test + public void shouldWatchSecret() throws IOException, KeyStoreException, InterruptedException { + final KeyStoreLoaderOptions options = KeyStoreLoaderOptions + .builder() + .withKeyStoreType(KeyStoreLoader.CERTIFICATE_FORMAT_PEM) + .withKubernetesLocations(Collections.singletonList("/gio/secrets/my-tls-secret")) + .withWatch(true) + .build(); + + cut = new KubernetesSecretKeyStoreLoader(options, kubernetesClient); + + final Secret secret = new Secret(); + secret.setType(KUBERNETES_TLS_SECRET); + + final HashMap data = new HashMap<>(); + data.put(KUBERNETES_TLS_CRT, readContent("localhost.cer")); + data.put(KUBERNETES_TLS_KEY, readContent("localhost.key")); + secret.setData(data); + + final ObjectMeta metadata = new ObjectMeta(); + metadata.setName("my-tls-secret"); + metadata.setUid("/namespaces/gio/secrets/my-tls-secret"); + secret.setMetadata(metadata); + + final Secret modifiedSecret = new Secret(); + modifiedSecret.setType(KUBERNETES_TLS_SECRET); + + final HashMap modifiedData = new HashMap<>(); + modifiedData.put(KUBERNETES_TLS_CRT, readContent("localhost2.cer")); + modifiedData.put(KUBERNETES_TLS_KEY, readContent("localhost2.key")); + modifiedSecret.setData(modifiedData); + + final ObjectMeta modifiedMetadata = new ObjectMeta(); + modifiedMetadata.setName("my-tls-secret"); + modifiedMetadata.setUid("/namespaces/gio/secrets/my-tls-secret"); + modifiedSecret.setMetadata(modifiedMetadata); + + final SecretEvent modifiedSecretEvent = new SecretEvent(); + modifiedSecretEvent.setType("MODIFIED"); + modifiedSecretEvent.setObject(modifiedSecret); + + Mockito.when(kubernetesClient.get(options.getKubernetesLocations().get(0), Secret.class)).thenReturn(Maybe.just(secret)); + Mockito + .when(kubernetesClient.watch(options.getKubernetesLocations().get(0), SecretEvent.class)) + .thenReturn(Flowable.just(modifiedSecretEvent)); + + CountDownLatch latch = new CountDownLatch(2); + AtomicReference bundleRef = new AtomicReference<>(null); + cut.addListener(bundle -> { + bundleRef.set(bundle); + latch.countDown(); + }); + + cut.start(); + + // Wait for the event to be processed. + latch.await(5000, TimeUnit.MILLISECONDS); + final KeyStoreBundle keyStoreBundle = bundleRef.get(); + + assertNotNull(keyStoreBundle); + assertEquals(1, keyStoreBundle.getKeyStore().size()); + // Make sure the kestore has been reloaded by checking the CN. + assertTrue(KeyStoreUtils.getCommonNamesByAlias(keyStoreBundle.getKeyStore()).containsKey("localhost2")); + } + + private String readContent(String resource) throws IOException { + return java.util.Base64.getEncoder().encodeToString(Files.readAllBytes(new File(getPath(resource)).toPath())); + } + + private String getPath(String resource) { + return this.getClass().getResource("/keystores/" + resource).getPath(); + } } diff --git a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/ManagementService.java b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/ManagementService.java index ce3e87f73..240954d61 100644 --- a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/ManagementService.java +++ b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/ManagementService.java @@ -29,47 +29,40 @@ */ public class ManagementService extends AbstractService { - private static final Logger LOGGER = LoggerFactory.getLogger( - ManagementService.class - ); + private static final Logger LOGGER = LoggerFactory.getLogger(ManagementService.class); - @Autowired - private Vertx vertx; + @Autowired + private Vertx vertx; - private String deploymentId; + private String deploymentId; - @Override - protected void doStart() throws Exception { - super.doStart(); + @Override + protected void doStart() throws Exception { + super.doStart(); - vertx.deployVerticle( - SpringVerticleFactory.VERTICLE_PREFIX + - ':' + - ManagementVerticle.class.getName(), - event -> { - if (event.failed()) { - LOGGER.error( - "Node Management API service can not be started", - event.cause() - ); - } + vertx.deployVerticle( + SpringVerticleFactory.VERTICLE_PREFIX + ':' + ManagementVerticle.class.getName(), + event -> { + if (event.failed()) { + LOGGER.error("Node Management API service can not be started", event.cause()); + } - deploymentId = event.result(); - } - ); - } + deploymentId = event.result(); + } + ); + } - @Override - protected void doStop() throws Exception { - super.doStop(); + @Override + protected void doStop() throws Exception { + super.doStop(); - if (deploymentId != null) { - vertx.undeploy(deploymentId); + if (deploymentId != null) { + vertx.undeploy(deploymentId); + } } - } - @Override - protected String name() { - return "Node Management API service"; - } + @Override + protected String name() { + return "Node Management API service"; + } } diff --git a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/configuration/ConfigurationEndpoint.java b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/configuration/ConfigurationEndpoint.java index ea5189595..ea42799dc 100644 --- a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/configuration/ConfigurationEndpoint.java +++ b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/configuration/ConfigurationEndpoint.java @@ -42,129 +42,109 @@ */ public class ConfigurationEndpoint implements ManagementEndpoint { - private final Logger LOGGER = LoggerFactory.getLogger( - ConfigurationEndpoint.class - ); - - private static final Set PROPERTY_PREFIXES = new HashSet<>( - Arrays.asList("gravitee.", "gravitee_", "GRAVITEE.", "GRAVITEE_") - ); - - private static final String ENDPOINT_PATH = "/configuration"; - - private static final String PROPERTY_SOURCE_CONFIGURATION = - "graviteeConfiguration"; - - @Autowired - private AbstractEnvironment environment; - - @Override - public HttpMethod method() { - return HttpMethod.GET; - } - - @Override - public String path() { - return ENDPOINT_PATH; - } - - @Override - public void handle(RoutingContext ctx) { - HttpServerResponse response = ctx.response(); - response.setStatusCode(HttpStatusCode.OK_200); - response.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); - response.setChunked(true); - - // Configuration is coming from gravitee.yml - PropertiesPropertySource nodeConfiguration = (PropertiesPropertySource) environment - .getPropertySources() - .get(PROPERTY_SOURCE_CONFIGURATION); - - // Configuration is coming from environment variables - Map systemEnvironment = environment.getSystemEnvironment(); - - Map prefixlessSystemEnvironment = systemEnvironment - .entrySet() - .stream() - .filter( - new Predicate>() { - @Override - public boolean test(Map.Entry entry) { - return ( - entry.getKey().length() > 9 && - PROPERTY_PREFIXES.contains(entry.getKey().substring(0, 9)) - ); - } - } - ) - .collect( - Collectors.toMap( - entry -> entry.getKey().substring(9), - Map.Entry::getValue - ) - ); - - TreeMap nodeProperties = Arrays - .stream(nodeConfiguration.getPropertyNames()) - .collect( - Collectors.toMap( - s -> s, - (Function) s -> environment.getProperty(s), - (v1, v2) -> { - throw new RuntimeException( - String.format("Duplicate key for values %s and %s", v1, v2) - ); - }, - TreeMap::new - ) - ); - - nodeProperties.putAll(prefixlessSystemEnvironment); - - io.vertx.core.json.jackson.DatabindCodec codec = (io.vertx.core.json.jackson.DatabindCodec) io.vertx.core.json.Json.CODEC; - codec - .prettyMapper() - .setSerializationInclusion(JsonInclude.Include.NON_NULL); - response.write( - Json.CODEC.toString(nodeProperties, true), - new Handler>() { - @Override - public void handle(AsyncResult event) { - if (event.failed()) { - response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR_500); - LOGGER.error( - "Unable to transform data object to JSON", - event.cause() - ); - } + private final Logger LOGGER = LoggerFactory.getLogger(ConfigurationEndpoint.class); - response.end(); - } - } - ); - } + private static final Set PROPERTY_PREFIXES = new HashSet<>(Arrays.asList("gravitee.", "gravitee_", "GRAVITEE.", "GRAVITEE_")); - public class Property implements Comparable { + private static final String ENDPOINT_PATH = "/configuration"; - private final String key; - private final Object value; + private static final String PROPERTY_SOURCE_CONFIGURATION = "graviteeConfiguration"; - public Property(String key, Object value) { - this.key = key; - this.value = value; - } + @Autowired + private AbstractEnvironment environment; - public String getKey() { - return key; + @Override + public HttpMethod method() { + return HttpMethod.GET; } - public Object getValue() { - return value; + @Override + public String path() { + return ENDPOINT_PATH; } @Override - public int compareTo(Object o) { - return this.getKey().compareTo(((Property) o).getKey()); + public void handle(RoutingContext ctx) { + HttpServerResponse response = ctx.response(); + response.setStatusCode(HttpStatusCode.OK_200); + response.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); + response.setChunked(true); + + // Configuration is coming from gravitee.yml + PropertiesPropertySource nodeConfiguration = (PropertiesPropertySource) environment + .getPropertySources() + .get(PROPERTY_SOURCE_CONFIGURATION); + + // Configuration is coming from environment variables + Map systemEnvironment = environment.getSystemEnvironment(); + + Map prefixlessSystemEnvironment = systemEnvironment + .entrySet() + .stream() + .filter( + new Predicate>() { + @Override + public boolean test(Map.Entry entry) { + return (entry.getKey().length() > 9 && PROPERTY_PREFIXES.contains(entry.getKey().substring(0, 9))); + } + } + ) + .collect(Collectors.toMap(entry -> entry.getKey().substring(9), Map.Entry::getValue)); + + TreeMap nodeProperties = Arrays + .stream(nodeConfiguration.getPropertyNames()) + .collect( + Collectors.toMap( + s -> s, + (Function) s -> environment.getProperty(s), + (v1, v2) -> { + throw new RuntimeException(String.format("Duplicate key for values %s and %s", v1, v2)); + }, + TreeMap::new + ) + ); + + nodeProperties.putAll(prefixlessSystemEnvironment); + + io.vertx.core.json.jackson.DatabindCodec codec = (io.vertx.core.json.jackson.DatabindCodec) io.vertx.core.json.Json.CODEC; + codec.prettyMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL); + response.write( + Json.CODEC.toString(nodeProperties, true), + new Handler>() { + @Override + public void handle(AsyncResult event) { + if (event.failed()) { + response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR_500); + LOGGER.error("Unable to transform data object to JSON", event.cause()); + } + + response.end(); + } + } + ); + } + + public class Property implements Comparable { + + private final String key; + private final Object value; + + public Property(String key, Object value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public Object getValue() { + return value; + } + + @Override + public int compareTo(Object o) { + return this.getKey().compareTo(((Property) o).getKey()); + } } - } } diff --git a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/endpoint/ManagementEndpoint.java b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/endpoint/ManagementEndpoint.java index 64987df23..21b34dc26 100644 --- a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/endpoint/ManagementEndpoint.java +++ b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/endpoint/ManagementEndpoint.java @@ -23,13 +23,13 @@ * @author GraviteeSource Team */ public interface ManagementEndpoint { - HttpMethod method(); + HttpMethod method(); - String path(); + String path(); - void handle(RoutingContext context); + void handle(RoutingContext context); - default boolean isWebhook() { - return false; - } + default boolean isWebhook() { + return false; + } } diff --git a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/endpoint/ManagementEndpointManager.java b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/endpoint/ManagementEndpointManager.java index a5eb4fec6..f750fea71 100644 --- a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/endpoint/ManagementEndpointManager.java +++ b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/endpoint/ManagementEndpointManager.java @@ -20,5 +20,5 @@ * @author GraviteeSource Team */ public interface ManagementEndpointManager { - void register(ManagementEndpoint endpoint); + void register(ManagementEndpoint endpoint); } diff --git a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/metrics/prometheus/PrometheusEndpoint.java b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/metrics/prometheus/PrometheusEndpoint.java index 06fd9517b..3f3d30f60 100644 --- a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/metrics/prometheus/PrometheusEndpoint.java +++ b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/metrics/prometheus/PrometheusEndpoint.java @@ -27,20 +27,19 @@ */ public class PrometheusEndpoint implements ManagementEndpoint { - @Override - public HttpMethod method() { - return HttpMethod.GET; - } + @Override + public HttpMethod method() { + return HttpMethod.GET; + } - @Override - public String path() { - return "/metrics/prometheus"; - } + @Override + public String path() { + return "/metrics/prometheus"; + } - @Override - public void handle(RoutingContext routingContext) { - String response = - ((PrometheusMeterRegistry) BackendRegistries.getDefaultNow()).scrape(); - routingContext.response().end(response); - } + @Override + public void handle(RoutingContext routingContext) { + String response = ((PrometheusMeterRegistry) BackendRegistries.getDefaultNow()).scrape(); + routingContext.response().end(response); + } } diff --git a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/node/NodeEndpoint.java b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/node/NodeEndpoint.java index 0d785195e..37b550969 100644 --- a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/node/NodeEndpoint.java +++ b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/node/NodeEndpoint.java @@ -38,98 +38,93 @@ */ public class NodeEndpoint implements ManagementEndpoint { - private final Logger LOGGER = LoggerFactory.getLogger(NodeEndpoint.class); - - @Autowired - private Node node; - - @Override - public HttpMethod method() { - return HttpMethod.GET; - } - - @Override - public String path() { - return "/"; - } - - @Override - public void handle(RoutingContext ctx) { - HttpServerResponse response = ctx.response(); - response.setStatusCode(HttpStatusCode.OK_200); - response.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); - response.setChunked(true); - - NodeInfos data = new NodeInfos(); - - data.setId(node.id()); - data.setName(node.name()); - data.setVersion(Version.RUNTIME_VERSION); - data.setMetadata(node.metadata()); - - io.vertx.core.json.jackson.DatabindCodec codec = (io.vertx.core.json.jackson.DatabindCodec) io.vertx.core.json.Json.CODEC; - codec - .prettyMapper() - .setSerializationInclusion(JsonInclude.Include.NON_NULL); - response.write( - codec.toString(data, true), - new Handler>() { - @Override - public void handle(AsyncResult event) { - if (event.failed()) { - response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR_500); - LOGGER.error( - "Unable to transform data object to JSON", - event.cause() - ); - } - - response.end(); - } - } - ); - } + private final Logger LOGGER = LoggerFactory.getLogger(NodeEndpoint.class); - public static class NodeInfos { + @Autowired + private Node node; - private String id; + @Override + public HttpMethod method() { + return HttpMethod.GET; + } - private String name; + @Override + public String path() { + return "/"; + } - private Map metadata; + @Override + public void handle(RoutingContext ctx) { + HttpServerResponse response = ctx.response(); + response.setStatusCode(HttpStatusCode.OK_200); + response.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); + response.setChunked(true); + + NodeInfos data = new NodeInfos(); + + data.setId(node.id()); + data.setName(node.name()); + data.setVersion(Version.RUNTIME_VERSION); + data.setMetadata(node.metadata()); + + io.vertx.core.json.jackson.DatabindCodec codec = (io.vertx.core.json.jackson.DatabindCodec) io.vertx.core.json.Json.CODEC; + codec.prettyMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL); + response.write( + codec.toString(data, true), + new Handler>() { + @Override + public void handle(AsyncResult event) { + if (event.failed()) { + response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR_500); + LOGGER.error("Unable to transform data object to JSON", event.cause()); + } + + response.end(); + } + } + ); + } - private Version version; + public static class NodeInfos { - public String getId() { - return id; - } + private String id; - public void setId(String id) { - this.id = id; - } + private String name; - public String getName() { - return name; - } + private Map metadata; - public void setName(String name) { - this.name = name; - } + private Version version; - public Map getMetadata() { - return metadata; - } + public String getId() { + return id; + } - public void setMetadata(Map metadata) { - this.metadata = metadata; - } + public void setId(String id) { + this.id = id; + } - public Version getVersion() { - return version; - } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Map getMetadata() { + return metadata; + } - public void setVersion(Version version) { - this.version = version; + public void setMetadata(Map metadata) { + this.metadata = metadata; + } + + public Version getVersion() { + return version; + } + + public void setVersion(Version version) { + this.version = version; + } } - } } diff --git a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/spring/ManagementConfiguration.java b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/spring/ManagementConfiguration.java index ca72f3d36..f95e4e0e7 100644 --- a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/spring/ManagementConfiguration.java +++ b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/spring/ManagementConfiguration.java @@ -35,33 +35,33 @@ @Import(HttpServerSpringConfiguration.class) public class ManagementConfiguration { - @Bean - public ManagementService managementService() { - return new ManagementService(); - } + @Bean + public ManagementService managementService() { + return new ManagementService(); + } - @Bean - public ManagementVerticle managementVerticle() { - return new ManagementVerticle(); - } + @Bean + public ManagementVerticle managementVerticle() { + return new ManagementVerticle(); + } - @Bean - public ManagementEndpointManager managementEndpointManager() { - return new ManagementEndpointManagerImpl(); - } + @Bean + public ManagementEndpointManager managementEndpointManager() { + return new ManagementEndpointManagerImpl(); + } - @Bean - public NodeEndpoint nodeEndpoint() { - return new NodeEndpoint(); - } + @Bean + public NodeEndpoint nodeEndpoint() { + return new NodeEndpoint(); + } - @Bean - public PrometheusEndpoint prometheusEndpoint() { - return new PrometheusEndpoint(); - } + @Bean + public PrometheusEndpoint prometheusEndpoint() { + return new PrometheusEndpoint(); + } - @Bean - public ConfigurationEndpoint configurationEndpoint() { - return new ConfigurationEndpoint(); - } + @Bean + public ConfigurationEndpoint configurationEndpoint() { + return new ConfigurationEndpoint(); + } } diff --git a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/auth/BasicAuthProvider.java b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/auth/BasicAuthProvider.java index 55f42b5a7..198c3c73d 100644 --- a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/auth/BasicAuthProvider.java +++ b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/auth/BasicAuthProvider.java @@ -30,33 +30,25 @@ */ public class BasicAuthProvider implements AuthProvider { - private static final String USERS_PREFIX_KEY = - "services.core.http.authentication.users."; - - @Autowired - private Environment environment; - - @Override - public void authenticate( - JsonObject authInfo, - Handler> resultHandler - ) { - String password = environment.getProperty( - USERS_PREFIX_KEY + authInfo.getString("username") - ); - - if (password != null) { - // Get password from incoming HTTP request - String presentedPassword = authInfo.getString("password"); - - if (password.equals(presentedPassword)) { - resultHandler.handle( - Future.succeededFuture(User.fromName(authInfo.getString("username"))) - ); - return; - } - } + private static final String USERS_PREFIX_KEY = "services.core.http.authentication.users."; + + @Autowired + private Environment environment; + + @Override + public void authenticate(JsonObject authInfo, Handler> resultHandler) { + String password = environment.getProperty(USERS_PREFIX_KEY + authInfo.getString("username")); - resultHandler.handle(Future.failedFuture("Unauthorized user")); - } + if (password != null) { + // Get password from incoming HTTP request + String presentedPassword = authInfo.getString("password"); + + if (password.equals(presentedPassword)) { + resultHandler.handle(Future.succeededFuture(User.fromName(authInfo.getString("username")))); + return; + } + } + + resultHandler.handle(Future.failedFuture("Unauthorized user")); + } } diff --git a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/configuration/HttpServerConfiguration.java b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/configuration/HttpServerConfiguration.java index a70abf7bd..83aa8091f 100644 --- a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/configuration/HttpServerConfiguration.java +++ b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/configuration/HttpServerConfiguration.java @@ -24,188 +24,184 @@ */ public class HttpServerConfiguration { - @Value("${services.core.http.enabled:true}") - private boolean enabled; + @Value("${services.core.http.enabled:true}") + private boolean enabled; - @Value("${services.core.http.port:18082}") - private int port; + @Value("${services.core.http.port:18082}") + private int port; - @Value("${services.core.http.host:localhost}") - private String host; + @Value("${services.core.http.host:localhost}") + private String host; - @Value("${services.core.http.authentication.type:basic}") - private String authenticationType; + @Value("${services.core.http.authentication.type:basic}") + private String authenticationType; - @Value("${services.core.http.secured:false}") - private boolean secured; + @Value("${services.core.http.secured:false}") + private boolean secured; - @Value("${services.core.http.alpn:false}") - private boolean alpn; + @Value("${services.core.http.alpn:false}") + private boolean alpn; - @Value("${http.ssl.tlsProtocols:#{null}}") - private String tlsProtocols; + @Value("${http.ssl.tlsProtocols:#{null}}") + private String tlsProtocols; - @Value("${http.ssl.tlsCiphers:#{null}}") - private String tlsCiphers; + @Value("${http.ssl.tlsCiphers:#{null}}") + private String tlsCiphers; - @Value("${services.core.http.ssl.keystore.path:#{null}}") - private String keyStorePath; + @Value("${services.core.http.ssl.keystore.path:#{null}}") + private String keyStorePath; - @Value("${services.core.http.ssl.keystore.password:#{null}}") - private String keyStorePassword; + @Value("${services.core.http.ssl.keystore.password:#{null}}") + private String keyStorePassword; - @Value("${services.core.http.ssl.keystore.type:#{null}}") - private String keyStoreType; + @Value("${services.core.http.ssl.keystore.type:#{null}}") + private String keyStoreType; - @Value("${services.core.http.ssl.truststore.path:#{null}}") - private String trustStorePath; + @Value("${services.core.http.ssl.truststore.path:#{null}}") + private String trustStorePath; - @Value("${services.core.http.ssl.truststore.password:#{null}}") - private String trustStorePassword; + @Value("${services.core.http.ssl.truststore.password:#{null}}") + private String trustStorePassword; - @Value("${services.core.http.ssl.truststore.type:#{null}}") - private String trustStoreType; + @Value("${services.core.http.ssl.truststore.type:#{null}}") + private String trustStoreType; - @Value( - "${services.core.http.idleTimeout:" + - HttpServerOptions.DEFAULT_IDLE_TIMEOUT + - "}" - ) - private int idleTimeout; + @Value("${services.core.http.idleTimeout:" + HttpServerOptions.DEFAULT_IDLE_TIMEOUT + "}") + private int idleTimeout; - /** - * null : REQUEST - * true : REQUIRED - * false : NONE - */ - @Value("${services.core.http.ssl.clientAuth:#{null}}") - private String clientAuth; + /** + * null : REQUEST + * true : REQUIRED + * false : NONE + */ + @Value("${services.core.http.ssl.clientAuth:#{null}}") + private String clientAuth; - public String getClientAuth() { - return clientAuth; - } + public String getClientAuth() { + return clientAuth; + } - public void setClientAuth(String clientAuth) { - this.clientAuth = clientAuth; - } + public void setClientAuth(String clientAuth) { + this.clientAuth = clientAuth; + } - public boolean isEnabled() { - return enabled; - } + public boolean isEnabled() { + return enabled; + } - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } - public int getPort() { - return port; - } + public int getPort() { + return port; + } - public void setPort(int port) { - this.port = port; - } + public void setPort(int port) { + this.port = port; + } - public String getHost() { - return host; - } + public String getHost() { + return host; + } - public void setHost(String host) { - this.host = host; - } + public void setHost(String host) { + this.host = host; + } - public String getAuthenticationType() { - return authenticationType; - } + public String getAuthenticationType() { + return authenticationType; + } - public void setAuthenticationType(String authenticationType) { - this.authenticationType = authenticationType; - } + public void setAuthenticationType(String authenticationType) { + this.authenticationType = authenticationType; + } - public boolean isSecured() { - return secured; - } + public boolean isSecured() { + return secured; + } - public void setSecured(boolean secured) { - this.secured = secured; - } + public void setSecured(boolean secured) { + this.secured = secured; + } - public boolean isAlpn() { - return alpn; - } + public boolean isAlpn() { + return alpn; + } - public void setAlpn(boolean alpn) { - this.alpn = alpn; - } + public void setAlpn(boolean alpn) { + this.alpn = alpn; + } - public String getTlsProtocols() { - return tlsProtocols; - } + public String getTlsProtocols() { + return tlsProtocols; + } - public void setTlsProtocols(String tlsProtocols) { - this.tlsProtocols = tlsProtocols; - } + public void setTlsProtocols(String tlsProtocols) { + this.tlsProtocols = tlsProtocols; + } - public String getTlsCiphers() { - return tlsCiphers; - } - - public void setTlsCiphers(String tlsCiphers) { - this.tlsCiphers = tlsCiphers; - } - - public String getKeyStorePath() { - return keyStorePath; - } - - public void setKeyStorePath(String keyStorePath) { - this.keyStorePath = keyStorePath; - } - - public String getKeyStorePassword() { - return keyStorePassword; - } - - public void setKeyStorePassword(String keyStorePassword) { - this.keyStorePassword = keyStorePassword; - } - - public String getKeyStoreType() { - return keyStoreType; - } - - public void setKeyStoreType(String keyStoreType) { - this.keyStoreType = keyStoreType; - } - - public String getTrustStorePath() { - return trustStorePath; - } + public String getTlsCiphers() { + return tlsCiphers; + } - public void setTrustStorePath(String trustStorePath) { - this.trustStorePath = trustStorePath; - } + public void setTlsCiphers(String tlsCiphers) { + this.tlsCiphers = tlsCiphers; + } - public String getTrustStorePassword() { - return trustStorePassword; - } + public String getKeyStorePath() { + return keyStorePath; + } - public void setTrustStorePassword(String trustStorePassword) { - this.trustStorePassword = trustStorePassword; - } + public void setKeyStorePath(String keyStorePath) { + this.keyStorePath = keyStorePath; + } - public String getTrustStoreType() { - return trustStoreType; - } + public String getKeyStorePassword() { + return keyStorePassword; + } + + public void setKeyStorePassword(String keyStorePassword) { + this.keyStorePassword = keyStorePassword; + } + + public String getKeyStoreType() { + return keyStoreType; + } + + public void setKeyStoreType(String keyStoreType) { + this.keyStoreType = keyStoreType; + } + + public String getTrustStorePath() { + return trustStorePath; + } - public void setTrustStoreType(String trustStoreType) { - this.trustStoreType = trustStoreType; - } + public void setTrustStorePath(String trustStorePath) { + this.trustStorePath = trustStorePath; + } - public int getIdleTimeout() { - return idleTimeout; - } + public String getTrustStorePassword() { + return trustStorePassword; + } - public void setIdleTimeout(int idleTimeout) { - this.idleTimeout = idleTimeout; - } + public void setTrustStorePassword(String trustStorePassword) { + this.trustStorePassword = trustStorePassword; + } + + public String getTrustStoreType() { + return trustStoreType; + } + + public void setTrustStoreType(String trustStoreType) { + this.trustStoreType = trustStoreType; + } + + public int getIdleTimeout() { + return idleTimeout; + } + + public void setIdleTimeout(int idleTimeout) { + this.idleTimeout = idleTimeout; + } } diff --git a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/endpoint/ManagementEndpointManagerImpl.java b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/endpoint/ManagementEndpointManagerImpl.java index 01880ded6..36a6d2a2a 100644 --- a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/endpoint/ManagementEndpointManagerImpl.java +++ b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/endpoint/ManagementEndpointManagerImpl.java @@ -28,65 +28,58 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class ManagementEndpointManagerImpl - implements ManagementEndpointManager { +public class ManagementEndpointManagerImpl implements ManagementEndpointManager { - private static final Logger LOGGER = LoggerFactory.getLogger( - ManagementEndpointManagerImpl.class - ); + private static final Logger LOGGER = LoggerFactory.getLogger(ManagementEndpointManagerImpl.class); - @Autowired - @Qualifier("managementRouter") - private Router nodeRouter; + @Autowired + @Qualifier("managementRouter") + private Router nodeRouter; - @Autowired - @Qualifier("managementWebhookRouter") - private Router nodeWebhookRouter; + @Autowired + @Qualifier("managementWebhookRouter") + private Router nodeWebhookRouter; - @Override - public void register(ManagementEndpoint endpoint) { - LOGGER.info( - "Register a new endpoint for Management API: {} {} [{}]", - endpoint.method(), - endpoint.path(), - endpoint.getClass().getName() - ); + @Override + public void register(ManagementEndpoint endpoint) { + LOGGER.info( + "Register a new endpoint for Management API: {} {} [{}]", + endpoint.method(), + endpoint.path(), + endpoint.getClass().getName() + ); - if (endpoint.isWebhook()) { - nodeWebhookRouter - .route(convert(endpoint.method()), endpoint.path()) - .handler(endpoint::handle); - } else { - nodeRouter - .route(convert(endpoint.method()), endpoint.path()) - .handler(endpoint::handle); + if (endpoint.isWebhook()) { + nodeWebhookRouter.route(convert(endpoint.method()), endpoint.path()).handler(endpoint::handle); + } else { + nodeRouter.route(convert(endpoint.method()), endpoint.path()).handler(endpoint::handle); + } } - } - private HttpMethod convert(io.gravitee.common.http.HttpMethod httpMethod) { - switch (httpMethod) { - case CONNECT: - return HttpMethod.CONNECT; - case DELETE: - return HttpMethod.DELETE; - case GET: - return HttpMethod.GET; - case HEAD: - return HttpMethod.HEAD; - case OPTIONS: - return HttpMethod.OPTIONS; - case PATCH: - return HttpMethod.PATCH; - case POST: - return HttpMethod.POST; - case PUT: - return HttpMethod.PUT; - case TRACE: - return HttpMethod.TRACE; - case OTHER: - return HttpMethod.valueOf(httpMethod.name()); - } + private HttpMethod convert(io.gravitee.common.http.HttpMethod httpMethod) { + switch (httpMethod) { + case CONNECT: + return HttpMethod.CONNECT; + case DELETE: + return HttpMethod.DELETE; + case GET: + return HttpMethod.GET; + case HEAD: + return HttpMethod.HEAD; + case OPTIONS: + return HttpMethod.OPTIONS; + case PATCH: + return HttpMethod.PATCH; + case POST: + return HttpMethod.POST; + case PUT: + return HttpMethod.PUT; + case TRACE: + return HttpMethod.TRACE; + case OTHER: + return HttpMethod.valueOf(httpMethod.name()); + } - return null; - } + return null; + } } diff --git a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/spring/HttpServerSpringConfiguration.java b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/spring/HttpServerSpringConfiguration.java index d21c3fc0b..dc29badb3 100644 --- a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/spring/HttpServerSpringConfiguration.java +++ b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/spring/HttpServerSpringConfiguration.java @@ -38,123 +38,97 @@ @Configuration public class HttpServerSpringConfiguration { - private static final String CERTIFICATE_FORMAT_JKS = "JKS"; - private static final String CERTIFICATE_FORMAT_PEM = "PEM"; - private static final String CERTIFICATE_FORMAT_PKCS12 = "PKCS12"; + private static final String CERTIFICATE_FORMAT_JKS = "JKS"; + private static final String CERTIFICATE_FORMAT_PEM = "PEM"; + private static final String CERTIFICATE_FORMAT_PKCS12 = "PKCS12"; - @Bean("managementRouter") - public Router router(Vertx vertx) { - return Router.router(vertx); - } + @Bean("managementRouter") + public Router router(Vertx vertx) { + return Router.router(vertx); + } - @Bean("managementWebhookRouter") - public Router webHookRouter(Vertx vertx) { - return Router.router(vertx); - } + @Bean("managementWebhookRouter") + public Router webHookRouter(Vertx vertx) { + return Router.router(vertx); + } - @Bean("managementHttpServer") - public HttpServer httpServer(Vertx vertx) { - HttpServerOptions options = new HttpServerOptions() - .setPort(httpServerConfiguration().getPort()) - .setHost(httpServerConfiguration().getHost()); + @Bean("managementHttpServer") + public HttpServer httpServer(Vertx vertx) { + HttpServerOptions options = new HttpServerOptions() + .setPort(httpServerConfiguration().getPort()) + .setHost(httpServerConfiguration().getHost()); - if (httpServerConfiguration().isSecured()) { - options.setSsl(httpServerConfiguration().isSecured()); - options.setUseAlpn(httpServerConfiguration().isAlpn()); + if (httpServerConfiguration().isSecured()) { + options.setSsl(httpServerConfiguration().isSecured()); + options.setUseAlpn(httpServerConfiguration().isAlpn()); - String clientAuth = httpServerConfiguration().getClientAuth(); - if (!StringUtils.isEmpty(clientAuth)) { - if (clientAuth.equalsIgnoreCase(Boolean.TRUE.toString())) { - options.setClientAuth(ClientAuth.REQUIRED); - } else { - options.setClientAuth(ClientAuth.NONE); - } - } else { - options.setClientAuth(ClientAuth.REQUEST); - } + String clientAuth = httpServerConfiguration().getClientAuth(); + if (!StringUtils.isEmpty(clientAuth)) { + if (clientAuth.equalsIgnoreCase(Boolean.TRUE.toString())) { + options.setClientAuth(ClientAuth.REQUIRED); + } else { + options.setClientAuth(ClientAuth.NONE); + } + } else { + options.setClientAuth(ClientAuth.REQUEST); + } - if (httpServerConfiguration().getTrustStorePath() != null) { - if ( - httpServerConfiguration().getTrustStoreType() == null || - httpServerConfiguration().getTrustStoreType().isEmpty() || - httpServerConfiguration() - .getTrustStoreType() - .equalsIgnoreCase(CERTIFICATE_FORMAT_JKS) - ) { - options.setTrustStoreOptions( - new JksOptions() - .setPath(httpServerConfiguration().getTrustStorePath()) - .setPassword(httpServerConfiguration().getTrustStorePassword()) - ); - } else if ( - httpServerConfiguration() - .getTrustStoreType() - .equalsIgnoreCase(CERTIFICATE_FORMAT_PEM) - ) { - options.setPemTrustOptions( - new PemTrustOptions() - .addCertPath(httpServerConfiguration().getTrustStorePath()) - ); - } else if ( - httpServerConfiguration() - .getTrustStoreType() - .equalsIgnoreCase(CERTIFICATE_FORMAT_PKCS12) - ) { - options.setPfxTrustOptions( - new PfxOptions() - .setPath(httpServerConfiguration().getTrustStorePath()) - .setPassword(httpServerConfiguration().getTrustStorePassword()) - ); - } - } + if (httpServerConfiguration().getTrustStorePath() != null) { + if ( + httpServerConfiguration().getTrustStoreType() == null || + httpServerConfiguration().getTrustStoreType().isEmpty() || + httpServerConfiguration().getTrustStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_JKS) + ) { + options.setTrustStoreOptions( + new JksOptions() + .setPath(httpServerConfiguration().getTrustStorePath()) + .setPassword(httpServerConfiguration().getTrustStorePassword()) + ); + } else if (httpServerConfiguration().getTrustStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_PEM)) { + options.setPemTrustOptions(new PemTrustOptions().addCertPath(httpServerConfiguration().getTrustStorePath())); + } else if (httpServerConfiguration().getTrustStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_PKCS12)) { + options.setPfxTrustOptions( + new PfxOptions() + .setPath(httpServerConfiguration().getTrustStorePath()) + .setPassword(httpServerConfiguration().getTrustStorePassword()) + ); + } + } - if (httpServerConfiguration().getKeyStorePath() != null) { - if ( - httpServerConfiguration().getKeyStoreType() == null || - httpServerConfiguration().getKeyStoreType().isEmpty() || - httpServerConfiguration() - .getKeyStoreType() - .equalsIgnoreCase(CERTIFICATE_FORMAT_JKS) - ) { - options.setKeyStoreOptions( - new JksOptions() - .setPath(httpServerConfiguration().getKeyStorePath()) - .setPassword(httpServerConfiguration().getKeyStorePassword()) - ); - } else if ( - httpServerConfiguration() - .getKeyStoreType() - .equalsIgnoreCase(CERTIFICATE_FORMAT_PEM) - ) { - options.setPemKeyCertOptions( - new PemKeyCertOptions() - .addCertPath(httpServerConfiguration().getKeyStorePath()) - ); - } else if ( - httpServerConfiguration() - .getKeyStoreType() - .equalsIgnoreCase(CERTIFICATE_FORMAT_PKCS12) - ) { - options.setPfxKeyCertOptions( - new PfxOptions() - .setPath(httpServerConfiguration().getKeyStorePath()) - .setPassword(httpServerConfiguration().getKeyStorePassword()) - ); + if (httpServerConfiguration().getKeyStorePath() != null) { + if ( + httpServerConfiguration().getKeyStoreType() == null || + httpServerConfiguration().getKeyStoreType().isEmpty() || + httpServerConfiguration().getKeyStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_JKS) + ) { + options.setKeyStoreOptions( + new JksOptions() + .setPath(httpServerConfiguration().getKeyStorePath()) + .setPassword(httpServerConfiguration().getKeyStorePassword()) + ); + } else if (httpServerConfiguration().getKeyStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_PEM)) { + options.setPemKeyCertOptions(new PemKeyCertOptions().addCertPath(httpServerConfiguration().getKeyStorePath())); + } else if (httpServerConfiguration().getKeyStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_PKCS12)) { + options.setPfxKeyCertOptions( + new PfxOptions() + .setPath(httpServerConfiguration().getKeyStorePath()) + .setPassword(httpServerConfiguration().getKeyStorePassword()) + ); + } + } } - } - } - options.setIdleTimeout(httpServerConfiguration().getIdleTimeout()); + options.setIdleTimeout(httpServerConfiguration().getIdleTimeout()); - return vertx.createHttpServer(options); - } + return vertx.createHttpServer(options); + } - @Bean("managementAuthProvider") - public AuthProvider authProvider() { - return new BasicAuthProvider(); - } + @Bean("managementAuthProvider") + public AuthProvider authProvider() { + return new BasicAuthProvider(); + } - @Bean("managementHttpServerConfiguration") - public HttpServerConfiguration httpServerConfiguration() { - return new HttpServerConfiguration(); - } + @Bean("managementHttpServerConfiguration") + public HttpServerConfiguration httpServerConfiguration() { + return new HttpServerConfiguration(); + } } diff --git a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/verticle/ManagementVerticle.java b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/verticle/ManagementVerticle.java index be1af8e9f..2001253ad 100644 --- a/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/verticle/ManagementVerticle.java +++ b/gravitee-node-management/src/main/java/io/gravitee/node/management/http/vertx/verticle/ManagementVerticle.java @@ -39,160 +39,136 @@ */ public class ManagementVerticle extends AbstractVerticle { - private static final Logger LOGGER = LoggerFactory.getLogger( - ManagementVerticle.class - ); + private static final Logger LOGGER = LoggerFactory.getLogger(ManagementVerticle.class); - private static final String PATH = "/_node"; - private static final String WEBHOOK_PATH = "/hooks"; + private static final String PATH = "/_node"; + private static final String WEBHOOK_PATH = "/hooks"; - private static final String AUTHENTICATION_TYPE_NONE = "none"; - private static final String AUTHENTICATION_TYPE_BASIC = "basic"; - private static final String AUTHENTICATION_BASIC_REALM = "gravitee.io"; + private static final String AUTHENTICATION_TYPE_NONE = "none"; + private static final String AUTHENTICATION_TYPE_BASIC = "basic"; + private static final String AUTHENTICATION_BASIC_REALM = "gravitee.io"; - @Autowired - @Qualifier("managementHttpServer") - private HttpServer httpServer; + @Autowired + @Qualifier("managementHttpServer") + private HttpServer httpServer; - @Autowired - @Qualifier("managementRouter") - private Router nodeRouter; + @Autowired + @Qualifier("managementRouter") + private Router nodeRouter; - @Autowired - @Qualifier("managementWebhookRouter") - private Router nodeWebhookRouter; + @Autowired + @Qualifier("managementWebhookRouter") + private Router nodeWebhookRouter; - @Autowired - private Vertx vertx; + @Autowired + private Vertx vertx; - @Autowired - @Qualifier("managementAuthProvider") - private AuthProvider authProvider; + @Autowired + @Qualifier("managementAuthProvider") + private AuthProvider authProvider; - @Autowired - private HttpServerConfiguration httpServerConfiguration; + @Autowired + private HttpServerConfiguration httpServerConfiguration; - @Autowired - private NodeEndpoint nodeEndpoint; + @Autowired + private NodeEndpoint nodeEndpoint; - @Autowired - private ConfigurationEndpoint configurationEndpoint; + @Autowired + private ConfigurationEndpoint configurationEndpoint; - @Autowired - private PrometheusEndpoint prometheusEndpoint; + @Autowired + private PrometheusEndpoint prometheusEndpoint; - @Autowired - private ManagementEndpointManager managementEndpointManager; + @Autowired + private ManagementEndpointManager managementEndpointManager; - @Autowired - private Environment environment; + @Autowired + private Environment environment; - @Override - public void start(Promise promise) throws Exception { - if (httpServerConfiguration.isEnabled()) { - doStart(promise); - } else { - promise.complete(); - LOGGER.info("Node Management API is disabled, skipping..."); - } - } - - @Override - public void stop(Promise promise) throws Exception { - if (httpServerConfiguration.isEnabled()) { - LOGGER.info("Stopping Management API..."); - httpServer.close( - new Handler>() { - @Override - public void handle(AsyncResult event) { - if (event.succeeded()) { - LOGGER.info("HTTP Server has been correctly stopped"); - promise.complete(); - } else { - LOGGER.error( - "Unexpected error while stopping HTTP listener for Node Management API", - event.cause() - ); - promise.fail(event.cause()); - } - } + @Override + public void start(Promise promise) throws Exception { + if (httpServerConfiguration.isEnabled()) { + doStart(promise); + } else { + promise.complete(); + LOGGER.info("Node Management API is disabled, skipping..."); } - ); - } - } - - private void doStart(Promise promise) throws Exception { - LOGGER.info("Start HTTP listener for Node Management API"); - - // Start HTTP server - Router mainRouter = Router.router(vertx); - mainRouter.mountSubRouter(WEBHOOK_PATH, nodeWebhookRouter); - mainRouter.mountSubRouter(PATH, nodeRouter); - - AuthenticationHandler authHandler = null; - switch (httpServerConfiguration.getAuthenticationType().toLowerCase()) { - case AUTHENTICATION_TYPE_NONE: - break; - case AUTHENTICATION_TYPE_BASIC: - authHandler = - BasicAuthHandler.create(authProvider, AUTHENTICATION_BASIC_REALM); - break; - default: - throw new IllegalArgumentException( - "Unsupported Authentication type " + - httpServerConfiguration.getAuthenticationType() + - " for HTTP core services" - ); } - // Set security handler is defined - if (authHandler != null) { - mainRouter.route().order(-1).handler(authHandler); - nodeRouter.route().order(-1).handler(authHandler); + @Override + public void stop(Promise promise) throws Exception { + if (httpServerConfiguration.isEnabled()) { + LOGGER.info("Stopping Management API..."); + httpServer.close( + new Handler>() { + @Override + public void handle(AsyncResult event) { + if (event.succeeded()) { + LOGGER.info("HTTP Server has been correctly stopped"); + promise.complete(); + } else { + LOGGER.error("Unexpected error while stopping HTTP listener for Node Management API", event.cause()); + promise.fail(event.cause()); + } + } + } + ); + } } - // Set default handler - mainRouter.route().handler(ctx -> ctx.fail(HttpStatusCode.NOT_FOUND_404)); - - // Add request handler - httpServer - .requestHandler(mainRouter) - .listen( - event -> { - if (event.failed()) { - LOGGER.error( - "HTTP listener for Node Management can not be started properly", - event.cause() - ); - promise.fail(event.cause()); - } else { - managementEndpointManager.register(nodeEndpoint); - managementEndpointManager.register(configurationEndpoint); - - // Metrics - boolean metricsEnabled = environment.getProperty( - "services.metrics.enabled", - Boolean.class, - false - ); - if (metricsEnabled) { - // Register Prometheus endpoint - boolean prometheusEnabled = environment.getProperty( - "services.metrics.prometheus.enabled", - Boolean.class, - true - ); - if (prometheusEnabled) { - managementEndpointManager.register(prometheusEndpoint); - } - } - LOGGER.info( - "HTTP listener for Node Management bind to port TCP:{}", - event.result().actualPort() - ); - promise.complete(); - } + private void doStart(Promise promise) throws Exception { + LOGGER.info("Start HTTP listener for Node Management API"); + + // Start HTTP server + Router mainRouter = Router.router(vertx); + mainRouter.mountSubRouter(WEBHOOK_PATH, nodeWebhookRouter); + mainRouter.mountSubRouter(PATH, nodeRouter); + + AuthenticationHandler authHandler = null; + switch (httpServerConfiguration.getAuthenticationType().toLowerCase()) { + case AUTHENTICATION_TYPE_NONE: + break; + case AUTHENTICATION_TYPE_BASIC: + authHandler = BasicAuthHandler.create(authProvider, AUTHENTICATION_BASIC_REALM); + break; + default: + throw new IllegalArgumentException( + "Unsupported Authentication type " + httpServerConfiguration.getAuthenticationType() + " for HTTP core services" + ); + } + + // Set security handler is defined + if (authHandler != null) { + mainRouter.route().order(-1).handler(authHandler); + nodeRouter.route().order(-1).handler(authHandler); } - ); - } + + // Set default handler + mainRouter.route().handler(ctx -> ctx.fail(HttpStatusCode.NOT_FOUND_404)); + + // Add request handler + httpServer + .requestHandler(mainRouter) + .listen(event -> { + if (event.failed()) { + LOGGER.error("HTTP listener for Node Management can not be started properly", event.cause()); + promise.fail(event.cause()); + } else { + managementEndpointManager.register(nodeEndpoint); + managementEndpointManager.register(configurationEndpoint); + + // Metrics + boolean metricsEnabled = environment.getProperty("services.metrics.enabled", Boolean.class, false); + if (metricsEnabled) { + // Register Prometheus endpoint + boolean prometheusEnabled = environment.getProperty("services.metrics.prometheus.enabled", Boolean.class, true); + if (prometheusEnabled) { + managementEndpointManager.register(prometheusEndpoint); + } + } + LOGGER.info("HTTP listener for Node Management bind to port TCP:{}", event.result().actualPort()); + promise.complete(); + } + }); + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/MonitoringConstants.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/MonitoringConstants.java index c826ef667..8bfcbe0b0 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/MonitoringConstants.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/MonitoringConstants.java @@ -20,15 +20,15 @@ * @author GraviteeSource Team */ public interface MonitoringConstants { - String PROPERTY_NODE_ID = "node.id"; - String PROPERTY_NODE_HOSTNAME = "node.hostname"; - String PROPERTY_NODE_APPLICATION = "node.application"; - String PROPERTY_NODE_EVENT = "node.event"; - String NODE_HEALTHCHECK = "NODE_HEALTHCHECK"; - String NODE_HEARTBEAT = "NODE_HEARTBEAT"; - String NODE_LIFECYCLE = "NODE_LIFECYCLE"; - String NODE_EVENT_START = "NODE_START"; - String NODE_EVENT_STOP = "NODE_STOP"; - String PROPERTY_NODE_HEALTHY = "node.healthy"; - String PROPERTY_PROBE_SUFFIX = "node.probe."; + String PROPERTY_NODE_ID = "node.id"; + String PROPERTY_NODE_HOSTNAME = "node.hostname"; + String PROPERTY_NODE_APPLICATION = "node.application"; + String PROPERTY_NODE_EVENT = "node.event"; + String NODE_HEALTHCHECK = "NODE_HEALTHCHECK"; + String NODE_HEARTBEAT = "NODE_HEARTBEAT"; + String NODE_LIFECYCLE = "NODE_LIFECYCLE"; + String NODE_EVENT_START = "NODE_START"; + String NODE_EVENT_STOP = "NODE_STOP"; + String PROPERTY_NODE_HEALTHY = "node.healthy"; + String PROPERTY_PROBE_SUFFIX = "node.probe."; } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/NoOpNodeMonitoringRepository.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/NoOpNodeMonitoringRepository.java index 91afc2c77..a67482969 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/NoOpNodeMonitoringRepository.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/NoOpNodeMonitoringRepository.java @@ -28,27 +28,23 @@ */ public class NoOpNodeMonitoringRepository implements NodeMonitoringRepository { - @Override - public Maybe findByNodeIdAndType(String nodeId, String type) { - return Maybe.empty(); - } + @Override + public Maybe findByNodeIdAndType(String nodeId, String type) { + return Maybe.empty(); + } - @Override - public Single create(Monitoring monitoring) { - return Single.just(monitoring); - } + @Override + public Single create(Monitoring monitoring) { + return Single.just(monitoring); + } - @Override - public Single update(Monitoring monitoring) { - return Single.just(monitoring); - } + @Override + public Single update(Monitoring monitoring) { + return Single.just(monitoring); + } - @Override - public Flowable findByTypeAndTimeFrame( - String type, - long from, - long to - ) { - return Flowable.empty(); - } + @Override + public Flowable findByTypeAndTimeFrame(String type, long from, long to) { + return Flowable.empty(); + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/NodeMonitoringService.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/NodeMonitoringService.java index 91d363e3e..46733b155 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/NodeMonitoringService.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/NodeMonitoringService.java @@ -38,89 +38,68 @@ @Component public class NodeMonitoringService { - private static final Logger LOGGER = LoggerFactory.getLogger( - NodeMonitoringService.class - ); - private static final int CLEANUP_DELAY = 600000; + private static final Logger LOGGER = LoggerFactory.getLogger(NodeMonitoringService.class); + private static final int CLEANUP_DELAY = 600000; - private final NodeMonitoringRepository repository; - private final Map monitoringHolder; + private final NodeMonitoringRepository repository; + private final Map monitoringHolder; - public NodeMonitoringService(@Lazy NodeMonitoringRepository repository) { - this.repository = repository; - this.monitoringHolder = new ConcurrentHashMap<>(); - } - - public Single createOrUpdate(Monitoring monitoring) { - if (repository == null) { - LOGGER.debug( - "There is nowhere to persist the monitoring data {}", - monitoring - ); - return Single.just(monitoring); + public NodeMonitoringService(@Lazy NodeMonitoringRepository repository) { + this.repository = repository; + this.monitoringHolder = new ConcurrentHashMap<>(); } - final String monitoringKey = monitoring.getNodeId() + monitoring.getType(); + public Single createOrUpdate(Monitoring monitoring) { + if (repository == null) { + LOGGER.debug("There is nowhere to persist the monitoring data {}", monitoring); + return Single.just(monitoring); + } - Maybe monitoringObs; + final String monitoringKey = monitoring.getNodeId() + monitoring.getType(); - // This part is mainly done for clustering purpose, to ensure all nodes know about each other in the context - // of a cluster once they are flagged as master to process node infos. - if (monitoringHolder.containsKey(monitoringKey)) { - monitoringObs = Maybe.just(monitoringHolder.get(monitoringKey)); - } else { - monitoringObs = - repository.findByNodeIdAndType( - monitoring.getNodeId(), - monitoring.getType() - ); - } + Maybe monitoringObs; - final Date now = new Date(); - return monitoringObs - .flatMap( - existing -> { - monitoring.setId(existing.getId()); - monitoring.setCreatedAt(existing.getCreatedAt()); - monitoring.setUpdatedAt(now); - return repository.update(monitoring).toMaybe(); + // This part is mainly done for clustering purpose, to ensure all nodes know about each other in the context + // of a cluster once they are flagged as master to process node infos. + if (monitoringHolder.containsKey(monitoringKey)) { + monitoringObs = Maybe.just(monitoringHolder.get(monitoringKey)); + } else { + monitoringObs = repository.findByNodeIdAndType(monitoring.getNodeId(), monitoring.getType()); } - ) - .switchIfEmpty( - Single.defer( - () -> { - monitoring.setId(UUID.random().toString()); - monitoring.setCreatedAt(now); - monitoring.setUpdatedAt(now); - return repository.create(monitoring); - } - ) - ) - .doOnSuccess(toCache -> monitoringHolder.put(monitoringKey, toCache)) - .doFinally(this::cleanupMonitorHolder); - } - /** - * Remove all Monitor that have not been updated since {@link #CLEANUP_DELAY} milliseconds. - */ - private void cleanupMonitorHolder() { - final Date cleanupDate = new Date( - System.currentTimeMillis() - CLEANUP_DELAY - ); - monitoringHolder - .entrySet() - .removeIf(entry -> entry.getValue().getUpdatedAt().before(cleanupDate)); - } + final Date now = new Date(); + return monitoringObs + .flatMap(existing -> { + monitoring.setId(existing.getId()); + monitoring.setCreatedAt(existing.getCreatedAt()); + monitoring.setUpdatedAt(now); + return repository.update(monitoring).toMaybe(); + }) + .switchIfEmpty( + Single.defer(() -> { + monitoring.setId(UUID.random().toString()); + monitoring.setCreatedAt(now); + monitoring.setUpdatedAt(now); + return repository.create(monitoring); + }) + ) + .doOnSuccess(toCache -> monitoringHolder.put(monitoringKey, toCache)) + .doFinally(this::cleanupMonitorHolder); + } - public Flowable findByTypeAndTimeframe( - String type, - long from, - long to - ) { - if (repository == null) { - return Flowable.empty(); + /** + * Remove all Monitor that have not been updated since {@link #CLEANUP_DELAY} milliseconds. + */ + private void cleanupMonitorHolder() { + final Date cleanupDate = new Date(System.currentTimeMillis() - CLEANUP_DELAY); + monitoringHolder.entrySet().removeIf(entry -> entry.getValue().getUpdatedAt().before(cleanupDate)); } - return repository.findByTypeAndTimeFrame(type, from, to); - } + public Flowable findByTypeAndTimeframe(String type, long from, long to) { + if (repository == null) { + return Flowable.empty(); + } + + return repository.findByTypeAndTimeFrame(type, from, to); + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/AbstractCodec.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/AbstractCodec.java index 3acc73bb2..b6e22d191 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/AbstractCodec.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/AbstractCodec.java @@ -32,75 +32,69 @@ */ abstract class AbstractCodec implements MessageCodec { - private static final Logger LOGGER = LoggerFactory.getLogger( - AbstractCodec.class - ); - - private final String codecName; - - protected AbstractCodec(String codecName) { - this.codecName = codecName; - } - - @Override - public void encodeToWire(Buffer buffer, T item) { - try { - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - final ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(item); - oos.flush(); - - byte[] data = bos.toByteArray(); - int length = data.length; - - buffer.appendInt(length); - buffer.appendBytes(data); - } catch (final Exception ex) { - LOGGER.error("Error while trying to encode a Monitor object", ex); + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractCodec.class); + + private final String codecName; + + protected AbstractCodec(String codecName) { + this.codecName = codecName; } - } - - @Override - public T decodeFromWire(int position, Buffer buffer) { - try { - // My custom message starting from this *position* of buffer - int pos = position; - - // Length of data - int length = buffer.getInt(pos); - - pos += 4; - final int start = pos; - final int end = pos + length; - byte[] data = buffer.getBytes(start, end); - - ByteArrayInputStream in = new ByteArrayInputStream(data); - ObjectInputStream is = new ObjectInputStream(in); - return (T) is.readObject(); - } catch (Exception ex) { - LOGGER.error( - "Error while trying to decode object using codec {}", - this.codecName, - ex - ); + + @Override + public void encodeToWire(Buffer buffer, T item) { + try { + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + final ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(item); + oos.flush(); + + byte[] data = bos.toByteArray(); + int length = data.length; + + buffer.appendInt(length); + buffer.appendBytes(data); + } catch (final Exception ex) { + LOGGER.error("Error while trying to encode a Monitor object", ex); + } } - return null; - } + @Override + public T decodeFromWire(int position, Buffer buffer) { + try { + // My custom message starting from this *position* of buffer + int pos = position; - @Override - public T transform(T item) { - // If a message is sent *locally* across the event bus, just send message just as is. - return item; - } + // Length of data + int length = buffer.getInt(pos); - @Override - public String name() { - return this.codecName; - } + pos += 4; + final int start = pos; + final int end = pos + length; + byte[] data = buffer.getBytes(start, end); + + ByteArrayInputStream in = new ByteArrayInputStream(data); + ObjectInputStream is = new ObjectInputStream(in); + return (T) is.readObject(); + } catch (Exception ex) { + LOGGER.error("Error while trying to decode object using codec {}", this.codecName, ex); + } + + return null; + } - @Override - public byte systemCodecID() { - return -1; - } + @Override + public T transform(T item) { + // If a message is sent *locally* across the event bus, just send message just as is. + return item; + } + + @Override + public String name() { + return this.codecName; + } + + @Override + public byte systemCodecID() { + return -1; + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/HealthCheckCodec.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/HealthCheckCodec.java index 13aea2a15..4c7e1e51b 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/HealthCheckCodec.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/HealthCheckCodec.java @@ -25,9 +25,9 @@ */ public class HealthCheckCodec extends AbstractCodec { - public static final String CODEC_NAME = "gio:bus:codec:node_healthcheck"; + public static final String CODEC_NAME = "gio:bus:codec:node_healthcheck"; - public HealthCheckCodec() { - super(CODEC_NAME); - } + public HealthCheckCodec() { + super(CODEC_NAME); + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/MonitorCodec.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/MonitorCodec.java index 9bf41342e..fd914cd29 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/MonitorCodec.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/MonitorCodec.java @@ -31,9 +31,9 @@ */ public class MonitorCodec extends AbstractCodec { - public static final String CODEC_NAME = "gio:bus:codec:node_monitor"; + public static final String CODEC_NAME = "gio:bus:codec:node_monitor"; - public MonitorCodec() { - super(CODEC_NAME); - } + public MonitorCodec() { + super(CODEC_NAME); + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/NodeInfosCodec.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/NodeInfosCodec.java index a55175674..5dec7beb7 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/NodeInfosCodec.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/eventbus/NodeInfosCodec.java @@ -23,9 +23,9 @@ */ public class NodeInfosCodec extends AbstractCodec { - public static final String CODEC_NAME = "gio:bus:codec:node_infos"; + public static final String CODEC_NAME = "gio:bus:codec:node_infos"; - public NodeInfosCodec() { - super(CODEC_NAME); - } + public NodeInfosCodec() { + super(CODEC_NAME); + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/handler/ClusteredNodeMonitoringEventHandler.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/handler/ClusteredNodeMonitoringEventHandler.java index 13e9c21ef..077b7c85d 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/handler/ClusteredNodeMonitoringEventHandler.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/handler/ClusteredNodeMonitoringEventHandler.java @@ -36,117 +36,97 @@ * @author Jeoffrey HAEYAERT (jeoffrey.haeyaert at graviteesource.com) * @author GraviteeSource Team */ -public class ClusteredNodeMonitoringEventHandler - extends NodeMonitoringEventHandler { - - private static final Logger LOGGER = LoggerFactory.getLogger( - ClusteredNodeMonitoringEventHandler.class - ); - - private final ClusterManager clusterManager; - private final HazelcastInstance hazelcastInstance; - - protected ITopic distributedHealthCheckTopic; - protected ITopic distributedMonitorTopic; - protected ITopic distributedNodeInfosTopic; - private UUID healthCheckTopicListenerId; - private UUID monitorTopicListenerId; - private UUID nodeInfosTopicListenerId; - - public ClusteredNodeMonitoringEventHandler( - Vertx vertx, - ObjectMapper objectMapper, - Node node, - NodeMonitoringService nodeMonitoringService, - ClusterManager clusterManager, - HazelcastInstance hazelcastInstance - ) { - super(vertx, objectMapper, node, nodeMonitoringService); - this.clusterManager = clusterManager; - this.hazelcastInstance = hazelcastInstance; - } - - @Override - protected void doStart() throws Exception { - super.doStart(); - prepareListeners(); - } - - @Override - protected void doStop() throws Exception { - super.doStop(); - removeListeners(); - } - - private void prepareListeners() { - this.distributedHealthCheckTopic = - hazelcastInstance.getReliableTopic("node-healthcheck"); - this.distributedMonitorTopic = - hazelcastInstance.getReliableTopic("node-monitor"); - this.distributedNodeInfosTopic = - hazelcastInstance.getReliableTopic("node-infos"); - - this.healthCheckTopicListenerId = - distributedHealthCheckTopic.addMessageListener( - message -> { - if (clusterManager.isMasterNode()) { - LOGGER.debug( - "Received health check message from distributed topic" - ); - handleHealthCheck(message.getMessageObject()); - } - } - ); - - this.monitorTopicListenerId = - distributedMonitorTopic.addMessageListener( - message -> { - if (clusterManager.isMasterNode()) { - LOGGER.debug("Received monitor message from distributed topic"); - handleMonitor(message.getMessageObject()); - } - } - ); - - this.nodeInfosTopicListenerId = - distributedNodeInfosTopic.addMessageListener( - message -> { - if (clusterManager.isMasterNode()) { - LOGGER.debug("Received node infos message from distributed topic"); - handleNodeInfos(message.getMessageObject()); - } - } - ); - } - - private void removeListeners() { - this.distributedHealthCheckTopic.removeMessageListener( - this.healthCheckTopicListenerId - ); - this.distributedMonitorTopic.removeMessageListener( - this.monitorTopicListenerId - ); - this.distributedNodeInfosTopic.removeMessageListener( - this.nodeInfosTopicListenerId - ); - } - - @Override - protected void handleHealthCheckMessage(Message message) { - LOGGER.debug("Received health check message from internal bus"); - // We are in a cluster and distributed node monitoring is enabled. Propagate monitoring data across the cluster, it will be handled by the master node. - distributedHealthCheckTopic.publish(message.body()); - } - - @Override - protected void handleMonitorMessage(Message message) { - LOGGER.debug("Received monitor message from internal bus"); - distributedMonitorTopic.publish(message.body()); - } - - @Override - protected void handleNodeInfosMessage(Message message) { - LOGGER.debug("Received health check message from internal bus"); - distributedNodeInfosTopic.publish(message.body()); - } +public class ClusteredNodeMonitoringEventHandler extends NodeMonitoringEventHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(ClusteredNodeMonitoringEventHandler.class); + + private final ClusterManager clusterManager; + private final HazelcastInstance hazelcastInstance; + + protected ITopic distributedHealthCheckTopic; + protected ITopic distributedMonitorTopic; + protected ITopic distributedNodeInfosTopic; + private UUID healthCheckTopicListenerId; + private UUID monitorTopicListenerId; + private UUID nodeInfosTopicListenerId; + + public ClusteredNodeMonitoringEventHandler( + Vertx vertx, + ObjectMapper objectMapper, + Node node, + NodeMonitoringService nodeMonitoringService, + ClusterManager clusterManager, + HazelcastInstance hazelcastInstance + ) { + super(vertx, objectMapper, node, nodeMonitoringService); + this.clusterManager = clusterManager; + this.hazelcastInstance = hazelcastInstance; + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + prepareListeners(); + } + + @Override + protected void doStop() throws Exception { + super.doStop(); + removeListeners(); + } + + private void prepareListeners() { + this.distributedHealthCheckTopic = hazelcastInstance.getReliableTopic("node-healthcheck"); + this.distributedMonitorTopic = hazelcastInstance.getReliableTopic("node-monitor"); + this.distributedNodeInfosTopic = hazelcastInstance.getReliableTopic("node-infos"); + + this.healthCheckTopicListenerId = + distributedHealthCheckTopic.addMessageListener(message -> { + if (clusterManager.isMasterNode()) { + LOGGER.debug("Received health check message from distributed topic"); + handleHealthCheck(message.getMessageObject()); + } + }); + + this.monitorTopicListenerId = + distributedMonitorTopic.addMessageListener(message -> { + if (clusterManager.isMasterNode()) { + LOGGER.debug("Received monitor message from distributed topic"); + handleMonitor(message.getMessageObject()); + } + }); + + this.nodeInfosTopicListenerId = + distributedNodeInfosTopic.addMessageListener(message -> { + if (clusterManager.isMasterNode()) { + LOGGER.debug("Received node infos message from distributed topic"); + handleNodeInfos(message.getMessageObject()); + } + }); + } + + private void removeListeners() { + this.distributedHealthCheckTopic.removeMessageListener(this.healthCheckTopicListenerId); + this.distributedMonitorTopic.removeMessageListener(this.monitorTopicListenerId); + this.distributedNodeInfosTopic.removeMessageListener(this.nodeInfosTopicListenerId); + } + + @Override + protected void handleHealthCheckMessage(Message message) { + LOGGER.debug("Received health check message from internal bus"); + // We are in a cluster and distributed node monitoring is enabled. Propagate monitoring data across the cluster, it will be handled by the master node. + distributedHealthCheckTopic.publish(message.body()); + } + + @Override + protected void handleMonitorMessage(Message message) { + LOGGER.debug("Received monitor message from internal bus"); + distributedMonitorTopic.publish(message.body()); + } + + @Override + protected void handleNodeInfosMessage(Message message) { + LOGGER.debug("Received health check message from internal bus"); + distributedNodeInfosTopic.publish(message.body()); + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/handler/NodeMonitoringEventHandler.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/handler/NodeMonitoringEventHandler.java index f0c1728b1..0a7d5ba91 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/handler/NodeMonitoringEventHandler.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/handler/NodeMonitoringEventHandler.java @@ -39,119 +39,94 @@ * @author Jeoffrey HAEYAERT (jeoffrey.haeyaert at graviteesource.com) * @author GraviteeSource Team */ -public class NodeMonitoringEventHandler - extends AbstractService { - - private static final Logger LOGGER = LoggerFactory.getLogger( - NodeMonitoringEventHandler.class - ); - - protected final Vertx vertx; - protected final ObjectMapper objectMapper; - protected final Node node; - protected final NodeMonitoringService nodeMonitoringService; - - public NodeMonitoringEventHandler( - Vertx vertx, - ObjectMapper objectMapper, - Node node, - NodeMonitoringService nodeMonitoringService - ) { - this.vertx = vertx; - this.objectMapper = objectMapper; - this.node = node; - this.nodeMonitoringService = nodeMonitoringService; - } - - @Override - protected void doStart() throws Exception { - super.doStart(); - vertx - .eventBus() - .localConsumer( - NodeInfosService.GIO_NODE_INFOS_BUS, - this::handleNodeInfosMessage - ); - vertx - .eventBus() - .localConsumer( - NodeHealthCheckService.GIO_NODE_HEALTHCHECK_BUS, - this::handleHealthCheckMessage - ); - vertx - .eventBus() - .localConsumer( - NodeMonitorService.GIO_NODE_MONITOR_BUS, - this::handleMonitorMessage - ); - } - - protected void handleNodeInfosMessage(Message message) { - LOGGER.debug("Received node infos message from internal bus"); - handleNodeInfos(message.body()); - } - - protected void handleHealthCheckMessage(Message message) { - LOGGER.debug("Received health check message from internal bus"); - handleHealthCheck(message.body()); - } - - protected void handleMonitorMessage(Message message) { - LOGGER.debug("Received monitor message from internal bus"); - handleMonitor(message.body()); - } - - protected void handleNodeInfos(NodeInfos nodeInfos) { - LOGGER.debug("Received node infos message from internal bus"); - nodeMonitoringService.createOrUpdate(convert(nodeInfos)).subscribe(); - } - - protected void handleHealthCheck(HealthCheck healthCheck) { - LOGGER.debug("Processing health check data"); - nodeMonitoringService.createOrUpdate(convert(healthCheck)).subscribe(); - } - - protected void handleMonitor(Monitor monitor) { - LOGGER.debug("Processing monitor data"); - nodeMonitoringService.createOrUpdate(convert(monitor)).subscribe(); - } - - private Monitoring convert(NodeInfos nodeInfos) { - final Monitoring monitoring = buildMonitoring(nodeInfos); - monitoring.setEvaluatedAt(new Date(nodeInfos.getEvaluatedAt())); - monitoring.setType(Monitoring.NODE_INFOS); - - return monitoring; - } - - private Monitoring convert(HealthCheck healthCheck) { - final Monitoring monitoring = buildMonitoring(healthCheck); - monitoring.setEvaluatedAt(new Date(healthCheck.getEvaluatedAt())); - monitoring.setType(Monitoring.HEALTH_CHECK); - - return monitoring; - } - - private Monitoring convert(Monitor monitor) { - final Monitoring monitoring = buildMonitoring(monitor); - monitoring.setEvaluatedAt(new Date(monitor.getTimestamp())); - monitoring.setType(Monitoring.MONITOR); - - return monitoring; - } - - private Monitoring buildMonitoring(Object payload) { - final Monitoring monitoring = new Monitoring(); - monitoring.setNodeId(node.id()); - - try { - monitoring.setPayload(objectMapper.writeValueAsString(payload)); - } catch (JsonProcessingException e) { - LOGGER.error( - "An error occurred when trying to serialize monitoring payload to json" - ); +public class NodeMonitoringEventHandler extends AbstractService { + + private static final Logger LOGGER = LoggerFactory.getLogger(NodeMonitoringEventHandler.class); + + protected final Vertx vertx; + protected final ObjectMapper objectMapper; + protected final Node node; + protected final NodeMonitoringService nodeMonitoringService; + + public NodeMonitoringEventHandler(Vertx vertx, ObjectMapper objectMapper, Node node, NodeMonitoringService nodeMonitoringService) { + this.vertx = vertx; + this.objectMapper = objectMapper; + this.node = node; + this.nodeMonitoringService = nodeMonitoringService; + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + vertx.eventBus().localConsumer(NodeInfosService.GIO_NODE_INFOS_BUS, this::handleNodeInfosMessage); + vertx.eventBus().localConsumer(NodeHealthCheckService.GIO_NODE_HEALTHCHECK_BUS, this::handleHealthCheckMessage); + vertx.eventBus().localConsumer(NodeMonitorService.GIO_NODE_MONITOR_BUS, this::handleMonitorMessage); + } + + protected void handleNodeInfosMessage(Message message) { + LOGGER.debug("Received node infos message from internal bus"); + handleNodeInfos(message.body()); + } + + protected void handleHealthCheckMessage(Message message) { + LOGGER.debug("Received health check message from internal bus"); + handleHealthCheck(message.body()); + } + + protected void handleMonitorMessage(Message message) { + LOGGER.debug("Received monitor message from internal bus"); + handleMonitor(message.body()); + } + + protected void handleNodeInfos(NodeInfos nodeInfos) { + LOGGER.debug("Received node infos message from internal bus"); + nodeMonitoringService.createOrUpdate(convert(nodeInfos)).subscribe(); + } + + protected void handleHealthCheck(HealthCheck healthCheck) { + LOGGER.debug("Processing health check data"); + nodeMonitoringService.createOrUpdate(convert(healthCheck)).subscribe(); } - return monitoring; - } + protected void handleMonitor(Monitor monitor) { + LOGGER.debug("Processing monitor data"); + nodeMonitoringService.createOrUpdate(convert(monitor)).subscribe(); + } + + private Monitoring convert(NodeInfos nodeInfos) { + final Monitoring monitoring = buildMonitoring(nodeInfos); + monitoring.setEvaluatedAt(new Date(nodeInfos.getEvaluatedAt())); + monitoring.setType(Monitoring.NODE_INFOS); + + return monitoring; + } + + private Monitoring convert(HealthCheck healthCheck) { + final Monitoring monitoring = buildMonitoring(healthCheck); + monitoring.setEvaluatedAt(new Date(healthCheck.getEvaluatedAt())); + monitoring.setType(Monitoring.HEALTH_CHECK); + + return monitoring; + } + + private Monitoring convert(Monitor monitor) { + final Monitoring monitoring = buildMonitoring(monitor); + monitoring.setEvaluatedAt(new Date(monitor.getTimestamp())); + monitoring.setType(Monitoring.MONITOR); + + return monitoring; + } + + private Monitoring buildMonitoring(Object payload) { + final Monitoring monitoring = new Monitoring(); + monitoring.setNodeId(node.id()); + + try { + monitoring.setPayload(objectMapper.writeValueAsString(payload)); + } catch (JsonProcessingException e) { + LOGGER.error("An error occurred when trying to serialize monitoring payload to json"); + } + + return monitoring; + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckManagementEndpoint.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckManagementEndpoint.java index 7c9818773..5131a4a1b 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckManagementEndpoint.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckManagementEndpoint.java @@ -39,78 +39,66 @@ */ public class NodeHealthCheckManagementEndpoint implements ManagementEndpoint { - private static final Logger LOGGER = LoggerFactory.getLogger( - NodeHealthCheckManagementEndpoint.class - ); - - private NodeHealthCheckThread registry; - - final ObjectMapper objectMapper; - - public static final String PROBE_FILTER = "probes"; - - public NodeHealthCheckManagementEndpoint() { - objectMapper = DatabindCodec.prettyMapper(); - objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - } - - @Override - public HttpMethod method() { - return HttpMethod.GET; - } - - @Override - public String path() { - return "/health"; - } - - @Override - public void handle(RoutingContext ctx) { - Map probes = registry - .getResults() - .entrySet() - .stream() - .filter( - entry -> - ctx.queryParams().contains(PROBE_FILTER) - ? ctx.queryParams().get(PROBE_FILTER).contains(entry.getKey().id()) - : entry.getKey().isVisibleByDefault() - ) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - - boolean healthyProbe = probes.values().stream().allMatch(Result::isHealthy); - - HttpServerResponse response = ctx.response(); - response.setStatusCode( - healthyProbe - ? HttpStatusCode.OK_200 - : HttpStatusCode.INTERNAL_SERVER_ERROR_500 - ); - response.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); - response.setChunked(true); - - Map results = probes - .entrySet() - .stream() - .collect( - Collectors.toMap( - probeResultEntry -> probeResultEntry.getKey().id(), - Map.Entry::getValue - ) - ); - - try { - final ObjectMapper objectMapper = DatabindCodec.prettyMapper(); - response.write(objectMapper.writeValueAsString(results)); - } catch (JsonProcessingException e) { - LOGGER.warn("Unable to encode health check result into json.", e); + private static final Logger LOGGER = LoggerFactory.getLogger(NodeHealthCheckManagementEndpoint.class); + + private NodeHealthCheckThread registry; + + final ObjectMapper objectMapper; + + public static final String PROBE_FILTER = "probes"; + + public NodeHealthCheckManagementEndpoint() { + objectMapper = DatabindCodec.prettyMapper(); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + } + + @Override + public HttpMethod method() { + return HttpMethod.GET; } - // End the response - response.end(); - } + @Override + public String path() { + return "/health"; + } - public void setRegistry(NodeHealthCheckThread registry) { - this.registry = registry; - } + @Override + public void handle(RoutingContext ctx) { + Map probes = registry + .getResults() + .entrySet() + .stream() + .filter(entry -> + ctx.queryParams().contains(PROBE_FILTER) + ? ctx.queryParams().get(PROBE_FILTER).contains(entry.getKey().id()) + : entry.getKey().isVisibleByDefault() + ) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + boolean healthyProbe = probes.values().stream().allMatch(Result::isHealthy); + + HttpServerResponse response = ctx.response(); + response.setStatusCode(healthyProbe ? HttpStatusCode.OK_200 : HttpStatusCode.INTERNAL_SERVER_ERROR_500); + response.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); + response.setChunked(true); + + Map results = probes + .entrySet() + .stream() + .collect(Collectors.toMap(probeResultEntry -> probeResultEntry.getKey().id(), Map.Entry::getValue)); + + try { + final ObjectMapper objectMapper = DatabindCodec.prettyMapper(); + response.write(objectMapper.writeValueAsString(results)); + } catch (JsonProcessingException e) { + LOGGER.warn("Unable to encode health check result into json.", e); + } + + // End the response + response.end(); + } + + public void setRegistry(NodeHealthCheckThread registry) { + this.registry = registry; + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckService.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckService.java index 1f0a853fc..edfcdf626 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckService.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckService.java @@ -39,76 +39,69 @@ */ public class NodeHealthCheckService extends AbstractService { - public static final String GIO_NODE_HEALTHCHECK_BUS = "gio:node:healthcheck"; + public static final String GIO_NODE_HEALTHCHECK_BUS = "gio:node:healthcheck"; - @Autowired - private ManagementEndpointManager managementEndpointManager; + @Autowired + private ManagementEndpointManager managementEndpointManager; - @Autowired - private ProbeManager probeManager; + @Autowired + private ProbeManager probeManager; - @Autowired - private NodeHealthCheckManagementEndpoint healthCheckEndpoint; + @Autowired + private NodeHealthCheckManagementEndpoint healthCheckEndpoint; - @Autowired - private Vertx vertx; + @Autowired + private Vertx vertx; - private long metricsPollerId = -1; + private long metricsPollerId = -1; - private static final long NODE_CHECKER_DELAY = 5000; + private static final long NODE_CHECKER_DELAY = 5000; - private MessageProducer producer; + private MessageProducer producer; - @Override - protected void doStart() throws Exception { - super.doStart(); + @Override + protected void doStart() throws Exception { + super.doStart(); - producer = - vertx - .eventBus() - .registerCodec(new HealthCheckCodec()) - .sender( - GIO_NODE_HEALTHCHECK_BUS, - new DeliveryOptions() - .setTracingPolicy(TracingPolicy.IGNORE) - .setCodecName(HealthCheckCodec.CODEC_NAME) - ); + producer = + vertx + .eventBus() + .registerCodec(new HealthCheckCodec()) + .sender( + GIO_NODE_HEALTHCHECK_BUS, + new DeliveryOptions().setTracingPolicy(TracingPolicy.IGNORE).setCodecName(HealthCheckCodec.CODEC_NAME) + ); - // Poll data - NodeHealthCheckThread statusRegistry = new NodeHealthCheckThread( - probeManager.getProbes(), - producer - ); + // Poll data + NodeHealthCheckThread statusRegistry = new NodeHealthCheckThread(probeManager.getProbes(), producer); - applicationContext - .getAutowireCapableBeanFactory() - .autowireBean(statusRegistry); + applicationContext.getAutowireCapableBeanFactory().autowireBean(statusRegistry); - metricsPollerId = vertx.setPeriodic(NODE_CHECKER_DELAY, statusRegistry); + metricsPollerId = vertx.setPeriodic(NODE_CHECKER_DELAY, statusRegistry); - healthCheckEndpoint.setRegistry(statusRegistry); - managementEndpointManager.register(healthCheckEndpoint); + healthCheckEndpoint.setRegistry(statusRegistry); + managementEndpointManager.register(healthCheckEndpoint); - MeterRegistry registry = BackendRegistries.getDefaultNow(); + MeterRegistry registry = BackendRegistries.getDefaultNow(); - if (registry instanceof PrometheusMeterRegistry) { - new NodeHealthCheckMicrometerHandler(statusRegistry).bindTo(registry); + if (registry instanceof PrometheusMeterRegistry) { + new NodeHealthCheckMicrometerHandler(statusRegistry).bindTo(registry); + } } - } - @Override - protected void doStop() throws Exception { - super.doStop(); + @Override + protected void doStop() throws Exception { + super.doStop(); - if (metricsPollerId > 0) { - vertx.cancelTimer(metricsPollerId); - } + if (metricsPollerId > 0) { + vertx.cancelTimer(metricsPollerId); + } - producer.close(); - } + producer.close(); + } - @Override - protected String name() { - return "Node Health-check service"; - } + @Override + protected String name() { + return "Node Health-check service"; + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckThread.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckThread.java index dc1e4b164..c5088eeae 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckThread.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckThread.java @@ -40,124 +40,96 @@ */ public class NodeHealthCheckThread implements Handler { - private static final Logger LOGGER = LoggerFactory.getLogger( - NodeHealthCheckThread.class - ); - - @Autowired - private AlertEventProducer eventProducer; - - @Autowired - private Node node; - - private long timestamp; - - private final Map results; - - private final MessageProducer producer; - - public NodeHealthCheckThread( - List probes, - MessageProducer producer - ) { - this.results = - probes - .stream() - .collect(Collectors.toMap(probe -> probe, probe -> Result.notReady())); - this.producer = producer; - } - - @Override - public void handle(Long tick) { - this.timestamp = System.currentTimeMillis(); - - for (Map.Entry probe : results.entrySet()) { - try { - probe.getKey().check().thenAccept(probe::setValue); - } catch (Exception ex) { - LOGGER.error( - "An error occurred when trying to evaluate health check probe {}. Switching probe to unhealthy.", - probe.getKey(), - ex - ); - probe.setValue(Result.unhealthy(ex)); - } + private static final Logger LOGGER = LoggerFactory.getLogger(NodeHealthCheckThread.class); + + @Autowired + private AlertEventProducer eventProducer; + + @Autowired + private Node node; + + private long timestamp; + + private final Map results; + + private final MessageProducer producer; + + public NodeHealthCheckThread(List probes, MessageProducer producer) { + this.results = probes.stream().collect(Collectors.toMap(probe -> probe, probe -> Result.notReady())); + this.producer = producer; } - // We want to propagate health-check with visible probes only. - final HealthCheck healthCheck = getHealthCheck(true); - producer.write(healthCheck); - sendAlertEngineEvent(healthCheck); - } - - private void sendAlertEngineEvent(HealthCheck healthCheck) { - DefaultEvent.Builder builder = Event.now().type(NODE_HEALTHCHECK); - - builder.property(PROPERTY_NODE_ID, node.id()); - builder.property(PROPERTY_NODE_HOSTNAME, node.hostname()); - builder.property(PROPERTY_NODE_APPLICATION, node.application()); - builder.property( - PROPERTY_NODE_HEALTHY, - String.valueOf(healthCheck.isHealthy()) - ); - builder.organizations( - (Set) node.metadata().get(Node.META_ORGANIZATIONS) - ); - builder.environments( - (Set) node.metadata().get(Node.META_ENVIRONMENTS) - ); - - healthCheck - .getResults() - .forEach( - (probeId, result) -> { - builder.property(PROPERTY_PROBE_SUFFIX + probeId, result.isHealthy()); - if (!result.isHealthy()) { - builder.property( - PROPERTY_PROBE_SUFFIX + probeId + ".message", - result.getMessage() - ); - } + @Override + public void handle(Long tick) { + this.timestamp = System.currentTimeMillis(); + + for (Map.Entry probe : results.entrySet()) { + try { + probe.getKey().check().thenAccept(probe::setValue); + } catch (Exception ex) { + LOGGER.error( + "An error occurred when trying to evaluate health check probe {}. Switching probe to unhealthy.", + probe.getKey(), + ex + ); + probe.setValue(Result.unhealthy(ex)); + } } - ); - - eventProducer.send(builder.build()); - } - - /** - * Returns the health-check with all probes which are visible by default. - * - * @return health-check with all probes which are visible by default. - */ - public HealthCheck getHealthCheck() { - return getHealthCheck(false); - } - - /** - * Returns the health-check with either all probes either only visible by default ones. - * - * @param filterVisibleByDefault flag indicating if probes must be filtered to visible by default or not. - * @return health-check with all probes which are visible by default. - */ - public HealthCheck getHealthCheck(boolean filterVisibleByDefault) { - Map results = - this.results.entrySet() - .stream() - .filter( - entry -> - !filterVisibleByDefault || entry.getKey().isVisibleByDefault() - ) - .collect( - Collectors.toMap( - probeResultEntry -> probeResultEntry.getKey().id(), - Map.Entry::getValue - ) - ); - - return new HealthCheck(timestamp, results); - } - - public Map getResults() { - return results; - } + + // We want to propagate health-check with visible probes only. + final HealthCheck healthCheck = getHealthCheck(true); + producer.write(healthCheck); + sendAlertEngineEvent(healthCheck); + } + + private void sendAlertEngineEvent(HealthCheck healthCheck) { + DefaultEvent.Builder builder = Event.now().type(NODE_HEALTHCHECK); + + builder.property(PROPERTY_NODE_ID, node.id()); + builder.property(PROPERTY_NODE_HOSTNAME, node.hostname()); + builder.property(PROPERTY_NODE_APPLICATION, node.application()); + builder.property(PROPERTY_NODE_HEALTHY, String.valueOf(healthCheck.isHealthy())); + builder.organizations((Set) node.metadata().get(Node.META_ORGANIZATIONS)); + builder.environments((Set) node.metadata().get(Node.META_ENVIRONMENTS)); + + healthCheck + .getResults() + .forEach((probeId, result) -> { + builder.property(PROPERTY_PROBE_SUFFIX + probeId, result.isHealthy()); + if (!result.isHealthy()) { + builder.property(PROPERTY_PROBE_SUFFIX + probeId + ".message", result.getMessage()); + } + }); + + eventProducer.send(builder.build()); + } + + /** + * Returns the health-check with all probes which are visible by default. + * + * @return health-check with all probes which are visible by default. + */ + public HealthCheck getHealthCheck() { + return getHealthCheck(false); + } + + /** + * Returns the health-check with either all probes either only visible by default ones. + * + * @param filterVisibleByDefault flag indicating if probes must be filtered to visible by default or not. + * @return health-check with all probes which are visible by default. + */ + public HealthCheck getHealthCheck(boolean filterVisibleByDefault) { + Map results = + this.results.entrySet() + .stream() + .filter(entry -> !filterVisibleByDefault || entry.getKey().isVisibleByDefault()) + .collect(Collectors.toMap(probeResultEntry -> probeResultEntry.getKey().id(), Map.Entry::getValue)); + + return new HealthCheck(timestamp, results); + } + + public Map getResults() { + return results; + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/ProbeManagerImpl.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/ProbeManagerImpl.java index 3031d7944..6a68d2e38 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/ProbeManagerImpl.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/ProbeManagerImpl.java @@ -27,33 +27,31 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class ProbeManagerImpl - extends SpringFactoriesLoader - implements ProbeManager { +public class ProbeManagerImpl extends SpringFactoriesLoader implements ProbeManager { - @Override - protected Class getObjectType() { - return Probe.class; - } + @Override + protected Class getObjectType() { + return Probe.class; + } - private Map probes = new HashMap<>(); + private Map probes = new HashMap<>(); - @Override - public List getProbes() { - ArrayList probes = new ArrayList<>(getFactoriesInstances()); - probes.addAll(this.probes.values()); - return probes; - } + @Override + public List getProbes() { + ArrayList probes = new ArrayList<>(getFactoriesInstances()); + probes.addAll(this.probes.values()); + return probes; + } - @Override - public void register(Probe probe) { - probes.put(probe.id(), probe); - } + @Override + public void register(Probe probe) { + probes.put(probe.id(), probe); + } - @Override - public void unregister(Probe probe) { - if (probes.containsKey(probe.id())) { - probes.remove(probe.id()); + @Override + public void unregister(Probe probe) { + if (probes.containsKey(probe.id())) { + probes.remove(probe.id()); + } } - } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/micrometer/NodeHealthCheckMicrometerHandler.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/micrometer/NodeHealthCheckMicrometerHandler.java index 158d73c8e..81c32a77d 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/micrometer/NodeHealthCheckMicrometerHandler.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/micrometer/NodeHealthCheckMicrometerHandler.java @@ -32,29 +32,23 @@ */ public class NodeHealthCheckMicrometerHandler implements MeterBinder { - private static final Logger LOGGER = LoggerFactory.getLogger( - NodeHealthCheckMicrometerHandler.class - ); + private static final Logger LOGGER = LoggerFactory.getLogger(NodeHealthCheckMicrometerHandler.class); - private final NodeHealthCheckThread statusRegistry; + private final NodeHealthCheckThread statusRegistry; - public NodeHealthCheckMicrometerHandler( - NodeHealthCheckThread statusRegistry - ) { - this.statusRegistry = statusRegistry; - } + public NodeHealthCheckMicrometerHandler(NodeHealthCheckThread statusRegistry) { + this.statusRegistry = statusRegistry; + } - @Override - public void bindTo(@NonNull MeterRegistry registry) { - for (Map.Entry entry : statusRegistry - .getResults() - .entrySet()) { - Gauge - .builder("node", entry, e -> e.getValue().isHealthy() ? 1 : 0) - .tag("probe", entry.getKey().id()) - .description("The health-check probes of the node") - .baseUnit("health") - .register(registry); + @Override + public void bindTo(@NonNull MeterRegistry registry) { + for (Map.Entry entry : statusRegistry.getResults().entrySet()) { + Gauge + .builder("node", entry, e -> e.getValue().isHealthy() ? 1 : 0) + .tag("probe", entry.getKey().id()) + .description("The health-check probes of the node") + .baseUnit("health") + .register(registry); + } } - } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/probe/CPUProbe.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/probe/CPUProbe.java index 2bef9e939..60540ab04 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/probe/CPUProbe.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/probe/CPUProbe.java @@ -27,35 +27,29 @@ */ public class CPUProbe implements Probe { - @Value("${services.health.threshold.cpu:80}") - private int threshold; + @Value("${services.health.threshold.cpu:80}") + private int threshold; - @Override - public String id() { - return "cpu"; - } + @Override + public String id() { + return "cpu"; + } - @Override - public boolean isVisibleByDefault() { - return false; - } + @Override + public boolean isVisibleByDefault() { + return false; + } - @Override - public CompletableFuture check() { - try { - return CompletableFuture.supplyAsync( - () -> - ProcessProbe.getInstance().getProcessCpuPercent() < threshold - ? Result.healthy() - : Result.unhealthy( - String.format( - "CPU percent is over the threshold of %d %%", - threshold - ) - ) - ); - } catch (Exception ex) { - return CompletableFuture.completedFuture(Result.unhealthy(ex)); + @Override + public CompletableFuture check() { + try { + return CompletableFuture.supplyAsync(() -> + ProcessProbe.getInstance().getProcessCpuPercent() < threshold + ? Result.healthy() + : Result.unhealthy(String.format("CPU percent is over the threshold of %d %%", threshold)) + ); + } catch (Exception ex) { + return CompletableFuture.completedFuture(Result.unhealthy(ex)); + } } - } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/probe/MemoryProbe.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/probe/MemoryProbe.java index cbd678de6..8d3e10c6d 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/probe/MemoryProbe.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/healthcheck/probe/MemoryProbe.java @@ -27,35 +27,29 @@ */ public class MemoryProbe implements Probe { - @Value("${services.health.threshold.memory:80}") - private int threshold; + @Value("${services.health.threshold.memory:80}") + private int threshold; - @Override - public String id() { - return "memory"; - } + @Override + public String id() { + return "memory"; + } - @Override - public boolean isVisibleByDefault() { - return false; - } + @Override + public boolean isVisibleByDefault() { + return false; + } - @Override - public CompletableFuture check() { - try { - return CompletableFuture.supplyAsync( - () -> - JvmProbe.getInstance().jvmInfo().mem.getHeapUsedPercent() < threshold - ? Result.healthy() - : Result.unhealthy( - String.format( - "Memory percent is over the threshold of %d %%", - threshold - ) - ) - ); - } catch (Exception ex) { - return CompletableFuture.completedFuture(Result.unhealthy(ex)); + @Override + public CompletableFuture check() { + try { + return CompletableFuture.supplyAsync(() -> + JvmProbe.getInstance().jvmInfo().mem.getHeapUsedPercent() < threshold + ? Result.healthy() + : Result.unhealthy(String.format("Memory percent is over the threshold of %d %%", threshold)) + ); + } catch (Exception ex) { + return CompletableFuture.completedFuture(Result.unhealthy(ex)); + } } - } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/infos/NodeInfosService.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/infos/NodeInfosService.java index 383a56186..aac67f544 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/infos/NodeInfosService.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/infos/NodeInfosService.java @@ -45,142 +45,131 @@ */ public class NodeInfosService extends AbstractService { - private static final Logger LOGGER = LoggerFactory.getLogger( - NodeInfosService.class - ); - public static final String GIO_NODE_INFOS_BUS = "gio:node:infos"; + private static final Logger LOGGER = LoggerFactory.getLogger(NodeInfosService.class); + public static final String GIO_NODE_INFOS_BUS = "gio:node:infos"; - @Autowired - private PluginRegistry pluginRegistry; + @Autowired + private PluginRegistry pluginRegistry; - @Autowired - private Environment environment; + @Autowired + private Environment environment; - @Autowired - private Node node; + @Autowired + private Node node; - @Autowired - private Vertx vertx; + @Autowired + private Vertx vertx; - private MessageProducer messageProducer; + private MessageProducer messageProducer; - private NodeInfos nodeInfos; + private NodeInfos nodeInfos; - @Override - protected void doStart() throws Exception { - LOGGER.info("Starting node infos service"); + @Override + protected void doStart() throws Exception { + LOGGER.info("Starting node infos service"); - super.doStart(); + super.doStart(); - messageProducer = - vertx - .eventBus() - .registerCodec(new NodeInfosCodec()) - .sender( - GIO_NODE_INFOS_BUS, - new DeliveryOptions() - .setCodecName(NodeInfosCodec.CODEC_NAME) - .setTracingPolicy(TracingPolicy.IGNORE) - ); + messageProducer = + vertx + .eventBus() + .registerCodec(new NodeInfosCodec()) + .sender( + GIO_NODE_INFOS_BUS, + new DeliveryOptions().setCodecName(NodeInfosCodec.CODEC_NAME).setTracingPolicy(TracingPolicy.IGNORE) + ); - nodeInfos = buildNodeInfos(); - nodeInfos.setStatus(NodeStatus.STARTED); - messageProducer.write(nodeInfos); + nodeInfos = buildNodeInfos(); + nodeInfos.setStatus(NodeStatus.STARTED); + messageProducer.write(nodeInfos); - LOGGER.info("Start node infos service: DONE"); - } + LOGGER.info("Start node infos service: DONE"); + } + + public NodeInfosService preStop() { + if (nodeInfos == null) { + return this; + } + + nodeInfos.setStatus(NodeStatus.STOPPED); + messageProducer.write(nodeInfos); - public NodeInfosService preStop() { - if (nodeInfos == null) { - return this; + return this; } - nodeInfos.setStatus(NodeStatus.STOPPED); - messageProducer.write(nodeInfos); + @Override + protected void doStop() throws Exception { + LOGGER.info("Stopping node infos service"); - return this; - } + super.doStop(); - @Override - protected void doStop() throws Exception { - LOGGER.info("Stopping node infos service"); + LOGGER.info("Stop node infos service : DONE"); + } + + @Override + protected String name() { + return "Node Infos Service"; + } - super.doStop(); + private NodeInfos buildNodeInfos() { + NodeInfos nodeInfos = new NodeInfos(); + + nodeInfos.setId(node.id()); + nodeInfos.setName(node.name()); + nodeInfos.setApplication(node.application()); + nodeInfos.setVersion(Version.RUNTIME_VERSION.toString()); + nodeInfos.setTags(getShardingTags()); + nodeInfos.setTenant(getTenant()); + nodeInfos.setPluginInfos(plugins()); + nodeInfos.setJdkVersion(Constants.JVM_NAME + " " + Constants.JVM_VERSION); + nodeInfos.setEvaluatedAt(System.currentTimeMillis()); + + try { + nodeInfos.setPort(getPort()); + } catch (NumberFormatException nfe) { + LOGGER.warn("Could not get http server port.", nfe); + } - LOGGER.info("Stop node infos service : DONE"); - } + try { + nodeInfos.setHostname(InetAddress.getLocalHost().getHostName()); + nodeInfos.setIp(InetAddress.getLocalHost().getHostAddress()); + } catch (UnknownHostException uhe) { + LOGGER.warn("Could not get hostname / IP", uhe); + } - @Override - protected String name() { - return "Node Infos Service"; - } + return nodeInfos; + } - private NodeInfos buildNodeInfos() { - NodeInfos nodeInfos = new NodeInfos(); + private Set plugins() { + return pluginRegistry + .plugins() + .stream() + .map(regPlugin -> { + PluginInfos plugin = new PluginInfos(); + plugin.setId(regPlugin.id()); + plugin.setName(regPlugin.manifest().name()); + plugin.setDescription(regPlugin.manifest().description()); + plugin.setVersion(regPlugin.manifest().version()); + plugin.setType(regPlugin.type().toLowerCase()); + plugin.setPlugin(regPlugin.clazz()); + return plugin; + }) + .collect(Collectors.toSet()); + } - nodeInfos.setId(node.id()); - nodeInfos.setName(node.name()); - nodeInfos.setApplication(node.application()); - nodeInfos.setVersion(Version.RUNTIME_VERSION.toString()); - nodeInfos.setTags(getShardingTags()); - nodeInfos.setTenant(getTenant()); - nodeInfos.setPluginInfos(plugins()); - nodeInfos.setJdkVersion(Constants.JVM_NAME + " " + Constants.JVM_VERSION); - nodeInfos.setEvaluatedAt(System.currentTimeMillis()); + private List getShardingTags() { + return Arrays.asList(environment.getProperty("tags", "").split(",")); + } - try { - nodeInfos.setPort(getPort()); - } catch (NumberFormatException nfe) { - LOGGER.warn("Could not get http server port.", nfe); + private String getTenant() { + return environment.getProperty("tenant"); } - try { - nodeInfos.setHostname(InetAddress.getLocalHost().getHostName()); - nodeInfos.setIp(InetAddress.getLocalHost().getHostAddress()); - } catch (UnknownHostException uhe) { - LOGGER.warn("Could not get hostname / IP", uhe); + private String getZone() { + return environment.getProperty("zone"); } - return nodeInfos; - } - - private Set plugins() { - return pluginRegistry - .plugins() - .stream() - .map( - regPlugin -> { - PluginInfos plugin = new PluginInfos(); - plugin.setId(regPlugin.id()); - plugin.setName(regPlugin.manifest().name()); - plugin.setDescription(regPlugin.manifest().description()); - plugin.setVersion(regPlugin.manifest().version()); - plugin.setType(regPlugin.type().toLowerCase()); - plugin.setPlugin(regPlugin.clazz()); - return plugin; - } - ) - .collect(Collectors.toSet()); - } - - private List getShardingTags() { - return Arrays.asList(environment.getProperty("tags", "").split(",")); - } - - private String getTenant() { - return environment.getProperty("tenant"); - } - - private String getZone() { - return environment.getProperty("zone"); - } - - private int getPort() { - return Integer.parseInt( - environment.getProperty( - "http.port", - environment.getProperty("jetty.port", "-1") - ) - ); - } + private int getPort() { + return Integer.parseInt(environment.getProperty("http.port", environment.getProperty("jetty.port", "-1"))); + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/NodeMonitorManagementEndpoint.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/NodeMonitorManagementEndpoint.java index da3b75711..1c144d7e4 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/NodeMonitorManagementEndpoint.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/NodeMonitorManagementEndpoint.java @@ -39,48 +39,44 @@ */ public class NodeMonitorManagementEndpoint implements ManagementEndpoint { - private static final Logger LOGGER = LoggerFactory.getLogger( - NodeMonitorManagementEndpoint.class - ); + private static final Logger LOGGER = LoggerFactory.getLogger(NodeMonitorManagementEndpoint.class); - @Autowired - private ObjectMapper mapper; + @Autowired + private ObjectMapper mapper; - @Override - public HttpMethod method() { - return HttpMethod.GET; - } + @Override + public HttpMethod method() { + return HttpMethod.GET; + } + + @Override + public String path() { + return "/monitor"; + } - @Override - public String path() { - return "/monitor"; - } + @Override + public void handle(RoutingContext context) { + HttpServerResponse response = context.response(); + try { + ObjectNode root = mapper.createObjectNode(); - @Override - public void handle(RoutingContext context) { - HttpServerResponse response = context.response(); - try { - ObjectNode root = mapper.createObjectNode(); + JsonNode os = mapper.valueToTree(OsProbe.getInstance().osInfo()); + JsonNode jvm = mapper.valueToTree(JvmProbe.getInstance().jvmInfo()); + JsonNode process = mapper.valueToTree(ProcessProbe.getInstance().processInfo()); - JsonNode os = mapper.valueToTree(OsProbe.getInstance().osInfo()); - JsonNode jvm = mapper.valueToTree(JvmProbe.getInstance().jvmInfo()); - JsonNode process = mapper.valueToTree( - ProcessProbe.getInstance().processInfo() - ); + root.set("os", os); + root.set("jvm", jvm); + root.set("process", process); - root.set("os", os); - root.set("jvm", jvm); - root.set("process", process); + response.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); + response.setChunked(true); + response.write(mapper.writeValueAsString(root)); + response.setStatusCode(HttpStatusCode.OK_200); + } catch (JsonProcessingException e) { + LOGGER.error("Unexpected error while generating monitoring", e); + response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR_500); + } - response.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); - response.setChunked(true); - response.write(mapper.writeValueAsString(root)); - response.setStatusCode(HttpStatusCode.OK_200); - } catch (JsonProcessingException e) { - LOGGER.error("Unexpected error while generating monitoring", e); - response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR_500); + response.end(); } - - response.end(); - } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/NodeMonitorService.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/NodeMonitorService.java index 378170a2b..452f6de83 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/NodeMonitorService.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/NodeMonitorService.java @@ -44,143 +44,118 @@ */ public class NodeMonitorService extends AbstractService { - public static final String GIO_NODE_MONITOR_BUS = "gio:node:monitor"; - - private static final Logger LOGGER = LoggerFactory.getLogger( - NodeMonitorService.class - ); - - @Value("${services.monitoring.enabled:true}") - private boolean enabled; - - @Value("${services.monitoring.delay:5000}") - private int delay; - - @Value("${services.monitoring.unit:MILLISECONDS}") - private TimeUnit unit; - - private ExecutorService executorService; - - @Autowired - private NodeMonitorManagementEndpoint nodeMonitorManagementEndpoint; - - @Autowired - private ManagementEndpointManager managementEndpointManager; - - @Autowired - private Node node; - - @Autowired - private AlertEventProducer eventProducer; - - @Autowired - private Vertx vertx; - - private MessageProducer producer; - - @Override - protected void doStart() throws Exception { - if (enabled) { - super.doStart(); - - executorService = - Executors.newSingleThreadScheduledExecutor( - r -> new Thread(r, "node-monitor") - ); - - producer = - vertx - .eventBus() - .registerCodec(new MonitorCodec()) - .sender( - GIO_NODE_MONITOR_BUS, - new DeliveryOptions() - .setTracingPolicy(TracingPolicy.IGNORE) - .setCodecName(MonitorCodec.CODEC_NAME) - ); - - NodeMonitorThread monitorThread = new NodeMonitorThread(producer); - this.applicationContext.getAutowireCapableBeanFactory() - .autowireBean(monitorThread); - - // Send an event to notify about the node status - eventProducer.send( - Event - .now() - .type(NODE_LIFECYCLE) - .property(PROPERTY_NODE_EVENT, NODE_EVENT_START) - .property(PROPERTY_NODE_ID, node.id()) - .property(PROPERTY_NODE_HOSTNAME, node.hostname()) - .property(PROPERTY_NODE_APPLICATION, node.application()) - .organizations( - (Set) node.metadata().get(Node.META_ORGANIZATIONS) - ) - .environments( - (Set) node.metadata().get(Node.META_ENVIRONMENTS) - ) - .build() - ); - - LOGGER.info( - "Node monitoring scheduled with fixed delay {} {} ", - delay, - unit.name() - ); - - ((ScheduledExecutorService) executorService).scheduleWithFixedDelay( - monitorThread, - 0, - delay, - unit - ); - - managementEndpointManager.register(nodeMonitorManagementEndpoint); - } - } - - @Override - public NodeMonitorService preStop() throws Exception { - if (enabled) { - // Send an event to notify about the node status - eventProducer.send( - Event - .now() - .type(NODE_LIFECYCLE) - .property(PROPERTY_NODE_EVENT, NODE_EVENT_STOP) - .property(PROPERTY_NODE_ID, node.id()) - .property(PROPERTY_NODE_HOSTNAME, node.hostname()) - .property(PROPERTY_NODE_APPLICATION, node.application()) - .organizations( - (Set) node.metadata().get(Node.META_ORGANIZATIONS) - ) - .environments( - (Set) node.metadata().get(Node.META_ENVIRONMENTS) - ) - .build() - ); + public static final String GIO_NODE_MONITOR_BUS = "gio:node:monitor"; + + private static final Logger LOGGER = LoggerFactory.getLogger(NodeMonitorService.class); + + @Value("${services.monitoring.enabled:true}") + private boolean enabled; + + @Value("${services.monitoring.delay:5000}") + private int delay; + + @Value("${services.monitoring.unit:MILLISECONDS}") + private TimeUnit unit; + + private ExecutorService executorService; + + @Autowired + private NodeMonitorManagementEndpoint nodeMonitorManagementEndpoint; + + @Autowired + private ManagementEndpointManager managementEndpointManager; + + @Autowired + private Node node; + + @Autowired + private AlertEventProducer eventProducer; + + @Autowired + private Vertx vertx; + + private MessageProducer producer; + + @Override + protected void doStart() throws Exception { + if (enabled) { + super.doStart(); + + executorService = Executors.newSingleThreadScheduledExecutor(r -> new Thread(r, "node-monitor")); + + producer = + vertx + .eventBus() + .registerCodec(new MonitorCodec()) + .sender( + GIO_NODE_MONITOR_BUS, + new DeliveryOptions().setTracingPolicy(TracingPolicy.IGNORE).setCodecName(MonitorCodec.CODEC_NAME) + ); + + NodeMonitorThread monitorThread = new NodeMonitorThread(producer); + this.applicationContext.getAutowireCapableBeanFactory().autowireBean(monitorThread); + + // Send an event to notify about the node status + eventProducer.send( + Event + .now() + .type(NODE_LIFECYCLE) + .property(PROPERTY_NODE_EVENT, NODE_EVENT_START) + .property(PROPERTY_NODE_ID, node.id()) + .property(PROPERTY_NODE_HOSTNAME, node.hostname()) + .property(PROPERTY_NODE_APPLICATION, node.application()) + .organizations((Set) node.metadata().get(Node.META_ORGANIZATIONS)) + .environments((Set) node.metadata().get(Node.META_ENVIRONMENTS)) + .build() + ); + + LOGGER.info("Node monitoring scheduled with fixed delay {} {} ", delay, unit.name()); + + ((ScheduledExecutorService) executorService).scheduleWithFixedDelay(monitorThread, 0, delay, unit); + + managementEndpointManager.register(nodeMonitorManagementEndpoint); + } } - return this; - } + @Override + public NodeMonitorService preStop() throws Exception { + if (enabled) { + // Send an event to notify about the node status + eventProducer.send( + Event + .now() + .type(NODE_LIFECYCLE) + .property(PROPERTY_NODE_EVENT, NODE_EVENT_STOP) + .property(PROPERTY_NODE_ID, node.id()) + .property(PROPERTY_NODE_HOSTNAME, node.hostname()) + .property(PROPERTY_NODE_APPLICATION, node.application()) + .organizations((Set) node.metadata().get(Node.META_ORGANIZATIONS)) + .environments((Set) node.metadata().get(Node.META_ENVIRONMENTS)) + .build() + ); + } + + return this; + } - @Override - protected void doStop() throws Exception { - if (enabled) { - if (!executorService.isShutdown()) { - LOGGER.info("Stop node monitor"); - executorService.shutdownNow(); - } else { - LOGGER.info("Node monitor already shutdown"); - } + @Override + protected void doStop() throws Exception { + if (enabled) { + if (!executorService.isShutdown()) { + LOGGER.info("Stop node monitor"); + executorService.shutdownNow(); + } else { + LOGGER.info("Node monitor already shutdown"); + } - super.doStop(); + super.doStop(); - LOGGER.info("Stop node monitor : DONE"); + LOGGER.info("Stop node monitor : DONE"); + } } - } - @Override - protected String name() { - return "Node Monitor Service"; - } + @Override + protected String name() { + return "Node Monitor Service"; + } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/NodeMonitorThread.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/NodeMonitorThread.java index 70dbb882c..502e3c786 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/NodeMonitorThread.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/NodeMonitorThread.java @@ -40,85 +40,71 @@ */ public class NodeMonitorThread implements Runnable { - private static final Logger LOGGER = LoggerFactory.getLogger( - NodeMonitorThread.class - ); - - private final MessageProducer producer; - - public NodeMonitorThread(final MessageProducer producer) { - this.producer = producer; - } - - @Autowired - private Node node; - - @Autowired - private AlertEventProducer eventProducer; - - @Override - public void run() { - try { - Monitor monitor = Monitor - .on(node.id()) - .at(System.currentTimeMillis()) - .os(OsProbe.getInstance().osInfo()) - .jvm(JvmProbe.getInstance().jvmInfo()) - .process(ProcessProbe.getInstance().processInfo()) - .build(); - - // And generate monitoring metrics - producer.write(monitor); - - if (!eventProducer.isEmpty()) { - DefaultEvent.Builder event = Event - .at(monitor.getTimestamp()) - .type(NODE_HEARTBEAT); - - event.property(PROPERTY_NODE_ID, node.id()); - event.property(PROPERTY_NODE_HOSTNAME, node.hostname()); - event.property(PROPERTY_NODE_APPLICATION, node.application()); - event.organizations( - (Set) node.metadata().get(Node.META_ORGANIZATIONS) - ); - event.environments( - (Set) node.metadata().get(Node.META_ENVIRONMENTS) - ); - - // OS metrics - OsInfo osInfo = monitor.getOs(); - event.property("os.cpu.percent", osInfo.cpu.getPercent()); - for (int i = 0; i < osInfo.cpu.getLoadAverage().length; i++) { - event.property("os.cpu.average." + i, osInfo.cpu.getLoadAverage()[i]); - } + private static final Logger LOGGER = LoggerFactory.getLogger(NodeMonitorThread.class); + + private final MessageProducer producer; - // Process metrics - ProcessInfo processInfo = monitor.getProcess(); - event.property("process.fd.open", processInfo.openFileDescriptors); - event.property("process.fd.max", processInfo.maxFileDescriptors); - event.property("process.cpu.percent", processInfo.cpu.percent); - event.property("process.cpu.total", processInfo.cpu.total); - event.property( - "process.mem.virtual.total", - processInfo.mem.totalVirtual - ); - - // JVM metrics - JvmInfo jvmInfo = monitor.getJvm(); - event.property("jvm.uptime", jvmInfo.uptime); - event.property("jvm.threads.count", jvmInfo.threads.count); - event.property("jvm.threads.peak", jvmInfo.threads.peakCount); - event.property("jvm.mem.heap.used", jvmInfo.mem.heapUsed); - event.property("jvm.mem.heap.max", jvmInfo.mem.heapMax); - event.property( - "jvm.mem.heap.percent", - jvmInfo.mem.getHeapUsedPercent() - ); - - eventProducer.send(event.build()); - } - } catch (Exception ex) { - LOGGER.error("Unexpected error occurs while monitoring the node", ex); + public NodeMonitorThread(final MessageProducer producer) { + this.producer = producer; + } + + @Autowired + private Node node; + + @Autowired + private AlertEventProducer eventProducer; + + @Override + public void run() { + try { + Monitor monitor = Monitor + .on(node.id()) + .at(System.currentTimeMillis()) + .os(OsProbe.getInstance().osInfo()) + .jvm(JvmProbe.getInstance().jvmInfo()) + .process(ProcessProbe.getInstance().processInfo()) + .build(); + + // And generate monitoring metrics + producer.write(monitor); + + if (!eventProducer.isEmpty()) { + DefaultEvent.Builder event = Event.at(monitor.getTimestamp()).type(NODE_HEARTBEAT); + + event.property(PROPERTY_NODE_ID, node.id()); + event.property(PROPERTY_NODE_HOSTNAME, node.hostname()); + event.property(PROPERTY_NODE_APPLICATION, node.application()); + event.organizations((Set) node.metadata().get(Node.META_ORGANIZATIONS)); + event.environments((Set) node.metadata().get(Node.META_ENVIRONMENTS)); + + // OS metrics + OsInfo osInfo = monitor.getOs(); + event.property("os.cpu.percent", osInfo.cpu.getPercent()); + for (int i = 0; i < osInfo.cpu.getLoadAverage().length; i++) { + event.property("os.cpu.average." + i, osInfo.cpu.getLoadAverage()[i]); + } + + // Process metrics + ProcessInfo processInfo = monitor.getProcess(); + event.property("process.fd.open", processInfo.openFileDescriptors); + event.property("process.fd.max", processInfo.maxFileDescriptors); + event.property("process.cpu.percent", processInfo.cpu.percent); + event.property("process.cpu.total", processInfo.cpu.total); + event.property("process.mem.virtual.total", processInfo.mem.totalVirtual); + + // JVM metrics + JvmInfo jvmInfo = monitor.getJvm(); + event.property("jvm.uptime", jvmInfo.uptime); + event.property("jvm.threads.count", jvmInfo.threads.count); + event.property("jvm.threads.peak", jvmInfo.threads.peakCount); + event.property("jvm.mem.heap.used", jvmInfo.mem.heapUsed); + event.property("jvm.mem.heap.max", jvmInfo.mem.heapMax); + event.property("jvm.mem.heap.percent", jvmInfo.mem.getHeapUsedPercent()); + + eventProducer.send(event.build()); + } + } catch (Exception ex) { + LOGGER.error("Unexpected error occurs while monitoring the node", ex); + } } - } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/Constants.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/Constants.java index 8f7c080fa..2f5965f7f 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/Constants.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/Constants.java @@ -21,32 +21,30 @@ */ public final class Constants { - private Constants() {} // can't construct + private Constants() {} // can't construct - /** JVM vendor info. */ - public static final String JVM_VENDOR = System.getProperty("java.vm.vendor"); - public static final String JVM_VERSION = System.getProperty( - "java.vm.version" - ); - public static final String JVM_NAME = System.getProperty("java.vm.name"); + /** JVM vendor info. */ + public static final String JVM_VENDOR = System.getProperty("java.vm.vendor"); + public static final String JVM_VERSION = System.getProperty("java.vm.version"); + public static final String JVM_NAME = System.getProperty("java.vm.name"); - /** The value of System.getProperty("java.version"). **/ - public static final String JAVA_VERSION = System.getProperty("java.version"); + /** The value of System.getProperty("java.version"). **/ + public static final String JAVA_VERSION = System.getProperty("java.version"); - /** The value of System.getProperty("os.name"). **/ - public static final String OS_NAME = System.getProperty("os.name"); - /** True iff running on Linux. */ - public static final boolean LINUX = OS_NAME.startsWith("Linux"); - /** True iff running on Windows. */ - public static final boolean WINDOWS = OS_NAME.startsWith("Windows"); - /** True iff running on SunOS. */ - public static final boolean SUN_OS = OS_NAME.startsWith("SunOS"); - /** True iff running on Mac OS X */ - public static final boolean MAC_OS_X = OS_NAME.startsWith("Mac OS X"); - /** True iff running on FreeBSD */ - public static final boolean FREE_BSD = OS_NAME.startsWith("FreeBSD"); + /** The value of System.getProperty("os.name"). **/ + public static final String OS_NAME = System.getProperty("os.name"); + /** True iff running on Linux. */ + public static final boolean LINUX = OS_NAME.startsWith("Linux"); + /** True iff running on Windows. */ + public static final boolean WINDOWS = OS_NAME.startsWith("Windows"); + /** True iff running on SunOS. */ + public static final boolean SUN_OS = OS_NAME.startsWith("SunOS"); + /** True iff running on Mac OS X */ + public static final boolean MAC_OS_X = OS_NAME.startsWith("Mac OS X"); + /** True iff running on FreeBSD */ + public static final boolean FREE_BSD = OS_NAME.startsWith("FreeBSD"); - public static final String OS_ARCH = System.getProperty("os.arch"); - public static final String OS_VERSION = System.getProperty("os.version"); - public static final String JAVA_VENDOR = System.getProperty("java.vendor"); + public static final String OS_ARCH = System.getProperty("os.arch"); + public static final String OS_VERSION = System.getProperty("os.version"); + public static final String JAVA_VENDOR = System.getProperty("java.vendor"); } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/JvmProbe.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/JvmProbe.java index b9d956fba..ab2f85cca 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/JvmProbe.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/JvmProbe.java @@ -28,148 +28,137 @@ */ public class JvmProbe { - private final Logger logger = LoggerFactory.getLogger(JvmProbe.class); - - private static final RuntimeMXBean runtimeMXBean; - private static final MemoryMXBean memoryMXBean; - private static final ThreadMXBean threadMXBean; - - static { - runtimeMXBean = ManagementFactory.getRuntimeMXBean(); - memoryMXBean = ManagementFactory.getMemoryMXBean(); - threadMXBean = ManagementFactory.getThreadMXBean(); - } - - private static class JvmProbeHolder { - - private static final JvmProbe INSTANCE = new JvmProbe(); - } - - public static JvmProbe getInstance() { - return JvmProbeHolder.INSTANCE; - } - - private JvmProbe() {} - - public JvmInfo jvmInfo() { - JvmInfo info = new JvmInfo( - System.currentTimeMillis(), - runtimeMXBean.getUptime() - ); - - info.mem = new JvmInfo.Mem(); - - MemoryUsage memUsage = memoryMXBean.getHeapMemoryUsage(); - info.mem.heapUsed = memUsage.getUsed() < 0 ? 0 : memUsage.getUsed(); - info.mem.heapCommitted = - memUsage.getCommitted() < 0 ? 0 : memUsage.getCommitted(); - info.mem.heapMax = memUsage.getMax() < 0 ? 0 : memUsage.getMax(); - memUsage = memoryMXBean.getNonHeapMemoryUsage(); - info.mem.nonHeapUsed = memUsage.getUsed() < 0 ? 0 : memUsage.getUsed(); - info.mem.nonHeapCommitted = - memUsage.getCommitted() < 0 ? 0 : memUsage.getCommitted(); - - List memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans(); - List pools = new ArrayList<>(); - for (int i = 0; i < memoryPoolMXBeans.size(); i++) { - try { - MemoryPoolMXBean memoryPoolMXBean = memoryPoolMXBeans.get(i); - MemoryUsage usage = memoryPoolMXBean.getUsage(); - MemoryUsage peakUsage = memoryPoolMXBean.getPeakUsage(); - String name = getByMemoryPoolName(memoryPoolMXBean.getName(), null); - if (name == null) { // if we can't resolve it, its not interesting.... (Per Gen, Code Cache) - continue; - } - pools.add( - new JvmInfo.MemoryPool( - name, - usage.getUsed() < 0 ? 0 : usage.getUsed(), - usage.getMax() < 0 ? 0 : usage.getMax(), - peakUsage.getUsed() < 0 ? 0 : peakUsage.getUsed(), - peakUsage.getMax() < 0 ? 0 : peakUsage.getMax() - ) - ); - } catch (OutOfMemoryError err) { - throw err; // rethrow - } catch (Exception ex) { - logger.debug("Unexpected exception", ex); - /* ignore some JVMs might barf here with: - * java.lang.InternalError: Memory Pool not found*/ - } - } - info.mem.pools = pools.toArray(new JvmInfo.MemoryPool[pools.size()]); - - info.threads = new JvmInfo.Threads(); - info.threads.count = threadMXBean.getThreadCount(); - info.threads.peakCount = threadMXBean.getPeakThreadCount(); - - List gcMxBeans = ManagementFactory.getGarbageCollectorMXBeans(); - info.gc = new JvmInfo.GarbageCollectors(); - info.gc.collectors = new JvmInfo.GarbageCollector[gcMxBeans.size()]; - for (int i = 0; i < info.gc.collectors.length; i++) { - GarbageCollectorMXBean gcMxBean = gcMxBeans.get(i); - info.gc.collectors[i] = new JvmInfo.GarbageCollector(); - info.gc.collectors[i].name = - getByGcName(gcMxBean.getName(), gcMxBean.getName()); - info.gc.collectors[i].collectionCount = gcMxBean.getCollectionCount(); - info.gc.collectors[i].collectionTime = gcMxBean.getCollectionTime(); + private final Logger logger = LoggerFactory.getLogger(JvmProbe.class); + + private static final RuntimeMXBean runtimeMXBean; + private static final MemoryMXBean memoryMXBean; + private static final ThreadMXBean threadMXBean; + + static { + runtimeMXBean = ManagementFactory.getRuntimeMXBean(); + memoryMXBean = ManagementFactory.getMemoryMXBean(); + threadMXBean = ManagementFactory.getThreadMXBean(); } - return info; - } - - private static final String YOUNG = "young"; - private static final String OLD = "old"; - private static final String SURVIVOR = "survivor"; - - /** - * Resolves the GC type by its memory pool name ({@link MemoryPoolMXBean#getName()}. - */ - static String getByMemoryPoolName(String poolName, String defaultName) { - if ( - "Eden Space".equals(poolName) || - "PS Eden Space".equals(poolName) || - "Par Eden Space".equals(poolName) || - "G1 Eden Space".equals(poolName) - ) { - return YOUNG; + private static class JvmProbeHolder { + + private static final JvmProbe INSTANCE = new JvmProbe(); } - if ( - "Survivor Space".equals(poolName) || - "PS Survivor Space".equals(poolName) || - "Par Survivor Space".equals(poolName) || - "G1 Survivor Space".equals(poolName) - ) { - return SURVIVOR; + + public static JvmProbe getInstance() { + return JvmProbeHolder.INSTANCE; } - if ( - "Tenured Gen".equals(poolName) || - "PS Old Gen".equals(poolName) || - "CMS Old Gen".equals(poolName) || - "G1 Old Gen".equals(poolName) - ) { - return OLD; + + private JvmProbe() {} + + public JvmInfo jvmInfo() { + JvmInfo info = new JvmInfo(System.currentTimeMillis(), runtimeMXBean.getUptime()); + + info.mem = new JvmInfo.Mem(); + + MemoryUsage memUsage = memoryMXBean.getHeapMemoryUsage(); + info.mem.heapUsed = memUsage.getUsed() < 0 ? 0 : memUsage.getUsed(); + info.mem.heapCommitted = memUsage.getCommitted() < 0 ? 0 : memUsage.getCommitted(); + info.mem.heapMax = memUsage.getMax() < 0 ? 0 : memUsage.getMax(); + memUsage = memoryMXBean.getNonHeapMemoryUsage(); + info.mem.nonHeapUsed = memUsage.getUsed() < 0 ? 0 : memUsage.getUsed(); + info.mem.nonHeapCommitted = memUsage.getCommitted() < 0 ? 0 : memUsage.getCommitted(); + + List memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans(); + List pools = new ArrayList<>(); + for (int i = 0; i < memoryPoolMXBeans.size(); i++) { + try { + MemoryPoolMXBean memoryPoolMXBean = memoryPoolMXBeans.get(i); + MemoryUsage usage = memoryPoolMXBean.getUsage(); + MemoryUsage peakUsage = memoryPoolMXBean.getPeakUsage(); + String name = getByMemoryPoolName(memoryPoolMXBean.getName(), null); + if (name == null) { // if we can't resolve it, its not interesting.... (Per Gen, Code Cache) + continue; + } + pools.add( + new JvmInfo.MemoryPool( + name, + usage.getUsed() < 0 ? 0 : usage.getUsed(), + usage.getMax() < 0 ? 0 : usage.getMax(), + peakUsage.getUsed() < 0 ? 0 : peakUsage.getUsed(), + peakUsage.getMax() < 0 ? 0 : peakUsage.getMax() + ) + ); + } catch (OutOfMemoryError err) { + throw err; // rethrow + } catch (Exception ex) { + logger.debug("Unexpected exception", ex); + /* ignore some JVMs might barf here with: + * java.lang.InternalError: Memory Pool not found*/ + } + } + info.mem.pools = pools.toArray(new JvmInfo.MemoryPool[pools.size()]); + + info.threads = new JvmInfo.Threads(); + info.threads.count = threadMXBean.getThreadCount(); + info.threads.peakCount = threadMXBean.getPeakThreadCount(); + + List gcMxBeans = ManagementFactory.getGarbageCollectorMXBeans(); + info.gc = new JvmInfo.GarbageCollectors(); + info.gc.collectors = new JvmInfo.GarbageCollector[gcMxBeans.size()]; + for (int i = 0; i < info.gc.collectors.length; i++) { + GarbageCollectorMXBean gcMxBean = gcMxBeans.get(i); + info.gc.collectors[i] = new JvmInfo.GarbageCollector(); + info.gc.collectors[i].name = getByGcName(gcMxBean.getName(), gcMxBean.getName()); + info.gc.collectors[i].collectionCount = gcMxBean.getCollectionCount(); + info.gc.collectors[i].collectionTime = gcMxBean.getCollectionTime(); + } + + return info; } - return defaultName; - } - - static String getByGcName(String gcName, String defaultName) { - if ( - "Copy".equals(gcName) || - "PS Scavenge".equals(gcName) || - "ParNew".equals(gcName) || - "G1 Young Generation".equals(gcName) - ) { - return YOUNG; + + private static final String YOUNG = "young"; + private static final String OLD = "old"; + private static final String SURVIVOR = "survivor"; + + /** + * Resolves the GC type by its memory pool name ({@link MemoryPoolMXBean#getName()}. + */ + static String getByMemoryPoolName(String poolName, String defaultName) { + if ( + "Eden Space".equals(poolName) || + "PS Eden Space".equals(poolName) || + "Par Eden Space".equals(poolName) || + "G1 Eden Space".equals(poolName) + ) { + return YOUNG; + } + if ( + "Survivor Space".equals(poolName) || + "PS Survivor Space".equals(poolName) || + "Par Survivor Space".equals(poolName) || + "G1 Survivor Space".equals(poolName) + ) { + return SURVIVOR; + } + if ( + "Tenured Gen".equals(poolName) || + "PS Old Gen".equals(poolName) || + "CMS Old Gen".equals(poolName) || + "G1 Old Gen".equals(poolName) + ) { + return OLD; + } + return defaultName; } - if ( - "MarkSweepCompact".equals(gcName) || - "PS MarkSweep".equals(gcName) || - "ConcurrentMarkSweep".equals(gcName) || - "G1 Old Generation".equals(gcName) - ) { - return OLD; + + static String getByGcName(String gcName, String defaultName) { + if ("Copy".equals(gcName) || "PS Scavenge".equals(gcName) || "ParNew".equals(gcName) || "G1 Young Generation".equals(gcName)) { + return YOUNG; + } + if ( + "MarkSweepCompact".equals(gcName) || + "PS MarkSweep".equals(gcName) || + "ConcurrentMarkSweep".equals(gcName) || + "G1 Old Generation".equals(gcName) + ) { + return OLD; + } + return defaultName; } - return defaultName; - } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/OsProbe.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/OsProbe.java index d164f8116..77fd4b388 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/OsProbe.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/OsProbe.java @@ -32,193 +32,177 @@ */ public class OsProbe { - private final Logger logger = LoggerFactory.getLogger(OsProbe.class); - - private static final OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean(); - - private static final Method getFreePhysicalMemorySize; - private static final Method getTotalPhysicalMemorySize; - private static final Method getFreeSwapSpaceSize; - private static final Method getTotalSwapSpaceSize; - private static final Method getSystemLoadAverage; - private static final Method getSystemCpuLoad; - - static { - getFreePhysicalMemorySize = getMethod("getFreePhysicalMemorySize"); - getTotalPhysicalMemorySize = getMethod("getTotalPhysicalMemorySize"); - getFreeSwapSpaceSize = getMethod("getFreeSwapSpaceSize"); - getTotalSwapSpaceSize = getMethod("getTotalSwapSpaceSize"); - getSystemLoadAverage = getMethod("getSystemLoadAverage"); - getSystemCpuLoad = getMethod("getSystemCpuLoad"); - } - - private static class OsProbeHolder { - - private static final OsProbe INSTANCE = new OsProbe(); - } - - public static OsProbe getInstance() { - return OsProbeHolder.INSTANCE; - } - - private OsProbe() {} - - /** - * Returns the amount of free physical memory in bytes. - */ - public long getFreePhysicalMemorySize() { - if (getFreePhysicalMemorySize == null) { - return -1; + private final Logger logger = LoggerFactory.getLogger(OsProbe.class); + + private static final OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean(); + + private static final Method getFreePhysicalMemorySize; + private static final Method getTotalPhysicalMemorySize; + private static final Method getFreeSwapSpaceSize; + private static final Method getTotalSwapSpaceSize; + private static final Method getSystemLoadAverage; + private static final Method getSystemCpuLoad; + + static { + getFreePhysicalMemorySize = getMethod("getFreePhysicalMemorySize"); + getTotalPhysicalMemorySize = getMethod("getTotalPhysicalMemorySize"); + getFreeSwapSpaceSize = getMethod("getFreeSwapSpaceSize"); + getTotalSwapSpaceSize = getMethod("getTotalSwapSpaceSize"); + getSystemLoadAverage = getMethod("getSystemLoadAverage"); + getSystemCpuLoad = getMethod("getSystemCpuLoad"); } - try { - return (long) getFreePhysicalMemorySize.invoke(osMxBean); - } catch (Exception ex) { - logger.debug("Unexpected exception", ex); - return -1; - } - } - - /** - * Returns the total amount of physical memory in bytes. - */ - public long getTotalPhysicalMemorySize() { - if (getTotalPhysicalMemorySize == null) { - return -1; - } - try { - return (long) getTotalPhysicalMemorySize.invoke(osMxBean); - } catch (Exception ex) { - logger.debug("Unexpected exception", ex); - return -1; - } - } - - /** - * Returns the amount of free swap space in bytes. - */ - public long getFreeSwapSpaceSize() { - if (getFreeSwapSpaceSize == null) { - return -1; + + private static class OsProbeHolder { + + private static final OsProbe INSTANCE = new OsProbe(); } - try { - return (long) getFreeSwapSpaceSize.invoke(osMxBean); - } catch (Exception ex) { - logger.debug("Unexpected exception", ex); - return -1; + + public static OsProbe getInstance() { + return OsProbeHolder.INSTANCE; } - } - - /** - * Returns the total amount of swap space in bytes. - */ - public long getTotalSwapSpaceSize() { - if (getTotalSwapSpaceSize == null) { - return -1; + + private OsProbe() {} + + /** + * Returns the amount of free physical memory in bytes. + */ + public long getFreePhysicalMemorySize() { + if (getFreePhysicalMemorySize == null) { + return -1; + } + try { + return (long) getFreePhysicalMemorySize.invoke(osMxBean); + } catch (Exception ex) { + logger.debug("Unexpected exception", ex); + return -1; + } } - try { - return (long) getTotalSwapSpaceSize.invoke(osMxBean); - } catch (Exception ex) { - logger.debug("Unexpected exception", ex); - return -1; + + /** + * Returns the total amount of physical memory in bytes. + */ + public long getTotalPhysicalMemorySize() { + if (getTotalPhysicalMemorySize == null) { + return -1; + } + try { + return (long) getTotalPhysicalMemorySize.invoke(osMxBean); + } catch (Exception ex) { + logger.debug("Unexpected exception", ex); + return -1; + } } - } - - /** - * Returns the system load averages - */ - public double[] getSystemLoadAverage() { - if (Constants.LINUX || Constants.FREE_BSD) { - final String procLoadAvg = Constants.LINUX - ? "/proc/loadavg" - : "/compat/linux/proc/loadavg"; - double[] loadAverage = readProcLoadavg(procLoadAvg); - if (loadAverage != null) { - return loadAverage; - } - // fallback + + /** + * Returns the amount of free swap space in bytes. + */ + public long getFreeSwapSpaceSize() { + if (getFreeSwapSpaceSize == null) { + return -1; + } + try { + return (long) getFreeSwapSpaceSize.invoke(osMxBean); + } catch (Exception ex) { + logger.debug("Unexpected exception", ex); + return -1; + } } - if (Constants.WINDOWS) { - return null; + + /** + * Returns the total amount of swap space in bytes. + */ + public long getTotalSwapSpaceSize() { + if (getTotalSwapSpaceSize == null) { + return -1; + } + try { + return (long) getTotalSwapSpaceSize.invoke(osMxBean); + } catch (Exception ex) { + logger.debug("Unexpected exception", ex); + return -1; + } } - if (getSystemLoadAverage == null) { - return null; + + /** + * Returns the system load averages + */ + public double[] getSystemLoadAverage() { + if (Constants.LINUX || Constants.FREE_BSD) { + final String procLoadAvg = Constants.LINUX ? "/proc/loadavg" : "/compat/linux/proc/loadavg"; + double[] loadAverage = readProcLoadavg(procLoadAvg); + if (loadAverage != null) { + return loadAverage; + } + // fallback + } + if (Constants.WINDOWS) { + return null; + } + if (getSystemLoadAverage == null) { + return null; + } + try { + double oneMinuteLoadAverage = (double) getSystemLoadAverage.invoke(osMxBean); + return new double[] { oneMinuteLoadAverage >= 0 ? oneMinuteLoadAverage : -1, -1, -1 }; + } catch (Exception ex) { + logger.debug("Unexpected exception", ex); + return null; + } } - try { - double oneMinuteLoadAverage = (double) getSystemLoadAverage.invoke( - osMxBean - ); - return new double[] { - oneMinuteLoadAverage >= 0 ? oneMinuteLoadAverage : -1, - -1, - -1, - }; - } catch (Exception ex) { - logger.debug("Unexpected exception", ex); - return null; + + private static double[] readProcLoadavg(String procLoadavg) { + try { + List lines = Files.readAllLines(FileSystems.getDefault().getPath(procLoadavg)); + if (!lines.isEmpty()) { + String[] fields = lines.get(0).split("\\s+"); + return new double[] { Double.parseDouble(fields[0]), Double.parseDouble(fields[1]), Double.parseDouble(fields[2]) }; + } + } catch (IOException e) {} + return null; } - } - - private static double[] readProcLoadavg(String procLoadavg) { - try { - List lines = Files.readAllLines( - FileSystems.getDefault().getPath(procLoadavg) - ); - if (!lines.isEmpty()) { - String[] fields = lines.get(0).split("\\s+"); - return new double[] { - Double.parseDouble(fields[0]), - Double.parseDouble(fields[1]), - Double.parseDouble(fields[2]), - }; - } - } catch (IOException e) {} - return null; - } - - public short getSystemCpuPercent() { - if (getSystemCpuLoad != null) { - try { - double load = (double) getSystemCpuLoad.invoke(osMxBean); - if (load >= 0) { - return (short) (load * 100); + + public short getSystemCpuPercent() { + if (getSystemCpuLoad != null) { + try { + double load = (double) getSystemCpuLoad.invoke(osMxBean); + if (load >= 0) { + return (short) (load * 100); + } + } catch (Throwable t) { + return -1; + } } - } catch (Throwable t) { return -1; - } } - return -1; - } - - public OsInfo osInfo() { - OsInfo info = new OsInfo(); - info.timestamp = System.currentTimeMillis(); - info.cpu = new OsInfo.Cpu(); - info.cpu.percent = getSystemCpuPercent(); - info.cpu.loadAverage = getSystemLoadAverage(); - - info.mem = new OsInfo.Mem(); - info.mem.total = getTotalPhysicalMemorySize(); - info.mem.free = getFreePhysicalMemorySize(); - - info.swap = new OsInfo.Swap(); - info.swap.total = getTotalSwapSpaceSize(); - info.swap.free = getFreeSwapSpaceSize(); - - return info; - } - - /** - * Returns a given method of the OperatingSystemMXBean, - * or null if the method is not found or unavailable. - */ - private static Method getMethod(String methodName) { - try { - return Class - .forName("com.sun.management.OperatingSystemMXBean") - .getMethod(methodName); - } catch (Throwable t) { - // not available - return null; + + public OsInfo osInfo() { + OsInfo info = new OsInfo(); + info.timestamp = System.currentTimeMillis(); + info.cpu = new OsInfo.Cpu(); + info.cpu.percent = getSystemCpuPercent(); + info.cpu.loadAverage = getSystemLoadAverage(); + + info.mem = new OsInfo.Mem(); + info.mem.total = getTotalPhysicalMemorySize(); + info.mem.free = getFreePhysicalMemorySize(); + + info.swap = new OsInfo.Swap(); + info.swap.total = getTotalSwapSpaceSize(); + info.swap.free = getFreeSwapSpaceSize(); + + return info; + } + + /** + * Returns a given method of the OperatingSystemMXBean, + * or null if the method is not found or unavailable. + */ + private static Method getMethod(String methodName) { + try { + return Class.forName("com.sun.management.OperatingSystemMXBean").getMethod(methodName); + } catch (Throwable t) { + // not available + return null; + } } - } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/ProcessProbe.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/ProcessProbe.java index ecbce76d0..938692765 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/ProcessProbe.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/monitor/probe/ProcessProbe.java @@ -28,161 +28,156 @@ */ public class ProcessProbe { - private final Logger logger = LoggerFactory.getLogger(ProcessProbe.class); - - private static final OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean(); - - private static final Method getMaxFileDescriptorCountField; - private static final Method getOpenFileDescriptorCountField; - private static final Method getProcessCpuLoad; - private static final Method getProcessCpuTime; - private static final Method getCommittedVirtualMemorySize; - - static { - getMaxFileDescriptorCountField = getUnixMethod("getMaxFileDescriptorCount"); - getOpenFileDescriptorCountField = - getUnixMethod("getOpenFileDescriptorCount"); - getProcessCpuLoad = getMethod("getProcessCpuLoad"); - getProcessCpuTime = getMethod("getProcessCpuTime"); - getCommittedVirtualMemorySize = getMethod("getCommittedVirtualMemorySize"); - } - - private static class ProcessProbeHolder { - - private static final ProcessProbe INSTANCE = new ProcessProbe(); - } - - public static ProcessProbe getInstance() { - return ProcessProbeHolder.INSTANCE; - } - - private ProcessProbe() {} - - /** - * Returns the maximum number of file descriptors allowed on the system, or -1 if not supported. - */ - public long getMaxFileDescriptorCount() { - if (getMaxFileDescriptorCountField == null) { - return -1; + private final Logger logger = LoggerFactory.getLogger(ProcessProbe.class); + + private static final OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean(); + + private static final Method getMaxFileDescriptorCountField; + private static final Method getOpenFileDescriptorCountField; + private static final Method getProcessCpuLoad; + private static final Method getProcessCpuTime; + private static final Method getCommittedVirtualMemorySize; + + static { + getMaxFileDescriptorCountField = getUnixMethod("getMaxFileDescriptorCount"); + getOpenFileDescriptorCountField = getUnixMethod("getOpenFileDescriptorCount"); + getProcessCpuLoad = getMethod("getProcessCpuLoad"); + getProcessCpuTime = getMethod("getProcessCpuTime"); + getCommittedVirtualMemorySize = getMethod("getCommittedVirtualMemorySize"); } - try { - return (Long) getMaxFileDescriptorCountField.invoke(osMxBean); - } catch (Exception ex) { - logger.debug("Unexpected exception", ex); - return -1; + + private static class ProcessProbeHolder { + + private static final ProcessProbe INSTANCE = new ProcessProbe(); + } + + public static ProcessProbe getInstance() { + return ProcessProbeHolder.INSTANCE; + } + + private ProcessProbe() {} + + /** + * Returns the maximum number of file descriptors allowed on the system, or -1 if not supported. + */ + public long getMaxFileDescriptorCount() { + if (getMaxFileDescriptorCountField == null) { + return -1; + } + try { + return (Long) getMaxFileDescriptorCountField.invoke(osMxBean); + } catch (Exception ex) { + logger.debug("Unexpected exception", ex); + return -1; + } } - } - - /** - * Returns the number of opened file descriptors associated with the current process, or -1 if not supported. - */ - public long getOpenFileDescriptorCount() { - if (getOpenFileDescriptorCountField == null) { - return -1; + + /** + * Returns the number of opened file descriptors associated with the current process, or -1 if not supported. + */ + public long getOpenFileDescriptorCount() { + if (getOpenFileDescriptorCountField == null) { + return -1; + } + try { + return (Long) getOpenFileDescriptorCountField.invoke(osMxBean); + } catch (Exception ex) { + logger.debug("Unexpected exception", ex); + return -1; + } } - try { - return (Long) getOpenFileDescriptorCountField.invoke(osMxBean); - } catch (Exception ex) { - logger.debug("Unexpected exception", ex); - return -1; + + public ProcessInfo processInfo() { + ProcessInfo info = new ProcessInfo(); + + info.timestamp = System.currentTimeMillis(); + info.openFileDescriptors = getOpenFileDescriptorCount(); + info.maxFileDescriptors = getMaxFileDescriptorCount(); + + info.cpu = new ProcessInfo.Cpu(); + info.cpu.percent = getProcessCpuPercent(); + info.cpu.total = getProcessCpuTotalTime(); + + info.mem = new ProcessInfo.Mem(); + info.mem.totalVirtual = getTotalVirtualMemorySize(); + + return info; } - } - - public ProcessInfo processInfo() { - ProcessInfo info = new ProcessInfo(); - - info.timestamp = System.currentTimeMillis(); - info.openFileDescriptors = getOpenFileDescriptorCount(); - info.maxFileDescriptors = getMaxFileDescriptorCount(); - - info.cpu = new ProcessInfo.Cpu(); - info.cpu.percent = getProcessCpuPercent(); - info.cpu.total = getProcessCpuTotalTime(); - - info.mem = new ProcessInfo.Mem(); - info.mem.totalVirtual = getTotalVirtualMemorySize(); - - return info; - } - - /** - * Returns the process CPU usage in percent - */ - public short getProcessCpuPercent() { - if (getProcessCpuLoad != null) { - try { - double load = (double) getProcessCpuLoad.invoke(osMxBean); - if (load >= 0) { - return (short) (load * 100); + + /** + * Returns the process CPU usage in percent + */ + public short getProcessCpuPercent() { + if (getProcessCpuLoad != null) { + try { + double load = (double) getProcessCpuLoad.invoke(osMxBean); + if (load >= 0) { + return (short) (load * 100); + } + } catch (Throwable t) { + return -1; + } } - } catch (Throwable t) { return -1; - } } - return -1; - } - - /** - * Returns the CPU time (in milliseconds) used by the process on which the Java virtual machine is running, or -1 if not supported. - */ - public long getProcessCpuTotalTime() { - if (getProcessCpuTime != null) { - try { - long time = (long) getProcessCpuTime.invoke(osMxBean); - if (time >= 0) { - return (time / 1_000_000L); + + /** + * Returns the CPU time (in milliseconds) used by the process on which the Java virtual machine is running, or -1 if not supported. + */ + public long getProcessCpuTotalTime() { + if (getProcessCpuTime != null) { + try { + long time = (long) getProcessCpuTime.invoke(osMxBean); + if (time >= 0) { + return (time / 1_000_000L); + } + } catch (Exception t) { + return -1; + } } - } catch (Exception t) { return -1; - } } - return -1; - } - - /** - * Returns the size (in bytes) of virtual memory that is guaranteed to be available to the running process - */ - public long getTotalVirtualMemorySize() { - if (getCommittedVirtualMemorySize != null) { - try { - long virtual = (long) getCommittedVirtualMemorySize.invoke(osMxBean); - if (virtual >= 0) { - return virtual; + + /** + * Returns the size (in bytes) of virtual memory that is guaranteed to be available to the running process + */ + public long getTotalVirtualMemorySize() { + if (getCommittedVirtualMemorySize != null) { + try { + long virtual = (long) getCommittedVirtualMemorySize.invoke(osMxBean); + if (virtual >= 0) { + return virtual; + } + } catch (Exception t) { + return -1; + } } - } catch (Exception t) { return -1; - } } - return -1; - } - - /** - * Returns a given method of the OperatingSystemMXBean, - * or null if the method is not found or unavailable. - */ - private static Method getMethod(String methodName) { - try { - return Class - .forName("com.sun.management.OperatingSystemMXBean") - .getMethod(methodName); - } catch (Throwable t) { - // not available - return null; + + /** + * Returns a given method of the OperatingSystemMXBean, + * or null if the method is not found or unavailable. + */ + private static Method getMethod(String methodName) { + try { + return Class.forName("com.sun.management.OperatingSystemMXBean").getMethod(methodName); + } catch (Throwable t) { + // not available + return null; + } } - } - - /** - * Returns a given method of the UnixOperatingSystemMXBean, - * or null if the method is not found or unavailable. - */ - private static Method getUnixMethod(String methodName) { - try { - return Class - .forName("com.sun.management.UnixOperatingSystemMXBean") - .getMethod(methodName); - } catch (Throwable t) { - // not available - return null; + + /** + * Returns a given method of the UnixOperatingSystemMXBean, + * or null if the method is not found or unavailable. + */ + private static Method getUnixMethod(String methodName) { + try { + return Class.forName("com.sun.management.UnixOperatingSystemMXBean").getMethod(methodName); + } catch (Throwable t) { + // not available + return null; + } } - } } diff --git a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/spring/MonitoringConfiguration.java b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/spring/MonitoringConfiguration.java index 9dc383abc..1c2374086 100644 --- a/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/spring/MonitoringConfiguration.java +++ b/gravitee-node-monitoring/src/main/java/io/gravitee/node/monitoring/spring/MonitoringConfiguration.java @@ -43,83 +43,73 @@ @Import(NodeMonitoringService.class) public class MonitoringConfiguration { - @Value("${services.monitoring.distributed:false}") - protected boolean distributed; + @Value("${services.monitoring.distributed:false}") + protected boolean distributed; - @Bean - public NodeMonitorService nodeMonitorService() { - return new NodeMonitorService(); - } + @Bean + public NodeMonitorService nodeMonitorService() { + return new NodeMonitorService(); + } - @Bean - public NodeMonitorManagementEndpoint nodeMonitorManagementEndpoint() { - return new NodeMonitorManagementEndpoint(); - } + @Bean + public NodeMonitorManagementEndpoint nodeMonitorManagementEndpoint() { + return new NodeMonitorManagementEndpoint(); + } - @Bean - public NodeHealthCheckService nodeHealthCheckService() { - return new NodeHealthCheckService(); - } + @Bean + public NodeHealthCheckService nodeHealthCheckService() { + return new NodeHealthCheckService(); + } - @Bean - public NodeHealthCheckManagementEndpoint nodeHealthCheckManagementEndpoint() { - return new NodeHealthCheckManagementEndpoint(); - } + @Bean + public NodeHealthCheckManagementEndpoint nodeHealthCheckManagementEndpoint() { + return new NodeHealthCheckManagementEndpoint(); + } - @Bean - public NodeInfosService nodeInfosService() { - return new NodeInfosService(); - } + @Bean + public NodeInfosService nodeInfosService() { + return new NodeInfosService(); + } - @Bean - public NodeMonitoringEventHandler nodeMonitoringEventHandler( - Vertx vertx, - ApplicationContext context, - ObjectMapper objectMapper, - Node node, - NodeMonitoringService nodeMonitoringService - ) { - // Instantiate the monitoring event handler depending on the clustering mode. - NodeMonitoringEventHandler nodeMonitoringEventHandler = null; + @Bean + public NodeMonitoringEventHandler nodeMonitoringEventHandler( + Vertx vertx, + ApplicationContext context, + ObjectMapper objectMapper, + Node node, + NodeMonitoringService nodeMonitoringService + ) { + // Instantiate the monitoring event handler depending on the clustering mode. + NodeMonitoringEventHandler nodeMonitoringEventHandler = null; - if (distributed) { - try { - // Try to retrieve cluster beans. - final ClusterManager clusterManager = context.getBean( - ClusterManager.class - ); - final HazelcastInstance hazelcastInstance = context.getBean( - HazelcastInstance.class - ); - nodeMonitoringEventHandler = - new ClusteredNodeMonitoringEventHandler( - vertx, - objectMapper, - node, - nodeMonitoringService, - clusterManager, - hazelcastInstance - ); - } catch (NoClassDefFoundError | NoSuchBeanDefinitionException e) { - // There is no clustering on that node. - } - } + if (distributed) { + try { + // Try to retrieve cluster beans. + final ClusterManager clusterManager = context.getBean(ClusterManager.class); + final HazelcastInstance hazelcastInstance = context.getBean(HazelcastInstance.class); + nodeMonitoringEventHandler = + new ClusteredNodeMonitoringEventHandler( + vertx, + objectMapper, + node, + nodeMonitoringService, + clusterManager, + hazelcastInstance + ); + } catch (NoClassDefFoundError | NoSuchBeanDefinitionException e) { + // There is no clustering on that node. + } + } - if (nodeMonitoringEventHandler == null) { - nodeMonitoringEventHandler = - new NodeMonitoringEventHandler( - vertx, - objectMapper, - node, - nodeMonitoringService - ); - } + if (nodeMonitoringEventHandler == null) { + nodeMonitoringEventHandler = new NodeMonitoringEventHandler(vertx, objectMapper, node, nodeMonitoringService); + } - return nodeMonitoringEventHandler; - } + return nodeMonitoringEventHandler; + } - @Bean - public ProbeManager probeManager() { - return new ProbeManagerImpl(); - } + @Bean + public ProbeManager probeManager() { + return new ProbeManagerImpl(); + } } diff --git a/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/NodeMonitoringServiceTest.java b/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/NodeMonitoringServiceTest.java index e641c5755..f7055c5f7 100644 --- a/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/NodeMonitoringServiceTest.java +++ b/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/NodeMonitoringServiceTest.java @@ -39,104 +39,94 @@ @RunWith(MockitoJUnitRunner.class) public class NodeMonitoringServiceTest { - @Mock - private NodeMonitoringRepository repository; - - private NodeMonitoringService cut; - - @Before - public void before() { - cut = new NodeMonitoringService(repository); - } - - @Test - public void shouldCreate() { - final Monitoring monitoring = new Monitoring(); - monitoring.setNodeId("node#1"); - monitoring.setCreatedAt(new Date()); - monitoring.setEvaluatedAt(new Date()); - monitoring.setPayload("payload health check"); - monitoring.setType(Monitoring.HEALTH_CHECK); - - when(repository.findByNodeIdAndType("node#1", Monitoring.HEALTH_CHECK)) - .thenReturn(Maybe.empty()); - when(repository.create(monitoring)) - .thenAnswer(i -> Single.just(i.getArgument(0))); - - final TestObserver obs = cut.createOrUpdate(monitoring).test(); - - obs.awaitTerminalEvent(); - obs.assertValue(monitoring); - } - - @Test - public void shouldUpdate() { - Monitoring monitoring = new Monitoring(); - monitoring.setNodeId("node#1"); - monitoring.setCreatedAt(new Date()); - monitoring.setEvaluatedAt(new Date()); - monitoring.setPayload("payload health check"); - monitoring.setType(Monitoring.HEALTH_CHECK); - - when(repository.findByNodeIdAndType("node#1", Monitoring.HEALTH_CHECK)) - .thenReturn(Maybe.empty()); - when(repository.create(monitoring)) - .thenAnswer(i -> Single.just(i.getArgument(0))); - - monitoring = cut.createOrUpdate(monitoring).blockingGet(); - - when(repository.update(monitoring)) - .thenAnswer(i -> Single.just(i.getArgument(0))); - - final TestObserver obs = cut.createOrUpdate(monitoring).test(); - - obs.awaitTerminalEvent(); - obs.assertValue(monitoring); - } - - @Test - public void shouldNotCreateOrUpdateIfNotRepository() { - final Monitoring monitoring = new Monitoring(); - cut = new NodeMonitoringService(null); - - final TestObserver obs = cut.createOrUpdate(monitoring).test(); - - obs.awaitTerminalEvent(); - obs.assertValue(monitoring); - - verifyZeroInteractions(repository); - } - - @Test - public void shouldFindByTypeAndTimeframe() { - long from = System.currentTimeMillis(); - long to = System.currentTimeMillis() + 1000; - - final Monitoring monitoring = new Monitoring(); - when(repository.findByTypeAndTimeFrame(Monitoring.HEALTH_CHECK, from, to)) - .thenReturn(Flowable.just(monitoring)); - - final TestSubscriber obs = cut - .findByTypeAndTimeframe(Monitoring.HEALTH_CHECK, from, to) - .test(); - - obs.awaitTerminalEvent(); - obs.assertValue(monitoring); - obs.assertComplete(); - } - - @Test - public void shouldNotFindByTypeAndTimeframeIfNoRepository() { - long from = System.currentTimeMillis(); - long to = System.currentTimeMillis() + 1000; - - cut = new NodeMonitoringService(null); - final TestSubscriber obs = cut - .findByTypeAndTimeframe(Monitoring.HEALTH_CHECK, from, to) - .test(); - - obs.awaitTerminalEvent(); - obs.assertNoValues(); - obs.assertComplete(); - } + @Mock + private NodeMonitoringRepository repository; + + private NodeMonitoringService cut; + + @Before + public void before() { + cut = new NodeMonitoringService(repository); + } + + @Test + public void shouldCreate() { + final Monitoring monitoring = new Monitoring(); + monitoring.setNodeId("node#1"); + monitoring.setCreatedAt(new Date()); + monitoring.setEvaluatedAt(new Date()); + monitoring.setPayload("payload health check"); + monitoring.setType(Monitoring.HEALTH_CHECK); + + when(repository.findByNodeIdAndType("node#1", Monitoring.HEALTH_CHECK)).thenReturn(Maybe.empty()); + when(repository.create(monitoring)).thenAnswer(i -> Single.just(i.getArgument(0))); + + final TestObserver obs = cut.createOrUpdate(monitoring).test(); + + obs.awaitTerminalEvent(); + obs.assertValue(monitoring); + } + + @Test + public void shouldUpdate() { + Monitoring monitoring = new Monitoring(); + monitoring.setNodeId("node#1"); + monitoring.setCreatedAt(new Date()); + monitoring.setEvaluatedAt(new Date()); + monitoring.setPayload("payload health check"); + monitoring.setType(Monitoring.HEALTH_CHECK); + + when(repository.findByNodeIdAndType("node#1", Monitoring.HEALTH_CHECK)).thenReturn(Maybe.empty()); + when(repository.create(monitoring)).thenAnswer(i -> Single.just(i.getArgument(0))); + + monitoring = cut.createOrUpdate(monitoring).blockingGet(); + + when(repository.update(monitoring)).thenAnswer(i -> Single.just(i.getArgument(0))); + + final TestObserver obs = cut.createOrUpdate(monitoring).test(); + + obs.awaitTerminalEvent(); + obs.assertValue(monitoring); + } + + @Test + public void shouldNotCreateOrUpdateIfNotRepository() { + final Monitoring monitoring = new Monitoring(); + cut = new NodeMonitoringService(null); + + final TestObserver obs = cut.createOrUpdate(monitoring).test(); + + obs.awaitTerminalEvent(); + obs.assertValue(monitoring); + + verifyZeroInteractions(repository); + } + + @Test + public void shouldFindByTypeAndTimeframe() { + long from = System.currentTimeMillis(); + long to = System.currentTimeMillis() + 1000; + + final Monitoring monitoring = new Monitoring(); + when(repository.findByTypeAndTimeFrame(Monitoring.HEALTH_CHECK, from, to)).thenReturn(Flowable.just(monitoring)); + + final TestSubscriber obs = cut.findByTypeAndTimeframe(Monitoring.HEALTH_CHECK, from, to).test(); + + obs.awaitTerminalEvent(); + obs.assertValue(monitoring); + obs.assertComplete(); + } + + @Test + public void shouldNotFindByTypeAndTimeframeIfNoRepository() { + long from = System.currentTimeMillis(); + long to = System.currentTimeMillis() + 1000; + + cut = new NodeMonitoringService(null); + final TestSubscriber obs = cut.findByTypeAndTimeframe(Monitoring.HEALTH_CHECK, from, to).test(); + + obs.awaitTerminalEvent(); + obs.assertNoValues(); + obs.assertComplete(); + } } diff --git a/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/handler/ClusteredNodeMonitoringEventHandlerTest.java b/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/handler/ClusteredNodeMonitoringEventHandlerTest.java index dc8c7d336..22f273286 100644 --- a/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/handler/ClusteredNodeMonitoringEventHandlerTest.java +++ b/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/handler/ClusteredNodeMonitoringEventHandlerTest.java @@ -48,103 +48,92 @@ @RunWith(MockitoJUnitRunner.class) public class ClusteredNodeMonitoringEventHandlerTest { - private static final String NODE_ID = "node#1"; + private static final String NODE_ID = "node#1"; - @Mock - protected Vertx vertx; + @Mock + protected Vertx vertx; - @Mock - protected Node node; + @Mock + protected Node node; - @Mock - protected NodeMonitoringService nodeMonitoringService; + @Mock + protected NodeMonitoringService nodeMonitoringService; - @Mock - protected ObjectMapper objectMapper; + @Mock + protected ObjectMapper objectMapper; - @Mock - private ClusterManager clusterManager; + @Mock + private ClusterManager clusterManager; - @Mock - private HazelcastInstance hazelcastInstance; + @Mock + private HazelcastInstance hazelcastInstance; - @Mock - private ITopic distributedHealthCheckTopic; + @Mock + private ITopic distributedHealthCheckTopic; - @Mock - private ITopic distributedMonitorTopic; + @Mock + private ITopic distributedMonitorTopic; - @Mock - private ITopic distributedNodeInfosTopic; + @Mock + private ITopic distributedNodeInfosTopic; - private ClusteredNodeMonitoringEventHandler cut; + private ClusteredNodeMonitoringEventHandler cut; - @Before - public void before() { - cut = - new ClusteredNodeMonitoringEventHandler( - vertx, - objectMapper, - node, - nodeMonitoringService, - clusterManager, - hazelcastInstance - ); - cut.distributedHealthCheckTopic = distributedHealthCheckTopic; - cut.distributedMonitorTopic = distributedMonitorTopic; - cut.distributedNodeInfosTopic = distributedNodeInfosTopic; - } + @Before + public void before() { + cut = new ClusteredNodeMonitoringEventHandler(vertx, objectMapper, node, nodeMonitoringService, clusterManager, hazelcastInstance); + cut.distributedHealthCheckTopic = distributedHealthCheckTopic; + cut.distributedMonitorTopic = distributedMonitorTopic; + cut.distributedNodeInfosTopic = distributedNodeInfosTopic; + } - @Test - public void handleNodeInfosMessage() throws JsonProcessingException { - final Message message = mock(Message.class); + @Test + public void handleNodeInfosMessage() throws JsonProcessingException { + final Message message = mock(Message.class); - final NodeInfos nodeInfos = new NodeInfos(); - nodeInfos.setEvaluatedAt(System.currentTimeMillis()); - nodeInfos.setStatus(NodeStatus.STARTED); - nodeInfos.setId(NODE_ID); + final NodeInfos nodeInfos = new NodeInfos(); + nodeInfos.setEvaluatedAt(System.currentTimeMillis()); + nodeInfos.setStatus(NodeStatus.STARTED); + nodeInfos.setId(NODE_ID); - when(message.body()).thenReturn(nodeInfos); + when(message.body()).thenReturn(nodeInfos); - cut.handleNodeInfosMessage(message); + cut.handleNodeInfosMessage(message); - verify(distributedNodeInfosTopic).publish(nodeInfos); - } + verify(distributedNodeInfosTopic).publish(nodeInfos); + } - @Test - public void handleMonitorMessageNot() throws JsonProcessingException { - final Message message = mock(Message.class); + @Test + public void handleMonitorMessageNot() throws JsonProcessingException { + final Message message = mock(Message.class); - final Monitor monitor = Monitor - .on(NODE_ID) - .at(System.currentTimeMillis()) - .os(OsProbe.getInstance().osInfo()) - .jvm(JvmProbe.getInstance().jvmInfo()) - .process(ProcessProbe.getInstance().processInfo()) - .build(); + final Monitor monitor = Monitor + .on(NODE_ID) + .at(System.currentTimeMillis()) + .os(OsProbe.getInstance().osInfo()) + .jvm(JvmProbe.getInstance().jvmInfo()) + .process(ProcessProbe.getInstance().processInfo()) + .build(); - when(message.body()).thenReturn(monitor); + when(message.body()).thenReturn(monitor); - cut.handleMonitorMessage(message); + cut.handleMonitorMessage(message); - verify(distributedMonitorTopic).publish(monitor); - } + verify(distributedMonitorTopic).publish(monitor); + } - @Test - public void handleHealthCheckMessage() throws JsonProcessingException { - final Message message = mock(Message.class); + @Test + public void handleHealthCheckMessage() throws JsonProcessingException { + final Message message = mock(Message.class); - final HashMap results = new HashMap<>(); - results.put("test", Result.healthy("ok")); - final HealthCheck healthCheck = new HealthCheck( - System.currentTimeMillis(), - results - ); + final HashMap results = new HashMap<>(); + results.put("test", Result.healthy("ok")); + final HealthCheck healthCheck = new HealthCheck(System.currentTimeMillis(), results); - when(message.body()).thenReturn(healthCheck); + when(message.body()).thenReturn(healthCheck); - cut.handleHealthCheckMessage(message); + cut.handleHealthCheckMessage(message); - verify(distributedHealthCheckTopic).publish(healthCheck); - } + verify(distributedHealthCheckTopic).publish(healthCheck); + } } diff --git a/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/handler/NodeMonitoringEventHandlerTest.java b/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/handler/NodeMonitoringEventHandlerTest.java index 55d701aba..beb5c3587 100644 --- a/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/handler/NodeMonitoringEventHandlerTest.java +++ b/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/handler/NodeMonitoringEventHandlerTest.java @@ -50,134 +50,110 @@ @RunWith(MockitoJUnitRunner.class) public class NodeMonitoringEventHandlerTest { - private static final String NODE_ID = "node#1"; - - @Mock - protected Vertx vertx; - - @Mock - protected Node node; - - @Mock - protected NodeMonitoringService nodeMonitoringService; - - @Mock - protected ObjectMapper objectMapper; - - private NodeMonitoringEventHandler cut; - - @Before - public void before() { - cut = - new NodeMonitoringEventHandler( - vertx, - objectMapper, - node, - nodeMonitoringService - ); - } - - @Test - public void handleNodeInfosMessage() throws JsonProcessingException { - final Message message = mock(Message.class); - - final NodeInfos nodeInfos = new NodeInfos(); - nodeInfos.setEvaluatedAt(System.currentTimeMillis()); - nodeInfos.setStatus(NodeStatus.STARTED); - nodeInfos.setId(NODE_ID); - - when(node.id()).thenReturn(NODE_ID); - when(message.body()).thenReturn(nodeInfos); - when(objectMapper.writeValueAsString(nodeInfos)).thenReturn("expected"); - - ArgumentCaptor captor = ArgumentCaptor.forClass( - Monitoring.class - ); - - when(nodeMonitoringService.createOrUpdate(any(Monitoring.class))) - .thenAnswer(i -> Single.just(i.getArgument(0))); - cut.handleNodeInfosMessage(message); - - verify(nodeMonitoringService).createOrUpdate(captor.capture()); - - final Monitoring monitoring = captor.getValue(); - - assertEquals(NODE_ID, monitoring.getNodeId()); - assertEquals( - nodeInfos.getEvaluatedAt(), - monitoring.getEvaluatedAt().getTime() - ); - assertEquals(Monitoring.NODE_INFOS, monitoring.getType()); - assertEquals("expected", monitoring.getPayload()); - } - - @Test - public void handleMonitorMessage() throws JsonProcessingException { - final Message message = mock(Message.class); - - final Monitor monitor = Monitor - .on(NODE_ID) - .at(System.currentTimeMillis()) - .os(OsProbe.getInstance().osInfo()) - .jvm(JvmProbe.getInstance().jvmInfo()) - .process(ProcessProbe.getInstance().processInfo()) - .build(); - - when(node.id()).thenReturn(NODE_ID); - when(message.body()).thenReturn(monitor); - when(objectMapper.writeValueAsString(monitor)).thenReturn("expected"); - - ArgumentCaptor captor = ArgumentCaptor.forClass( - Monitoring.class - ); - - when(nodeMonitoringService.createOrUpdate(any(Monitoring.class))) - .thenAnswer(i -> Single.just(i.getArgument(0))); - cut.handleMonitorMessage(message); - - verify(nodeMonitoringService).createOrUpdate(captor.capture()); - - final Monitoring monitoring = captor.getValue(); - - assertEquals(NODE_ID, monitoring.getNodeId()); - assertEquals(monitor.getTimestamp(), monitoring.getEvaluatedAt().getTime()); - assertEquals(Monitoring.MONITOR, monitoring.getType()); - assertEquals("expected", monitoring.getPayload()); - } - - @Test - public void handleHealthCheckMessage() throws JsonProcessingException { - final Message message = mock(Message.class); - - final HashMap results = new HashMap<>(); - results.put("test", Result.healthy("ok")); - final HealthCheck healthCheck = new HealthCheck( - System.currentTimeMillis(), - results - ); - - when(node.id()).thenReturn(NODE_ID); - when(message.body()).thenReturn(healthCheck); - when(objectMapper.writeValueAsString(healthCheck)).thenReturn("expected"); - - ArgumentCaptor captor = ArgumentCaptor.forClass( - Monitoring.class - ); - - when(nodeMonitoringService.createOrUpdate(any(Monitoring.class))) - .thenAnswer(i -> Single.just(i.getArgument(0))); - cut.handleHealthCheckMessage(message); - - verify(nodeMonitoringService).createOrUpdate(captor.capture()); - - final Monitoring monitoring = captor.getValue(); - - assertEquals(NODE_ID, monitoring.getNodeId()); - assertEquals( - healthCheck.getEvaluatedAt(), - monitoring.getEvaluatedAt().getTime() - ); - assertEquals(Monitoring.HEALTH_CHECK, monitoring.getType()); - assertEquals("expected", monitoring.getPayload()); - } + private static final String NODE_ID = "node#1"; + + @Mock + protected Vertx vertx; + + @Mock + protected Node node; + + @Mock + protected NodeMonitoringService nodeMonitoringService; + + @Mock + protected ObjectMapper objectMapper; + + private NodeMonitoringEventHandler cut; + + @Before + public void before() { + cut = new NodeMonitoringEventHandler(vertx, objectMapper, node, nodeMonitoringService); + } + + @Test + public void handleNodeInfosMessage() throws JsonProcessingException { + final Message message = mock(Message.class); + + final NodeInfos nodeInfos = new NodeInfos(); + nodeInfos.setEvaluatedAt(System.currentTimeMillis()); + nodeInfos.setStatus(NodeStatus.STARTED); + nodeInfos.setId(NODE_ID); + + when(node.id()).thenReturn(NODE_ID); + when(message.body()).thenReturn(nodeInfos); + when(objectMapper.writeValueAsString(nodeInfos)).thenReturn("expected"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(Monitoring.class); + + when(nodeMonitoringService.createOrUpdate(any(Monitoring.class))).thenAnswer(i -> Single.just(i.getArgument(0))); + cut.handleNodeInfosMessage(message); + + verify(nodeMonitoringService).createOrUpdate(captor.capture()); + + final Monitoring monitoring = captor.getValue(); + + assertEquals(NODE_ID, monitoring.getNodeId()); + assertEquals(nodeInfos.getEvaluatedAt(), monitoring.getEvaluatedAt().getTime()); + assertEquals(Monitoring.NODE_INFOS, monitoring.getType()); + assertEquals("expected", monitoring.getPayload()); + } + + @Test + public void handleMonitorMessage() throws JsonProcessingException { + final Message message = mock(Message.class); + + final Monitor monitor = Monitor + .on(NODE_ID) + .at(System.currentTimeMillis()) + .os(OsProbe.getInstance().osInfo()) + .jvm(JvmProbe.getInstance().jvmInfo()) + .process(ProcessProbe.getInstance().processInfo()) + .build(); + + when(node.id()).thenReturn(NODE_ID); + when(message.body()).thenReturn(monitor); + when(objectMapper.writeValueAsString(monitor)).thenReturn("expected"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(Monitoring.class); + + when(nodeMonitoringService.createOrUpdate(any(Monitoring.class))).thenAnswer(i -> Single.just(i.getArgument(0))); + cut.handleMonitorMessage(message); + + verify(nodeMonitoringService).createOrUpdate(captor.capture()); + + final Monitoring monitoring = captor.getValue(); + + assertEquals(NODE_ID, monitoring.getNodeId()); + assertEquals(monitor.getTimestamp(), monitoring.getEvaluatedAt().getTime()); + assertEquals(Monitoring.MONITOR, monitoring.getType()); + assertEquals("expected", monitoring.getPayload()); + } + + @Test + public void handleHealthCheckMessage() throws JsonProcessingException { + final Message message = mock(Message.class); + + final HashMap results = new HashMap<>(); + results.put("test", Result.healthy("ok")); + final HealthCheck healthCheck = new HealthCheck(System.currentTimeMillis(), results); + + when(node.id()).thenReturn(NODE_ID); + when(message.body()).thenReturn(healthCheck); + when(objectMapper.writeValueAsString(healthCheck)).thenReturn("expected"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(Monitoring.class); + + when(nodeMonitoringService.createOrUpdate(any(Monitoring.class))).thenAnswer(i -> Single.just(i.getArgument(0))); + cut.handleHealthCheckMessage(message); + + verify(nodeMonitoringService).createOrUpdate(captor.capture()); + + final Monitoring monitoring = captor.getValue(); + + assertEquals(NODE_ID, monitoring.getNodeId()); + assertEquals(healthCheck.getEvaluatedAt(), monitoring.getEvaluatedAt().getTime()); + assertEquals(Monitoring.HEALTH_CHECK, monitoring.getType()); + assertEquals("expected", monitoring.getPayload()); + } } diff --git a/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckManagementEndpointTest.java b/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckManagementEndpointTest.java index f7721406c..a7f350dc2 100644 --- a/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckManagementEndpointTest.java +++ b/gravitee-node-monitoring/src/test/java/io/gravitee/node/monitoring/healthcheck/NodeHealthCheckManagementEndpointTest.java @@ -40,211 +40,196 @@ @RunWith(MockitoJUnitRunner.class) public class NodeHealthCheckManagementEndpointTest { - @Mock - private NodeHealthCheckThread probeStatusRegistry; - - @Mock - private RoutingContext routingContext; - - @Mock - private MultiMap queryParams; - - private NodeHealthCheckManagementEndpoint nodeHealthCheckManagementEndpoint; - - @Mock - private HttpServerResponse httpServerResponse; - - @Before - public void setUp() { - nodeHealthCheckManagementEndpoint = new NodeHealthCheckManagementEndpoint(); - nodeHealthCheckManagementEndpoint.setRegistry(probeStatusRegistry); - - when(routingContext.response()).thenReturn(httpServerResponse); - } - - @Test - public void shouldNotFilterAllHealthy() throws Exception { - Map probeResultMap = fakeProbeResults(true); - when(probeStatusRegistry.getResults()).thenReturn(probeResultMap); - when(routingContext.queryParams()).thenReturn(queryParams); - when(queryParams.contains(any())).thenReturn(false); - - ArgumentCaptor statusCaptor = ArgumentCaptor.forClass( - Integer.class - ); - ArgumentCaptor writeCaptor = ArgumentCaptor.forClass(String.class); - - nodeHealthCheckManagementEndpoint.handle(routingContext); - - verify(httpServerResponse).setStatusCode(statusCaptor.capture()); - assertThat((int) statusCaptor.getValue()).isEqualTo(HttpStatusCode.OK_200); - verify(httpServerResponse).write(writeCaptor.capture()); - - String expected = - "{\n" + - " \"ratelimit-repository\" : {\n" + - " \"healthy\" : true\n" + - " },\n" + - " \"management-repository\" : {\n" + - " \"healthy\" : true\n" + - " },\n" + - " \"http-server\" : {\n" + - " \"healthy\" : true\n" + - " }\n" + - "}"; - - assertThat(writeCaptor.getValue()).isEqualTo(expected); - } - - @Test - public void shouldNotFilterOneUnhealthyHealthy() throws Exception { - Map probeResultMap = fakeProbeResults(false); - when(probeStatusRegistry.getResults()).thenReturn(probeResultMap); - when(routingContext.queryParams()).thenReturn(queryParams); - when(queryParams.contains(any())).thenReturn(false); - - ArgumentCaptor statusCaptor = ArgumentCaptor.forClass( - Integer.class - ); - ArgumentCaptor writeCaptor = ArgumentCaptor.forClass(String.class); - - nodeHealthCheckManagementEndpoint.handle(routingContext); - - verify(httpServerResponse).setStatusCode(statusCaptor.capture()); - assertThat((int) statusCaptor.getValue()) - .isEqualTo(HttpStatusCode.INTERNAL_SERVER_ERROR_500); - verify(httpServerResponse).write(writeCaptor.capture()); - - String expected = - "{\n" + - " \"ratelimit-repository\" : {\n" + - " \"healthy\" : false\n" + - " },\n" + - " \"management-repository\" : {\n" + - " \"healthy\" : true\n" + - " },\n" + - " \"http-server\" : {\n" + - " \"healthy\" : true\n" + - " }\n" + - "}"; - - assertThat(writeCaptor.getValue()).isEqualTo(expected); - } - - @Test - public void shouldFilterAllHealthy() throws Exception { - Map probeResultMap = fakeProbeResults(true); - when(probeStatusRegistry.getResults()).thenReturn(probeResultMap); - when(routingContext.queryParams()).thenReturn(queryParams); - when(queryParams.contains(any())).thenReturn(true); - when(queryParams.get(any())) - .thenReturn("ratelimit-repository,management-repository"); - - ArgumentCaptor statusCaptor = ArgumentCaptor.forClass( - Integer.class - ); - ArgumentCaptor writeCaptor = ArgumentCaptor.forClass(String.class); - - nodeHealthCheckManagementEndpoint.handle(routingContext); - - verify(httpServerResponse).setStatusCode(statusCaptor.capture()); - assertThat((int) statusCaptor.getValue()).isEqualTo(HttpStatusCode.OK_200); - verify(httpServerResponse).write(writeCaptor.capture()); - - String expected = - "{\n" + - " \"ratelimit-repository\" : {\n" + - " \"healthy\" : true\n" + - " },\n" + - " \"management-repository\" : {\n" + - " \"healthy\" : true\n" + - " }\n" + - "}"; - - assertThat(writeCaptor.getValue()).isEqualTo(expected); - } - - @Test - public void shouldFilterByProbeId() throws Exception { - Map probeResultMap = fakeProbeResults(false); - when(probeStatusRegistry.getResults()).thenReturn(probeResultMap); - when(routingContext.queryParams()).thenReturn(queryParams); - when(queryParams.contains(any())).thenReturn(true); - when(queryParams.get(any())) - .thenReturn("ratelimit-repository,management-repository,cpu"); - - ArgumentCaptor statusCaptor = ArgumentCaptor.forClass( - Integer.class - ); - ArgumentCaptor writeCaptor = ArgumentCaptor.forClass(String.class); - - nodeHealthCheckManagementEndpoint.handle(routingContext); - - verify(httpServerResponse).setStatusCode(statusCaptor.capture()); - assertThat((int) statusCaptor.getValue()) - .isEqualTo(HttpStatusCode.INTERNAL_SERVER_ERROR_500); - verify(httpServerResponse).write(writeCaptor.capture()); - - String expected = - "{\n" + - " \"ratelimit-repository\" : {\n" + - " \"healthy\" : false\n" + - " },\n" + - " \"management-repository\" : {\n" + - " \"healthy\" : true\n" + - " },\n" + - " \"cpu\" : {\n" + - " \"healthy\" : true\n" + - " }\n" + - "}"; - - assertThat(writeCaptor.getValue()).isEqualTo(expected); - } - - private Map fakeProbeResults(boolean allHealthy) { - Map probesMap = new HashMap<>(); - probesMap.put(new TestingProbe("http-server"), mockResult(true)); - probesMap.put(new TestingProbe("management-repository"), mockResult(true)); - probesMap.put( - new TestingProbe("ratelimit-repository"), - mockResult(allHealthy) - ); - probesMap.put(new TestingProbe("cpu", false), mockResult(true)); - - return probesMap; - } - - private Result mockResult(boolean isHealthy) { - return isHealthy ? Result.healthy() : Result.unhealthy((String) null); - } - - private static class TestingProbe implements Probe { - - private final String id; - private boolean isVisibleByDefault = true; - - public TestingProbe(String id) { - this.id = id; + @Mock + private NodeHealthCheckThread probeStatusRegistry; + + @Mock + private RoutingContext routingContext; + + @Mock + private MultiMap queryParams; + + private NodeHealthCheckManagementEndpoint nodeHealthCheckManagementEndpoint; + + @Mock + private HttpServerResponse httpServerResponse; + + @Before + public void setUp() { + nodeHealthCheckManagementEndpoint = new NodeHealthCheckManagementEndpoint(); + nodeHealthCheckManagementEndpoint.setRegistry(probeStatusRegistry); + + when(routingContext.response()).thenReturn(httpServerResponse); + } + + @Test + public void shouldNotFilterAllHealthy() throws Exception { + Map probeResultMap = fakeProbeResults(true); + when(probeStatusRegistry.getResults()).thenReturn(probeResultMap); + when(routingContext.queryParams()).thenReturn(queryParams); + when(queryParams.contains(any())).thenReturn(false); + + ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor writeCaptor = ArgumentCaptor.forClass(String.class); + + nodeHealthCheckManagementEndpoint.handle(routingContext); + + verify(httpServerResponse).setStatusCode(statusCaptor.capture()); + assertThat((int) statusCaptor.getValue()).isEqualTo(HttpStatusCode.OK_200); + verify(httpServerResponse).write(writeCaptor.capture()); + + String expected = + "{\n" + + " \"ratelimit-repository\" : {\n" + + " \"healthy\" : true\n" + + " },\n" + + " \"management-repository\" : {\n" + + " \"healthy\" : true\n" + + " },\n" + + " \"http-server\" : {\n" + + " \"healthy\" : true\n" + + " }\n" + + "}"; + + assertThat(writeCaptor.getValue()).isEqualTo(expected); } - public TestingProbe(String id, boolean isVisibleByDefault) { - this.id = id; - this.isVisibleByDefault = isVisibleByDefault; + @Test + public void shouldNotFilterOneUnhealthyHealthy() throws Exception { + Map probeResultMap = fakeProbeResults(false); + when(probeStatusRegistry.getResults()).thenReturn(probeResultMap); + when(routingContext.queryParams()).thenReturn(queryParams); + when(queryParams.contains(any())).thenReturn(false); + + ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor writeCaptor = ArgumentCaptor.forClass(String.class); + + nodeHealthCheckManagementEndpoint.handle(routingContext); + + verify(httpServerResponse).setStatusCode(statusCaptor.capture()); + assertThat((int) statusCaptor.getValue()).isEqualTo(HttpStatusCode.INTERNAL_SERVER_ERROR_500); + verify(httpServerResponse).write(writeCaptor.capture()); + + String expected = + "{\n" + + " \"ratelimit-repository\" : {\n" + + " \"healthy\" : false\n" + + " },\n" + + " \"management-repository\" : {\n" + + " \"healthy\" : true\n" + + " },\n" + + " \"http-server\" : {\n" + + " \"healthy\" : true\n" + + " }\n" + + "}"; + + assertThat(writeCaptor.getValue()).isEqualTo(expected); } - @Override - public String id() { - return id; + @Test + public void shouldFilterAllHealthy() throws Exception { + Map probeResultMap = fakeProbeResults(true); + when(probeStatusRegistry.getResults()).thenReturn(probeResultMap); + when(routingContext.queryParams()).thenReturn(queryParams); + when(queryParams.contains(any())).thenReturn(true); + when(queryParams.get(any())).thenReturn("ratelimit-repository,management-repository"); + + ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor writeCaptor = ArgumentCaptor.forClass(String.class); + + nodeHealthCheckManagementEndpoint.handle(routingContext); + + verify(httpServerResponse).setStatusCode(statusCaptor.capture()); + assertThat((int) statusCaptor.getValue()).isEqualTo(HttpStatusCode.OK_200); + verify(httpServerResponse).write(writeCaptor.capture()); + + String expected = + "{\n" + + " \"ratelimit-repository\" : {\n" + + " \"healthy\" : true\n" + + " },\n" + + " \"management-repository\" : {\n" + + " \"healthy\" : true\n" + + " }\n" + + "}"; + + assertThat(writeCaptor.getValue()).isEqualTo(expected); } - @Override - public boolean isVisibleByDefault() { - return this.isVisibleByDefault; + @Test + public void shouldFilterByProbeId() throws Exception { + Map probeResultMap = fakeProbeResults(false); + when(probeStatusRegistry.getResults()).thenReturn(probeResultMap); + when(routingContext.queryParams()).thenReturn(queryParams); + when(queryParams.contains(any())).thenReturn(true); + when(queryParams.get(any())).thenReturn("ratelimit-repository,management-repository,cpu"); + + ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor writeCaptor = ArgumentCaptor.forClass(String.class); + + nodeHealthCheckManagementEndpoint.handle(routingContext); + + verify(httpServerResponse).setStatusCode(statusCaptor.capture()); + assertThat((int) statusCaptor.getValue()).isEqualTo(HttpStatusCode.INTERNAL_SERVER_ERROR_500); + verify(httpServerResponse).write(writeCaptor.capture()); + + String expected = + "{\n" + + " \"ratelimit-repository\" : {\n" + + " \"healthy\" : false\n" + + " },\n" + + " \"management-repository\" : {\n" + + " \"healthy\" : true\n" + + " },\n" + + " \"cpu\" : {\n" + + " \"healthy\" : true\n" + + " }\n" + + "}"; + + assertThat(writeCaptor.getValue()).isEqualTo(expected); } - @Override - public CompletableFuture check() { - return null; + private Map fakeProbeResults(boolean allHealthy) { + Map probesMap = new HashMap<>(); + probesMap.put(new TestingProbe("http-server"), mockResult(true)); + probesMap.put(new TestingProbe("management-repository"), mockResult(true)); + probesMap.put(new TestingProbe("ratelimit-repository"), mockResult(allHealthy)); + probesMap.put(new TestingProbe("cpu", false), mockResult(true)); + + return probesMap; + } + + private Result mockResult(boolean isHealthy) { + return isHealthy ? Result.healthy() : Result.unhealthy((String) null); + } + + private static class TestingProbe implements Probe { + + private final String id; + private boolean isVisibleByDefault = true; + + public TestingProbe(String id) { + this.id = id; + } + + public TestingProbe(String id, boolean isVisibleByDefault) { + this.id = id; + this.isVisibleByDefault = isVisibleByDefault; + } + + @Override + public String id() { + return id; + } + + @Override + public boolean isVisibleByDefault() { + return this.isVisibleByDefault; + } + + @Override + public CompletableFuture check() { + return null; + } } - } } diff --git a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/NotifierServiceImpl.java b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/NotifierServiceImpl.java index 076e3ae08..aa9e3a7de 100644 --- a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/NotifierServiceImpl.java +++ b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/NotifierServiceImpl.java @@ -45,159 +45,112 @@ @Component public class NotifierServiceImpl implements NotifierService { - private final Logger logger = LoggerFactory.getLogger( - NotifierServiceImpl.class - ); - - @Value("${services.notifier.enabled:false}") - private boolean enabled; - - @Value("${services.notifier.tryAvoidDuplicateNotification:false}") - private boolean tryAvoidDuplicateNotification; - - @Autowired - private Vertx vertx; - - @Autowired - private NotifierPluginFactory notifierFactory; - - @Autowired - @Lazy - private NotificationAcknowledgeRepository notificationAcknowledgeRepository; - - private Map triggers = Maps.newConcurrentMap(); - private Map> definitions = Maps.newConcurrentMap(); - - @Override - public void register( - NotificationDefinition definition, - NotificationCondition condition, - ResendNotificationCondition resendCondition - ) { - if (enabled) { - final var notificationTrigger = getTrigger( - definition, - condition, - resendCondition - ); - final String id = buildNotificationId( - definition.getResourceId(), - definition.getResourceType(), - definition.getType(), - definition.getAudienceId() - ); - triggers.put(id, notificationTrigger); - preserveNotificationDefinition(definition); - - notificationTrigger.start(); - } else { - logger.debug("Node notifier service disabled"); + private final Logger logger = LoggerFactory.getLogger(NotifierServiceImpl.class); + + @Value("${services.notifier.enabled:false}") + private boolean enabled; + + @Value("${services.notifier.tryAvoidDuplicateNotification:false}") + private boolean tryAvoidDuplicateNotification; + + @Autowired + private Vertx vertx; + + @Autowired + private NotifierPluginFactory notifierFactory; + + @Autowired + @Lazy + private NotificationAcknowledgeRepository notificationAcknowledgeRepository; + + private Map triggers = Maps.newConcurrentMap(); + private Map> definitions = Maps.newConcurrentMap(); + + @Override + public void register(NotificationDefinition definition, NotificationCondition condition, ResendNotificationCondition resendCondition) { + if (enabled) { + final var notificationTrigger = getTrigger(definition, condition, resendCondition); + final String id = buildNotificationId( + definition.getResourceId(), + definition.getResourceType(), + definition.getType(), + definition.getAudienceId() + ); + triggers.put(id, notificationTrigger); + preserveNotificationDefinition(definition); + + notificationTrigger.start(); + } else { + logger.debug("Node notifier service disabled"); + } + } + + private void preserveNotificationDefinition(NotificationDefinition definition) { + final String resourceKey = buildResourceKey(definition.getResourceId(), definition.getResourceType()); + definitions.computeIfAbsent(resourceKey, key -> Collections.synchronizedList(new ArrayList<>())).add(definition); } - } - - private void preserveNotificationDefinition( - NotificationDefinition definition - ) { - final String resourceKey = buildResourceKey( - definition.getResourceId(), - definition.getResourceType() - ); - definitions - .computeIfAbsent( - resourceKey, - key -> Collections.synchronizedList(new ArrayList<>()) - ) - .add(definition); - } - - @Override - public void unregisterAll(String resourceId, String resourceType) { - final String resourceKey = buildResourceKey(resourceId, resourceType); - List defs = definitions.get(resourceKey); - if (defs != null) { - defs.forEach( - def -> { - final String id = buildNotificationId( - def.getResourceId(), - def.getResourceType(), - def.getType(), - def.getAudienceId() - ); - stopAndRemoveTrigger(id); + + @Override + public void unregisterAll(String resourceId, String resourceType) { + final String resourceKey = buildResourceKey(resourceId, resourceType); + List defs = definitions.get(resourceKey); + if (defs != null) { + defs.forEach(def -> { + final String id = buildNotificationId(def.getResourceId(), def.getResourceType(), def.getType(), def.getAudienceId()); + stopAndRemoveTrigger(id); + }); + definitions.remove(resourceKey); } - ); - definitions.remove(resourceKey); } - } - - @Override - public void unregister( - String resourceId, - String resourceType, - String type, - String audienceId - ) { - final String id = buildNotificationId( - resourceId, - resourceType, - type, - audienceId - ); - stopAndRemoveTrigger(id); - - removeDefinition(resourceId, resourceType, type, audienceId); - } - - private void stopAndRemoveTrigger(String id) { - Optional - .ofNullable(triggers.get(id)) - .ifPresent( - trigger -> { - trigger.stop(); - triggers.remove(id); + + @Override + public void unregister(String resourceId, String resourceType, String type, String audienceId) { + final String id = buildNotificationId(resourceId, resourceType, type, audienceId); + stopAndRemoveTrigger(id); + + removeDefinition(resourceId, resourceType, type, audienceId); + } + + private void stopAndRemoveTrigger(String id) { + Optional + .ofNullable(triggers.get(id)) + .ifPresent(trigger -> { + trigger.stop(); + triggers.remove(id); + }); + } + + private void removeDefinition(String resourceId, String resourceType, String type, String audienceId) { + final NotificationDefinition definitionToDelete = new NotificationDefinition(); + definitionToDelete.setResourceType(resourceType); + definitionToDelete.setResourceId(resourceId); + definitionToDelete.setAudienceId(audienceId); + definitionToDelete.setType(type); + final String resourceKey = buildResourceKey(resourceId, resourceType); + if (definitions.containsKey(resourceKey)) { + definitions.get(resourceKey).remove(definitionToDelete); } - ); - } - - private void removeDefinition( - String resourceId, - String resourceType, - String type, - String audienceId - ) { - final NotificationDefinition definitionToDelete = new NotificationDefinition(); - definitionToDelete.setResourceType(resourceType); - definitionToDelete.setResourceId(resourceId); - definitionToDelete.setAudienceId(audienceId); - definitionToDelete.setType(type); - final String resourceKey = buildResourceKey(resourceId, resourceType); - if (definitions.containsKey(resourceKey)) { - definitions.get(resourceKey).remove(definitionToDelete); } - } - - @Override - public Completable deleteAcknowledge(String resourceId, String resourceType) { - return this.notificationAcknowledgeRepository.deleteByResourceId( - resourceId, - resourceType - ); - } - - private NotificationTrigger getTrigger( - NotificationDefinition definition, - NotificationCondition condition, - ResendNotificationCondition resendCondition - ) { - NotificationTrigger trigger = new NotificationTrigger( - vertx, - notificationAcknowledgeRepository, - notifierFactory, - definition, - condition, - resendCondition, - this.tryAvoidDuplicateNotification - ); - return trigger; - } + + @Override + public Completable deleteAcknowledge(String resourceId, String resourceType) { + return this.notificationAcknowledgeRepository.deleteByResourceId(resourceId, resourceType); + } + + private NotificationTrigger getTrigger( + NotificationDefinition definition, + NotificationCondition condition, + ResendNotificationCondition resendCondition + ) { + NotificationTrigger trigger = new NotificationTrigger( + vertx, + notificationAcknowledgeRepository, + notifierFactory, + definition, + condition, + resendCondition, + this.tryAvoidDuplicateNotification + ); + return trigger; + } } diff --git a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/NotifierUtils.java b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/NotifierUtils.java index 38c614681..dbe41c450 100644 --- a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/NotifierUtils.java +++ b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/NotifierUtils.java @@ -21,16 +21,11 @@ */ public class NotifierUtils { - public static String buildNotificationId( - String resource, - String resourceType, - String type, - String audience - ) { - return resource + "-" + resourceType + "-" + type + "-" + audience; - } + public static String buildNotificationId(String resource, String resourceType, String type, String audience) { + return resource + "-" + resourceType + "-" + type + "-" + audience; + } - public static String buildResourceKey(String resource, String resourceType) { - return resource + "-" + resourceType; - } + public static String buildResourceKey(String resource, String resourceType) { + return resource + "-" + resourceType; + } } diff --git a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/NotifierPluginConfigurationFactory.java b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/NotifierPluginConfigurationFactory.java index 81e56ba67..4ae0ab77b 100644 --- a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/NotifierPluginConfigurationFactory.java +++ b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/NotifierPluginConfigurationFactory.java @@ -22,8 +22,5 @@ * @author GraviteeSource Team */ public interface NotifierPluginConfigurationFactory { - T create( - Class notifierConfigurationClass, - String configuration - ); + T create(Class notifierConfigurationClass, String configuration); } diff --git a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/NotifierPluginFactory.java b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/NotifierPluginFactory.java index 85376c266..aeee69098 100644 --- a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/NotifierPluginFactory.java +++ b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/NotifierPluginFactory.java @@ -24,5 +24,5 @@ * @author GraviteeSource Team */ public interface NotifierPluginFactory { - Optional create(NotificationDefinition notification); + Optional create(NotificationDefinition notification); } diff --git a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/impl/NotifierPluginConfigurationFactoryImpl.java b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/impl/NotifierPluginConfigurationFactoryImpl.java index 0988fd486..40dfdb354 100644 --- a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/impl/NotifierPluginConfigurationFactoryImpl.java +++ b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/impl/NotifierPluginConfigurationFactoryImpl.java @@ -27,38 +27,25 @@ * @author Eric LELEU (eric.leleu at graviteesource.com) * @author GraviteeSource Team */ -public class NotifierPluginConfigurationFactoryImpl - implements NotifierPluginConfigurationFactory { +public class NotifierPluginConfigurationFactoryImpl implements NotifierPluginConfigurationFactory { - private final Logger LOGGER = LoggerFactory.getLogger( - NotifierPluginConfigurationFactoryImpl.class - ); + private final Logger LOGGER = LoggerFactory.getLogger(NotifierPluginConfigurationFactoryImpl.class); - private final ObjectMapper mapper = new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + private final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - @Override - public T create( - Class notifierConfigurationClass, - String configuration - ) { - if (configuration == null || configuration.isEmpty()) { - LOGGER.debug( - "Unable to create a Notifier configuration from a null or empty configuration data" - ); - return null; - } + @Override + public T create(Class notifierConfigurationClass, String configuration) { + if (configuration == null || configuration.isEmpty()) { + LOGGER.debug("Unable to create a Notifier configuration from a null or empty configuration data"); + return null; + } - try { - return mapper.readValue(configuration, notifierConfigurationClass); - } catch (IOException ex) { - LOGGER.error( - "Unable to instance Notifier configuration for {}", - notifierConfigurationClass.getName(), - ex - ); - } + try { + return mapper.readValue(configuration, notifierConfigurationClass); + } catch (IOException ex) { + LOGGER.error("Unable to instance Notifier configuration for {}", notifierConfigurationClass.getName(), ex); + } - return null; - } + return null; + } } diff --git a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/impl/NotifierPluginFactoryImpl.java b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/impl/NotifierPluginFactoryImpl.java index a49dffa47..ad7ad4e35 100644 --- a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/impl/NotifierPluginFactoryImpl.java +++ b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/plugin/impl/NotifierPluginFactoryImpl.java @@ -47,221 +47,154 @@ */ public class NotifierPluginFactoryImpl implements NotifierPluginFactory { - private final Logger logger = LoggerFactory.getLogger( - NotifierPluginFactoryImpl.class - ); + private final Logger logger = LoggerFactory.getLogger(NotifierPluginFactoryImpl.class); - @Autowired - private ConfigurablePluginManager notifierManager; + @Autowired + private ConfigurablePluginManager notifierManager; - @Autowired - private NotifierPluginConfigurationFactory notifierConfigurationFactory; + @Autowired + private NotifierPluginConfigurationFactory notifierConfigurationFactory; - @Autowired - private NotifierClassLoaderFactory notifierClassLoaderFactory; + @Autowired + private NotifierClassLoaderFactory notifierClassLoaderFactory; - @Autowired - private ApplicationContext applicationContext; + @Autowired + private ApplicationContext applicationContext; - @Override - public Optional create(NotificationDefinition notification) { - logger.debug( - "Create a new notifier instance for {}", - notification.getType() - ); - NotifierPlugin plugin = notifierManager.get(notification.getType()); + @Override + public Optional create(NotificationDefinition notification) { + logger.debug("Create a new notifier instance for {}", notification.getType()); + NotifierPlugin plugin = notifierManager.get(notification.getType()); - if (plugin == null) { - logger.error( - "No notifier plugin is available to handle notification's type: {}", - notification.getType() - ); - return Optional.empty(); - } + if (plugin == null) { + logger.error("No notifier plugin is available to handle notification's type: {}", notification.getType()); + return Optional.empty(); + } - PluginClassLoader notifierClassLoader = notifierClassLoaderFactory.getOrCreateClassLoader( - plugin - ); + PluginClassLoader notifierClassLoader = notifierClassLoaderFactory.getOrCreateClassLoader(plugin); - try { - NotifierConfiguration configuration = notifierConfigurationFactory.create( - (Class) ClassUtils.forName( - plugin.configuration().getName(), - notifierClassLoader - ), - notification.getConfiguration() - ); + try { + NotifierConfiguration configuration = notifierConfigurationFactory.create( + (Class) ClassUtils.forName(plugin.configuration().getName(), notifierClassLoader), + notification.getConfiguration() + ); - return Optional.ofNullable( - create( - (Class) ClassUtils.forName( - plugin.clazz(), - notifierClassLoader - ), - configuration - ) - ); - } catch (ClassNotFoundException e) { - logger.error("Unable to instantiate the class {}", plugin.clazz(), e); + return Optional.ofNullable( + create((Class) ClassUtils.forName(plugin.clazz(), notifierClassLoader), configuration) + ); + } catch (ClassNotFoundException e) { + logger.error("Unable to instantiate the class {}", plugin.clazz(), e); + } + + return Optional.empty(); } - return Optional.empty(); - } + private Notifier create(Class notifierClass, C notifierConfiguration) { + Notifier notifierInst = null; - private Notifier create( - Class notifierClass, - C notifierConfiguration - ) { - Notifier notifierInst = null; + Constructor constr = lookingForConstructor(notifierClass); - Constructor constr = lookingForConstructor( - notifierClass - ); + if (constr != null) { + try { + notifierInst = constr.newInstance(notifierConfiguration); + } catch (IllegalAccessException | InstantiationException | InvocationTargetException ex) { + logger.error("Unable to instantiate notifier {}", notifierClass, ex); + } + } - if (constr != null) { - try { - notifierInst = constr.newInstance(notifierConfiguration); - } catch ( - IllegalAccessException - | InstantiationException - | InvocationTargetException ex - ) { - logger.error("Unable to instantiate notifier {}", notifierClass, ex); - } - } + if (notifierInst != null) { + applicationContext.getAutowireCapableBeanFactory().autowireBean(notifierInst); - if (notifierInst != null) { - applicationContext - .getAutowireCapableBeanFactory() - .autowireBean(notifierInst); + if (notifierInst instanceof ApplicationContextAware) { + ((ApplicationContextAware) notifierInst).setApplicationContext(applicationContext); + } + + Set fields = lookingForInjectableFields(notifierClass); + if (fields != null) { + for (Field field : fields) { + boolean accessible = field.isAccessible(); + Map, Object> injectables = new HashMap<>(); + injectables.put(notifierConfiguration.getClass(), notifierConfiguration); + + Class type = field.getType(); + Optional value = injectables.values().stream().filter(o -> type.isAssignableFrom(o.getClass())).findFirst(); + + if (value.isPresent()) { + logger.debug("Inject value into field {} [{}] in {}", field.getName(), type.getName(), notifierClass); + try { + field.setAccessible(true); + field.set(notifierInst, value.get()); + } catch (IllegalAccessException iae) { + logger.error("Unable to set field value for {} in {}", field.getName(), notifierClass, iae); + } finally { + field.setAccessible(accessible); + } + } + } + } + } - if (notifierInst instanceof ApplicationContextAware) { - ((ApplicationContextAware) notifierInst).setApplicationContext( - applicationContext - ); - } + return notifierInst; + } - Set fields = lookingForInjectableFields(notifierClass); - if (fields != null) { - for (Field field : fields) { - boolean accessible = field.isAccessible(); - Map, Object> injectables = new HashMap<>(); - injectables.put( - notifierConfiguration.getClass(), - notifierConfiguration - ); + private Constructor lookingForConstructor(Class notifierClass) { + logger.debug("Looking for a constructor to inject notifier configuration"); + Constructor constructor = null; - Class type = field.getType(); - Optional value = injectables - .values() - .stream() - .filter(o -> type.isAssignableFrom(o.getClass())) - .findFirst(); + Set resourceConstructors = ReflectionUtils.getConstructors( + notifierClass, + withModifier(Modifier.PUBLIC), + withParametersAssignableFrom(NotifierConfiguration.class), + withParametersCount(1) + ); - if (value.isPresent()) { + if (resourceConstructors.isEmpty()) { logger.debug( - "Inject value into field {} [{}] in {}", - field.getName(), - type.getName(), - notifierClass + "No configuration can be injected for {} because there is no valid constructor. " + "Using default empty constructor.", + notifierClass.getName() ); try { - field.setAccessible(true); - field.set(notifierInst, value.get()); - } catch (IllegalAccessException iae) { - logger.error( - "Unable to set field value for {} in {}", - field.getName(), - notifierClass, - iae - ); - } finally { - field.setAccessible(accessible); + constructor = notifierClass.getConstructor(); + } catch (NoSuchMethodException nsme) { + logger.error("Unable to find default empty constructor for {}", notifierClass.getName(), nsme); } - } + } else if (resourceConstructors.size() == 1) { + constructor = resourceConstructors.iterator().next(); + } else { + logger.info("Too much constructors to instantiate notifier {}", notifierClass.getName()); } - } - } - - return notifierInst; - } - - private Constructor lookingForConstructor( - Class notifierClass - ) { - logger.debug("Looking for a constructor to inject notifier configuration"); - Constructor constructor = null; - - Set resourceConstructors = ReflectionUtils.getConstructors( - notifierClass, - withModifier(Modifier.PUBLIC), - withParametersAssignableFrom(NotifierConfiguration.class), - withParametersCount(1) - ); - if (resourceConstructors.isEmpty()) { - logger.debug( - "No configuration can be injected for {} because there is no valid constructor. " + - "Using default empty constructor.", - notifierClass.getName() - ); - try { - constructor = notifierClass.getConstructor(); - } catch (NoSuchMethodException nsme) { - logger.error( - "Unable to find default empty constructor for {}", - notifierClass.getName(), - nsme - ); - } - } else if (resourceConstructors.size() == 1) { - constructor = resourceConstructors.iterator().next(); - } else { - logger.info( - "Too much constructors to instantiate notifier {}", - notifierClass.getName() - ); + return constructor; } - return constructor; - } - - private Set lookingForInjectableFields(Class resourceClass) { - return ReflectionUtils.getAllFields( - resourceClass, - withAnnotation(Inject.class) - ); - } + private Set lookingForInjectableFields(Class resourceClass) { + return ReflectionUtils.getAllFields(resourceClass, withAnnotation(Inject.class)); + } - public static Predicate withParametersAssignableFrom( - final Class... types - ) { - return input -> { - if (input != null) { - Class[] parameterTypes = parameterTypes(input); - if (parameterTypes.length == types.length) { - for (int i = 0; i < parameterTypes.length; i++) { - if ( - !types[i].isAssignableFrom(parameterTypes[i]) || - (parameterTypes[i] == Object.class && types[i] != Object.class) - ) { - return false; + public static Predicate withParametersAssignableFrom(final Class... types) { + return input -> { + if (input != null) { + Class[] parameterTypes = parameterTypes(input); + if (parameterTypes.length == types.length) { + for (int i = 0; i < parameterTypes.length; i++) { + if ( + !types[i].isAssignableFrom(parameterTypes[i]) || (parameterTypes[i] == Object.class && types[i] != Object.class) + ) { + return false; + } + } + return true; + } } - } - return true; - } - } - return false; - }; - } + return false; + }; + } - private static Class[] parameterTypes(Member member) { - return member != null - ? member.getClass() == Method.class - ? ((Method) member).getParameterTypes() - : member.getClass() == Constructor.class - ? ((Constructor) member).getParameterTypes() - : null - : null; - } + private static Class[] parameterTypes(Member member) { + return member != null + ? member.getClass() == Method.class + ? ((Method) member).getParameterTypes() + : member.getClass() == Constructor.class ? ((Constructor) member).getParameterTypes() : null + : null; + } } diff --git a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/spring/NotifierConfiguration.java b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/spring/NotifierConfiguration.java index 42b62831d..cdc62c166 100644 --- a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/spring/NotifierConfiguration.java +++ b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/spring/NotifierConfiguration.java @@ -29,13 +29,13 @@ @Configuration public class NotifierConfiguration { - @Bean - public NotifierPluginFactory getNotifierPluginFactory() { - return new NotifierPluginFactoryImpl(); - } + @Bean + public NotifierPluginFactory getNotifierPluginFactory() { + return new NotifierPluginFactoryImpl(); + } - @Bean - public NotifierPluginConfigurationFactory getNotifierPluginConfigurationFactory() { - return new NotifierPluginConfigurationFactoryImpl(); - } + @Bean + public NotifierPluginConfigurationFactory getNotifierPluginConfigurationFactory() { + return new NotifierPluginConfigurationFactoryImpl(); + } } diff --git a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/trigger/NotificationTrigger.java b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/trigger/NotificationTrigger.java index 05073c7c5..6b492aae0 100644 --- a/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/trigger/NotificationTrigger.java +++ b/gravitee-node-notifier/src/main/java/io/gravitee/node/notifier/trigger/NotificationTrigger.java @@ -39,227 +39,194 @@ */ public class NotificationTrigger implements Handler { - private static final Logger LOGGER = LoggerFactory.getLogger( - NotificationTrigger.class - ); + private static final Logger LOGGER = LoggerFactory.getLogger(NotificationTrigger.class); - private Vertx vertx; + private Vertx vertx; - private NotificationAcknowledgeRepository notificationAcknowledgeRepository; + private NotificationAcknowledgeRepository notificationAcknowledgeRepository; - private NotifierPluginFactory notifierFactory; + private NotifierPluginFactory notifierFactory; - private NotificationDefinition definition; + private NotificationDefinition definition; - private NotificationCondition condition; + private NotificationCondition condition; - private ResendNotificationCondition resendCondition; + private ResendNotificationCondition resendCondition; - private Long scheduledTaskId; + private Long scheduledTaskId; - private CronExpression cronExpression; + private CronExpression cronExpression; - private final int randomDelayInMs; + private final int randomDelayInMs; - public NotificationTrigger( - Vertx vertx, - NotificationAcknowledgeRepository notificationAcknowledgeRepository, - NotifierPluginFactory notifierFactory, - NotificationDefinition definition, - NotificationCondition condition, - ResendNotificationCondition resendCondition, - boolean tryToAvoidMultipleNotif - ) { - this.vertx = vertx; - this.notificationAcknowledgeRepository = notificationAcknowledgeRepository; - this.notifierFactory = notifierFactory; - this.definition = definition; - this.condition = condition; - this.resendCondition = resendCondition; - this.cronExpression = CronExpression.parse(definition.getCron()); - if (tryToAvoidMultipleNotif) { - this.randomDelayInMs = Math.max(1, new Random().nextInt(10)) * 1000; - } else { - this.randomDelayInMs = -1; + public NotificationTrigger( + Vertx vertx, + NotificationAcknowledgeRepository notificationAcknowledgeRepository, + NotifierPluginFactory notifierFactory, + NotificationDefinition definition, + NotificationCondition condition, + ResendNotificationCondition resendCondition, + boolean tryToAvoidMultipleNotif + ) { + this.vertx = vertx; + this.notificationAcknowledgeRepository = notificationAcknowledgeRepository; + this.notifierFactory = notifierFactory; + this.definition = definition; + this.condition = condition; + this.resendCondition = resendCondition; + this.cronExpression = CronExpression.parse(definition.getCron()); + if (tryToAvoidMultipleNotif) { + this.randomDelayInMs = Math.max(1, new Random().nextInt(10)) * 1000; + } else { + this.randomDelayInMs = -1; + } } - } - - public void start() { - scheduleNextAttempt(); - } - private void scheduleNextAttempt() { - this.scheduledTaskId = this.vertx.setTimer(computeNextAttempt(), this); - } + public void start() { + scheduleNextAttempt(); + } - public void stop() { - if ( - this.scheduledTaskId != null && - this.vertx.cancelTimer(this.scheduledTaskId) - ) { - LOGGER.debug("Notification Trigger cancelled !"); - } else { - LOGGER.debug("Notification Trigger can't be cancelled or doesn't exist"); + private void scheduleNextAttempt() { + this.scheduledTaskId = this.vertx.setTimer(computeNextAttempt(), this); } - } - private long computeNextAttempt() { - final LocalDateTime now = LocalDateTime.now(); - final long delay = - toEpochMillis(this.cronExpression.next(now)) - toEpochMillis(now); - return randomDelayInMs > 0 ? delay + randomDelayInMs : delay; - } + public void stop() { + if (this.scheduledTaskId != null && this.vertx.cancelTimer(this.scheduledTaskId)) { + LOGGER.debug("Notification Trigger cancelled !"); + } else { + LOGGER.debug("Notification Trigger can't be cancelled or doesn't exist"); + } + } - private long toEpochMillis(LocalDateTime dateTime) { - return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); - } + private long computeNextAttempt() { + final LocalDateTime now = LocalDateTime.now(); + final long delay = toEpochMillis(this.cronExpression.next(now)) - toEpochMillis(now); + return randomDelayInMs > 0 ? delay + randomDelayInMs : delay; + } - @Override - public void handle(Long event) { - if (condition.test(definition)) { - // keep EventLoop context in order to use it to execute the notifier's send method - final Context triggerContext = vertx.getOrCreateContext(); - this.notificationAcknowledgeRepository.findByResourceIdAndTypeAndAudienceId( - this.definition.getResourceId(), - this.definition.getResourceType(), - definition.getType(), - definition.getAudienceId() - ) - .map(Optional::ofNullable) - .switchIfEmpty(Maybe.just(Optional.empty())) - .subscribe( - notifAck -> { - final boolean firstNotification = notifAck.isEmpty(); - if ( - firstNotification || - resendCondition.apply(definition, notifAck.get()) - ) { - // instantiate the plugin and send notification - final Optional optNotifier = notifierFactory.create( - definition - ); - if (optNotifier.isPresent()) { - LOGGER.debug( - "Send Notification with notifier type {} to audience {} about resource {}", - definition.getType(), - definition.getAudienceId(), - definition.getResourceId() - ); - final Notifier notifier = optNotifier.get(); - // execute the send method into the triggerContext to avoid NullPointer as some notifiers rely on Vertx.currentContext - // that will be null as this block of code is executed in a RxJava ThreadPool and not into the Vertx EventLoop - triggerContext.runOnContext( - aVoid -> - notifier - .send(buildNotification(definition), definition.getData()) - .whenComplete( - (Void anotherVoid, Throwable throwable) -> { - if (throwable != null) { - LOGGER.error( - "An error occurs while sending notification to {}", - definition.getType(), - throwable - ); - // trigger a new attempt - this.scheduleNextAttempt(); - } else { - LOGGER.debug( - "A notification has been sent to {}", - definition.getType() - ); + private long toEpochMillis(LocalDateTime dateTime) { + return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + } - NotificationAcknowledge notificationAcknowledge = notifAck.orElse( - new NotificationAcknowledge() - ); - Date now = new Date(); - notificationAcknowledge.setUpdatedAt(now); - if (firstNotification) { - // Acknowledge has just been created - notificationAcknowledge.setCreatedAt(now); - notificationAcknowledge.setType( - definition.getType() - ); - notificationAcknowledge.setAudienceId( - definition.getAudienceId() - ); - notificationAcknowledge.setResourceId( - definition.getResourceId() - ); - notificationAcknowledge.setResourceType( - definition.getResourceType() - ); + @Override + public void handle(Long event) { + if (condition.test(definition)) { + // keep EventLoop context in order to use it to execute the notifier's send method + final Context triggerContext = vertx.getOrCreateContext(); + this.notificationAcknowledgeRepository.findByResourceIdAndTypeAndAudienceId( + this.definition.getResourceId(), + this.definition.getResourceType(), + definition.getType(), + definition.getAudienceId() + ) + .map(Optional::ofNullable) + .switchIfEmpty(Maybe.just(Optional.empty())) + .subscribe( + notifAck -> { + final boolean firstNotification = notifAck.isEmpty(); + if (firstNotification || resendCondition.apply(definition, notifAck.get())) { + // instantiate the plugin and send notification + final Optional optNotifier = notifierFactory.create(definition); + if (optNotifier.isPresent()) { + LOGGER.debug( + "Send Notification with notifier type {} to audience {} about resource {}", + definition.getType(), + definition.getAudienceId(), + definition.getResourceId() + ); + final Notifier notifier = optNotifier.get(); + // execute the send method into the triggerContext to avoid NullPointer as some notifiers rely on Vertx.currentContext + // that will be null as this block of code is executed in a RxJava ThreadPool and not into the Vertx EventLoop + triggerContext.runOnContext(aVoid -> + notifier + .send(buildNotification(definition), definition.getData()) + .whenComplete((Void anotherVoid, Throwable throwable) -> { + if (throwable != null) { + LOGGER.error( + "An error occurs while sending notification to {}", + definition.getType(), + throwable + ); + // trigger a new attempt + this.scheduleNextAttempt(); + } else { + LOGGER.debug("A notification has been sent to {}", definition.getType()); + + NotificationAcknowledge notificationAcknowledge = notifAck.orElse( + new NotificationAcknowledge() + ); + Date now = new Date(); + notificationAcknowledge.setUpdatedAt(now); + if (firstNotification) { + // Acknowledge has just been created + notificationAcknowledge.setCreatedAt(now); + notificationAcknowledge.setType(definition.getType()); + notificationAcknowledge.setAudienceId(definition.getAudienceId()); + notificationAcknowledge.setResourceId(definition.getResourceId()); + notificationAcknowledge.setResourceType(definition.getResourceType()); + } else { + // existing acknowledge, increment the number of notifications + notificationAcknowledge.incrementCounter(); + } + + final Single saveAcknowledge = firstNotification + ? notificationAcknowledgeRepository.create(notificationAcknowledge) + : notificationAcknowledgeRepository.update(notificationAcknowledge); + + saveAcknowledge + .doOnError(error -> + LOGGER.warn( + "Unable to store acknowledge for notification with audience {} and resource {}", + definition.getAudienceId(), + definition.getResourceId(), + error + ) + ) + .doFinally(() -> + //trigger a new attempt + this.scheduleNextAttempt() + ) + .subscribe(); + } + }) + ); } else { - // existing acknowledge, increment the number of notifications - notificationAcknowledge.incrementCounter(); - } - - final Single saveAcknowledge = firstNotification - ? notificationAcknowledgeRepository.create( - notificationAcknowledge - ) - : notificationAcknowledgeRepository.update( - notificationAcknowledge - ); - - saveAcknowledge - .doOnError( - error -> - LOGGER.warn( - "Unable to store acknowledge for notification with audience {} and resource {}", + LOGGER.warn( + "Notifier {} not found, unable to send notification to target {} about resource {}", + definition.getType(), definition.getAudienceId(), - definition.getResourceId(), - error - ) - ) - .doFinally( - () -> - //trigger a new attempt - this.scheduleNextAttempt() - ) - .subscribe(); - } + definition.getResourceId() + ); + } + } else { + LOGGER.debug( + "Notification about resource {} already sent to target {}", + definition.getResourceId(), + definition.getAudienceId() + ); + // trigger a new attempt. + // this will allow a new notification + // if DB entries are purged as we will have no + // way to know if the notification has been sent or not + this.scheduleNextAttempt(); } - ) - ); - } else { - LOGGER.warn( - "Notifier {} not found, unable to send notification to target {} about resource {}", - definition.getType(), - definition.getAudienceId(), - definition.getResourceId() + }, + error -> { + //trigger a new attempt + this.scheduleNextAttempt(); + LOGGER.warn("Notification can't be send : {}", error.getMessage()); + } ); - } - } else { - LOGGER.debug( - "Notification about resource {} already sent to target {}", - definition.getResourceId(), - definition.getAudienceId() - ); - // trigger a new attempt. - // this will allow a new notification - // if DB entries are purged as we will have no - // way to know if the notification has been sent or not - this.scheduleNextAttempt(); - } - }, - error -> { - //trigger a new attempt + } else { + // if rule isn't respected, trigger a new attempt this.scheduleNextAttempt(); - LOGGER.warn("Notification can't be send : {}", error.getMessage()); - } - ); - } else { - // if rule isn't respected, trigger a new attempt - this.scheduleNextAttempt(); + } } - } - private final Notification buildNotification( - NotificationDefinition definition - ) { - Notification notification = new Notification(); - notification.setConfiguration(definition.getConfiguration()); - notification.setType(definition.getType()); - return notification; - } + private final Notification buildNotification(NotificationDefinition definition) { + Notification notification = new Notification(); + notification.setConfiguration(definition.getConfiguration()); + notification.setType(definition.getType()); + return notification; + } } diff --git a/gravitee-node-notifier/src/test/java/io/gravitee/node/notifier/trigger/NotificationTriggerTest.java b/gravitee-node-notifier/src/test/java/io/gravitee/node/notifier/trigger/NotificationTriggerTest.java index 27b527431..2a563264a 100644 --- a/gravitee-node-notifier/src/test/java/io/gravitee/node/notifier/trigger/NotificationTriggerTest.java +++ b/gravitee-node-notifier/src/test/java/io/gravitee/node/notifier/trigger/NotificationTriggerTest.java @@ -39,188 +39,152 @@ @RunWith(MockitoJUnitRunner.class) public class NotificationTriggerTest { - @Spy - private NotificationDefinition definition = new NotificationDefinition(); - - @Mock - private NotificationCondition condition; - - @Mock - private ResendNotificationCondition resendCondition; - - @Spy - private Vertx vertx = Vertx.vertx(); - - @Mock - private NotificationAcknowledgeRepository notificationAcknowledgeRepository; - - @Mock - private NotifierPluginFactory notifierFactory; - - @Mock - private Notifier notifier; - - @Test - public void testShouldScheludeIfConditionNotTrue() { - definition.setCron("*/10 * * * * *"); - - NotificationTrigger cut = new NotificationTrigger( - vertx, - notificationAcknowledgeRepository, - notifierFactory, - definition, - condition, - resendCondition, - true - ); - - when(condition.test(any())).thenReturn(false); - - cut.handle(1l); - - verify(notificationAcknowledgeRepository, never()) - .findByResourceIdAndTypeAndAudienceId(any(), any(), any(), any()); - verify(notificationAcknowledgeRepository, never()).create(any()); - verify(vertx).setTimer(anyLong(), any()); - } - - @Test - public void testShouldNotify() throws Exception { - definition.setCron("*/10 * * * * *"); - definition.setResourceId("notifid"); - definition.setAudienceId("audid"); - definition.setType("email"); - - NotificationTrigger cut = new NotificationTrigger( - vertx, - notificationAcknowledgeRepository, - notifierFactory, - definition, - condition, - resendCondition, - true - ); - - when(condition.test(any())).thenReturn(true); - when( - notificationAcknowledgeRepository.findByResourceIdAndTypeAndAudienceId( - any(), - any(), - any(), - any() - ) - ) - .thenReturn(Maybe.empty(), Maybe.just(new NotificationAcknowledge())); - when(notifierFactory.create(any())).thenReturn(Optional.of(notifier)); - when(notifier.send(any(), any())).thenReturn(CompletableFuture.allOf()); - when(notificationAcknowledgeRepository.create(any())) - .thenReturn(Single.just(new NotificationAcknowledge())); - - cut.handle(1l); - - Thread.sleep(2000); - - verify(notificationAcknowledgeRepository, atLeast(1)) - .findByResourceIdAndTypeAndAudienceId(any(), any(), any(), any()); - verify(notificationAcknowledgeRepository) - .create( - argThat( - na -> - na.getResourceId().equals("notifid") && na.getType().equals("email") - ) - ); - } - - @Test - public void testShouldNotNotify_IfAlreadyAcknowledged() throws Exception { - definition.setCron("*/10 * * * * *"); - definition.setResourceId("notifid"); - definition.setAudienceId("audid"); - definition.setType("email"); - - NotificationTrigger cut = new NotificationTrigger( - vertx, - notificationAcknowledgeRepository, - notifierFactory, - definition, - condition, - resendCondition, - true - ); - - when(condition.test(any())).thenReturn(true); - when(resendCondition.apply(any(), any())).thenReturn(false); - when( - notificationAcknowledgeRepository.findByResourceIdAndTypeAndAudienceId( - any(), - any(), - any(), - any() - ) - ) - .thenReturn(Maybe.just(new NotificationAcknowledge())); - - cut.handle(1l); - - Thread.sleep(2000); - - verify(notificationAcknowledgeRepository, atLeast(1)) - .findByResourceIdAndTypeAndAudienceId(any(), any(), any(), any()); - verify(notificationAcknowledgeRepository, never()).create(any()); - verify(notificationAcknowledgeRepository, never()).update(any()); - } - - @Test - public void testShouldResendNotification() throws Exception { - definition.setCron("*/10 * * * * *"); - definition.setResourceId("notifid"); - definition.setAudienceId("audid"); - definition.setType("email"); - - NotificationTrigger cut = new NotificationTrigger( - vertx, - notificationAcknowledgeRepository, - notifierFactory, - definition, - condition, - resendCondition, - true - ); - - when(condition.test(any())).thenReturn(true); - when(resendCondition.apply(any(), any())).thenReturn(true); - final NotificationAcknowledge notificationAcknowledge = new NotificationAcknowledge(); - notificationAcknowledge.setCreatedAt(new Date()); - notificationAcknowledge.setType(definition.getType()); - notificationAcknowledge.setAudienceId(definition.getAudienceId()); - notificationAcknowledge.setResourceId(definition.getResourceId()); - notificationAcknowledge.setResourceType(definition.getResourceType()); - - when( - notificationAcknowledgeRepository.findByResourceIdAndTypeAndAudienceId( - any(), - any(), - any(), - any() - ) - ) - .thenReturn(Maybe.just(notificationAcknowledge)); - when(notifierFactory.create(any())).thenReturn(Optional.of(notifier)); - when(notifier.send(any(), any())).thenReturn(CompletableFuture.allOf()); - - cut.handle(1l); - - Thread.sleep(2000); - - verify(notificationAcknowledgeRepository, atLeast(1)) - .findByResourceIdAndTypeAndAudienceId(any(), any(), any(), any()); - verify(notificationAcknowledgeRepository, never()).create(any()); - verify(notificationAcknowledgeRepository) - .update( - argThat( - na -> - na.getResourceId().equals("notifid") && na.getType().equals("email") - ) - ); - } + @Spy + private NotificationDefinition definition = new NotificationDefinition(); + + @Mock + private NotificationCondition condition; + + @Mock + private ResendNotificationCondition resendCondition; + + @Spy + private Vertx vertx = Vertx.vertx(); + + @Mock + private NotificationAcknowledgeRepository notificationAcknowledgeRepository; + + @Mock + private NotifierPluginFactory notifierFactory; + + @Mock + private Notifier notifier; + + @Test + public void testShouldScheludeIfConditionNotTrue() { + definition.setCron("*/10 * * * * *"); + + NotificationTrigger cut = new NotificationTrigger( + vertx, + notificationAcknowledgeRepository, + notifierFactory, + definition, + condition, + resendCondition, + true + ); + + when(condition.test(any())).thenReturn(false); + + cut.handle(1l); + + verify(notificationAcknowledgeRepository, never()).findByResourceIdAndTypeAndAudienceId(any(), any(), any(), any()); + verify(notificationAcknowledgeRepository, never()).create(any()); + verify(vertx).setTimer(anyLong(), any()); + } + + @Test + public void testShouldNotify() throws Exception { + definition.setCron("*/10 * * * * *"); + definition.setResourceId("notifid"); + definition.setAudienceId("audid"); + definition.setType("email"); + + NotificationTrigger cut = new NotificationTrigger( + vertx, + notificationAcknowledgeRepository, + notifierFactory, + definition, + condition, + resendCondition, + true + ); + + when(condition.test(any())).thenReturn(true); + when(notificationAcknowledgeRepository.findByResourceIdAndTypeAndAudienceId(any(), any(), any(), any())) + .thenReturn(Maybe.empty(), Maybe.just(new NotificationAcknowledge())); + when(notifierFactory.create(any())).thenReturn(Optional.of(notifier)); + when(notifier.send(any(), any())).thenReturn(CompletableFuture.allOf()); + when(notificationAcknowledgeRepository.create(any())).thenReturn(Single.just(new NotificationAcknowledge())); + + cut.handle(1l); + + Thread.sleep(2000); + + verify(notificationAcknowledgeRepository, atLeast(1)).findByResourceIdAndTypeAndAudienceId(any(), any(), any(), any()); + verify(notificationAcknowledgeRepository) + .create(argThat(na -> na.getResourceId().equals("notifid") && na.getType().equals("email"))); + } + + @Test + public void testShouldNotNotify_IfAlreadyAcknowledged() throws Exception { + definition.setCron("*/10 * * * * *"); + definition.setResourceId("notifid"); + definition.setAudienceId("audid"); + definition.setType("email"); + + NotificationTrigger cut = new NotificationTrigger( + vertx, + notificationAcknowledgeRepository, + notifierFactory, + definition, + condition, + resendCondition, + true + ); + + when(condition.test(any())).thenReturn(true); + when(resendCondition.apply(any(), any())).thenReturn(false); + when(notificationAcknowledgeRepository.findByResourceIdAndTypeAndAudienceId(any(), any(), any(), any())) + .thenReturn(Maybe.just(new NotificationAcknowledge())); + + cut.handle(1l); + + Thread.sleep(2000); + + verify(notificationAcknowledgeRepository, atLeast(1)).findByResourceIdAndTypeAndAudienceId(any(), any(), any(), any()); + verify(notificationAcknowledgeRepository, never()).create(any()); + verify(notificationAcknowledgeRepository, never()).update(any()); + } + + @Test + public void testShouldResendNotification() throws Exception { + definition.setCron("*/10 * * * * *"); + definition.setResourceId("notifid"); + definition.setAudienceId("audid"); + definition.setType("email"); + + NotificationTrigger cut = new NotificationTrigger( + vertx, + notificationAcknowledgeRepository, + notifierFactory, + definition, + condition, + resendCondition, + true + ); + + when(condition.test(any())).thenReturn(true); + when(resendCondition.apply(any(), any())).thenReturn(true); + final NotificationAcknowledge notificationAcknowledge = new NotificationAcknowledge(); + notificationAcknowledge.setCreatedAt(new Date()); + notificationAcknowledge.setType(definition.getType()); + notificationAcknowledge.setAudienceId(definition.getAudienceId()); + notificationAcknowledge.setResourceId(definition.getResourceId()); + notificationAcknowledge.setResourceType(definition.getResourceType()); + + when(notificationAcknowledgeRepository.findByResourceIdAndTypeAndAudienceId(any(), any(), any(), any())) + .thenReturn(Maybe.just(notificationAcknowledge)); + when(notifierFactory.create(any())).thenReturn(Optional.of(notifier)); + when(notifier.send(any(), any())).thenReturn(CompletableFuture.allOf()); + + cut.handle(1l); + + Thread.sleep(2000); + + verify(notificationAcknowledgeRepository, atLeast(1)).findByResourceIdAndTypeAndAudienceId(any(), any(), any(), any()); + verify(notificationAcknowledgeRepository, never()).create(any()); + verify(notificationAcknowledgeRepository) + .update(argThat(na -> na.getResourceId().equals("notifid") && na.getType().equals("email"))); + } } diff --git a/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/ServiceManager.java b/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/ServiceManager.java index 77cb15a1d..fa65b1604 100644 --- a/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/ServiceManager.java +++ b/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/ServiceManager.java @@ -23,5 +23,5 @@ * @author GraviteeSource Team */ public interface ServiceManager extends Service { - void register(AbstractService service); + void register(AbstractService service); } diff --git a/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/handler/ServicePluginHandler.java b/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/handler/ServicePluginHandler.java index a404e89bd..1de30076e 100644 --- a/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/handler/ServicePluginHandler.java +++ b/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/handler/ServicePluginHandler.java @@ -26,37 +26,33 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class ServicePluginHandler - extends AbstractSpringPluginHandler { - - private static final String PLUGIN_TYPE = "service"; - - @Autowired - private ServiceManager serviceManager; - - @Autowired - private PluginClassLoaderFactory pluginClassLoaderFactory; - - @Override - public boolean canHandle(Plugin plugin) { - return PLUGIN_TYPE.equalsIgnoreCase(plugin.type()); - } - - @Override - protected String type() { - return "services"; - } - - @Override - protected ClassLoader getClassLoader(Plugin plugin) throws Exception { - return pluginClassLoaderFactory.getOrCreateClassLoader( - plugin, - this.getClass().getClassLoader() - ); - } - - @Override - protected void register(AbstractService plugin) { - serviceManager.register(plugin); - } +public class ServicePluginHandler extends AbstractSpringPluginHandler { + + private static final String PLUGIN_TYPE = "service"; + + @Autowired + private ServiceManager serviceManager; + + @Autowired + private PluginClassLoaderFactory pluginClassLoaderFactory; + + @Override + public boolean canHandle(Plugin plugin) { + return PLUGIN_TYPE.equalsIgnoreCase(plugin.type()); + } + + @Override + protected String type() { + return "services"; + } + + @Override + protected ClassLoader getClassLoader(Plugin plugin) throws Exception { + return pluginClassLoaderFactory.getOrCreateClassLoader(plugin, this.getClass().getClassLoader()); + } + + @Override + protected void register(AbstractService plugin) { + serviceManager.register(plugin); + } } diff --git a/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/impl/ServiceManagerImpl.java b/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/impl/ServiceManagerImpl.java index c2c978af0..215432c6e 100644 --- a/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/impl/ServiceManagerImpl.java +++ b/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/impl/ServiceManagerImpl.java @@ -30,87 +30,80 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class ServiceManagerImpl - extends AbstractService - implements ServiceManager { +public class ServiceManagerImpl extends AbstractService implements ServiceManager { - private static final Logger LOGGER = LoggerFactory.getLogger( - ServiceManagerImpl.class - ); + private static final Logger LOGGER = LoggerFactory.getLogger(ServiceManagerImpl.class); - private final List services = new ArrayList<>(); + private final List services = new ArrayList<>(); - @Override - public void register(AbstractService service) { - services.add(service); - } + @Override + public void register(AbstractService service) { + services.add(service); + } - @Override - protected void doStart() throws Exception { - super.doStart(); + @Override + protected void doStart() throws Exception { + super.doStart(); - List orderedServices = services - .stream() - .sorted(comparing(AbstractService::getOrder)) - .collect(toList()); + List orderedServices = services.stream().sorted(comparing(AbstractService::getOrder)).collect(toList()); - for (AbstractService service : orderedServices) { - try { - service.preStart(); - } catch (Exception ex) { - LOGGER.error("Unexpected error while pre-starting service", ex); - } - } - for (AbstractService service : orderedServices) { - try { - service.start(); - } catch (Exception ex) { - LOGGER.error("Unexpected error while starting service", ex); - } - } - for (AbstractService service : orderedServices) { - try { - service.postStart(); - } catch (Exception ex) { - LOGGER.error("Unexpected error while post-starting service", ex); - } + for (AbstractService service : orderedServices) { + try { + service.preStart(); + } catch (Exception ex) { + LOGGER.error("Unexpected error while pre-starting service", ex); + } + } + for (AbstractService service : orderedServices) { + try { + service.start(); + } catch (Exception ex) { + LOGGER.error("Unexpected error while starting service", ex); + } + } + for (AbstractService service : orderedServices) { + try { + service.postStart(); + } catch (Exception ex) { + LOGGER.error("Unexpected error while post-starting service", ex); + } + } } - } - @Override - protected void doStop() throws Exception { - super.doStop(); + @Override + protected void doStop() throws Exception { + super.doStop(); - List orderedServices = services - .stream() - .sorted(comparing(AbstractService::getOrder, reverseOrder())) - .collect(toList()); + List orderedServices = services + .stream() + .sorted(comparing(AbstractService::getOrder, reverseOrder())) + .collect(toList()); - for (AbstractService service : orderedServices) { - try { - service.preStop(); - } catch (Exception ex) { - LOGGER.error("Unexpected error while pre-stopping service", ex); - } + for (AbstractService service : orderedServices) { + try { + service.preStop(); + } catch (Exception ex) { + LOGGER.error("Unexpected error while pre-stopping service", ex); + } + } + for (AbstractService service : orderedServices) { + try { + service.stop(); + } catch (Exception ex) { + LOGGER.error("Unexpected error while stopping service", ex); + } + } + for (AbstractService service : orderedServices) { + try { + service.postStop(); + } catch (Exception ex) { + LOGGER.error("Unexpected error while post-stopping service", ex); + } + } } - for (AbstractService service : orderedServices) { - try { - service.stop(); - } catch (Exception ex) { - LOGGER.error("Unexpected error while stopping service", ex); - } - } - for (AbstractService service : orderedServices) { - try { - service.postStop(); - } catch (Exception ex) { - LOGGER.error("Unexpected error while post-stopping service", ex); - } - } - } - @Override - protected String name() { - return "Plugins - Services Manager"; - } + @Override + protected String name() { + return "Plugins - Services Manager"; + } } diff --git a/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/spring/ServiceConfiguration.java b/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/spring/ServiceConfiguration.java index 8057fd7de..1d1d5d8ed 100644 --- a/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/spring/ServiceConfiguration.java +++ b/gravitee-node-plugins/gravitee-node-plugins-service/src/main/java/io/gravitee/node/plugins/service/spring/ServiceConfiguration.java @@ -27,8 +27,8 @@ @Configuration public class ServiceConfiguration { - @Bean - public ServiceManager serviceManager() { - return new ServiceManagerImpl(); - } + @Bean + public ServiceManager serviceManager() { + return new ServiceManagerImpl(); + } } diff --git a/gravitee-node-plugins/gravitee-node-plugins-service/src/test/java/io/gravitee/node/plugins/service/impl/ServiceManagerImplTest.java b/gravitee-node-plugins/gravitee-node-plugins-service/src/test/java/io/gravitee/node/plugins/service/impl/ServiceManagerImplTest.java index e0f559573..027bc75ba 100644 --- a/gravitee-node-plugins/gravitee-node-plugins-service/src/test/java/io/gravitee/node/plugins/service/impl/ServiceManagerImplTest.java +++ b/gravitee-node-plugins/gravitee-node-plugins-service/src/test/java/io/gravitee/node/plugins/service/impl/ServiceManagerImplTest.java @@ -28,67 +28,65 @@ @RunWith(MockitoJUnitRunner.class) public class ServiceManagerImplTest { - private final ServiceManagerImpl serviceManager = new ServiceManagerImpl(); - - @Mock - private AbstractService service1, service2, service3, service4; - - @Before - public void setup() { - doReturn(700).when(service1).getOrder(); - doReturn(900).when(service2).getOrder(); - doReturn(750).when(service3).getOrder(); - doReturn(699).when(service4).getOrder(); - - serviceManager.register(service1); - serviceManager.register(service2); - serviceManager.register(service3); - serviceManager.register(service4); - } - - @Test - public void doStart_should_prestart_start_and_poststart_in_order() - throws Exception { - serviceManager.doStart(); - - InOrder inOrder = inOrder(service4, service1, service3, service2); - - inOrder.verify(service4, times(1)).preStart(); - inOrder.verify(service1, times(1)).preStart(); - inOrder.verify(service3, times(1)).preStart(); - inOrder.verify(service2, times(1)).preStart(); - - inOrder.verify(service4, times(1)).start(); - inOrder.verify(service1, times(1)).start(); - inOrder.verify(service3, times(1)).start(); - inOrder.verify(service2, times(1)).start(); - - inOrder.verify(service4, times(1)).postStart(); - inOrder.verify(service1, times(1)).postStart(); - inOrder.verify(service3, times(1)).postStart(); - inOrder.verify(service2, times(1)).postStart(); - } - - @Test - public void doStop_should_prestop_stop_and_poststop_in_reverse_order() - throws Exception { - serviceManager.doStop(); - - InOrder inOrder = inOrder(service4, service1, service3, service2); - - inOrder.verify(service2, times(1)).preStop(); - inOrder.verify(service3, times(1)).preStop(); - inOrder.verify(service1, times(1)).preStop(); - inOrder.verify(service4, times(1)).preStop(); - - inOrder.verify(service2, times(1)).stop(); - inOrder.verify(service3, times(1)).stop(); - inOrder.verify(service1, times(1)).stop(); - inOrder.verify(service4, times(1)).stop(); - - inOrder.verify(service2, times(1)).postStop(); - inOrder.verify(service3, times(1)).postStop(); - inOrder.verify(service1, times(1)).postStop(); - inOrder.verify(service4, times(1)).postStop(); - } + private final ServiceManagerImpl serviceManager = new ServiceManagerImpl(); + + @Mock + private AbstractService service1, service2, service3, service4; + + @Before + public void setup() { + doReturn(700).when(service1).getOrder(); + doReturn(900).when(service2).getOrder(); + doReturn(750).when(service3).getOrder(); + doReturn(699).when(service4).getOrder(); + + serviceManager.register(service1); + serviceManager.register(service2); + serviceManager.register(service3); + serviceManager.register(service4); + } + + @Test + public void doStart_should_prestart_start_and_poststart_in_order() throws Exception { + serviceManager.doStart(); + + InOrder inOrder = inOrder(service4, service1, service3, service2); + + inOrder.verify(service4, times(1)).preStart(); + inOrder.verify(service1, times(1)).preStart(); + inOrder.verify(service3, times(1)).preStart(); + inOrder.verify(service2, times(1)).preStart(); + + inOrder.verify(service4, times(1)).start(); + inOrder.verify(service1, times(1)).start(); + inOrder.verify(service3, times(1)).start(); + inOrder.verify(service2, times(1)).start(); + + inOrder.verify(service4, times(1)).postStart(); + inOrder.verify(service1, times(1)).postStart(); + inOrder.verify(service3, times(1)).postStart(); + inOrder.verify(service2, times(1)).postStart(); + } + + @Test + public void doStop_should_prestop_stop_and_poststop_in_reverse_order() throws Exception { + serviceManager.doStop(); + + InOrder inOrder = inOrder(service4, service1, service3, service2); + + inOrder.verify(service2, times(1)).preStop(); + inOrder.verify(service3, times(1)).preStop(); + inOrder.verify(service1, times(1)).preStop(); + inOrder.verify(service4, times(1)).preStop(); + + inOrder.verify(service2, times(1)).stop(); + inOrder.verify(service3, times(1)).stop(); + inOrder.verify(service1, times(1)).stop(); + inOrder.verify(service4, times(1)).stop(); + + inOrder.verify(service2, times(1)).postStop(); + inOrder.verify(service3, times(1)).postStop(); + inOrder.verify(service1, times(1)).postStop(); + inOrder.verify(service4, times(1)).postStop(); + } } diff --git a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/ReporterManager.java b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/ReporterManager.java index dddea65ba..6e6a581db 100644 --- a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/ReporterManager.java +++ b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/ReporterManager.java @@ -23,5 +23,5 @@ * @author GraviteeSource Team */ public interface ReporterManager extends Service { - void register(Reporter reporter); + void register(Reporter reporter); } diff --git a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/ReporterService.java b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/ReporterService.java index 766ba9dcc..892c9d0a0 100644 --- a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/ReporterService.java +++ b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/ReporterService.java @@ -22,5 +22,5 @@ * @author GraviteeSource Team */ public interface ReporterService { - void report(Reportable reportable); + void report(Reportable reportable); } diff --git a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/plugin/ReporterPluginHandler.java b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/plugin/ReporterPluginHandler.java index ed70eb21a..14c7ee951 100644 --- a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/plugin/ReporterPluginHandler.java +++ b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/plugin/ReporterPluginHandler.java @@ -26,37 +26,33 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class ReporterPluginHandler - extends AbstractSpringPluginHandler { - - private static final String PLUGIN_TYPE = "reporter"; - - @Autowired - private PluginClassLoaderFactory pluginClassLoaderFactory; - - @Autowired - private ReporterManager reporterManager; - - @Override - public boolean canHandle(Plugin plugin) { - return PLUGIN_TYPE.equalsIgnoreCase(plugin.type()); - } - - @Override - protected String type() { - return "reporters"; - } - - @Override - protected ClassLoader getClassLoader(Plugin plugin) throws Exception { - return pluginClassLoaderFactory.getOrCreateClassLoader( - plugin, - this.getClass().getClassLoader() - ); - } - - @Override - protected void register(Reporter plugin) { - reporterManager.register(plugin); - } +public class ReporterPluginHandler extends AbstractSpringPluginHandler { + + private static final String PLUGIN_TYPE = "reporter"; + + @Autowired + private PluginClassLoaderFactory pluginClassLoaderFactory; + + @Autowired + private ReporterManager reporterManager; + + @Override + public boolean canHandle(Plugin plugin) { + return PLUGIN_TYPE.equalsIgnoreCase(plugin.type()); + } + + @Override + protected String type() { + return "reporters"; + } + + @Override + protected ClassLoader getClassLoader(Plugin plugin) throws Exception { + return pluginClassLoaderFactory.getOrCreateClassLoader(plugin, this.getClass().getClassLoader()); + } + + @Override + protected void register(Reporter plugin) { + reporterManager.register(plugin); + } } diff --git a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/spring/ReporterConfiguration.java b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/spring/ReporterConfiguration.java index fae0734c0..34e286fd2 100644 --- a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/spring/ReporterConfiguration.java +++ b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/spring/ReporterConfiguration.java @@ -29,13 +29,13 @@ @Configuration public class ReporterConfiguration { - @Bean - public ReporterManager reporterManager() { - return new ReporterManagerImpl(); - } + @Bean + public ReporterManager reporterManager() { + return new ReporterManagerImpl(); + } - @Bean - public ReporterVerticle reporterVerticle() { - return new ReporterVerticle(); - } + @Bean + public ReporterVerticle reporterVerticle() { + return new ReporterVerticle(); + } } diff --git a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/ReporterManagerImpl.java b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/ReporterManagerImpl.java index 355ec1048..e9527b13a 100644 --- a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/ReporterManagerImpl.java +++ b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/ReporterManagerImpl.java @@ -32,122 +32,110 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class ReporterManagerImpl - extends AbstractService - implements ReporterManager { - - private static final Logger LOGGER = LoggerFactory.getLogger( - ReporterManagerImpl.class - ); - - @Autowired - private Vertx vertx; - - private String deploymentId; - - private final Collection reporters = new ArrayList<>(); - - @Override - protected void doStart() throws Exception { - super.doStart(); - - vertx.deployVerticle( - SpringVerticleFactory.VERTICLE_PREFIX + - ':' + - ReporterVerticle.class.getName(), - event -> { - if (event.failed()) { - LOGGER.error("Reporter service can not be started", event.cause()); - } else { - if (!reporters.isEmpty()) { - for (Reporter reporter : reporters) { - try { - LOGGER.debug("Pre-starting reporter: {}", reporter); - reporter.preStart(); - } catch (Exception ex) { - LOGGER.error( - "Unexpected error while pre-starting reporter", - ex - ); - } - } - - for (Reporter reporter : reporters) { - try { - LOGGER.info("Starting reporter: {}", reporter); - reporter.start(); - } catch (Exception ex) { - LOGGER.error("Unexpected error while starting reporter", ex); - } +public class ReporterManagerImpl extends AbstractService implements ReporterManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReporterManagerImpl.class); + + @Autowired + private Vertx vertx; + + private String deploymentId; + + private final Collection reporters = new ArrayList<>(); + + @Override + protected void doStart() throws Exception { + super.doStart(); + + vertx.deployVerticle( + SpringVerticleFactory.VERTICLE_PREFIX + ':' + ReporterVerticle.class.getName(), + event -> { + if (event.failed()) { + LOGGER.error("Reporter service can not be started", event.cause()); + } else { + if (!reporters.isEmpty()) { + for (Reporter reporter : reporters) { + try { + LOGGER.debug("Pre-starting reporter: {}", reporter); + reporter.preStart(); + } catch (Exception ex) { + LOGGER.error("Unexpected error while pre-starting reporter", ex); + } + } + + for (Reporter reporter : reporters) { + try { + LOGGER.info("Starting reporter: {}", reporter); + reporter.start(); + } catch (Exception ex) { + LOGGER.error("Unexpected error while starting reporter", ex); + } + } + + for (Reporter reporter : reporters) { + try { + LOGGER.debug("Port-starting reporter: {}", reporter); + reporter.postStart(); + } catch (Exception ex) { + LOGGER.error("Unexpected error while post-starting reporter", ex); + } + } + } else { + LOGGER.info("\tThere is no reporter to start"); + } + } + + deploymentId = event.result(); } + ); + } - for (Reporter reporter : reporters) { - try { - LOGGER.debug("Port-starting reporter: {}", reporter); - reporter.postStart(); - } catch (Exception ex) { - LOGGER.error( - "Unexpected error while post-starting reporter", - ex - ); - } - } - } else { - LOGGER.info("\tThere is no reporter to start"); - } - } + @Override + public void register(Reporter reporter) { + reporters.add(new EventBusReporterWrapper(vertx, reporter)); + } - deploymentId = event.result(); - } - ); - } - - @Override - public void register(Reporter reporter) { - reporters.add(new EventBusReporterWrapper(vertx, reporter)); - } - - @Override - protected void doStop() throws Exception { - super.doStop(); - - if (deploymentId != null) { - vertx.undeploy( - deploymentId, - event -> { - for (Reporter reporter : reporters) { - try { - LOGGER.debug("Pre-stopping reporter: {}", reporter); - reporter.preStop(); - } catch (Exception ex) { - LOGGER.error("Unexpected error while pre-stopping reporter", ex); - } - } - - for (Reporter reporter : reporters) { - try { - LOGGER.info("Stopping reporter: {}", reporter); - reporter.stop(); - } catch (Exception ex) { - LOGGER.error("Unexpected error while stopping reporter", ex); - } - } - - for (Reporter reporter : reporters) { - try { - LOGGER.debug("Post-stopping reporter: {}", reporter); - reporter.postStop(); - } catch (Exception ex) { - LOGGER.error("Unexpected error while post-stopping reporter", ex); - } - } + @Override + protected void doStop() throws Exception { + super.doStop(); + + if (deploymentId != null) { + vertx.undeploy( + deploymentId, + event -> { + for (Reporter reporter : reporters) { + try { + LOGGER.debug("Pre-stopping reporter: {}", reporter); + reporter.preStop(); + } catch (Exception ex) { + LOGGER.error("Unexpected error while pre-stopping reporter", ex); + } + } + + for (Reporter reporter : reporters) { + try { + LOGGER.info("Stopping reporter: {}", reporter); + reporter.stop(); + } catch (Exception ex) { + LOGGER.error("Unexpected error while stopping reporter", ex); + } + } + + for (Reporter reporter : reporters) { + try { + LOGGER.debug("Post-stopping reporter: {}", reporter); + reporter.postStop(); + } catch (Exception ex) { + LOGGER.error("Unexpected error while post-stopping reporter", ex); + } + } + } + ); } - ); } - } - @Override - protected String name() { - return "Reporter service"; - } + @Override + protected String name() { + return "Reporter service"; + } } diff --git a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/eventbus/EventBusReporterWrapper.java b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/eventbus/EventBusReporterWrapper.java index 11ca2473e..468f09a69 100644 --- a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/eventbus/EventBusReporterWrapper.java +++ b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/eventbus/EventBusReporterWrapper.java @@ -30,73 +30,68 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class EventBusReporterWrapper - implements Reporter, Handler> { +public class EventBusReporterWrapper implements Reporter, Handler> { - private final Logger logger = LoggerFactory.getLogger( - EventBusReporterWrapper.class - ); + private final Logger logger = LoggerFactory.getLogger(EventBusReporterWrapper.class); - private static final String EVENT_BUS_ADDRESS = "node:metrics"; - private final Reporter reporter; - private final Vertx vertx; + private static final String EVENT_BUS_ADDRESS = "node:metrics"; + private final Reporter reporter; + private final Vertx vertx; - public EventBusReporterWrapper(final Vertx vertx, final Reporter reporter) { - this.vertx = vertx; - this.reporter = reporter; - } + public EventBusReporterWrapper(final Vertx vertx, final Reporter reporter) { + this.vertx = vertx; + this.reporter = reporter; + } - @Override - public void report(Reportable reportable) { - // Done by the event bus handler - // See handle method - } + @Override + public void report(Reportable reportable) { + // Done by the event bus handler + // See handle method + } - @Override - public Lifecycle.State lifecycleState() { - return reporter.lifecycleState(); - } + @Override + public Lifecycle.State lifecycleState() { + return reporter.lifecycleState(); + } - @Override - public Object start() throws Exception { - vertx.executeBlocking( - new Handler>() { - @Override - public void handle(Promise event) { - try { - reporter.start(); - event.complete(reporter); - } catch (Exception ex) { - logger.error("Error while starting reporter", ex); - event.fail(ex); - } - } - }, - new Handler>() { - @Override - public void handle(AsyncResult event) { - if (event.succeeded()) { - vertx - .eventBus() - .consumer(EVENT_BUS_ADDRESS, EventBusReporterWrapper.this); - } - } - } - ); + @Override + public Object start() throws Exception { + vertx.executeBlocking( + new Handler>() { + @Override + public void handle(Promise event) { + try { + reporter.start(); + event.complete(reporter); + } catch (Exception ex) { + logger.error("Error while starting reporter", ex); + event.fail(ex); + } + } + }, + new Handler>() { + @Override + public void handle(AsyncResult event) { + if (event.succeeded()) { + vertx.eventBus().consumer(EVENT_BUS_ADDRESS, EventBusReporterWrapper.this); + } + } + } + ); - return reporter; - } + return reporter; + } - @Override - public Object stop() throws Exception { - return reporter.stop(); - } + @Override + public Object stop() throws Exception { + return reporter.stop(); + } - @Override - public void handle(Message reportableMsg) { - Reportable reportable = reportableMsg.body(); - if (reporter.canHandle(reportable)) { - reporter.report(reportable); + @Override + public void handle(Message reportableMsg) { + Reportable reportable = reportableMsg.body(); + if (reporter.canHandle(reportable)) { + reporter.report(reportable); + } } - } } diff --git a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/eventbus/ReportableMessageCodec.java b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/eventbus/ReportableMessageCodec.java index 2ee9eee77..e9c31790e 100644 --- a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/eventbus/ReportableMessageCodec.java +++ b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/eventbus/ReportableMessageCodec.java @@ -27,65 +27,64 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class ReportableMessageCodec - implements MessageCodec { +public class ReportableMessageCodec implements MessageCodec { - public static final String CODEC_NAME = "reportable-codec"; + public static final String CODEC_NAME = "reportable-codec"; - @Override - public void encodeToWire(Buffer buffer, Reportable reportable) { - try { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(reportable); - oos.flush(); + @Override + public void encodeToWire(Buffer buffer, Reportable reportable) { + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(reportable); + oos.flush(); - byte[] data = bos.toByteArray(); - int length = data.length; + byte[] data = bos.toByteArray(); + int length = data.length; - // Write data into given buffer - buffer.appendInt(length); - buffer.appendBytes(data); - } catch (Exception ex) { - ex.printStackTrace(); + // Write data into given buffer + buffer.appendInt(length); + buffer.appendBytes(data); + } catch (Exception ex) { + ex.printStackTrace(); + } } - } - @Override - public Reportable decodeFromWire(int position, Buffer buffer) { - try { - // My custom message starting from this *position* of buffer - int pos = position; + @Override + public Reportable decodeFromWire(int position, Buffer buffer) { + try { + // My custom message starting from this *position* of buffer + int pos = position; - // Length of data - int length = buffer.getInt(pos); + // Length of data + int length = buffer.getInt(pos); - byte[] data = buffer.getBytes(pos += 4, pos += length); + byte[] data = buffer.getBytes(pos += 4, pos += length); - ByteArrayInputStream in = new ByteArrayInputStream(data); - ObjectInputStream is = new ObjectInputStream(in); - return (Reportable) is.readObject(); - } catch (Exception ex) { - ex.printStackTrace(); - } + ByteArrayInputStream in = new ByteArrayInputStream(data); + ObjectInputStream is = new ObjectInputStream(in); + return (Reportable) is.readObject(); + } catch (Exception ex) { + ex.printStackTrace(); + } - return null; - } + return null; + } - @Override - public Reportable transform(Reportable reportable) { - // If a message is sent *locally* across the event bus. - // This example sends message just as is - return reportable; - } + @Override + public Reportable transform(Reportable reportable) { + // If a message is sent *locally* across the event bus. + // This example sends message just as is + return reportable; + } - @Override - public String name() { - return CODEC_NAME; - } + @Override + public String name() { + return CODEC_NAME; + } - @Override - public byte systemCodecID() { - return -1; - } + @Override + public byte systemCodecID() { + return -1; + } } diff --git a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/verticle/ReporterVerticle.java b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/verticle/ReporterVerticle.java index db20d347e..2af92fc4c 100644 --- a/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/verticle/ReporterVerticle.java +++ b/gravitee-node-reporter/src/main/java/io/gravitee/node/reporter/vertx/verticle/ReporterVerticle.java @@ -31,65 +31,52 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class ReporterVerticle - extends AbstractVerticle - implements ReporterService { +public class ReporterVerticle extends AbstractVerticle implements ReporterService { - private static final Logger LOGGER = LoggerFactory.getLogger( - ReporterVerticle.class - ); + private static final Logger LOGGER = LoggerFactory.getLogger(ReporterVerticle.class); - private static final String EVENT_BUS_ADDRESS = "node:metrics"; + private static final String EVENT_BUS_ADDRESS = "node:metrics"; - private MessageProducer producer; + private MessageProducer producer; - @Override - public void start(Promise promise) throws Exception { - // Register specific codec - vertx.eventBus().registerCodec(new ReportableMessageCodec()); + @Override + public void start(Promise promise) throws Exception { + // Register specific codec + vertx.eventBus().registerCodec(new ReportableMessageCodec()); - producer = - vertx - .eventBus() - .publisher( - EVENT_BUS_ADDRESS, - new DeliveryOptions() - .setCodecName(ReportableMessageCodec.CODEC_NAME) - .setTracingPolicy(TracingPolicy.IGNORE) - ); + producer = + vertx + .eventBus() + .publisher( + EVENT_BUS_ADDRESS, + new DeliveryOptions().setCodecName(ReportableMessageCodec.CODEC_NAME).setTracingPolicy(TracingPolicy.IGNORE) + ); - // By default we report node monitor data. - vertx - .eventBus() - .localConsumer( - "gio:node:monitor", - event -> producer.write(event.body()) - ); + // By default we report node monitor data. + vertx.eventBus().localConsumer("gio:node:monitor", event -> producer.write(event.body())); - promise.complete(); - } + promise.complete(); + } - @Override - public void stop(Promise promise) throws Exception { - if (producer != null) { - producer.close( - event -> { - if (event.succeeded()) { - LOGGER.debug("Reporter publisher has been closed successfully."); + @Override + public void stop(Promise promise) throws Exception { + if (producer != null) { + producer.close(event -> { + if (event.succeeded()) { + LOGGER.debug("Reporter publisher has been closed successfully."); + promise.complete(); + } else { + promise.fail(event.cause()); + } + }); + } else { promise.complete(); - } else { - promise.fail(event.cause()); - } } - ); - } else { - promise.complete(); } - } - public void report(Reportable reportable) { - if (producer != null) { - producer.write(reportable); + public void report(Reportable reportable) { + if (producer != null) { + producer.write(reportable); + } } - } } diff --git a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/LazyTracer.java b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/LazyTracer.java index b3fa86ea6..a6d7eb6a1 100644 --- a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/LazyTracer.java +++ b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/LazyTracer.java @@ -24,19 +24,19 @@ */ public class LazyTracer implements Tracer, TracingService.TracerListener { - private io.gravitee.node.api.tracing.Tracer tracer; + private io.gravitee.node.api.tracing.Tracer tracer; - @Override - public Span span(String spanName) { - if (tracer != null) { - return tracer.trace(spanName); - } + @Override + public Span span(String spanName) { + if (tracer != null) { + return tracer.trace(spanName); + } - return new NoOpSpan(); - } + return new NoOpSpan(); + } - @Override - public void onRegister(io.gravitee.node.api.tracing.Tracer tracer) { - this.tracer = tracer; - } + @Override + public void onRegister(io.gravitee.node.api.tracing.Tracer tracer) { + this.tracer = tracer; + } } diff --git a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/NoOpSpan.java b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/NoOpSpan.java index 737e1520d..4a19ce886 100644 --- a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/NoOpSpan.java +++ b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/NoOpSpan.java @@ -23,31 +23,31 @@ */ public class NoOpSpan implements Span { - @Override - public Span withAttribute(String name, String value) { - return this; - } - - @Override - public Span withAttribute(String name, boolean value) { - return this; - } - - @Override - public Span withAttribute(String name, long value) { - return this; - } - - @Override - public Span reportError(Throwable throwable) { - return this; - } - - @Override - public Span reportError(String message) { - return this; - } - - @Override - public void end() {} + @Override + public Span withAttribute(String name, String value) { + return this; + } + + @Override + public Span withAttribute(String name, boolean value) { + return this; + } + + @Override + public Span withAttribute(String name, long value) { + return this; + } + + @Override + public Span reportError(Throwable throwable) { + return this; + } + + @Override + public Span reportError(String message) { + return this; + } + + @Override + public void end() {} } diff --git a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/TracingService.java b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/TracingService.java index a7b452b03..ead37097a 100644 --- a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/TracingService.java +++ b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/TracingService.java @@ -35,64 +35,54 @@ */ public class TracingService implements InitializingBean { - private final Logger logger = LoggerFactory.getLogger(TracingService.class); + private final Logger logger = LoggerFactory.getLogger(TracingService.class); - private final List listeners = new ArrayList<>(); + private final List listeners = new ArrayList<>(); - @Autowired - private PluginClassLoaderFactory pluginClassLoaderFactory; + @Autowired + private PluginClassLoaderFactory pluginClassLoaderFactory; - @Autowired - private Environment environment; + @Autowired + private Environment environment; - @Autowired - private PluginContextFactory pluginContextFactory; + @Autowired + private PluginContextFactory pluginContextFactory; - public void register(Plugin plugin) { - String tracerType = environment.getProperty("services.tracing.type"); + public void register(Plugin plugin) { + String tracerType = environment.getProperty("services.tracing.type"); - if (tracerType != null && plugin.id().contains(tracerType)) { - try { - PluginClassLoader classLoader = pluginClassLoaderFactory.getOrCreateClassLoader( - plugin - ); - Class clazz = classLoader.loadClass(plugin.clazz()); + if (tracerType != null && plugin.id().contains(tracerType)) { + try { + PluginClassLoader classLoader = pluginClassLoaderFactory.getOrCreateClassLoader(plugin); + Class clazz = classLoader.loadClass(plugin.clazz()); - ApplicationContext context = this.pluginContextFactory.create(plugin); - Tracer tracer = (Tracer) context.getBean(clazz); + ApplicationContext context = this.pluginContextFactory.create(plugin); + Tracer tracer = (Tracer) context.getBean(clazz); - tracer.start(); + tracer.start(); - for (TracerListener listener : listeners) { - listener.onRegister(tracer); + for (TracerListener listener : listeners) { + listener.onRegister(tracer); + } + } catch (Exception ex) { + logger.error("Unable to create an instance of Tracer: {}", plugin.id(), ex); + } + } else { + logger.warn("Tracing support is enabled for tracer name[{}]. Skipping the {} tracer installation", tracerType, plugin.id()); } - } catch (Exception ex) { - logger.error( - "Unable to create an instance of Tracer: {}", - plugin.id(), - ex - ); - } - } else { - logger.warn( - "Tracing support is enabled for tracer name[{}]. Skipping the {} tracer installation", - tracerType, - plugin.id() - ); } - } - public void addTracerListener(TracerListener listener) { - listeners.add(listener); - } + public void addTracerListener(TracerListener listener) { + listeners.add(listener); + } - @Override - public void afterPropertiesSet() throws Exception { - String tracerType = environment.getProperty("services.tracing.type"); - logger.info("Tracing support is enabled with tracer: name[{}]", tracerType); - } + @Override + public void afterPropertiesSet() throws Exception { + String tracerType = environment.getProperty("services.tracing.type"); + logger.info("Tracing support is enabled with tracer: name[{}]", tracerType); + } - public interface TracerListener { - void onRegister(Tracer tracer); - } + public interface TracerListener { + void onRegister(Tracer tracer); + } } diff --git a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/plugin/TracerPlugin.java b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/plugin/TracerPlugin.java index 89c17b9b0..351663692 100644 --- a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/plugin/TracerPlugin.java +++ b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/plugin/TracerPlugin.java @@ -22,5 +22,5 @@ * @author GraviteeSource Team */ public interface TracerPlugin extends Plugin { - String PLUGIN_TYPE = "tracer"; + String PLUGIN_TYPE = "tracer"; } diff --git a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/plugin/TracingPluginHandler.java b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/plugin/TracingPluginHandler.java index da7e5c34b..4bebde574 100644 --- a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/plugin/TracingPluginHandler.java +++ b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/plugin/TracingPluginHandler.java @@ -28,42 +28,35 @@ */ public class TracingPluginHandler extends AbstractPluginHandler { - @Autowired - private PluginClassLoaderFactory pluginClassLoaderFactory; - - @Autowired - private TracingService tracingService; - - @Autowired - private Environment environment; - - @Override - public boolean canHandle(Plugin plugin) { - return ( - environment.getProperty( - "services.tracing.enabled", - Boolean.class, - false - ) && - TracerPlugin.PLUGIN_TYPE.equalsIgnoreCase(plugin.type()) - ); - } - - @Override - protected String type() { - return "tracers"; - } - - @Override - protected ClassLoader getClassLoader(Plugin plugin) throws Exception { - return pluginClassLoaderFactory.getOrCreateClassLoader( - plugin, - this.getClass().getClassLoader() - ); - } - - @Override - protected void handle(Plugin plugin, Class aClass) { - tracingService.register(plugin); - } + @Autowired + private PluginClassLoaderFactory pluginClassLoaderFactory; + + @Autowired + private TracingService tracingService; + + @Autowired + private Environment environment; + + @Override + public boolean canHandle(Plugin plugin) { + return ( + environment.getProperty("services.tracing.enabled", Boolean.class, false) && + TracerPlugin.PLUGIN_TYPE.equalsIgnoreCase(plugin.type()) + ); + } + + @Override + protected String type() { + return "tracers"; + } + + @Override + protected ClassLoader getClassLoader(Plugin plugin) throws Exception { + return pluginClassLoaderFactory.getOrCreateClassLoader(plugin, this.getClass().getClassLoader()); + } + + @Override + protected void handle(Plugin plugin, Class aClass) { + tracingService.register(plugin); + } } diff --git a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/spring/TracingConfiguration.java b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/spring/TracingConfiguration.java index 02014d6e0..785347cf2 100644 --- a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/spring/TracingConfiguration.java +++ b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/spring/TracingConfiguration.java @@ -28,22 +28,20 @@ @Configuration public class TracingConfiguration { - @Bean - public TracingService tracingService() { - return new TracingService(); - } + @Bean + public TracingService tracingService() { + return new TracingService(); + } - @Bean - public LazyVertxTracerFactory vertxTracerFactory( - TracingService tracingService - ) { - return new LazyVertxTracerFactory(tracingService); - } + @Bean + public LazyVertxTracerFactory vertxTracerFactory(TracingService tracingService) { + return new LazyVertxTracerFactory(tracingService); + } - @Bean - public LazyTracer lazyTracer(TracingService tracingService) { - LazyTracer tracer = new LazyTracer(); - tracingService.addTracerListener(tracer); - return tracer; - } + @Bean + public LazyTracer lazyTracer(TracingService tracingService) { + LazyTracer tracer = new LazyTracer(); + tracingService.addTracerListener(tracer); + return tracer; + } } diff --git a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/vertx/LazyVertxTracer.java b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/vertx/LazyVertxTracer.java index 17f30d037..2c8080b66 100644 --- a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/vertx/LazyVertxTracer.java +++ b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/vertx/LazyVertxTracer.java @@ -29,99 +29,69 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class LazyVertxTracer - implements VertxTracer, TracingService.TracerListener { +public class LazyVertxTracer implements VertxTracer, TracingService.TracerListener { - private io.gravitee.node.tracing.vertx.VertxTracer tracer; + private io.gravitee.node.tracing.vertx.VertxTracer tracer; - @Override - public Object receiveRequest( - Context context, - SpanKind kind, - TracingPolicy policy, - R request, - String operation, - Iterable> headers, - TagExtractor tagExtractor - ) { - if (tracer != null) { - return tracer.receiveRequest( - context, - kind, - policy, - request, - operation, - headers, - tagExtractor - ); - } - - return request; - } + @Override + public Object receiveRequest( + Context context, + SpanKind kind, + TracingPolicy policy, + R request, + String operation, + Iterable> headers, + TagExtractor tagExtractor + ) { + if (tracer != null) { + return tracer.receiveRequest(context, kind, policy, request, operation, headers, tagExtractor); + } - @Override - public void sendResponse( - Context context, - R response, - Object payload, - Throwable failure, - TagExtractor tagExtractor - ) { - if (tracer != null) { - tracer.sendResponse(context, response, payload, failure, tagExtractor); + return request; } - } - @Override - public Object sendRequest( - Context context, - SpanKind kind, - TracingPolicy policy, - R request, - String operation, - BiConsumer headers, - TagExtractor tagExtractor - ) { - if (tracer != null) { - return tracer.sendRequest( - context, - kind, - policy, - request, - operation, - headers, - tagExtractor - ); + @Override + public void sendResponse(Context context, R response, Object payload, Throwable failure, TagExtractor tagExtractor) { + if (tracer != null) { + tracer.sendResponse(context, response, payload, failure, tagExtractor); + } } - return request; - } + @Override + public Object sendRequest( + Context context, + SpanKind kind, + TracingPolicy policy, + R request, + String operation, + BiConsumer headers, + TagExtractor tagExtractor + ) { + if (tracer != null) { + return tracer.sendRequest(context, kind, policy, request, operation, headers, tagExtractor); + } + + return request; + } - @Override - public void receiveResponse( - Context context, - R response, - Object payload, - Throwable failure, - TagExtractor tagExtractor - ) { - if (tracer != null) { - tracer.receiveResponse(context, response, payload, failure, tagExtractor); + @Override + public void receiveResponse(Context context, R response, Object payload, Throwable failure, TagExtractor tagExtractor) { + if (tracer != null) { + tracer.receiveResponse(context, response, payload, failure, tagExtractor); + } } - } - @Override - public void close() { - if (tracer != null) { - tracer.close(); + @Override + public void close() { + if (tracer != null) { + tracer.close(); + } } - } - @Override - public void onRegister(Tracer tracer) { - if (tracer instanceof io.gravitee.node.tracing.vertx.VertxTracer) { - this.tracer = - (io.gravitee.node.tracing.vertx.VertxTracer) tracer; + @Override + public void onRegister(Tracer tracer) { + if (tracer instanceof io.gravitee.node.tracing.vertx.VertxTracer) { + this.tracer = (io.gravitee.node.tracing.vertx.VertxTracer) tracer; + } } - } } diff --git a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/vertx/LazyVertxTracerFactory.java b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/vertx/LazyVertxTracerFactory.java index 767c7090f..9645bd278 100644 --- a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/vertx/LazyVertxTracerFactory.java +++ b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/vertx/LazyVertxTracerFactory.java @@ -28,31 +28,31 @@ */ public class LazyVertxTracerFactory implements VertxTracerFactory { - private final TracingService tracingService; - - public LazyVertxTracerFactory(final TracingService tracingService) { - this.tracingService = tracingService; - } - - @Override - public void init(VertxBuilder builder) { - VertxTracerFactory.super.init(builder); - } - - @Override - public VertxTracer tracer(TracingOptions options) { - LazyVertxTracer tracer = new LazyVertxTracer(); - tracingService.addTracerListener(tracer); - return tracer; - } - - @Override - public TracingOptions newOptions() { - return VertxTracerFactory.super.newOptions(); - } - - @Override - public TracingOptions newOptions(JsonObject jsonObject) { - return VertxTracerFactory.super.newOptions(jsonObject); - } + private final TracingService tracingService; + + public LazyVertxTracerFactory(final TracingService tracingService) { + this.tracingService = tracingService; + } + + @Override + public void init(VertxBuilder builder) { + VertxTracerFactory.super.init(builder); + } + + @Override + public VertxTracer tracer(TracingOptions options) { + LazyVertxTracer tracer = new LazyVertxTracer(); + tracingService.addTracerListener(tracer); + return tracer; + } + + @Override + public TracingOptions newOptions() { + return VertxTracerFactory.super.newOptions(); + } + + @Override + public TracingOptions newOptions(JsonObject jsonObject) { + return VertxTracerFactory.super.newOptions(jsonObject); + } } diff --git a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/vertx/VertxTracer.java b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/vertx/VertxTracer.java index 62a5c0011..79090f9d6 100644 --- a/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/vertx/VertxTracer.java +++ b/gravitee-node-tracing/src/main/java/io/gravitee/node/tracing/vertx/VertxTracer.java @@ -21,5 +21,4 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public interface VertxTracer - extends Tracer, io.vertx.core.spi.tracing.VertxTracer {} +public interface VertxTracer extends Tracer, io.vertx.core.spi.tracing.VertxTracer {} diff --git a/gravitee-node-vertx/src/main/java/io/gravitee/node/vertx/AbstractVertxHttpServerFactory.java b/gravitee-node-vertx/src/main/java/io/gravitee/node/vertx/AbstractVertxHttpServerFactory.java index d392a072a..9fe368738 100644 --- a/gravitee-node-vertx/src/main/java/io/gravitee/node/vertx/AbstractVertxHttpServerFactory.java +++ b/gravitee-node-vertx/src/main/java/io/gravitee/node/vertx/AbstractVertxHttpServerFactory.java @@ -35,190 +35,119 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public abstract class AbstractVertxHttpServerFactory - implements FactoryBean { - - private final HttpServerConfiguration httpServerConfiguration; - private final KeyStoreLoaderManager keyStoreLoaderManager; - - public AbstractVertxHttpServerFactory( - HttpServerConfiguration httpServerConfiguration, - KeyStoreLoaderManager keyStoreLoaderManager - ) { - this.httpServerConfiguration = httpServerConfiguration; - this.keyStoreLoaderManager = keyStoreLoaderManager; - } - - protected HttpServerOptions getHttpServerOptions() { - HttpServerOptions options = new HttpServerOptions(); - options.setTracingPolicy(httpServerConfiguration.getTracingPolicy()); - - // Binding port - options.setPort(httpServerConfiguration.getPort()); - options.setHost(httpServerConfiguration.getHost()); - - if (httpServerConfiguration.isSecured()) { - if (keyStoreLoaderManager == null) { - throw new IllegalArgumentException( - "You must provide a KeyStoreLoaderManager when 'secured' is enabled." - ); - } - - if (httpServerConfiguration.isOpenssl()) { - options.setSslEngineOptions(new OpenSSLEngineOptions()); - } - - options.setSsl(httpServerConfiguration.isSecured()); - options.setUseAlpn(httpServerConfiguration.isAlpn()); - options.setSni(httpServerConfiguration.isSni()); - - // TLS protocol support - if (httpServerConfiguration.getTlsProtocols() != null) { - options.setEnabledSecureTransportProtocols( - new HashSet<>( - Arrays.asList( - httpServerConfiguration.getTlsProtocols().split("\\s*,\\s*") - ) - ) - ); - } - - // restrict the authorized ciphers - if (httpServerConfiguration.getAuthorizedTlsCipherSuites() != null) { - httpServerConfiguration - .getAuthorizedTlsCipherSuites() - .stream() - .map(String::trim) - .forEach(options::addEnabledCipherSuite); - } - - options.setClientAuth(httpServerConfiguration.getClientAuth()); - - if ( - httpServerConfiguration.getTrustStorePaths() != null && - !httpServerConfiguration.getTrustStorePaths().isEmpty() - ) { - if ( - httpServerConfiguration.getTrustStoreType() == null || - httpServerConfiguration.getTrustStoreType().isEmpty() || - httpServerConfiguration - .getTrustStoreType() - .equalsIgnoreCase(CERTIFICATE_FORMAT_JKS) - ) { - options.setTrustStoreOptions( - new JksOptions() - .setPath(httpServerConfiguration.getTrustStorePaths().get(0)) - .setPassword(httpServerConfiguration.getTrustStorePassword()) - ); - } else if ( - httpServerConfiguration - .getTrustStoreType() - .equalsIgnoreCase(CERTIFICATE_FORMAT_PEM) - ) { - final PemTrustOptions pemTrustOptions = new PemTrustOptions(); - httpServerConfiguration - .getTrustStorePaths() - .forEach(pemTrustOptions::addCertPath); - options.setPemTrustOptions(pemTrustOptions); - } else if ( - httpServerConfiguration - .getTrustStoreType() - .equalsIgnoreCase(CERTIFICATE_FORMAT_PKCS12) - ) { - options.setPfxTrustOptions( - new PfxOptions() - .setPath(httpServerConfiguration.getTrustStorePaths().get(0)) - .setPassword(httpServerConfiguration.getTrustStorePassword()) - ); - } - } else if ( - CERTIFICATE_FORMAT_SELF_SIGNED.equalsIgnoreCase( - httpServerConfiguration.getTrustStoreType() - ) - ) { - options.setPemTrustOptions( - SelfSignedCertificate.create().trustOptions() - ); - } - - final KeyStoreLoaderOptions keyStoreLoaderOptions = KeyStoreLoaderOptions - .builder() - .withKeyStorePath(httpServerConfiguration.getKeyStorePath()) - .withKeyStorePassword(httpServerConfiguration.getKeyStorePassword()) - .withKeyStoreType(httpServerConfiguration.getKeyStoreType()) - .withKeyStoreCertificates( - httpServerConfiguration.getKeyStoreCertificates() - ) - .withKubernetesLocations( - httpServerConfiguration.getKeystoreKubernetes() - ) - .withWatch(true) // TODO: allow to configure watch (globally, just for keystore, ...) ? - .withDefaultAlias(httpServerConfiguration.getKeyStoreDefaultAlias()) - .build(); - - final VertxCertificateManager certificateManager = new VertxCertificateManager( - httpServerConfiguration.isSni() - ); - final KeyStoreLoader keyStoreLoader = keyStoreLoaderManager.create( - keyStoreLoaderOptions - ); - certificateManager.registerLoader(keyStoreLoader); - options.setKeyCertOptions(certificateManager.getKeyCertOptions()); - keyStoreLoader.start(); - } +public abstract class AbstractVertxHttpServerFactory implements FactoryBean { - if (httpServerConfiguration.isProxyProtocol()) { - options - .setUseProxyProtocol(true) - .setProxyProtocolTimeout( - httpServerConfiguration.getProxyProtocolTimeout() - ); - } + private final HttpServerConfiguration httpServerConfiguration; + private final KeyStoreLoaderManager keyStoreLoaderManager; - // Customizable configuration - options.setHandle100ContinueAutomatically( - httpServerConfiguration.isHandle100Continue() - ); - options.setCompressionSupported( - httpServerConfiguration.isCompressionSupported() - ); - options.setIdleTimeout(httpServerConfiguration.getIdleTimeout()); - options.setTcpKeepAlive(httpServerConfiguration.isTcpKeepAlive()); - options.setMaxChunkSize(httpServerConfiguration.getMaxChunkSize()); - options.setMaxHeaderSize(httpServerConfiguration.getMaxHeaderSize()); - options.setMaxInitialLineLength( - httpServerConfiguration.getMaxInitialLineLength() - ); - options.setMaxFormAttributeSize( - httpServerConfiguration.getMaxFormAttributeSize() - ); - - // Configure websocket - System.setProperty( - "vertx.disableWebsockets", - Boolean.toString(!httpServerConfiguration.isWebsocketEnabled()) - ); - if ( - httpServerConfiguration.isWebsocketEnabled() && - httpServerConfiguration.getWebsocketSubProtocols() != null - ) { - options.setWebSocketSubProtocols( - new ArrayList<>( - Arrays.asList( - httpServerConfiguration - .getWebsocketSubProtocols() - .split("\\s*,\\s*") - ) - ) - ); - options.setPerMessageWebSocketCompressionSupported( - httpServerConfiguration.isPerMessageWebSocketCompressionSupported() - ); - options.setPerFrameWebSocketCompressionSupported( - httpServerConfiguration.isPerFrameWebSocketCompressionSupported() - ); + public AbstractVertxHttpServerFactory(HttpServerConfiguration httpServerConfiguration, KeyStoreLoaderManager keyStoreLoaderManager) { + this.httpServerConfiguration = httpServerConfiguration; + this.keyStoreLoaderManager = keyStoreLoaderManager; } - return options; - } + protected HttpServerOptions getHttpServerOptions() { + HttpServerOptions options = new HttpServerOptions(); + options.setTracingPolicy(httpServerConfiguration.getTracingPolicy()); + + // Binding port + options.setPort(httpServerConfiguration.getPort()); + options.setHost(httpServerConfiguration.getHost()); + + if (httpServerConfiguration.isSecured()) { + if (keyStoreLoaderManager == null) { + throw new IllegalArgumentException("You must provide a KeyStoreLoaderManager when 'secured' is enabled."); + } + + if (httpServerConfiguration.isOpenssl()) { + options.setSslEngineOptions(new OpenSSLEngineOptions()); + } + + options.setSsl(httpServerConfiguration.isSecured()); + options.setUseAlpn(httpServerConfiguration.isAlpn()); + options.setSni(httpServerConfiguration.isSni()); + + // TLS protocol support + if (httpServerConfiguration.getTlsProtocols() != null) { + options.setEnabledSecureTransportProtocols( + new HashSet<>(Arrays.asList(httpServerConfiguration.getTlsProtocols().split("\\s*,\\s*"))) + ); + } + + // restrict the authorized ciphers + if (httpServerConfiguration.getAuthorizedTlsCipherSuites() != null) { + httpServerConfiguration.getAuthorizedTlsCipherSuites().stream().map(String::trim).forEach(options::addEnabledCipherSuite); + } + + options.setClientAuth(httpServerConfiguration.getClientAuth()); + + if (httpServerConfiguration.getTrustStorePaths() != null && !httpServerConfiguration.getTrustStorePaths().isEmpty()) { + if ( + httpServerConfiguration.getTrustStoreType() == null || + httpServerConfiguration.getTrustStoreType().isEmpty() || + httpServerConfiguration.getTrustStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_JKS) + ) { + options.setTrustStoreOptions( + new JksOptions() + .setPath(httpServerConfiguration.getTrustStorePaths().get(0)) + .setPassword(httpServerConfiguration.getTrustStorePassword()) + ); + } else if (httpServerConfiguration.getTrustStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_PEM)) { + final PemTrustOptions pemTrustOptions = new PemTrustOptions(); + httpServerConfiguration.getTrustStorePaths().forEach(pemTrustOptions::addCertPath); + options.setPemTrustOptions(pemTrustOptions); + } else if (httpServerConfiguration.getTrustStoreType().equalsIgnoreCase(CERTIFICATE_FORMAT_PKCS12)) { + options.setPfxTrustOptions( + new PfxOptions() + .setPath(httpServerConfiguration.getTrustStorePaths().get(0)) + .setPassword(httpServerConfiguration.getTrustStorePassword()) + ); + } + } else if (CERTIFICATE_FORMAT_SELF_SIGNED.equalsIgnoreCase(httpServerConfiguration.getTrustStoreType())) { + options.setPemTrustOptions(SelfSignedCertificate.create().trustOptions()); + } + + final KeyStoreLoaderOptions keyStoreLoaderOptions = KeyStoreLoaderOptions + .builder() + .withKeyStorePath(httpServerConfiguration.getKeyStorePath()) + .withKeyStorePassword(httpServerConfiguration.getKeyStorePassword()) + .withKeyStoreType(httpServerConfiguration.getKeyStoreType()) + .withKeyStoreCertificates(httpServerConfiguration.getKeyStoreCertificates()) + .withKubernetesLocations(httpServerConfiguration.getKeystoreKubernetes()) + .withWatch(true) // TODO: allow to configure watch (globally, just for keystore, ...) ? + .withDefaultAlias(httpServerConfiguration.getKeyStoreDefaultAlias()) + .build(); + + final VertxCertificateManager certificateManager = new VertxCertificateManager(httpServerConfiguration.isSni()); + final KeyStoreLoader keyStoreLoader = keyStoreLoaderManager.create(keyStoreLoaderOptions); + certificateManager.registerLoader(keyStoreLoader); + options.setKeyCertOptions(certificateManager.getKeyCertOptions()); + keyStoreLoader.start(); + } + + if (httpServerConfiguration.isProxyProtocol()) { + options.setUseProxyProtocol(true).setProxyProtocolTimeout(httpServerConfiguration.getProxyProtocolTimeout()); + } + + // Customizable configuration + options.setHandle100ContinueAutomatically(httpServerConfiguration.isHandle100Continue()); + options.setCompressionSupported(httpServerConfiguration.isCompressionSupported()); + options.setIdleTimeout(httpServerConfiguration.getIdleTimeout()); + options.setTcpKeepAlive(httpServerConfiguration.isTcpKeepAlive()); + options.setMaxChunkSize(httpServerConfiguration.getMaxChunkSize()); + options.setMaxHeaderSize(httpServerConfiguration.getMaxHeaderSize()); + options.setMaxInitialLineLength(httpServerConfiguration.getMaxInitialLineLength()); + options.setMaxFormAttributeSize(httpServerConfiguration.getMaxFormAttributeSize()); + + // Configure websocket + System.setProperty("vertx.disableWebsockets", Boolean.toString(!httpServerConfiguration.isWebsocketEnabled())); + if (httpServerConfiguration.isWebsocketEnabled() && httpServerConfiguration.getWebsocketSubProtocols() != null) { + options.setWebSocketSubProtocols( + new ArrayList<>(Arrays.asList(httpServerConfiguration.getWebsocketSubProtocols().split("\\s*,\\s*"))) + ); + options.setPerMessageWebSocketCompressionSupported(httpServerConfiguration.isPerMessageWebSocketCompressionSupported()); + options.setPerFrameWebSocketCompressionSupported(httpServerConfiguration.isPerFrameWebSocketCompressionSupported()); + } + + return options; + } } diff --git a/gravitee-node-vertx/src/main/java/io/gravitee/node/vertx/ReactivexVertxHttpServerFactory.java b/gravitee-node-vertx/src/main/java/io/gravitee/node/vertx/ReactivexVertxHttpServerFactory.java index 6bccfc190..a8c968f85 100644 --- a/gravitee-node-vertx/src/main/java/io/gravitee/node/vertx/ReactivexVertxHttpServerFactory.java +++ b/gravitee-node-vertx/src/main/java/io/gravitee/node/vertx/ReactivexVertxHttpServerFactory.java @@ -26,34 +26,33 @@ * @author David BRASSELY (david.brassely at graviteesource.com) * @author GraviteeSource Team */ -public class ReactivexVertxHttpServerFactory - extends AbstractVertxHttpServerFactory { +public class ReactivexVertxHttpServerFactory extends AbstractVertxHttpServerFactory { - private final Vertx vertx; + private final Vertx vertx; - @Autowired - public ReactivexVertxHttpServerFactory( - Vertx vertx, - HttpServerConfiguration httpServerConfiguration, - KeyStoreLoaderManager keyStoreLoaderManager - ) { - super(httpServerConfiguration, keyStoreLoaderManager); - this.vertx = vertx; - } + @Autowired + public ReactivexVertxHttpServerFactory( + Vertx vertx, + HttpServerConfiguration httpServerConfiguration, + KeyStoreLoaderManager keyStoreLoaderManager + ) { + super(httpServerConfiguration, keyStoreLoaderManager); + this.vertx = vertx; + } - @Override - public HttpServer getObject() throws Exception { - return VertxHttpServerProvider.create(vertx, getHttpServerOptions()); - } + @Override + public HttpServer getObject() throws Exception { + return VertxHttpServerProvider.create(vertx, getHttpServerOptions()); + } - @Override - public Class getObjectType() { - return HttpServer.class; - } + @Override + public Class getObjectType() { + return HttpServer.class; + } - @Override - public boolean isSingleton() { - // Scope is managed indirectly by Vertx verticle. - return false; - } + @Override + public boolean isSingleton() { + // Scope is managed indirectly by Vertx verticle. + return false; + } } diff --git a/gravitee-node-vertx/src/main/java/io/gravitee/node/vertx/VertxFactory.java b/gravitee-node-vertx/src/main/java/io/gravitee/node/vertx/VertxFactory.java index 1829ad3e8..263df641b 100644 --- a/gravitee-node-vertx/src/main/java/io/gravitee/node/vertx/VertxFactory.java +++ b/gravitee-node-vertx/src/main/java/io/gravitee/node/vertx/VertxFactory.java @@ -49,204 +49,171 @@ */ public class VertxFactory implements FactoryBean { - private static final String PROMETHEUS_LABEL_VERSION_3_10 = "3.10"; + private static final String PROMETHEUS_LABEL_VERSION_3_10 = "3.10"; - private static final Logger LOGGER = LoggerFactory.getLogger( - VertxFactory.class - ); + private static final Logger LOGGER = LoggerFactory.getLogger(VertxFactory.class); - @Autowired - private Node node; + @Autowired + private Node node; - @Autowired - private Environment environment; + @Autowired + private Environment environment; - @Autowired - private SpringVerticleFactory springVerticleFactory; + @Autowired + private SpringVerticleFactory springVerticleFactory; - @Autowired - private LazyVertxTracerFactory vertxTracerFactory; + @Autowired + private LazyVertxTracerFactory vertxTracerFactory; - @Override - public Vertx getObject() throws Exception { - LOGGER.debug("Creating a new instance of Vert.x"); - VertxOptions options = getVertxOptions(); + @Override + public Vertx getObject() throws Exception { + LOGGER.debug("Creating a new instance of Vert.x"); + VertxOptions options = getVertxOptions(); - boolean metricsEnabled = environment.getProperty( - "services.metrics.enabled", - Boolean.class, - false - ); - if (metricsEnabled) { - configureMetrics(options); - } + boolean metricsEnabled = environment.getProperty("services.metrics.enabled", Boolean.class, false); + if (metricsEnabled) { + configureMetrics(options); + } + + boolean tracingEnabled = environment.getProperty("services.tracing.enabled", Boolean.class, false); + if (tracingEnabled) { + configureTracing(options); + } + + Vertx instance = Vertx.vertx(options); + instance.registerVerticleFactory(springVerticleFactory); + + if (metricsEnabled) { + MeterRegistry registry = BackendRegistries.getDefaultNow(); - boolean tracingEnabled = environment.getProperty( - "services.tracing.enabled", - Boolean.class, - false - ); - if (tracingEnabled) { - configureTracing(options); + registry + .config() + .meterFilter(new RenameVertxFilter()) + .commonTags("application", node.application()) + .commonTags("instance", node.hostname()); + + new FileDescriptorMetrics().bindTo(registry); + new ClassLoaderMetrics().bindTo(registry); + new JvmMemoryMetrics().bindTo(registry); + new JvmGcMetrics().bindTo(registry); + new ProcessorMetrics().bindTo(registry); + new JvmThreadMetrics().bindTo(registry); + } + + return instance; } - Vertx instance = Vertx.vertx(options); - instance.registerVerticleFactory(springVerticleFactory); + private void configureMetrics(VertxOptions options) { + LOGGER.info("Metrics support is enabled"); + + MicrometerMetricsOptions micrometerMetricsOptions = new MicrometerMetricsOptions(); + micrometerMetricsOptions + .setDisabledMetricsCategories( + new HashSet<>( + Arrays.asList( + MetricsDomain.DATAGRAM_SOCKET.toCategory(), + MetricsDomain.NAMED_POOLS.toCategory(), + MetricsDomain.VERTICLES.toCategory(), + MetricsDomain.EVENT_BUS.toCategory() + ) + ) + ) + .setEnabled(true); + + String namesVersion = environment.getProperty("services.metrics.prometheus.naming.version"); + + // Ensure compatibility with previous labels (Vertx 3.x) + if (PROMETHEUS_LABEL_VERSION_3_10.equals(namesVersion)) { + micrometerMetricsOptions.setMetricsNaming(MetricsNaming.v3Names()); + } - if (metricsEnabled) { - MeterRegistry registry = BackendRegistries.getDefaultNow(); + // Read labels + Set labels = loadLabels(); + if (labels != null && !labels.isEmpty()) { + Set