DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • How To Build Web Service Using Spring Boot 2.x
  • Visually Designing Views for Java Web Apps
  • How to Activate New User Accounts by Email
  • How To Read the Properties File Outside the Jar in Spring Boot

Trending

  • Build an MCP Server Using Go to Connect AI Agents With Databases
  • Segmentation Violation and How Rust Helps Overcome It
  • Optimize Deployment Pipelines for Speed, Security and Seamless Automation
  • How to Configure and Customize the Go SDK for Azure Cosmos DB
  1. DZone
  2. Coding
  3. Frameworks
  4. Externalising Mule 3.x Properties

Externalising Mule 3.x Properties

See a tutorial that explains how to load properties from an external source by overriding the Spring PropertyPlaceholderConfigurer class.

By 
Josh Rai user avatar
Josh Rai
·
Mar. 25, 19 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
8.8K Views

Join the DZone community and get the full member experience.

Join For Free

Properties always make life easier. When it comes to Mule, there is a sweet and simple set of functionality to load properties based on the environment. Usually, a property file is used in the environment where the application is getting deployed, however, this involves creating multiple property files, one for each environment e.g. Dev, QA, SIT, Prod, etc. A detailed reference to this approach can be found here.

Image title

Although this approach is straightforward to implement, it presents an issue in that all the configuration properties are embedded in the code. Anyone who has access to the code can access all your production systems, which is a situation you never really want to get in to. In most organizations, the IT team will never give away production credentials for systems.

CI/CD best practices recommend having a single deployable artifact that can run in all environments (dev – prod) by using different properties. To implement something like this, properties will have to be fetched from an external source system like a simple file server, SFTP, Database, or an API. This is exactly what we will be describing further in this post.

Image title

What to Do?

We need to load properties from an external source (SFTP in this example) by overriding the Spring PropertyPlaceholderConfigurer class. Loading of properties will be done in the same way as Mule or Spring loads properties, with a bit of customization.

How to Do It?

There are three areas we will have to cover to get this working:

  • Adding dependencies in POM.xml
  • Writing a custom Java class for loading properties.
  • Creating a bean to trigger java class in the mule configuration XML file

Adding Dependencies in POM.xml

To override Spring context properties, we will need to load them first. These three dependencies are needed for Spring, SFTP, and logging.

<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.55</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.5</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.9.RELEASE</version>
</dependency>

Writing a Custom Java Class for Loading Properties

Create a class called ExternalProperties in src/main/java with the following code. This class reads a property file from an SFTP server but can be modified to pull properties from an API or database as well. This class should also contain the decryption logic for all properties if properties are encrypted at the source.

package com.integralzone.mule.properties;

import java.io.IOException;
import java.io.StringReader;
import java.util.Properties;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

import org.apache.log4j.Logger;

/**
 * @author Vibhanshu Thakur
 * Extending PropertyPlaceholderConfigurer which is Spring's way 
 * of loading properties into application.
 *
 */
public class ExternalProperties extends PropertyPlaceholderConfigurer {
//for logging
public static final Logger LOGGER = Logger.getLogger(ExternalProperties.class);

/* (non-Javadoc)
 * @see org.springframework.beans.factory.config.PropertyResourceConfigurer#convertProperties(java.util.Properties)
 * This functions gets automatically triggered on creation of a bean of this class.
 * Parameter props is not be passed at any point, function will self trigger.
 */
protected void convertProperties(Properties props) {
LOGGER.info("properties loading process started");

try {
//loading properties from SFTP file into a StringReader(expected type for load())
StringReader interimReaderProperties = new StringReader(ExternalProperties.readSFTP());
//loading properties into application - thats how easy it is
props.load(interimReaderProperties);
} catch (IOException e1) {
e1.printStackTrace();
}

LOGGER.info("Properties loaded successfully");
}


/**
     * Function to read asked file from SFTP
 * @return String containing the entire file picked up from SFTP
 * @throws IOException
 */
private static String readSFTP() throws IOException {
        JSch jsch = new JSch();
        Session session = null;
        try {
        //sftp credentials and details
            session = jsch.getSession("user", "127.0.0.1", 22);
            session.setConfig("StrictHostKeyChecking", "no");
            session.setPassword("password");
            session.connect();

            Channel channel = session.openChannel("sftp");
            channel.connect();
            ChannelSftp sftpChannel = (ChannelSftp) channel;
            // file to be picked up
            InputStream stream = sftpChannel.get("config.properties");
            String finalFile = "";
            try {
            //reading file
                BufferedReader br = new BufferedReader(new InputStreamReader(stream));
                String line;
                while ((line = br.readLine()) != null) {
                //storing content of file to string for consolidating
                finalFile+=line + "\n";
                }
            } catch (IOException io) {
                System.out.println("Exception occurred during reading file from SFTP server due to " + io.getMessage());
                io.getMessage();

            } catch (Exception e) {
                System.out.println("Exception occurred during reading file from SFTP server due to " + e.getMessage());
                e.getMessage();

            }
            sftpChannel.exit();
            session.disconnect();
            return finalFile;
        } catch (JSchException e) {
            e.printStackTrace();
            return null;
        } catch (SftpException e) {
            e.printStackTrace();
            return null;
        }
    }
}

Creating a Bean to Trigger the Java Class in the Mule Configuration XML File

Now the only step remaining is to use the code that we have written so far. For this, a
bean should be created in any one of the mule configuration xml files in your application.

Make sure you remove any <context:property-placeholder> or <secure-property-placeholder:config> tags from all your XMLs. Since we override the Spring property loader, these tags will not work and will fail the deployment of your application. We will also see in the bean definition how to load properties from a local/accessible file system (doing what context:property-placeholder does) so that the basic property loading functionality is not missed.

<spring:beans>
<spring:bean id="propertyLoader" class="com.integralzone.mule.properties.ExternalProperties">
<spring:property name="locations">
<spring:list>
<spring:value>common.properties</spring:value>
<spring:value>error_codes.properties</spring:value>
<spring:value>logger_config.properties</spring:value>
</spring:list>
</spring:property>
</spring:bean>
</spring:beans>

The Spring bean created in the above code will automatically trigger our function to load properties from the SFTP location. Your code is now ready to read property files from external SFTP location.

If there is a requirement to load other property files present in src/main/resources or other local file directories, then a property of the type list called “locations” should be passed while creating the propertyLoader bean. The value of this list should contain all the property file names in the required sequence to load these files like common, error_code and logger_config property in the above example. No additional code/setup is required to load these common properties.

Let us know if this was helpful.

Property (programming) File system Spring Framework

Published at DZone with permission of Josh Rai. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • How To Build Web Service Using Spring Boot 2.x
  • Visually Designing Views for Java Web Apps
  • How to Activate New User Accounts by Email
  • How To Read the Properties File Outside the Jar in Spring Boot

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!