Integrating Mule application build with Jenkins

Just ran across this bit of information for integrating Mule application builds with Jenkins as part of a continuous integration.  The reference is from the Mulesoft Knowledge Center. Note that the variables (ie: ${var_name} are all standard Jenkins values.  Here is what the knowledge center post says:

When leveraging continuous integration, we might want to publish the newly built applications to MMC so they can get easily deployed.
This can be done using the MMC REST API. Jenkins as well provides a useful set of information that can be leveraged to achieve this goal.

Configuration Steps:

 

1) Configure a new Maven process with your source code repository and adapt it to your preferences.

2) Add a new command line ‘Post Step’ that runs only upon successful builds, the contents of the post-step would be the following:
 
curl –basic -u admin:admin -F file=@${WORKSPACE}/target/${POM_ARTIFACTID}-${POM_VERSION}.zip -F name=${POM_ARTIFACTID} -F version=1.0 –header ‘Content-Type: multipart/form-data’ http://localhost:8080/mmc/api/repository
This way the resulting application will be published to the MMC repository and it will be ready for you to create a deployment. Please note that you would need to adapt the MMC URL to match your infrastructure.
For more information about the options you have, please visit the MMC REST API documentation page:
Advertisements

Memcached Component for Mule

This code snippet can be used for Mule application workflows that require the ability to place a serializable object into a memcached or pull a serialized object from memcached.  The component is implemented as an Anypoint custom transformer that uses the payload as the source of the put and the target of the get operations.

Usage

The following xml is an Anypoint application with a workflow that performs a get and a second workflow that performs a put.  Both use an Http inbound endpoint to trigger the memcached operation.  Note that the transformer uses a spring bean to configure an xmemcached client builder (the factory).  Transformer properties are used to define the operation to be performed (put or get), the key value to use in the memcached and memcachedClientBuilder references the xmemcached client builder defined in the spring bean.  For the put operation, the expire property defines the number of seconds to hold the cache entry before it is evicted from memcached.

Sample Anypoint Application XML

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:http="http://www.mulesoft.org/schema/mule/http"
	xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns="http://www.mulesoft.org/schema/mule/core"
	xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
	xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.5.1"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd">
	<spring:beans>
		<spring:bean id="memcachedClientBuilder" scope="prototype"
			name="memcachedClientBuilder" class="net.rubyeye.xmemcached.XMemcachedClientBuilder">
			<!-- list of memcached server ports. -->
			<spring:constructor-arg value="192.168.191.129:11211" />
			<spring:property name="connectionPoolSize" value="5"></spring:property>
			<spring:property name="commandFactory">
				<spring:bean class="net.rubyeye.xmemcached.command.BinaryCommandFactory"></spring:bean>
			</spring:property>
			<spring:property name="sessionLocator">
				<spring:bean
					class="net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator"></spring:bean>
			</spring:property>
			<spring:property name="transcoder">
				<spring:bean
					class="net.rubyeye.xmemcached.transcoders.SerializingTranscoder" />
			</spring:property>
		</spring:bean>
	</spring:beans>

	<flow name="putFlow" doc:name="putFlow">
		<http:inbound-endpoint exchange-pattern="request-response"
			host="localhost" port="8081" path="put" doc:name="HTTP"/>
        <object-to-string-transformer doc:name="Object to String"/>
		<logger message="#[payload]" level="INFO" doc:name="Logger" />
		<custom-transformer class="org.pdd.memcached.MemcachedTransformer"
			doc:name="Java">
			<spring:property name="operation" value="put" />
			<spring:property name="key" value="abc" />
            <spring:property name="memcachedClientBuilder" ref="memcachedClientBuilder"/>
            <spring:property name="expire" value="30"/>
		</custom-transformer>
	</flow>

	<flow name="getFlow" doc:name="getFlow">
		<http:inbound-endpoint exchange-pattern="request-response"
			host="localhost" port="8082" path="get" doc:name="HTTP" />
		<logger message="#[payload]" level="INFO" doc:name="Logger" />
		<custom-transformer class="org.pdd.memcached.MemcachedTransformer"
			doc:name="Java">
			<spring:property name="operation" value="get" />
			<spring:property name="key" value="abc" />
            <spring:property name="memcachedClientBuilder" ref="memcachedClientBuilder"/>
		</custom-transformer>
	</flow>
</mule>

Cut and paste the Java code below into the Anypoint (or Mule) studio as a new Java class file (in the src directory).

Code


package org.pdd.memcached;

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;

import org.apache.log4j.Logger;
import org.mule.api.MuleEvent;
import org.mule.api.MuleException;
import org.mule.api.MuleMessage;
import org.mule.api.interceptor.Interceptor;
import org.mule.api.transformer.TransformerException;
import org.mule.config.i18n.MessageFactory;
import org.mule.processor.AbstractInterceptingMessageProcessor;
import org.mule.transformer.AbstractMessageTransformer;
import org.mule.transformer.AbstractTransformer;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 
 * Get or put a payload using memcached entry referenced by a key value. This
 * requires setting up a Spring Bean in the flow to define the memcached client
 * builder. 
    
		
                
                
                
                
                        
                
                
                        
                
                
                        
                
        
    
 * 
 * 
 * Then configure a custom java transformer in the flow. For instance: 
 		
			
			
            
		
