diff --git a/modules/commons/src/main/java/org/apache/synapse/commons/property/PropertyHolder.java b/modules/commons/src/main/java/org/apache/synapse/commons/property/PropertyHolder.java new file mode 100644 index 0000000000..8d2ddcbf97 --- /dev/null +++ b/modules/commons/src/main/java/org/apache/synapse/commons/property/PropertyHolder.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. 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.synapse.commons.property; + +import java.util.concurrent.ConcurrentHashMap; + +/** + * Property Holder is the class used to store the properties in the map + */ +public class PropertyHolder { + + private ConcurrentHashMap properties; + + private static class PropertyLoaderHelper { + private static final PropertyHolder INSTANCE = new PropertyHolder(); + } + + private PropertyHolder() {} + + public static PropertyHolder getInstance() { + return PropertyLoaderHelper.INSTANCE; + } + + public void setProperty(String key, String value) { + getProperties().put(key, value); + } + + public String getPropertyValue(String key) { + return getProperties().get(key); + } + + public Boolean hasKey(String key) { + return getProperties().containsKey(key); + } + + public ConcurrentHashMap getProperties() { + if (properties == null) { + this.properties = new ConcurrentHashMap<>(); + } + return this.properties; + } +} diff --git a/modules/commons/src/main/java/org/apache/synapse/commons/resolvers/ConfigResolver.java b/modules/commons/src/main/java/org/apache/synapse/commons/resolvers/ConfigResolver.java new file mode 100644 index 0000000000..f1d8f9531a --- /dev/null +++ b/modules/commons/src/main/java/org/apache/synapse/commons/resolvers/ConfigResolver.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. 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.synapse.commons.resolvers; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.synapse.commons.property.PropertyHolder; + +/** + * Config Resolver can be used to resolve configurable property variables in the synapse config. + */ +public class ConfigResolver implements Resolver { + + private static final Log LOG = LogFactory.getLog(FilePropertyResolver.class); + + private String input; + + @Override + public void setVariable(String input) { + this.input = input; + } + + @Override + public String resolve() { + String propertyValue = PropertyHolder.getInstance().getPropertyValue(this.input); + if (propertyValue == null) { + throw new ResolverException("Parameter key: " + input + " could not be found"); + } + if (LOG.isDebugEnabled()) { + LOG.debug("Resolving parameter key: "+ input + " value: " + propertyValue); + } + return propertyValue; + } +} diff --git a/modules/commons/src/main/java/org/apache/synapse/commons/resolvers/ResolverFactory.java b/modules/commons/src/main/java/org/apache/synapse/commons/resolvers/ResolverFactory.java index 3577c0227c..227593047d 100644 --- a/modules/commons/src/main/java/org/apache/synapse/commons/resolvers/ResolverFactory.java +++ b/modules/commons/src/main/java/org/apache/synapse/commons/resolvers/ResolverFactory.java @@ -30,13 +30,14 @@ public class ResolverFactory { private static final Log LOG = LogFactory.getLog(ResolverFactory.class); private static final int RESOLVER_INDEX = 2; - private static ResolverFactory resolverFactory = new ResolverFactory(); + private static final ResolverFactory resolverFactory = new ResolverFactory(); private final Pattern rePattern = Pattern.compile("(\\$)([_a-zA-Z0-9]+):([_a-zA-Z0-9]+)"); private static final String SYSTEM_VARIABLE_PREFIX = "$SYSTEM"; private static final String FILE_PROPERTY_VARIABLE_PREFIX = "$FILE"; private static final String CUSTOM_PROPERTY_VARIABLE_PREFIX = "$CUSTOM_"; + private static final String CONFIGURABLE_VARIABLE_PREFIX = "$config:"; - private Map> resolverMap = new HashMap<>(); + private final Map> resolverMap = new HashMap<>(); /** * This function return an object of Resolver factory @@ -61,58 +62,25 @@ public Resolver getResolver(String input) { if (input == null) { return null; } - - if (input.startsWith(SYSTEM_VARIABLE_PREFIX)) { - Matcher matcher = rePattern.matcher(input); - Resolver resolverObject = null; + Matcher matcher = rePattern.matcher(input); + if (input.startsWith(CONFIGURABLE_VARIABLE_PREFIX)) { if (matcher.find()) { - Class resolverClass = resolverMap.get(matcher.group(RESOLVER_INDEX).toLowerCase()); - if (resolverClass != null) { - try { - resolverObject = resolverClass.newInstance(); - resolverObject.setVariable(matcher.group(3)); - return resolverObject; - } catch (IllegalAccessException | InstantiationException e) { - throw new ResolverException("Resolver could not be found"); - } - } else { - throw new ResolverException("Resolver could not be found"); - } + return getResolver(matcher.group(RESOLVER_INDEX).toLowerCase(), matcher); } - } else if(input.startsWith(FILE_PROPERTY_VARIABLE_PREFIX)){ - Matcher matcher = rePattern.matcher(input); - Resolver resolverObject = null; - if (matcher.find()){ - Class resolverClass = resolverMap.get(matcher.group(RESOLVER_INDEX).toLowerCase()); - if (resolverClass != null) { - try { - resolverObject = resolverClass.newInstance(); - resolverObject.setVariable(matcher.group(3)); - return resolverObject; - } catch (IllegalAccessException | InstantiationException e) { - throw new ResolverException("Resolver could not be initialized", e); - } - } else { - throw new ResolverException("Resolver could not be found"); - } + } else if (input.startsWith(SYSTEM_VARIABLE_PREFIX)) { + if (matcher.find()) { + return getResolver(matcher.group(RESOLVER_INDEX).toLowerCase(), matcher); + } + } else if(input.startsWith(FILE_PROPERTY_VARIABLE_PREFIX)) { + if (matcher.find()) { + return getResolver(matcher.group(RESOLVER_INDEX).toLowerCase(), matcher); } } else if(input.startsWith(CUSTOM_PROPERTY_VARIABLE_PREFIX)) { - Matcher matcher = rePattern.matcher(input); - Resolver resolverObject = null; if (matcher.find()){ String nameWithPlaceholder = matcher.group(RESOLVER_INDEX).toLowerCase(); String className = nameWithPlaceholder.substring(CUSTOM_PROPERTY_VARIABLE_PREFIX.length() - 1); - Class resolverClass = resolverMap.get(className); - if (resolverClass != null) { - try { - resolverObject = resolverClass.newInstance(); - resolverObject.setVariable(matcher.group(3)); - return resolverObject; - } catch (IllegalAccessException | InstantiationException e) { - throw new ResolverException("Resolver could not be initialized", e); - } - } else { - throw new ResolverException("Resolver could not be found"); + if (matcher.find()) { + return getResolver(className, matcher); } } } @@ -126,6 +94,7 @@ public Resolver getResolver(String input) { private void registerResolvers() { resolverMap.put("system", SystemResolver.class); resolverMap.put("file", FilePropertyResolver.class); + resolverMap.put("config", ConfigResolver.class); } private void registerExterns() { @@ -147,4 +116,19 @@ private void registerExterns() { } } } + + private Resolver getResolver(String className, Matcher matcher) { + Class resolverClass = resolverMap.get(className); + if (resolverClass != null) { + try { + Resolver resolverObject = resolverClass.newInstance(); + resolverObject.setVariable(matcher.group(3)); + return resolverObject; + } catch (IllegalAccessException | InstantiationException e) { + throw new ResolverException("Resolver could not be initialized", e); + } + } else { + throw new ResolverException("Resolver could not be found"); + } + } } diff --git a/modules/commons/src/main/java/org/apache/synapse/commons/util/FilePropertyLoader.java b/modules/commons/src/main/java/org/apache/synapse/commons/util/FilePropertyLoader.java index 26117b8e67..be8f72cacc 100644 --- a/modules/commons/src/main/java/org/apache/synapse/commons/util/FilePropertyLoader.java +++ b/modules/commons/src/main/java/org/apache/synapse/commons/util/FilePropertyLoader.java @@ -22,9 +22,10 @@ import org.apache.synapse.commons.SynapseCommonsException; import java.io.File; -import java.io.FileInputStream; import java.io.InputStream; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -101,7 +102,7 @@ private void loadPropertiesFile() throws SynapseCommonsException { File file = new File(propertiesFilePath); if (file.exists()) { if (file.lastModified() > lastModifiedTimestamp) { - try (InputStream in = new FileInputStream(propertiesFilePath)) { + try (InputStream in = Files.newInputStream(Paths.get(propertiesFilePath))) { Properties rawProps = new Properties(); Map tempPropertyMap = new HashMap<>(); rawProps.load(in); diff --git a/modules/core/src/main/java/org/apache/synapse/mediators/builtin/PropertyMediator.java b/modules/core/src/main/java/org/apache/synapse/mediators/builtin/PropertyMediator.java index 8f217ac438..6ea7609893 100644 --- a/modules/core/src/main/java/org/apache/synapse/mediators/builtin/PropertyMediator.java +++ b/modules/core/src/main/java/org/apache/synapse/mediators/builtin/PropertyMediator.java @@ -211,7 +211,7 @@ public int compare(String o1, String o2) { org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS, headersMap); } - }else if(XMLConfigConstants.SCOPE_OPERATION.equals(scope) + } else if(XMLConfigConstants.SCOPE_OPERATION.equals(scope) && synCtx instanceof Axis2MessageContext){ //Setting Transport Headers Axis2MessageContext axis2smc = (Axis2MessageContext) synCtx; @@ -504,7 +504,7 @@ private String getMatchedValue(String value, SynapseLog synLog) { matchedValue = matcher.group(group); } else { if (synLog.isTraceOrDebugEnabled()) { - String msg = "Failed to get a match for regx : " + + String msg = "Failed to get a match for regex : " + pattern.toString() + " with the property value :" + value + " for group :" + group; synLog.traceOrDebug(msg); @@ -515,7 +515,7 @@ private String getMatchedValue(String value, SynapseLog synLog) { } else { if (synLog.isTraceOrDebugEnabled()) { - String msg = "Unable to find a match for regx : " + + String msg = "Unable to find a match for regex : " + pattern.toString() + " with the property value :" + value; synLog.traceOrDebug(msg); } diff --git a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/HeadersAndPropertiesAccessNode.java b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/HeadersAndPropertiesAccessNode.java index 31af957dfc..d8640bd0c2 100644 --- a/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/HeadersAndPropertiesAccessNode.java +++ b/modules/core/src/main/java/org/apache/synapse/util/synapse/expression/ast/HeadersAndPropertiesAccessNode.java @@ -19,6 +19,8 @@ package org.apache.synapse.util.synapse.expression.ast; import org.apache.synapse.SynapseConstants; +import org.apache.synapse.commons.property.PropertyHolder; +import org.apache.synapse.commons.resolvers.ResolverException; import org.apache.synapse.util.synapse.expression.context.EvaluationContext; import org.apache.synapse.util.synapse.expression.exception.EvaluationException; @@ -60,6 +62,12 @@ public ExpressionResult evaluate(EvaluationContext context) { Object value; if (Type.HEADER.equals(type)) { value = context.getHeader(name); + } else if (Type.CONFIG.equals(type)) { + try { + value = PropertyHolder.getInstance().getPropertyValue(name); + } catch (ResolverException e) { + throw new EvaluationException("The value of the key:[" + name + "] is null"); + } } else { if (SynapseConstants.URI_PARAM.equals(scope)) { value = context.getProperty("uri.var." + name, SynapseConstants.SYNAPSE); diff --git a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/config/ClientConnFactoryBuilder.java b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/config/ClientConnFactoryBuilder.java index a3564baaa1..66fde8487c 100644 --- a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/config/ClientConnFactoryBuilder.java +++ b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/config/ClientConnFactoryBuilder.java @@ -370,7 +370,9 @@ private SSLContext createSSLContext(OMElement keyStoreElt, OMElement trustStoreE if (log.isDebugEnabled()) { log.debug(name + " Loading Trust Keystore from : " + location); } - + SslSenderTrustStoreHolder.getInstance().setLocation(location); + SslSenderTrustStoreHolder.getInstance().setPassword(passwordElement.getText()); + SslSenderTrustStoreHolder.getInstance().setType(type); trustStore.load(fis, storePassword.toCharArray()); TrustManagerFactory trustManagerfactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm()); diff --git a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/config/SslSenderTrustStoreHolder.java b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/config/SslSenderTrustStoreHolder.java new file mode 100644 index 0000000000..ae1a4dcb6d --- /dev/null +++ b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/config/SslSenderTrustStoreHolder.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. 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.synapse.transport.nhttp.config; + +/** + * The SSL Sender TrustStore Holder class to store the client trust store's configurable details. + */ +public class SslSenderTrustStoreHolder { + + private static volatile SslSenderTrustStoreHolder instance; + + private SslSenderTrustStoreHolder() {} + + private String location; + private String password; + private String type; + + public static SslSenderTrustStoreHolder getInstance() { + + if (instance == null) { + synchronized (TrustStoreHolder.class) { + if (instance == null) { + instance = new SslSenderTrustStoreHolder(); + } + } + } + return instance; + } + + public void setLocation(String location) { + this.location = location; + } + + public String getLocation() { + return this.location; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPassword() { + return this.password; + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return this.type; + } +}