This is an automated email from the ASF dual-hosted git repository.
amagyar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new 3f3a65bad KNOX-2955 - Knox Readiness Awareness and Notification (#792)
3f3a65bad is described below
commit 3f3a65baddb58e4ad5d6bb0c0aa1d039fba688b5
Author: Attila Magyar <[email protected]>
AuthorDate: Mon Sep 11 11:36:02 2023 +0200
KNOX-2955 - Knox Readiness Awareness and Notification (#792)
---
.../org/apache/knox/gateway/GatewayMessages.java | 19 ++++-
.../org/apache/knox/gateway/GatewayServer.java | 7 ++
.../gateway/config/impl/GatewayConfigImpl.java | 8 ++
.../gateway/services/DefaultGatewayServices.java | 2 +
.../factory/GatewayStatusServiceFactory.java | 49 +++++++++++
.../topology/impl/GatewayStatusService.java | 98 ++++++++++++++++++++++
...org.apache.knox.gateway.services.ServiceFactory | 3 +-
.../services/AbstractGatewayServicesTest.java | 1 +
.../topology/impl/GatewayStatusServiceTest.java | 46 ++++++++++
.../knox/gateway/service/health/PingResource.java | 31 ++++++-
.../gateway/service/health/PingResourceTest.java | 2 +-
.../org/apache/knox/gateway/GatewayTestConfig.java | 5 ++
.../apache/knox/gateway/config/GatewayConfig.java | 2 +
.../apache/knox/gateway/services/ServiceType.java | 3 +-
.../gateway/SimpleDescriptorHandlerFuncTest.java | 5 ++
.../hadoop/xml/HadoopXmlResourceMonitor.java | 3 +-
.../topology/simple/SimpleDescriptorHandler.java | 2 +-
17 files changed, 276 insertions(+), 10 deletions(-)
diff --git
a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
index c5830bd8c..f8998ce7f 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
@@ -18,6 +18,7 @@
package org.apache.knox.gateway;
import java.io.File;
+import java.io.IOException;
import java.net.URI;
import java.time.Instant;
import java.util.Date;
@@ -32,8 +33,6 @@ import org.apache.knox.gateway.i18n.messages.StackTrace;
import org.apache.knox.gateway.services.security.KeystoreServiceException;
import org.apache.knox.gateway.topology.monitor.db.LocalDirectory;
-import java.io.IOException;
-
@Messages(logger="org.apache.knox.gateway")
public interface GatewayMessages {
@@ -785,4 +784,20 @@ public interface GatewayMessages {
@Message(level = MessageLevel.DEBUG,
text = "Request {0} is wrapped to url encoded form request.")
void wrappingRequestToUrlEncodedFormRequest(String requestURI);
+
+ @Message(level = MessageLevel.INFO,
+ text = "Checking gateway status. Deployed topologies: {0}. Waiting
for: {1}")
+ void checkingGatewayStatus(Set<String> deployedTopologies, Set<String>
missingTopologies);
+
+ @Message(level = MessageLevel.INFO,
+ text = "Checking gateway status. No topologies to check")
+ void noTopologiesToCheck();
+
+ @Message(level = MessageLevel.INFO,
+ text = "Collected topologies for health check: {0}")
+ void collectedTopologiesForHealthCheck(Set<String> result);
+
+ @Message(level = MessageLevel.INFO,
+ text = "Starting gateway status service. Topologies to check: {0}")
+ void startingStatusMonitor(Set<String> topologyNames);
}
diff --git
a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayServer.java
b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayServer.java
index 8485ec86d..bb7b44ae8 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayServer.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayServer.java
@@ -43,6 +43,7 @@ import
org.apache.knox.gateway.services.registry.ServiceRegistry;
import org.apache.knox.gateway.services.security.AliasServiceException;
import org.apache.knox.gateway.services.security.SSLService;
import org.apache.knox.gateway.services.topology.TopologyService;
+import org.apache.knox.gateway.services.topology.impl.GatewayStatusService;
import org.apache.knox.gateway.topology.Application;
import org.apache.knox.gateway.topology.Topology;
import org.apache.knox.gateway.topology.TopologyEvent;
@@ -146,6 +147,7 @@ public class GatewayServer {
private TopologyListener listener;
private Map<String, WebAppContext> deployments;
private AtomicBoolean stopped = new AtomicBoolean(false);
+ private GatewayStatusService gatewayStatusService;
public static void main( String[] args ) {
try {
@@ -630,6 +632,10 @@ public class GatewayServer {
// by the descriptor monitor
handleHadoopXmlResources();
+ // at this point descriptors are supposed to be generated from hxr
+ gatewayStatusService =
services.getService(ServiceType.GATEWAY_STATUS_SERVICE);
+ gatewayStatusService.initTopologiesToCheck();
+
monitor.addTopologyChangeListener(listener);
log.loadingTopologiesFromDirectory(topologiesDir.getAbsolutePath());
monitor.reloadTopologies();
@@ -1038,6 +1044,7 @@ public class GatewayServer {
log.redeployedTopology( topology.getName() );
}
cleanupTopologyDeployments( deployDir, topology );
+ gatewayStatusService.onTopologyReady(topology.getName());
} catch( Throwable e ) {
auditor.audit( Action.DEPLOY, topology.getName(),
ResourceType.TOPOLOGY, ActionOutcome.FAILURE );
log.failedToDeployTopology( topology.getName(), e );
diff --git
a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
index b76b48c22..e3f4847ed 100644
---
a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
+++
b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
@@ -331,6 +331,8 @@ public class GatewayConfigImpl extends Configuration
implements GatewayConfig {
private static final String GATEWAY_SERVLET_ASYNC_SUPPORTED =
GATEWAY_CONFIG_FILE_PREFIX + ".servlet.async.supported";
private static final boolean GATEWAY_SERVLET_ASYNC_SUPPORTED_DEFAULT = false;
+ private static final String GATEWAY_HEALTH_CHECK_TOPOLOGIES =
GATEWAY_CONFIG_FILE_PREFIX + ".health.check.topologies";
+
public GatewayConfigImpl() {
init();
}
@@ -1469,6 +1471,12 @@ public class GatewayConfigImpl extends Configuration
implements GatewayConfig {
return
getLong(GATEWAY_SESSION_VERIFICATION_EXPIRED_TOKENS_CLEANING_PERIOD,
GATEWAY_SESSION_VERIFICATION_EXPIRED_TOKENS_CLEANING_PERIOD_DEFAULT);
}
+ @Override
+ public Set<String> getHealthCheckTopologies() {
+ final Collection<String> topologies =
getTrimmedStringCollection(GATEWAY_HEALTH_CHECK_TOPOLOGIES);
+ return topologies == null ? Collections.emptySet() : new
HashSet<>(topologies);
+ }
+
@Override
public boolean isAsyncSupported() {
return getBoolean(GATEWAY_SERVLET_ASYNC_SUPPORTED,
GATEWAY_SERVLET_ASYNC_SUPPORTED_DEFAULT);
diff --git
a/gateway-server/src/main/java/org/apache/knox/gateway/services/DefaultGatewayServices.java
b/gateway-server/src/main/java/org/apache/knox/gateway/services/DefaultGatewayServices.java
index 994025e5e..676202d5f 100644
---
a/gateway-server/src/main/java/org/apache/knox/gateway/services/DefaultGatewayServices.java
+++
b/gateway-server/src/main/java/org/apache/knox/gateway/services/DefaultGatewayServices.java
@@ -80,6 +80,8 @@ public class DefaultGatewayServices extends
AbstractGatewayServices {
addService(ServiceType.METRICS_SERVICE, gatewayServiceFactory.create(this,
ServiceType.METRICS_SERVICE, config, options));
addService(ServiceType.CONCURRENT_SESSION_VERIFIER,
gatewayServiceFactory.create(this, ServiceType.CONCURRENT_SESSION_VERIFIER,
config, options));
+
+ addService(ServiceType.GATEWAY_STATUS_SERVICE,
gatewayServiceFactory.create(this, ServiceType.GATEWAY_STATUS_SERVICE, config,
options));
}
@Override
diff --git
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/GatewayStatusServiceFactory.java
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/GatewayStatusServiceFactory.java
new file mode 100644
index 000000000..69559ad03
--- /dev/null
+++
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/GatewayStatusServiceFactory.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.topology.impl.GatewayStatusService;
+
+public class GatewayStatusServiceFactory extends AbstractServiceFactory {
+
+ @Override
+ protected Service createService(GatewayServices gatewayServices, ServiceType
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String
implementation) throws ServiceLifecycleException {
+ return new GatewayStatusService();
+ }
+
+ @Override
+ protected ServiceType getServiceType() {
+ return ServiceType.GATEWAY_STATUS_SERVICE;
+ }
+
+ @Override
+ protected Collection<String> getKnownImplementations() {
+ return unmodifiableList(asList(GatewayStatusService.class.getName()));
+ }
+}
diff --git
a/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/GatewayStatusService.java
b/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/GatewayStatusService.java
new file mode 100644
index 000000000..08ad866b2
--- /dev/null
+++
b/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/GatewayStatusService.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.topology.impl;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.knox.gateway.GatewayMessages;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+
+public class GatewayStatusService implements Service {
+ private static final GatewayMessages LOG =
MessagesFactory.get(GatewayMessages.class);
+ private final Set<String> deployedTopologies = new HashSet<>();
+ private Set<String> topologyNamesToCheck = new HashSet<>();
+ private GatewayConfig config;
+
+ public synchronized void onTopologyReady(String topologyName) {
+ deployedTopologies.add(topologyName);
+ }
+
+ public synchronized boolean status() {
+ if (topologyNamesToCheck.isEmpty()) {
+ LOG.noTopologiesToCheck();
+ return false;
+ }
+ Set<String> missing = new HashSet<>(topologyNamesToCheck);
+ missing.removeAll(deployedTopologies);
+ LOG.checkingGatewayStatus(deployedTopologies, missing);
+ return missing.isEmpty();
+ }
+
+ /**
+ * The list of topologies (which will be used to check the gateway status.)
+ * are either coming from the config or collected automatically.
+ * In the later case this should be called at startup, after the hadoop xml
resource parser
+ * already generated the descriptors from the hxr
+ */
+ public synchronized void initTopologiesToCheck() {
+ Set<String> healthCheckTopologies = config.getHealthCheckTopologies();
+ if (healthCheckTopologies.isEmpty()) {
+ topologyNamesToCheck = collectTopologies(config);
+ } else {
+ topologyNamesToCheck = healthCheckTopologies;
+ }
+ LOG.startingStatusMonitor(topologyNamesToCheck);
+ }
+
+ private Set<String> collectTopologies(GatewayConfig config) {
+ Set<String> result = new HashSet<>();
+ collectFiles(result, config.getGatewayTopologyDir(), ".xml");
+ collectFiles(result, config.getGatewayDescriptorsDir(), ".json");
+ LOG.collectedTopologiesForHealthCheck(result);
+ return result;
+ }
+
+ private void collectFiles(Set<String> result, String directory, String
extension) {
+ File[] files = new File(directory).getAbsoluteFile()
+ .listFiles((dir, name) ->
name.toLowerCase(Locale.ROOT).endsWith(extension));
+ if (files != null) {
+ for (File file : files) {
+ result.add(FilenameUtils.getBaseName(file.getName()));
+ }
+ }
+ }
+ @Override
+ public void init(GatewayConfig config, Map<String, String> options) throws
ServiceLifecycleException {
+ this.config = config;
+ // this is soon to collect the topologies, topologies are collected in
initTopologiesToCheck
+ }
+
+ @Override
+ public void start() throws ServiceLifecycleException {}
+
+ @Override
+ public void stop() throws ServiceLifecycleException {}
+}
diff --git
a/gateway-server/src/main/resources/META-INF/services/org.apache.knox.gateway.services.ServiceFactory
b/gateway-server/src/main/resources/META-INF/services/org.apache.knox.gateway.services.ServiceFactory
index b8a4fc49d..4c015979f 100644
---
a/gateway-server/src/main/resources/META-INF/services/org.apache.knox.gateway.services.ServiceFactory
+++
b/gateway-server/src/main/resources/META-INF/services/org.apache.knox.gateway.services.ServiceFactory
@@ -31,4 +31,5 @@ org.apache.knox.gateway.services.factory.SslServiceFactory
org.apache.knox.gateway.services.factory.TokenServiceFactory
org.apache.knox.gateway.services.factory.TokenStateServiceFactory
org.apache.knox.gateway.services.factory.TopologyServiceFactory
-org.apache.knox.gateway.services.factory.ConcurrentSessionVerifierFactory
\ No newline at end of file
+org.apache.knox.gateway.services.factory.ConcurrentSessionVerifierFactory
+org.apache.knox.gateway.services.factory.GatewayStatusServiceFactory
\ No newline at end of file
diff --git
a/gateway-server/src/test/java/org/apache/knox/gateway/services/AbstractGatewayServicesTest.java
b/gateway-server/src/test/java/org/apache/knox/gateway/services/AbstractGatewayServicesTest.java
index fb1ce553d..f38bc8b27 100644
---
a/gateway-server/src/test/java/org/apache/knox/gateway/services/AbstractGatewayServicesTest.java
+++
b/gateway-server/src/test/java/org/apache/knox/gateway/services/AbstractGatewayServicesTest.java
@@ -65,6 +65,7 @@ public class AbstractGatewayServicesTest {
ServiceType.SERVICE_REGISTRY_SERVICE,
ServiceType.CONCURRENT_SESSION_VERIFIER,
ServiceType.REMOTE_CONFIGURATION_MONITOR,
+ ServiceType.GATEWAY_STATUS_SERVICE
};
assertNotEquals(ServiceType.values(), orderedServiceTypes);
diff --git
a/gateway-server/src/test/java/org/apache/knox/gateway/services/topology/impl/GatewayStatusServiceTest.java
b/gateway-server/src/test/java/org/apache/knox/gateway/services/topology/impl/GatewayStatusServiceTest.java
new file mode 100644
index 000000000..fe866a660
--- /dev/null
+++
b/gateway-server/src/test/java/org/apache/knox/gateway/services/topology/impl/GatewayStatusServiceTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.topology.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+public class GatewayStatusServiceTest {
+
+ @Test
+ public void testReadyStatus() throws Exception {
+ GatewayStatusService statusService = new GatewayStatusService();
+ GatewayConfig config = EasyMock.createNiceMock(GatewayConfig.class);
+ statusService.init(config, null);
+ assertFalse(statusService.status());
+ EasyMock.expect(config.getHealthCheckTopologies()).andReturn(new
HashSet<>(Arrays.asList("t1", "t2"))).anyTimes();
+ EasyMock.replay(config);
+ statusService.initTopologiesToCheck();
+ statusService.onTopologyReady("t1");
+ assertFalse(statusService.status());
+ statusService.onTopologyReady("t2");
+ assertTrue(statusService.status());
+ }
+}
\ No newline at end of file
diff --git
a/gateway-service-health/src/main/java/org/apache/knox/gateway/service/health/PingResource.java
b/gateway-service-health/src/main/java/org/apache/knox/gateway/service/health/PingResource.java
index 5a73ef273..2d4f4e720 100644
---
a/gateway-service-health/src/main/java/org/apache/knox/gateway/service/health/PingResource.java
+++
b/gateway-service-health/src/main/java/org/apache/knox/gateway/service/health/PingResource.java
@@ -18,6 +18,9 @@
package org.apache.knox.gateway.service.health;
import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.topology.impl.GatewayStatusService;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
@@ -39,8 +42,9 @@ import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
@Path(PingResource.RESOURCE_PATH)
public class PingResource {
static final String VERSION_TAG = "v1";
- static final String RESOURCE_PATH = "/" + VERSION_TAG + "/ping";
- public static final String CONTENT = "OK";
+ static final String RESOURCE_PATH = "/" + VERSION_TAG;
+ public static final String OK = "OK";
+ public static final String PENDING = "PENDING";
private static HealthServiceMessages log =
MessagesFactory.get(HealthServiceMessages.class);
private static final String CONTENT_TYPE = "text/plain";
private static final String CACHE_CONTROL = "Cache-Control";
@@ -57,12 +61,14 @@ public class PingResource {
@GET
@Produces({APPLICATION_JSON, TEXT_PLAIN})
+ @Path("ping")
public Response doGet() {
return getPingResponse();
}
@POST
@Produces({APPLICATION_JSON, TEXT_PLAIN})
+ @Path("ping")
public Response doPost() {
return getPingResponse();
}
@@ -81,7 +87,26 @@ public class PingResource {
}
String getPingContent() {
- return CONTENT;
+ return OK;
+ }
+
+ @GET
+ @Produces({TEXT_PLAIN})
+ @Path("gateway-status")
+ public Response status() {
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.setHeader(CACHE_CONTROL, NO_CACHE);
+ response.setContentType(CONTENT_TYPE);
+ GatewayServices services = (GatewayServices) request.getServletContext()
+ .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+ GatewayStatusService statusService =
services.getService(ServiceType.GATEWAY_STATUS_SERVICE);
+ try (PrintWriter writer = response.getWriter()) {
+ writer.println(statusService.status() ? OK : PENDING);
+ } catch (IOException e) {
+ log.logException("status", e);
+ return Response.serverError().entity(String.format(Locale.ROOT, "Failed
to reply correctly due to : %s ", e)).build();
+ }
+ return Response.ok().build();
}
}
diff --git
a/gateway-service-health/src/test/java/org/apache/knox/gateway/service/health/PingResourceTest.java
b/gateway-service-health/src/test/java/org/apache/knox/gateway/service/health/PingResourceTest.java
index 8a28d3caf..86526ce5b 100644
---
a/gateway-service-health/src/test/java/org/apache/knox/gateway/service/health/PingResourceTest.java
+++
b/gateway-service-health/src/test/java/org/apache/knox/gateway/service/health/PingResourceTest.java
@@ -24,6 +24,6 @@ public class PingResourceTest {
@Test
public void testPingCdoGetontent() {
PingResource pr = new PingResource();
- Assert.assertEquals(pr.getPingContent(), pr.CONTENT);
+ Assert.assertEquals(pr.getPingContent(), pr.OK);
}
}
\ No newline at end of file
diff --git
a/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
b/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
index 801cfca85..64c4e4366 100644
---
a/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
+++
b/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
@@ -1042,6 +1042,11 @@ public class GatewayTestConfig extends Configuration
implements GatewayConfig {
return 0;
}
+ @Override
+ public Set<String> getHealthCheckTopologies() {
+ return Collections.emptySet();
+ }
+
@Override
public boolean isAsyncSupported() {
return false;
diff --git
a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
index c07411206..8de39010c 100644
---
a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
+++
b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
@@ -873,6 +873,8 @@ public interface GatewayConfig {
long getConcurrentSessionVerifierExpiredTokensCleaningPeriod();
+ Set<String> getHealthCheckTopologies();
+
/**
* @return true if the async supported flag is enabled in jetty gateway
servlet; false otherwise (defaults to false)
*/
diff --git
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceType.java
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceType.java
index f0123043c..de4a83db9 100644
---
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceType.java
+++
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceType.java
@@ -37,7 +37,8 @@ public enum ServiceType {
TOKEN_STATE_SERVICE("TokenStateService"),
TOPOLOGY_SERVICE("TopologyService"),
CONCURRENT_SESSION_VERIFIER("ConcurrentSessionVerifier"),
- REMOTE_CONFIGURATION_MONITOR("RemoteConfigurationMonitor");
+ REMOTE_CONFIGURATION_MONITOR("RemoteConfigurationMonitor"),
+ GATEWAY_STATUS_SERVICE("GatewayStatusService");
private final String serviceTypeName;
private final String shortName;
diff --git
a/gateway-test/src/test/java/org/apache/knox/gateway/SimpleDescriptorHandlerFuncTest.java
b/gateway-test/src/test/java/org/apache/knox/gateway/SimpleDescriptorHandlerFuncTest.java
index 7f3f5552b..d0f5cd752 100644
---
a/gateway-test/src/test/java/org/apache/knox/gateway/SimpleDescriptorHandlerFuncTest.java
+++
b/gateway-test/src/test/java/org/apache/knox/gateway/SimpleDescriptorHandlerFuncTest.java
@@ -25,6 +25,7 @@ import org.apache.knox.gateway.services.security.AliasService;
import org.apache.knox.gateway.services.security.KeystoreService;
import org.apache.knox.gateway.services.security.MasterService;
import org.apache.knox.gateway.services.topology.TopologyService;
+import org.apache.knox.gateway.services.topology.impl.GatewayStatusService;
import org.apache.knox.gateway.topology.discovery.ServiceDiscovery;
import org.apache.knox.gateway.topology.discovery.ServiceDiscoveryConfig;
import org.apache.knox.gateway.topology.discovery.ServiceDiscoveryType;
@@ -226,6 +227,10 @@ public class SimpleDescriptorHandlerFuncTest {
EasyMock.replay(ts);
EasyMock.expect(gatewayServices.getService(ServiceType.TOPOLOGY_SERVICE)).andReturn(ts).anyTimes();
+ GatewayStatusService statusService =
EasyMock.createNiceMock(GatewayStatusService.class);
+ EasyMock.replay(statusService);
+
EasyMock.expect(gatewayServices.getService(ServiceType.GATEWAY_STATUS_SERVICE)).andReturn(statusService).anyTimes();
+
EasyMock.replay(gatewayServices);
// Start a GatewayService with the GatewayServices mock
diff --git
a/gateway-topology-hadoop-xml/src/main/java/org/apache/knox/gateway/topology/hadoop/xml/HadoopXmlResourceMonitor.java
b/gateway-topology-hadoop-xml/src/main/java/org/apache/knox/gateway/topology/hadoop/xml/HadoopXmlResourceMonitor.java
index be5a40516..f77d419f4 100644
---
a/gateway-topology-hadoop-xml/src/main/java/org/apache/knox/gateway/topology/hadoop/xml/HadoopXmlResourceMonitor.java
+++
b/gateway-topology-hadoop-xml/src/main/java/org/apache/knox/gateway/topology/hadoop/xml/HadoopXmlResourceMonitor.java
@@ -72,7 +72,8 @@ public class HadoopXmlResourceMonitor implements
AdvancedServiceDiscoveryConfigC
public void setupMonitor() {
if (monitoringInterval > 0) {
final ScheduledExecutorService executorService =
Executors.newSingleThreadScheduledExecutor(new
BasicThreadFactory.Builder().namingPattern("ClouderaManagerDescriptorMonitor-%d").build());
- executorService.scheduleAtFixedRate(() ->
monitorClouderaManagerDescriptors(false), 0, monitoringInterval,
TimeUnit.MILLISECONDS);
+ monitorClouderaManagerDescriptors(false); // call it explicitly first to
generate descriptors up front, so that the health checker can pick them up
+ executorService.scheduleAtFixedRate(() ->
monitorClouderaManagerDescriptors(false), monitoringInterval,
monitoringInterval, TimeUnit.MILLISECONDS);
LOG.monitoringHadoopXmlResources(descriptorsDir);
}
}
diff --git
a/gateway-topology-simple/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorHandler.java
b/gateway-topology-simple/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorHandler.java
index 81e15a012..1ce217efd 100644
---
a/gateway-topology-simple/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorHandler.java
+++
b/gateway-topology-simple/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorHandler.java
@@ -91,7 +91,7 @@ public class SimpleDescriptorHandler {
private static final Map<String, ServiceDiscovery> discoveryInstances =
new HashMap<>();
- private static final Set<String> ALLOWED_SERVICES_WITHOUT_URLS_AND_PARAMS
= Collections.unmodifiableSet(Stream.of("KNOX", "KNOX-METADATA", "KNOXSSOUT",
"KNOX-SESSION").collect(Collectors.toSet()));
+ private static final Set<String> ALLOWED_SERVICES_WITHOUT_URLS_AND_PARAMS
= Collections.unmodifiableSet(Stream.of("KNOX", "KNOX-METADATA", "KNOXSSOUT",
"KNOX-SESSION", "HEALTH").collect(Collectors.toSet()));
public static Map<String, File> handle(GatewayConfig config, File desc,
File destDirectory, Service...gatewayServices) throws IOException {
return handle(config,
SimpleDescriptorFactory.parse(desc.getAbsolutePath()), desc.getParentFile(),
destDirectory, gatewayServices);