-
Notifications
You must be signed in to change notification settings - Fork 5.1k
CAMEL-23302: camel-xslt - Auto-disable content cache in routes-reload (dev) mode #23127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
fbdf44f
CAMEL-23302: camel-xslt - Auto-disable content cache in routes-reload…
ammachado 21d8339
CAMEL-23302: adding missing generated files
ammachado 130cfc6
CAMEL-23302: Make `DevModeContentCacheStrategy` package-private visib…
ammachado 431bae0
CAMEL-23302: Moving implementation from `ContentCacheAware` SPI to `P…
ammachado File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
core/camel-main/src/main/java/org/apache/camel/main/DevModeContentCacheStrategy.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| * (the "License"); you may not use this file except in compliance with | ||
| * the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package org.apache.camel.main; | ||
|
|
||
| import org.apache.camel.Component; | ||
| import org.apache.camel.spi.PropertyConfigurer; | ||
| import org.apache.camel.spi.PropertyConfigurerGetter; | ||
| import org.apache.camel.support.LifecycleStrategySupport; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| /** | ||
| * Lifecycle strategy that disables {@code contentCache} on resource-based components when routes-reload is enabled, so | ||
| * users can edit a resource file (e.g. an XSLT stylesheet, FreeMarker template) and see the change applied live. | ||
| * | ||
| * Components are detected via their generated {@link PropertyConfigurer}: any component whose configurer exposes a | ||
| * {@code contentCache} option currently evaluating to {@link Boolean#TRUE} is flipped to {@code false}. User properties | ||
| * applied later (e.g. {@code camel.component.<name>.contentCache=true}) will override this default. | ||
| */ | ||
| class DevModeContentCacheStrategy extends LifecycleStrategySupport { | ||
|
|
||
| private static final Logger LOG = LoggerFactory.getLogger(DevModeContentCacheStrategy.class); | ||
|
|
||
| private static final String CONTENT_CACHE = "contentCache"; | ||
|
|
||
| @Override | ||
| public void onComponentAdd(String name, Component component) { | ||
| PropertyConfigurer configurer = component.getComponentPropertyConfigurer(); | ||
| if (!(configurer instanceof PropertyConfigurerGetter getter)) { | ||
| return; | ||
| } | ||
| Object value = getter.getOptionValue(component, CONTENT_CACHE, true); | ||
| if (Boolean.TRUE.equals(value) | ||
| && configurer.configure(component.getCamelContext(), component, CONTENT_CACHE, Boolean.FALSE, true)) { | ||
| LOG.debug("Routes-reload is enabled: disabling contentCache on component '{}' for live resource reload", | ||
| name); | ||
| } | ||
| } | ||
| } |
204 changes: 204 additions & 0 deletions
204
core/camel-main/src/test/java/org/apache/camel/main/MainDevModeContentCacheTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,204 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| * (the "License"); you may not use this file except in compliance with | ||
| * the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package org.apache.camel.main; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| import org.apache.camel.CamelContext; | ||
| import org.apache.camel.Consumer; | ||
| import org.apache.camel.Endpoint; | ||
| import org.apache.camel.Processor; | ||
| import org.apache.camel.Producer; | ||
| import org.apache.camel.spi.PropertyConfigurer; | ||
| import org.apache.camel.spi.PropertyConfigurerGetter; | ||
| import org.apache.camel.support.DefaultComponent; | ||
| import org.apache.camel.support.DefaultEndpoint; | ||
| import org.apache.camel.support.component.PropertyConfigurerSupport; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertFalse; | ||
| import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
|
||
| public class MainDevModeContentCacheTest { | ||
|
|
||
| @Test | ||
| public void shouldDisableContentCacheWhenRoutesReloadEnabled() { | ||
| Main main = new Main(); | ||
| main.configure().withRoutesReloadEnabled(true); | ||
| main.bind("dummy", new TestContentCacheComponent()); | ||
|
|
||
| main.start(); | ||
| try { | ||
| TestContentCacheComponent c = main.getCamelContext().getComponent("dummy", TestContentCacheComponent.class); | ||
| assertFalse(c.isContentCache(), | ||
| "contentCache should be auto-disabled when routesReloadEnabled=true"); | ||
| } finally { | ||
| main.stop(); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void shouldKeepContentCacheEnabledWhenRoutesReloadDisabled() { | ||
| Main main = new Main(); | ||
| // routesReloadEnabled defaults to false | ||
| main.bind("dummy", new TestContentCacheComponent()); | ||
|
|
||
| main.start(); | ||
| try { | ||
| TestContentCacheComponent c = main.getCamelContext().getComponent("dummy", TestContentCacheComponent.class); | ||
| assertTrue(c.isContentCache(), | ||
| "contentCache should remain at its default (true) when routesReloadEnabled is not active"); | ||
| } finally { | ||
| main.stop(); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void shouldRespectExplicitContentCacheFalse() { | ||
| Main main = new Main(); | ||
| main.configure().withRoutesReloadEnabled(true); | ||
| TestContentCacheComponent component = new TestContentCacheComponent(); | ||
| component.setContentCache(false); | ||
| main.bind("dummy", component); | ||
|
|
||
| main.start(); | ||
| try { | ||
| TestContentCacheComponent c = main.getCamelContext().getComponent("dummy", TestContentCacheComponent.class); | ||
| assertFalse(c.isContentCache(), | ||
| "explicit user setting (false) must not be touched by dev-mode auto-flip"); | ||
| } finally { | ||
| main.stop(); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void shouldHonorMainPropertyOverride() { | ||
| Main main = new Main(); | ||
| main.configure().withRoutesReloadEnabled(true); | ||
| main.addInitialProperty("camel.component.dummy.contentCache", "true"); | ||
| main.bind("dummy", new TestContentCacheComponent()); | ||
|
|
||
| main.start(); | ||
| try { | ||
| TestContentCacheComponent c = main.getCamelContext().getComponent("dummy", TestContentCacheComponent.class); | ||
| assertTrue(c.isContentCache(), | ||
| "camel.component.<name>.contentCache=true must override the dev-mode auto-flip"); | ||
| } finally { | ||
| main.stop(); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void shouldRespectExplicitContentCacheOnUri() { | ||
| Main main = new Main(); | ||
| main.configure().withRoutesReloadEnabled(true); | ||
| main.bind("dummy", new TestContentCacheComponent()); | ||
|
|
||
| main.start(); | ||
| try { | ||
| TestContentCacheComponent c = main.getCamelContext().getComponent("dummy", TestContentCacheComponent.class); | ||
| assertFalse(c.isContentCache(), "component-level contentCache should be auto-disabled"); | ||
|
|
||
| TestContentCacheEndpoint endpoint | ||
| = (TestContentCacheEndpoint) main.getCamelContext().getEndpoint("dummy:foo?contentCache=true"); | ||
| assertTrue(endpoint.isContentCache(), | ||
| "explicit contentCache=true on URI must override the component-level auto-flip"); | ||
| } finally { | ||
| main.stop(); | ||
| } | ||
| } | ||
|
|
||
| static final class TestContentCacheComponent extends DefaultComponent { | ||
|
|
||
| private boolean contentCache = true; | ||
|
|
||
| public boolean isContentCache() { | ||
| return contentCache; | ||
| } | ||
|
|
||
| public void setContentCache(boolean contentCache) { | ||
| this.contentCache = contentCache; | ||
| } | ||
|
|
||
| @Override | ||
| public PropertyConfigurer getComponentPropertyConfigurer() { | ||
| return new TestContentCacheComponentConfigurer(); | ||
| } | ||
|
|
||
| @Override | ||
| protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { | ||
| TestContentCacheEndpoint endpoint = new TestContentCacheEndpoint(uri, this); | ||
| endpoint.setContentCache(contentCache); | ||
| setProperties(endpoint, parameters); | ||
| return endpoint; | ||
| } | ||
| } | ||
|
|
||
| static final class TestContentCacheComponentConfigurer | ||
| extends PropertyConfigurerSupport | ||
| implements PropertyConfigurer, PropertyConfigurerGetter { | ||
|
|
||
| @Override | ||
| public boolean configure(CamelContext camelContext, Object target, String name, Object value, boolean ignoreCase) { | ||
| if ("contentcache".equalsIgnoreCase(name)) { | ||
| ((TestContentCacheComponent) target).setContentCache(property(camelContext, boolean.class, value)); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| @Override | ||
| public Object getOptionValue(Object target, String name, boolean ignoreCase) { | ||
| if ("contentcache".equalsIgnoreCase(name)) { | ||
| return ((TestContentCacheComponent) target).isContentCache(); | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| @Override | ||
| public Class<?> getOptionType(String name, boolean ignoreCase) { | ||
| return "contentcache".equalsIgnoreCase(name) ? boolean.class : null; | ||
| } | ||
| } | ||
|
|
||
| static final class TestContentCacheEndpoint extends DefaultEndpoint { | ||
|
|
||
| private boolean contentCache; | ||
|
|
||
| TestContentCacheEndpoint(String uri, TestContentCacheComponent component) { | ||
| super(uri, component); | ||
| } | ||
|
|
||
| public boolean isContentCache() { | ||
| return contentCache; | ||
| } | ||
|
|
||
| public void setContentCache(boolean contentCache) { | ||
| this.contentCache = contentCache; | ||
| } | ||
|
|
||
| @Override | ||
| public Producer createProducer() { | ||
| throw new UnsupportedOperationException(); | ||
| } | ||
|
|
||
| @Override | ||
| public Consumer createConsumer(Processor processor) { | ||
| throw new UnsupportedOperationException(); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.