* 
 * 
 * @author peterdunworth
 * 
 */
public class MemcachedTransformer extends AbstractMessageTransformer {

	public static Logger log = Logger.getLogger(MemcachedTransformer.class);

	private static String operator_msg = "operation property must be specified as either get or put";

	private MemcachedClientBuilder memcachedClientBuilder = null;
	// get or put
	private String operation = "get";
	private String key = null;
	private String resultClass = null;
	private String expire = null;
	private int ttl = 54000; // seconds=15min

	public MemcachedClientBuilder getMemcachedClientBuilder() {
		return memcachedClientBuilder;
	}

	public void setMemcachedClientBuilder(
			MemcachedClientBuilder memcachedClientBuilder) {
		this.memcachedClientBuilder = memcachedClientBuilder;
	}

	public String getOperation() {
		return operation;
	}

	public void setOperation(String operation) {
		this.operation = operation.trim().toLowerCase();
	}

	public String getResultClass() {
		return resultClass;
	}

	public void setResultClass(String resultClass) {
		this.resultClass = resultClass;
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key.trim();
	}

	public String getExpire() {
		expire = Integer.toString(ttl);
		return expire;
	}

	public void setExpire(String expire) {
		this.ttl = Integer.parseInt(expire);
		this.expire = expire;
	}

	public int getTtl() {
		return ttl;
	}

	public void setTtl(int ttl) {
		this.ttl = ttl;
	}

	@Override
	public Object transformMessage(MuleMessage message, String encoding)
			throws TransformerException {

		if (memcachedClientBuilder == null) {
			throw new TransformerException(
					MessageFactory
							.createStaticMessage("Missing Spring bean memcachedClientBuilder"));
		}
		if (operation == null || operation.isEmpty()) {
			throw new TransformerException(
					MessageFactory.createStaticMessage(operator_msg));
		}
		if (key == null || key.isEmpty()) {
			throw new TransformerException(
					MessageFactory
							.createStaticMessage("key property must be the cache key value"));
		}
		try {
			MemcachedClient memcachedClient = memcachedClientBuilder.build();

			if (operation.equals("get")) {
				return memcachedClient.get(key);
			} else if (operation.equals("put")) {
				memcachedClient.set(key, ttl, message.getPayload());
				return message.getPayload();
			} else {
				throw new TransformerException(
						MessageFactory.createStaticMessage(operator_msg));
			}
		} catch (TransformerException e) {
			throw e;
		} catch (Exception e) {
			e.printStackTrace();
			throw new TransformerException(
					MessageFactory.createStaticMessage("transformMessage caught Exception: "
							+ e.toString()), e);
		}
	}
}

Eclipse Maven Dependencies

If this code is built in Eclipse instead of Anypoint (Mule) Studio, the following maven dependencies are required. Once built, the jar file can be dropped into the lib folder of the Mule project directory (and the jar file added to the build path).

<project xmlns=”http://maven.apache.org/POM/4.0.0&#8243; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”&gt;
<modelVersion>4.0.0</modelVersion>
<groupId>org.pdd.memcached</groupId>
<artifactId>memcached-transformer</artifactId>
<version>0.0.1</version>
<name>memcached transformer</name><properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><mule.version>3.5.0</mule.version>
<eclipsePluginVersion>2.8</eclipsePluginVersion>
<jdkName>JavaSE-1.7</jdkName>
<jdk.version>1.7</jdk.version>
<junit.version>4.9</junit.version>
</properties><build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<encoding>ISO-8859-1</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>project</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
<version>2.0.0</version>
</dependency>

<dependency>
<groupId>org.mule</groupId>
<artifactId>mule-core</artifactId>
<version>${mule.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mulesoft.muleesb.modules</groupId>
<artifactId>mule-module-boot-ee</artifactId>
<version>${mule.version}</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.mule.modules</groupId>
<artifactId>mule-module-spring-config</artifactId>
<version>${mule.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.cloveretl</groupId>
<artifactId>cloveretl-engine</artifactId>
<version>${mule.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<repositories>
<repository>
<id>Central</id>
<name>Central</name>
<url>http://repo1.maven.org/maven2/</url&gt;
<layout>default</layout>
</repository>
<repository>
<id>mulesoft-releases</id>
<name>MuleSoft Releases Repository</name>
<url>http://repository.mulesoft.org/releases/</url&gt;
<layout>default</layout>
</repository>
<repository>
<id>mulesoft-snapshots</id>
<name>MuleSoft Snapshots Repository</name>
<url>http://repository.mulesoft.org/snapshots/</url&gt;
<layout>default</layout>
</repository>
</repositories>
</project>