This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch properties in repository https://gitbox.apache.org/repos/asf/camel.git
commit 1794a610f5a503d04696b3c5878313be8960b2ce Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Wed Jul 3 11:50:27 2019 +0200 CAMEL-13708: Properties component should have API to make it easier to lookup a property on-demand or from all pre-loaded properties. --- .../config/CamelMicroProfilePropertiesSource.java | 2 + .../src/main/docs/properties-component.adoc | 2 +- .../properties/ClasspathPropertiesSource.java | 70 +++++++++++++ .../properties/DefaultPropertiesResolver.java | 1 + .../component/properties/FilePropertiesSource.java | 70 +++++++++++++ .../properties/LocationPropertiesSource.java | 22 ++++ .../LocationPropertiesSourceSupport.java | 114 +++++++++++++++++++++ .../component/properties/PropertiesComponent.java | 106 ++++++++++++++----- .../component/properties/PropertiesLocation.java | 2 +- .../component/properties/RefPropertiesSource.java | 54 ++++++++++ .../properties/PropertiesComponentRestartTest.java | 67 ------------ .../properties/PropertiesResolverTest.java | 73 ------------- .../issues/PropertiesAvailableEverywhereTest.java | 14 +-- .../PropertiesComponentConfiguration.java | 5 + 14 files changed, 422 insertions(+), 180 deletions(-) diff --git a/components/camel-microprofile-config/src/main/java/org/apache/camel/component/microprofile/config/CamelMicroProfilePropertiesSource.java b/components/camel-microprofile-config/src/main/java/org/apache/camel/component/microprofile/config/CamelMicroProfilePropertiesSource.java index 7622889..ce9ca88 100644 --- a/components/camel-microprofile-config/src/main/java/org/apache/camel/component/microprofile/config/CamelMicroProfilePropertiesSource.java +++ b/components/camel-microprofile-config/src/main/java/org/apache/camel/component/microprofile/config/CamelMicroProfilePropertiesSource.java @@ -33,6 +33,8 @@ import org.slf4j.LoggerFactory; */ public class CamelMicroProfilePropertiesSource extends ServiceSupport implements LoadablePropertiesSource { + // TODO: Should not be loadable but regular source so we lookup on demand + private static final Logger LOG = LoggerFactory.getLogger(CamelMicroProfilePropertiesSource.class); private final Properties properties = new OrderedProperties(); diff --git a/components/camel-properties/src/main/docs/properties-component.adoc b/components/camel-properties/src/main/docs/properties-component.adoc index da6bce5..8e784be 100644 --- a/components/camel-properties/src/main/docs/properties-component.adoc +++ b/components/camel-properties/src/main/docs/properties-component.adoc @@ -25,7 +25,7 @@ The Properties component supports 16 options, which are listed below. | *locations* (common) | A list of locations to load properties. This option will override any default locations and only use the locations from this option. | | List | *location* (common) | A list of locations to load properties. You can use comma to separate multiple locations. This option will override any default locations and only use the locations from this option. | | String | *encoding* (common) | Encoding to use when loading properties file from the file system or classpath. If no encoding has been set, then the properties files is loaded using ISO-8859-1 encoding (latin-1) as documented by java.util.Properties#load(java.io.InputStream) | | String -| *propertiesResolver* (common) | To use a custom PropertiesResolver | | PropertiesResolver +| *propertiesResolver* (common) | *Deprecated* To use a custom PropertiesResolver | | PropertiesResolver | *propertiesParser* (common) | To use a custom PropertiesParser | | PropertiesParser | *cache* (common) | Whether or not to cache loaded properties. The default value is true. | true | boolean | *defaultFallbackEnabled* (common) | If false, the component does not attempt to find a default for the key by looking after the colon separator. | true | boolean diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/ClasspathPropertiesSource.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/ClasspathPropertiesSource.java new file mode 100644 index 0000000..a69e836 --- /dev/null +++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/ClasspathPropertiesSource.java @@ -0,0 +1,70 @@ +/** + * 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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.properties; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Properties; + +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.util.IOHelper; +import org.apache.camel.util.OrderedProperties; + +public class ClasspathPropertiesSource extends LocationPropertiesSourceSupport { + + public ClasspathPropertiesSource(PropertiesComponent propertiesComponent, PropertiesLocation location, boolean ignoreMissingLocation) { + super(propertiesComponent, location, ignoreMissingLocation); + } + + @Override + public String getName() { + return "ClasspathPropertiesSource[" + getLocation().getPath() + "]"; + } + + @Override + protected Properties loadPropertiesFromLocation(PropertiesComponent propertiesComponent, boolean ignoreMissingLocation, PropertiesLocation location) { + Properties answer = new OrderedProperties(); + String path = location.getPath(); + + InputStream is = propertiesComponent.getCamelContext().getClassResolver().loadResourceAsStream(path); + Reader reader = null; + if (is == null) { + if (!ignoreMissingLocation && !location.isOptional()) { + throw RuntimeCamelException.wrapRuntimeCamelException(new FileNotFoundException("Properties file " + path + " not found in classpath")); + } + } else { + try { + if (propertiesComponent.getEncoding() != null) { + reader = new BufferedReader(new InputStreamReader(is, propertiesComponent.getEncoding())); + answer.load(reader); + } else { + answer.load(is); + } + } catch (IOException e) { + throw RuntimeCamelException.wrapRuntimeCamelException(e); + } finally { + IOHelper.close(reader, is); + } + } + return answer; + } + +} diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/DefaultPropertiesResolver.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/DefaultPropertiesResolver.java index 1e164ff..a88c587 100644 --- a/components/camel-properties/src/main/java/org/apache/camel/component/properties/DefaultPropertiesResolver.java +++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/DefaultPropertiesResolver.java @@ -39,6 +39,7 @@ import org.apache.camel.util.OrderedProperties; * You can denote <tt>classpath:</tt> or <tt>file:</tt> as prefix in the uri to select whether the file * is located in the classpath or on the file system. */ +@Deprecated public class DefaultPropertiesResolver implements PropertiesResolver { private final PropertiesComponent propertiesComponent; diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/FilePropertiesSource.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/FilePropertiesSource.java new file mode 100644 index 0000000..3ac9810 --- /dev/null +++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/FilePropertiesSource.java @@ -0,0 +1,70 @@ +/** + * 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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.properties; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Properties; + +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.util.IOHelper; +import org.apache.camel.util.OrderedProperties; + +public class FilePropertiesSource extends LocationPropertiesSourceSupport { + + protected FilePropertiesSource(PropertiesComponent propertiesComponent, PropertiesLocation location, boolean ignoreMissingLocation) { + super(propertiesComponent, location, ignoreMissingLocation); + } + + @Override + public String getName() { + return "FilePropertiesSource[" + getLocation().getPath() + "]"; + } + + protected Properties loadPropertiesFromLocation(PropertiesComponent propertiesComponent, boolean ignoreMissingLocation, PropertiesLocation location) { + Properties answer = new OrderedProperties(); + String path = location.getPath(); + + InputStream is = null; + Reader reader = null; + try { + is = new FileInputStream(path); + if (propertiesComponent.getEncoding() != null) { + reader = new BufferedReader(new InputStreamReader(is, propertiesComponent.getEncoding())); + answer.load(reader); + } else { + answer.load(is); + } + } catch (FileNotFoundException e) { + if (!ignoreMissingLocation && !location.isOptional()) { + throw RuntimeCamelException.wrapRuntimeCamelException(e); + } + } catch (IOException e) { + throw RuntimeCamelException.wrapRuntimeCamelException(e); + } finally { + IOHelper.close(reader, is); + } + + return answer; + } + +} diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/LocationPropertiesSource.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/LocationPropertiesSource.java new file mode 100644 index 0000000..4fbf5ca --- /dev/null +++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/LocationPropertiesSource.java @@ -0,0 +1,22 @@ +/** + * 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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.properties; + +public interface LocationPropertiesSource extends PropertiesSource { + + PropertiesLocation getLocation(); +} diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/LocationPropertiesSourceSupport.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/LocationPropertiesSourceSupport.java new file mode 100644 index 0000000..73bd40a --- /dev/null +++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/LocationPropertiesSourceSupport.java @@ -0,0 +1,114 @@ +/** + * 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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.properties; + +import java.util.Map; +import java.util.Properties; + +import org.apache.camel.support.service.ServiceSupport; +import org.apache.camel.util.OrderedProperties; + +public abstract class LocationPropertiesSourceSupport extends ServiceSupport implements LoadablePropertiesSource, LocationPropertiesSource { + + private final Properties properties = new OrderedProperties(); + private final PropertiesComponent propertiesComponent; + private final PropertiesLocation location; + private final boolean ignoreMissingLocation; + + protected LocationPropertiesSourceSupport(PropertiesComponent propertiesComponent, PropertiesLocation location, boolean ignoreMissingLocation) { + this.propertiesComponent = propertiesComponent; + this.location = location; + this.ignoreMissingLocation = ignoreMissingLocation; + } + + abstract Properties loadPropertiesFromLocation(PropertiesComponent propertiesComponent, boolean ignoreMissingLocation, PropertiesLocation location); + + public PropertiesLocation getLocation() { + return location; + } + + @Override + public Properties loadProperties() { + return properties; + } + + @Override + public String getProperty(String name) { + return properties.getProperty(name); + } + + @Override + protected void doInit() throws Exception { + super.doInit(); + + Properties prop = loadPropertiesFromLocation(propertiesComponent, ignoreMissingLocation, location); + prop = prepareLoadedProperties(prop); + properties.putAll(prop); + } + + @Override + protected void doStart() throws Exception { + // noop + } + + @Override + protected void doStop() throws Exception { + // noop + } + + /** + * Strategy to prepare loaded properties before being used by Camel. + * <p/> + * This implementation will ensure values are trimmed, as loading properties from + * a file with values having trailing spaces is not automatic trimmed by the Properties API + * from the JDK. + * + * @param properties the properties + * @return the prepared properties + */ + protected static Properties prepareLoadedProperties(Properties properties) { + Properties answer = new OrderedProperties(); + for (Map.Entry<Object, Object> entry : properties.entrySet()) { + Object key = entry.getKey(); + Object value = entry.getValue(); + if (value instanceof String) { + String s = (String) value; + + // trim any trailing spaces which can be a problem when loading from + // a properties file, note that java.util.Properties does already this + // for any potential leading spaces so there's nothing to do there + value = trimTrailingWhitespaces(s); + } + answer.put(key, value); + } + return answer; + } + + private static String trimTrailingWhitespaces(String s) { + int endIndex = s.length(); + for (int index = s.length() - 1; index >= 0; index--) { + if (s.charAt(index) == ' ') { + endIndex = index; + } else { + break; + } + } + String answer = s.substring(0, endIndex); + return answer; + } + +} diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java index f6dde5d..1e109c6 100644 --- a/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java +++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java @@ -100,7 +100,7 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. private static final Logger LOG = LoggerFactory.getLogger(PropertiesComponent.class); - @SuppressWarnings("unchecked") + // TODO: Get rid of cacheMap private final Map<CacheKey, Properties> cacheMap = LRUCacheFactory.newLRUSoftCache(1000); private transient Properties cachedLoadedProperties; private final Map<String, PropertiesFunction> functions = new LinkedHashMap<>(); @@ -108,6 +108,7 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. private PropertiesParser propertiesParser = new DefaultPropertiesParser(this); private List<PropertiesLocation> locations = Collections.emptyList(); private final List<PropertiesSource> sources = new ArrayList<>(); + private final List<LocationPropertiesSource> locationSources = new ArrayList<>(); @Metadata private boolean ignoreMissingLocation; @@ -178,12 +179,18 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. public String parseUri(String uri) { // optimise to only load properties once as we use the configured locations - if (cache && cachedLoadedProperties == null) { - cachedLoadedProperties = doLoadProperties(locations); + if (cache) { + if (cachedLoadedProperties == null) { + cachedLoadedProperties = doLoadProperties(null); + } + return parseUri(uri, cachedLoadedProperties); + } else { + Properties prop = doLoadProperties(null); + return parseUri(uri, prop); } - return cachedLoadedProperties != null ? parseUri(uri, cachedLoadedProperties) : parseUri(uri, doLoadProperties(locations)); } + @Deprecated public String parseUri(String uri, String... locations) { return parseUri( uri, @@ -193,20 +200,26 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. } public Properties loadProperties() { - if (cache && cachedLoadedProperties == null) { - cachedLoadedProperties = doLoadProperties(locations); + if (cache) { + if (cachedLoadedProperties == null) { + cachedLoadedProperties = doLoadProperties(null); + } + return cachedLoadedProperties; + } else { + return doLoadProperties(null); } - return cachedLoadedProperties != null ? cachedLoadedProperties : doLoadProperties(locations); } + @Deprecated public Properties loadProperties(String... locations) { if (locations != null) { return doLoadProperties(Arrays.stream(locations).map(PropertiesLocation::new).collect(Collectors.toList())); + } else { + return new OrderedProperties(); } - return new OrderedProperties(); } - protected Properties doLoadProperties(List<PropertiesLocation> paths) { + protected Properties doLoadProperties(List<PropertiesLocation> extraLocations) { Properties prop = new OrderedProperties(); // use initial properties @@ -214,22 +227,11 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. prop.putAll(initialProperties); } - // add 3rd party sources - if (!sources.isEmpty()) { - for (PropertiesSource ps : sources) { - if (ps instanceof LoadablePropertiesSource) { - LoadablePropertiesSource lps = (LoadablePropertiesSource) ps; - Properties p = lps.loadProperties(); - prop.putAll(p); - } - } - } - - // use locations - if (paths != null) { + // use the old way with locations + if (extraLocations != null) { // location may contain JVM system property or OS environment variables // so we need to parse those - List<PropertiesLocation> locations = parseLocations(paths); + List<PropertiesLocation> locations = parseLocations(extraLocations); // check cache first CacheKey key = new CacheKey(locations); @@ -241,6 +243,26 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. } } prop.putAll(locationsProp); + } else { + // else use the new way with property sources + if (!locationSources.isEmpty()) { + for (PropertiesSource ps : locationSources) { + if (ps instanceof LoadablePropertiesSource) { + LoadablePropertiesSource lps = (LoadablePropertiesSource) ps; + Properties p = lps.loadProperties(); + prop.putAll(p); + } + } + } + if (!sources.isEmpty()) { + for (PropertiesSource ps : sources) { + if (ps instanceof LoadablePropertiesSource) { + LoadablePropertiesSource lps = (LoadablePropertiesSource) ps; + Properties p = lps.loadProperties(); + prop.putAll(p); + } + } + } } // use override properties @@ -274,6 +296,9 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. return propertiesParser.parseUri(uri, properties, prefixToken, suffixToken, defaultFallbackEnabled); } + /** + * Gets the configured locations + */ public List<PropertiesLocation> getLocations() { return locations; } @@ -283,7 +308,15 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. * This option will override any default locations and only use the locations from this option. */ public void setLocations(List<PropertiesLocation> locations) { + // reset locations + locations = parseLocations(locations); this.locations = Collections.unmodifiableList(locations); + + // we need to reset them as sources as well + this.locationSources.clear(); + for (PropertiesLocation loc : locations) { + addPropertiesLocationsAsPropertiesSource(loc); + } } /** @@ -355,6 +388,7 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. this.encoding = encoding; } + @Deprecated public PropertiesResolver getPropertiesResolver() { return propertiesResolver; } @@ -362,6 +396,7 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. /** * To use a custom PropertiesResolver */ + @Deprecated public void setPropertiesResolver(PropertiesResolver propertiesResolver) { this.propertiesResolver = propertiesResolver; } @@ -548,12 +583,14 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. * Adds a custom {@link PropertiesSource} */ public void addPropertiesSource(PropertiesSource propertiesSource) { - // prepare properties sources which we must do eager if (propertiesSource instanceof CamelContextAware) { ((CamelContextAware) propertiesSource).setCamelContext(getCamelContext()); } - ServiceHelper.initService(propertiesSource); - sources.add(propertiesSource); + if (propertiesSource instanceof LocationPropertiesSource) { + locationSources.add((LocationPropertiesSource) propertiesSource); + } else { + sources.add(propertiesSource); + } } @Override @@ -586,8 +623,9 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. super.doStart(); // sort the sources + locationSources.sort(OrderedComparator.get()); sources.sort(OrderedComparator.get()); - ServiceHelper.startService(sources); + ServiceHelper.startService(locationSources, sources); if (systemPropertiesMode != SYSTEM_PROPERTIES_MODE_NEVER && systemPropertiesMode != SYSTEM_PROPERTIES_MODE_FALLBACK @@ -610,10 +648,22 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. protected void doStop() throws Exception { cacheMap.clear(); cachedLoadedProperties = null; - ServiceHelper.stopAndShutdownService(sources); + ServiceHelper.stopAndShutdownServices(locationSources, sources); super.doStop(); } + private void addPropertiesLocationsAsPropertiesSource(PropertiesLocation location) { + if ("ref".equals(location.getResolver())) { + addPropertiesSource(new RefPropertiesSource(this, location, ignoreMissingLocation)); + } else if ("file".equals(location.getResolver())) { + addPropertiesSource(new FilePropertiesSource(this, location, ignoreMissingLocation)); + } else if ("classpath".equals(location.getResolver())) { + addPropertiesSource(new ClasspathPropertiesSource(this, location, ignoreMissingLocation)); + } else { + // classpath is also default + addPropertiesSource(new ClasspathPropertiesSource(this, location, ignoreMissingLocation)); + } + } private List<PropertiesLocation> parseLocations(List<PropertiesLocation> locations) { List<PropertiesLocation> answer = new ArrayList<>(); diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesLocation.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesLocation.java index 888438b..9902ebb 100644 --- a/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesLocation.java +++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesLocation.java @@ -18,7 +18,7 @@ package org.apache.camel.component.properties; import org.apache.camel.util.StringHelper; -public class PropertiesLocation { +public final class PropertiesLocation { private final String resolver; private final String path; private final boolean optional; diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/RefPropertiesSource.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/RefPropertiesSource.java new file mode 100644 index 0000000..1c9511a --- /dev/null +++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/RefPropertiesSource.java @@ -0,0 +1,54 @@ +/** + * 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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.properties; + +import java.io.FileNotFoundException; +import java.util.Map; +import java.util.Properties; + +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.util.OrderedProperties; + +public class RefPropertiesSource extends LocationPropertiesSourceSupport { + + public RefPropertiesSource(PropertiesComponent propertiesComponent, PropertiesLocation location, boolean ignoreMissingLocation) { + super(propertiesComponent, location, ignoreMissingLocation); + } + + @Override + public String getName() { + return "RefPropertiesSource[" + getLocation().getPath() + "]"; + } + + protected Properties loadPropertiesFromLocation(PropertiesComponent propertiesComponent, boolean ignoreMissingLocation, PropertiesLocation location) { + String path = location.getPath(); + Properties answer; + try { + answer = propertiesComponent.getCamelContext().getRegistry().lookupByNameAndType(path, Properties.class); + } catch (Exception ex) { + // just look up the Map as a fault back + Map map = propertiesComponent.getCamelContext().getRegistry().lookupByNameAndType(path, Map.class); + answer = new OrderedProperties(); + answer.putAll(map); + } + if (answer == null && (!ignoreMissingLocation && !location.isOptional())) { + throw RuntimeCamelException.wrapRuntimeCamelException(new FileNotFoundException("Properties " + path + " not found in registry")); + } + return answer != null ? answer : new OrderedProperties(); + } + +} diff --git a/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentRestartTest.java b/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentRestartTest.java deleted file mode 100644 index 1f398d5..0000000 --- a/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentRestartTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.component.properties; - -import java.util.List; -import java.util.Properties; - -import org.apache.camel.CamelContext; -import org.apache.camel.ContextTestSupport; -import org.apache.camel.impl.DefaultCamelContext; -import org.junit.Test; - -public class PropertiesComponentRestartTest extends ContextTestSupport { - - private int resolvedCount; - - @Test - public void testPropertiesComponentCacheClearedOnStop() throws Exception { - - context.start(); - - context.resolvePropertyPlaceholders("{{cool.end}}"); - context.resolvePropertyPlaceholders("{{cool.end}}"); - context.resolvePropertyPlaceholders("{{cool.end}}"); - assertEquals(1, resolvedCount); // one cache miss - - context.stop(); - context.start(); - - context.resolvePropertyPlaceholders("{{cool.end}}"); - context.resolvePropertyPlaceholders("{{cool.end}}"); - context.resolvePropertyPlaceholders("{{cool.end}}"); - assertEquals(2, resolvedCount); // one more cache miss -- stop() cleared the cache - } - - @Override - protected CamelContext createCamelContext() throws Exception { - final PropertiesComponent pc = new PropertiesComponent("classpath:org/apache/camel/component/properties/myproperties.properties"); - pc.setPropertiesResolver(new PropertiesResolver() { - public Properties resolveProperties(CamelContext context, boolean ignoreMissingLocation, List<PropertiesLocation> locations) { - resolvedCount++; - return new DefaultPropertiesResolver(pc).resolveProperties(context, ignoreMissingLocation, locations); - } - }); - - // put the properties component into the registry so that it survives restarts - - CamelContext context = new DefaultCamelContext(); - context.getRegistry().bind("properties", pc); - return context; - } - -} diff --git a/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesResolverTest.java b/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesResolverTest.java deleted file mode 100644 index a71db59..0000000 --- a/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesResolverTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.component.properties; - -import java.util.List; -import java.util.Properties; - -import org.apache.camel.CamelContext; -import org.apache.camel.ContextTestSupport; -import org.apache.camel.builder.RouteBuilder; -import org.junit.Test; - -public class PropertiesResolverTest extends ContextTestSupport { - - @Test - public void testPropertiesResolver() throws Exception { - getMockEndpoint("mock:result").expectedMessageCount(1); - - template.sendBody("direct:start", "Hello World"); - - assertMockEndpointsSatisfied(); - } - - @Override - protected RouteBuilder createRouteBuilder() throws Exception { - return new RouteBuilder() { - @Override - public void configure() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start").to("properties:foo"); - } - }); - } - }; - } - - protected CamelContext createCamelContext() throws Exception { - CamelContext context = super.createCamelContext(); - - PropertiesComponent pc = new PropertiesComponent(); - pc.setLocation("foo"); - pc.setPropertiesResolver(new MyCustomResolver()); - context.addComponent("properties", pc); - - return context; - } - - public static class MyCustomResolver implements PropertiesResolver { - - public Properties resolveProperties(CamelContext context, boolean ignoreMissingLocation, List<PropertiesLocation> locations) { - Properties answer = new Properties(); - answer.put("foo", "mock:result"); - return answer; - } - } - -} \ No newline at end of file diff --git a/core/camel-core/src/test/java/org/apache/camel/issues/PropertiesAvailableEverywhereTest.java b/core/camel-core/src/test/java/org/apache/camel/issues/PropertiesAvailableEverywhereTest.java index 8840784..7413799 100644 --- a/core/camel-core/src/test/java/org/apache/camel/issues/PropertiesAvailableEverywhereTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/issues/PropertiesAvailableEverywhereTest.java @@ -16,15 +16,12 @@ */ package org.apache.camel.issues; -import java.util.List; import java.util.Properties; import org.apache.camel.CamelContext; import org.apache.camel.ContextTestSupport; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.properties.PropertiesComponent; -import org.apache.camel.component.properties.PropertiesLocation; -import org.apache.camel.component.properties.PropertiesResolver; import org.junit.Test; public class PropertiesAvailableEverywhereTest extends ContextTestSupport { @@ -35,14 +32,11 @@ public class PropertiesAvailableEverywhereTest extends ContextTestSupport { final Properties properties = new Properties(); properties.put("foo", "bar"); + + camelContext.getRegistry().bind("myProp", properties); + PropertiesComponent pc = camelContext.getComponent("properties", PropertiesComponent.class); - pc.setLocations(new String[0]); - pc.setPropertiesResolver(new PropertiesResolver() { - @Override - public Properties resolveProperties(CamelContext context, boolean ignoreMissingLocation, List<PropertiesLocation> locations) { - return properties; - } - }); + pc.addLocation("ref:myProp"); return camelContext; } diff --git a/platforms/spring-boot/components-starter/camel-properties-starter/src/main/java/org/apache/camel/component/properties/springboot/PropertiesComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-properties-starter/src/main/java/org/apache/camel/component/properties/springboot/PropertiesComponentConfiguration.java index 3d81f6c..7bda5fc 100644 --- a/platforms/spring-boot/components-starter/camel-properties-starter/src/main/java/org/apache/camel/component/properties/springboot/PropertiesComponentConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-properties-starter/src/main/java/org/apache/camel/component/properties/springboot/PropertiesComponentConfiguration.java @@ -21,6 +21,7 @@ import javax.annotation.Generated; import org.apache.camel.component.properties.PropertiesLocation; import org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; /** * The properties component is used for using property placeholders in endpoint @@ -61,6 +62,7 @@ public class PropertiesComponentConfiguration * To use a custom PropertiesResolver. The option is a * org.apache.camel.component.properties.PropertiesResolver type. */ + @Deprecated private String propertiesResolver; /** * To use a custom PropertiesParser. The option is a @@ -151,10 +153,13 @@ public class PropertiesComponentConfiguration this.encoding = encoding; } + @Deprecated + @DeprecatedConfigurationProperty public String getPropertiesResolver() { return propertiesResolver; } + @Deprecated public void setPropertiesResolver(String propertiesResolver) { this.propertiesResolver = propertiesResolver; }