This is an automated email from the ASF dual-hosted git repository.
smolnar 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 3a18b13 KNOX-2692 - Topology redeployment can be configured to
require changes in topologies (#520)
3a18b13 is described below
commit 3a18b13aeb729e98807e21d0efaac54c5483193e
Author: Sandor Molnar <[email protected]>
AuthorDate: Tue Nov 30 16:37:30 2021 +0100
KNOX-2692 - Topology redeployment can be configured to require changes in
topologies (#520)
---
.../gateway/config/impl/GatewayConfigImpl.java | 6 ++++
.../topology/impl/DefaultTopologyService.java | 7 +++-
.../topology/DefaultTopologyServiceTest.java | 37 +++++++++++++++-------
.../apache/knox/gateway/config/GatewayConfig.java | 9 ++++++
.../org/apache/knox/gateway/GatewayTestConfig.java | 5 +++
5 files changed, 52 insertions(+), 12 deletions(-)
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 1aa5fc3..c16814b 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
@@ -185,6 +185,7 @@ public class GatewayConfigImpl extends Configuration
implements GatewayConfig {
private static final String DESCRIPTORS_DIR_NAME = "descriptors";
public static final String REMOTE_ALIAS_SERVICE_ENABLED =
GATEWAY_CONFIG_FILE_PREFIX + ".remote.alias.service.enabled";
public static final String STRICT_TOPOLOGY_VALIDATION =
GATEWAY_CONFIG_FILE_PREFIX + ".strict.topology.validation";
+ private static final String TOPOLOGY_REDEPLOYMENT_REQUIRES_CHANGES =
GATEWAY_CONFIG_FILE_PREFIX + ".topology.redeploy.requires.changes";
/**
* Comma-separated list of topology names, which should be forcibly treated
as read-only.
@@ -1131,6 +1132,11 @@ public class GatewayConfigImpl extends Configuration
implements GatewayConfig {
}
@Override
+ public boolean topologyRedeploymentRequiresChanges() {
+ return getBoolean(TOPOLOGY_REDEPLOYMENT_REQUIRES_CHANGES, false);
+ }
+
+ @Override
public List<String> getXForwardContextAppendServices() {
String value = get( X_FORWARD_CONTEXT_HEADER_APPEND_SERVICES );
if ( value != null && !value.isEmpty() &&
!"none".equalsIgnoreCase(value.trim()) ) {
diff --git
a/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/DefaultTopologyService.java
b/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/DefaultTopologyService.java
index 5796972..3e8392b 100644
---
a/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/DefaultTopologyService.java
+++
b/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/DefaultTopologyService.java
@@ -218,7 +218,7 @@ public class DefaultTopologyService extends
FileAlterationListenerAdaptor implem
for (Entry<File, Topology> newTopology : newTopologies.entrySet()) {
if (oldTopologies.containsKey(newTopology.getKey())) {
Topology oldTopology = oldTopologies.get(newTopology.getKey());
- if (newTopology.getValue().getTimestamp() > oldTopology.getTimestamp()
&& !oldTopology.equals(newTopology.getValue())) {
+ if (shouldMarkTopologyUpdated(newTopology.getValue(), oldTopology)) {
events.add(new TopologyEvent(TopologyEvent.Type.UPDATED,
newTopology.getValue()));
}
} else {
@@ -228,6 +228,11 @@ public class DefaultTopologyService extends
FileAlterationListenerAdaptor implem
return events;
}
+ private boolean shouldMarkTopologyUpdated(Topology newTopology, Topology
oldTopology) {
+ final boolean timestampUpdated = newTopology.getTimestamp() >
oldTopology.getTimestamp();
+ return config.topologyRedeploymentRequiresChanges() ? timestampUpdated &&
!oldTopology.equals(newTopology) : timestampUpdated;
+ }
+
private File calculateAbsoluteTopologiesDir(GatewayConfig config) {
File topoDir = new File(config.getGatewayTopologyDir());
topoDir = topoDir.getAbsoluteFile();
diff --git
a/gateway-server/src/test/java/org/apache/knox/gateway/services/topology/DefaultTopologyServiceTest.java
b/gateway-server/src/test/java/org/apache/knox/gateway/services/topology/DefaultTopologyServiceTest.java
index 6ae1ebf..86903b2 100644
---
a/gateway-server/src/test/java/org/apache/knox/gateway/services/topology/DefaultTopologyServiceTest.java
+++
b/gateway-server/src/test/java/org/apache/knox/gateway/services/topology/DefaultTopologyServiceTest.java
@@ -90,7 +90,7 @@ public class DefaultTopologyServiceTest {
assertNotNull(content);
IOUtils.copy(content, output);
}
- file.setLastModified(timestamp);
+ assertTrue(file.setLastModified(timestamp));
assertTrue("Failed to create test file " + file.getAbsolutePath(),
file.exists());
assertTrue("Failed to populate test file " + file.getAbsolutePath(),
file.length() > 0);
@@ -99,7 +99,7 @@ public class DefaultTopologyServiceTest {
private File touchFile(File parent, String name) throws IOException {
final File file = new File(parent, name);
- if (!file.exists()) {
+ if (file.exists()) {
FileUtils.touch(file);
}
return file;
@@ -712,7 +712,16 @@ public class DefaultTopologyServiceTest {
}
@Test
- public void testTopologyNotRedeployedIfNotChanged() throws Exception {
+ public void testTopologyRedeployedIfChangeNotRequired() throws Exception {
+ testTopologyRedeployment(false);
+ }
+
+ @Test
+ public void testTopologyNotRedeployedIfNotChangedAndChangeRequired() throws
Exception {
+ testTopologyRedeployment(true);
+ }
+
+ private void testTopologyRedeployment(boolean requiresChange) throws
Exception {
final File dir = createDir();
try {
final String topologyFileName = "one.xml";
@@ -720,12 +729,12 @@ public class DefaultTopologyServiceTest {
createFile(topologyDir, topologyFileName,
"org/apache/knox/gateway/topology/file/topology-one.xml",
topologyDir.lastModified());
final TestTopologyListener topoListener = new TestTopologyListener();
final TopologyService topologyService = new DefaultTopologyService();
- final Map<String, String> c = new HashMap<>();
final GatewayConfig config =
EasyMock.createNiceMock(GatewayConfig.class);
EasyMock.expect(config.getGatewayTopologyDir()).andReturn(topologyDir.getAbsolutePath()).anyTimes();
+
EasyMock.expect(config.topologyRedeploymentRequiresChanges()).andReturn(requiresChange).anyTimes();
EasyMock.replay(config);
- topologyService.init(config, c);
+ topologyService.init(config, new HashMap<>());
topologyService.addTopologyChangeListener(topoListener);
topologyService.reloadTopologies();
assertThat(topoListener.events.size(), is(1));
@@ -734,8 +743,12 @@ public class DefaultTopologyServiceTest {
assertThat(events.get(0).getType(), is(TopologyEvent.Type.CREATED));
topoListener.events.clear();
- // actually update the file
- TestUtils.updateFile(topologyDir, topologyFileName, "host-one",
"host-one-b");
+ if (requiresChange) {
+ TestUtils.updateFile(topologyDir, topologyFileName, "host-one",
"host-one-b");
+ } else {
+ touchFile(topologyDir, topologyFileName);
+ }
+
topologyService.reloadTopologies();
assertThat(topoListener.events.size(), is(1));
events = topoListener.events.get(0);
@@ -743,10 +756,12 @@ public class DefaultTopologyServiceTest {
assertThat(events.get(0).getType(), is(TopologyEvent.Type.UPDATED));
topoListener.events.clear();
- // simply touch the file, but not change it -> this should not trigger
any update event
- touchFile(topologyDir, topologyFileName);
- topologyService.reloadTopologies();
- assertThat(topoListener.events.size(), is(0));
+ if (requiresChange) {
+ // simply touch the file, but not change it -> this should not trigger
any update event
+ touchFile(topologyDir, topologyFileName);
+ topologyService.reloadTopologies();
+ assertThat(topoListener.events.size(), is(0));
+ }
} finally {
FileUtils.deleteQuietly(dir);
}
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 b6bd58b..f76dff0 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
@@ -639,6 +639,15 @@ public interface GatewayConfig {
boolean isTopologyValidationEnabled();
/**
+ * @return true if topology re-deployment requires an actual change in the
+ * topology. Defaults to <code>false</code> to be backward compatible
+ * with previous chanages.
+ *
+ * @since 2.0.0
+ */
+ boolean topologyRedeploymentRequiresChanges();
+
+ /**
* Returns a list of services that need service name appended to
* X-Forward-Context header as a result of which the new header would look
* /{gateway}/{sandbox}/{serviceName}
diff --git
a/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
b/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
index 19514a6..5122935 100644
---
a/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
+++
b/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
@@ -767,6 +767,11 @@ public class GatewayTestConfig extends Configuration
implements GatewayConfig {
}
@Override
+ public boolean topologyRedeploymentRequiresChanges() {
+ return false;
+ }
+
+ @Override
public List<String> getXForwardContextAppendServices() {
return null;
}