Setup Custom Domain on Heroku from GoDaddy

Add new custom domain to Heroku

heroku domains:add www.example.com
heroku domains:add example.com

Add both with www. and no www. domain names.

It will look like the following
Screen Shot 2014-04-23 at 5.54.34 PM

Login to Godaddy and add/edit host:www to your heroku app, it will looks like follows:
Screen Shot 2014-04-23 at 5.50.46 PM

Add a forwarding rule to that http://example.com will be directed to http://www.example.com
Screen Shot 2014-04-23 at 5.50.21 PM

New-Relic Add-on for Java Application on Heroku Setup

Add New Relic Agent Dependency

 <dependency>
  	<groupId>com.newrelic.agent.java</groupId>
  	<artifactId>newrelic-agent</artifactId>
  	<version>3.5.1</version>
  	<scope>provided</scope>
</dependency>

pom.xml build tag

  <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
                <version>2.3.2</version>
            </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.2</version>
            </plugin>
            
            <plugin>
				<groupId>com.mysema.maven</groupId>
				<artifactId>apt-maven-plugin</artifactId>
				<version>1.0.8</version>
				<dependencies>
					<dependency>
						<groupId>com.mysema.querydsl</groupId>
						<artifactId>querydsl-apt</artifactId>
						<version>2.9.0</version>
					</dependency>
				</dependencies>
				<executions>
					<execution>
						<phase>generate-sources</phase>
						<goals>
							<goal>process</goal>
						</goals>
						<configuration>
							<outputDirectory>target/generated-sources</outputDirectory>
							<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
						</configuration>
					</execution>
				</executions>
			</plugin>
            
            
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                           <goal>copy</goal>
                        </goals>
                         
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>com.github.jsimone</groupId>
                                    <artifactId>webapp-runner</artifactId>
                                    <version>7.0.22.3</version>
                                    <destFileName>webapp-runner.jar</destFileName>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                   <execution>
         				 <id>copy-new-relic</id>
          					<phase>package</phase>
         				<goals>
          					 <goal>copy-dependencies</goal>
         				 </goals>
         				 <configuration>
           					 <includeGroupIds>com.newrelic.agent.java</includeGroupIds>
           					 <includeArtifactIds>newrelic-agent</includeArtifactIds>
           					 <stripVersion>true</stripVersion>
          					</configuration>
        			</execution>
                </executions>
            </plugin>
        </plugins>
        <pluginManagement>
	<plugins>
    <!-- Ignore/Execute plugin execution -->
    <plugin>
        <groupId>org.eclipse.m2e</groupId>
        <artifactId>lifecycle-mapping</artifactId>
        <version>1.0.0</version>
        <configuration>
            <lifecycleMappingMetadata>
                <pluginExecutions>
                    <!-- copy-dependency plugin -->
                    <pluginExecution>
                        <pluginExecutionFilter>
                            <groupId>org.apache.maven.plugins</groupId>
                            <artifactId>maven-dependency-plugin</artifactId>
                            <versionRange>[1.0.0,)</versionRange>
                            <goals>
                                <goal>copy-dependencies</goal>
                            </goals>
                        </pluginExecutionFilter>
                        <action>
                            <ignore />
                        </action>
                    </pluginExecution>
                </pluginExecutions>
            </lifecycleMappingMetadata>
        </configuration>
    </plugin>
   </plugins></pluginManagement>
        
    </build>
    <name>CloudSole Developer</name>
    <description>CloudSole Developer</description>
    <organization>
    	<name>Thys Michels</name>
    	<url>http://www.thysmichels.com</url>
    </organization>

Create newrelic.yml and save to project route (same level as pom.xml)

.....
license_key: 'OURLICENCEKEYHERE'
....
app_name: CloudSole
....

Add the following flag to your JAVA_OPTS config var on Heroku:

heroku config:set JAVA_OPTS='-Xmx384m -Xss512k -XX:+UseCompressedOops -javaagent:target/dependency/newrelic-agent.jar' NEW_RELIC_APP_NAME="CloudSole"

Setup Memcached on Heroku

Add memcachedcloud to your project:
heroku addons:add memcachedcloud

1. Setup Memcached Configuration
2. Setup Memcached Service

1. Setup Memcached Configuration

package com.example.cache;

import java.io.IOException;

import net.spy.memcached.AddrUtil;
import net.spy.memcached.ConnectionFactoryBuilder;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.auth.AuthDescriptor;
import net.spy.memcached.auth.PlainCallbackHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CacheConfiguration {
	
	@Bean
	public MemcachedClient memcachedCloudConfiguration() {
		try {
		    AuthDescriptor ad = new AuthDescriptor(new String[] { "PLAIN" },
		        new PlainCallbackHandler(System.getenv("MEMCACHEDCLOUD_USERNAME"), System.getenv("MEMCACHEDCLOUD_PASSWORD")));

		    MemcachedClient mc = new MemcachedClient(
		              new ConnectionFactoryBuilder()
		                  .setProtocol(ConnectionFactoryBuilder.Protocol.BINARY)
		                  .setAuthDescriptor(ad).build(),
		          AddrUtil.getAddresses(System.getenv("MEMCACHEDCLOUD_SERVERS")));
		    return mc;
		} catch (IOException ex) {
		    // the Memcached client could not be initialized.
		}
		return null;
	}
}

2. Setup Memcached Service

package com.example.cache;

import java.math.BigInteger;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import net.spy.memcached.MemcachedClient;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Service;

import com.example.model.Customer;
import com.example.service.CustomerService;

@Service
@Import({CacheConfiguration.class})
public class CacheCustomerService implements CustomerService{

	@Autowired MemcachedClient memCachedClient;
	
	@Override
	public Customer getCustomerById(BigInteger id) {
		return (Customer) memCachedClient.get(String.valueOf(id));
	}

	@Override
	public void createCustomer(String fn, String ln) {
		memCachedClient.set("customerKey", 3600, new Customer(fn, ln));
	}

	@Override
	public void deleteCustomer(BigInteger id) {
		memCachedClient.delete(String.valueOf(id));
	}

	@Override
	public void createCustomer(Customer newCustomer) {
		memCachedClient.set("customerKey", 3600, newCustomer);
	}	
}

Setup Spring Jndi Factory

package com.sforce.datasource;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.InitialContextFactoryBuilder;
/**
 * @author tmichels
 */
class LocalContext extends InitialContext implements InitialContextFactoryBuilder, InitialContextFactory {

	Map<Object,Object> dataSources;
	
	LocalContext() throws NamingException {
		super();
		dataSources = new HashMap<Object,Object>();
	}
	
	public void addDataSource(String name, String connectionString, String username, String password) {
		this.
		dataSources.put(name, new LocalDataSource(connectionString,username,password));
	}

	public InitialContextFactory createInitialContextFactory(
			Hashtable<?, ?> hsh) throws NamingException {
		dataSources.putAll(hsh);
		return this;
	}

	public Context getInitialContext(Hashtable<?, ?> arg0)
			throws NamingException {
		return this;
	}

	@Override
	public Object lookup(String name) throws NamingException {
		Object ret = dataSources.get(name);
		return (ret != null) ? ret : super.lookup(name);
	}	
}

package com.sforce.datasource;

import javax.naming.spi.NamingManager;
/**
 * @author tmichels
 */
public class LocalContextFactory {

	private LocalContextFactory() {}
	public static LocalContext createLocalContext(String databaseDriver) {

		try { 
			LocalContext ctx = new LocalContext();
			Class.forName(databaseDriver);	
			NamingManager.setInitialContextFactoryBuilder(ctx); 			
			return ctx;
		}
		catch(Exception e) {
			
		}
		return null;
	}	
}
package com.sforce.datasource;

import java.io.PrintWriter;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import javax.sql.DataSource;
/**
 * @author tmichels
 */
class LocalDataSource implements DataSource , Serializable {
	
	private static final long serialVersionUID = 1L;
	private String connectionString;
    private String username;
    private String password;
    
    LocalDataSource(String connectionString, String username, String password) {
        this.connectionString = connectionString;
        this.username = username;
        this.password = password;
    }
    
    public Connection getConnection() throws SQLException{
        return DriverManager.getConnection(connectionString, username, password);
    }

	public Connection getConnection(String username, String password)
			throws SQLException {return null;}
	public PrintWriter getLogWriter() throws SQLException {return null;}
	public int getLoginTimeout() throws SQLException {return 0;}
	public void setLogWriter(PrintWriter out) throws SQLException {	}
	public void setLoginTimeout(int seconds) throws SQLException {}

	@Override
	public boolean isWrapperFor(Class<?> arg0) throws SQLException {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public <T> T unwrap(Class<T> arg0) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}
}
package com.sforce.datasource;

import java.sql.Driver;

import javax.inject.Inject;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

import com.google.common.base.Preconditions;
/**
 * @author tmichels
 */
@Configuration
public class DataSourceConfigImpl implements DataSourceConfig{

	@Bean(name="jndiDwSetup")
	public LocalContext setupJndiDataSource() {
		LocalContext ctx = LocalContextFactory.createLocalContext("oracle.jdbc.driver.OracleDriver");
		ctx.addDataSource("jdbc/devpool","jdbc:oracle:thin:@developer.localhost.com:1521:developer", "developer", "developer");
		return ctx;
	}
	
	@Bean(name="jndiDwDataSource")
	public DataSource dwJndiDataSource() throws NamingException{
		try {
			DataSource dataSource = (DataSource) new InitialContext().lookup("jdbc/devpool");
			
		} catch (NamingException e) {
			e.printStackTrace();
		}
		return null;
	}
}

Setup Quartz on Heroku

There are two ways to use Quartz on Heroku:
1. Setup your own Quartz on Heroku
2. Use Heroku Quartz Addon

1. Setup your own Quartz on Heroku

Create Postgres db:
heroku addons:add heroku-postgresql:dev

Get Postgres properties:
heroku config

Use these properties to specify your:

  • org.quartz.dataSource.dataSource.URL
  • org.quartz.dataSource.dataSource.user
  • org.quartz.dataSource.dataSource.password

Your quartz.properties file

org.quartz.scheduler.instanceName = BatchScheduler
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = dataSource
org.quartz.dataSource.dataSource.driver = org.postgresql.Driver
org.quartz.dataSource.dataSource.URL = jdbc:postgresql://ec2-23-21-133-106.compute-1.amazonaws.com:5432/dsqpq2m83g9jc
org.quartz.dataSource.dataSource.user = YOURUSERNAME
org.quartz.dataSource.dataSource.password = YOURPASSWORD
org.quartz.dataSource.dataSource.maxConnections = 1 

Create your Quartz tables in Postgres:
heroku pg:psql

Copy your Postgres query in the console:
Quartz tables for Quartz 2.1.6

Make sure you are using the same version of tables as specified in your pom.xml in this case my pom looks like:

<dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>2.1.6</version>
</dependency>

2. Use Heroku Quartz Addon

Add Heroku scheduler to your project:
heroku addons:add scheduler:standard

Add the Quartz class Heroku must call in your Procfile:
scheduler: java $JAVA_OPTS -cp target/classes:target/dependency/* com.example.service.SchedulerService

Example of SchedulerService:

package com.example.service;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.repeatSecondlyForever;
import static org.quartz.TriggerBuilder.newTrigger;

public class SchedulerService {
	
    final static Logger logger = LoggerFactory.getLogger(SchedulerService.class);
    public static void main(String[] args) throws Exception {
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        scheduler.start();
        JobDetail jobDetail = newJob(DatabaseJob.class).build();
        Trigger trigger = newTrigger()
                .startNow()
                .withSchedule(repeatSecondlyForever(5))
                .build();
        scheduler.scheduleJob(jobDetail, trigger);
    }

    public static class DatabaseJob implements Job {
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            try {
              //Add your job that needs to execute here
            }
            catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
    }
}

Setup Postgres, Mongodb and Redis on Heroku

Below is the instruction to setup Postgres, Mongodb and Redis on Heroku:

Setup Postgres

heroku addons:add heroku-postgresql:dev

package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
import java.net.URI;

/**
 * @author Thys Michels
 */
@Configuration
@Profile("default")
public class LocalDataSourceConfiguration implements DataSourceConfiguration {
	
	@Bean
        public DataSource dataSource() throws Exception {
    	   final URI dbUrl = new URI(System.getenv("DATABASE_URL"));
           final DriverManagerDataSource dataSource = new DriverManagerDataSource();
           dataSource.setDriverClassName("org.postgresql.Driver");
           dataSource.setUrl("jdbc:postgresql://" + dbUrl.getHost() + dbUrl.getPath());
           dataSource.setUsername(dbUrl.getUserInfo().split(":")[0]);
           dataSource.setPassword(dbUrl.getUserInfo().split(":")[1]);
        return dataSource;
    }
}

Setup MongoDB

heroku addons:add mongohq:sandbox

package com.example.mongo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;

import com.mongodb.Mongo;
import com.mongodb.MongoURI;

@Configuration
@Profile("default")
public class LocalMongoConfiguration {
	
	    @Bean
	    public MongoDbFactory mongoDbFactory1(Environment environment) throws Exception {
	    	MongoURI mongoURI = new MongoURI(System.getenv("MONGOHQ_URL"));
	        Mongo mongo = new Mongo(mongoURI);
	        return new SimpleMongoDbFactory(mongo, mongoURI.getDatabase());
	    }
}

Setup Redis

heroku addons:add rediscloud:20

package com.example.redis;

import java.net.URI;
import java.net.URISyntaxException;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;

import redis.clients.jedis.Protocol;

@Configuration
@Profile("default")
public class LocalRedisConfiguration {
	
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
    	
		try {
			URI redisUri = new URI(System.getenv("REDISCLOUD_URL"));
			JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
			redisConnectionFactory.setHostName(redisUri.getHost());
			redisConnectionFactory.setPort(redisUri.getPort());
			redisConnectionFactory.setTimeout(Protocol.DEFAULT_TIMEOUT);
			redisConnectionFactory.setPassword(redisUri.getUserInfo().split(":",2)[1]);
			
                        return redisConnectionFactory;
		} catch (URISyntaxException e) {
			e.printStackTrace();
			return null;
		}
    }
}

Jdbc, Hibernate, Jpa, Spring Data setup with no xml

Below is a very easy way in Spring to create DataSources with no XML:

1. DataSource
1.1 Define DataSource Interface
1.2 Implement DataSource Interface
1.3 Test if DataSource is connected

2. Jdbc
2.1 Define Jdbc Configuration
2.2 Define Jdbc Service
2.3 Test Jdbc Service

3. Hibernate
3.1 Define Hibernate Configuration
3.2 Define Hibernate Service
3.3 Test Hibernate Service

4. Jpa
4.1 Define Jpa Configuration
4.2 Define Jpa Service
4.3 Test Jpa Service

5. Spring Data
5.1 Define Spring Data Configuration
5.2 Define Spring Data Service
5.3 Test Spring Data Service

1.1 Define DataSource Interface

package com.example.config;

import javax.sql.DataSource;

/**
 * handles configuring the datasource per environment
 *
 * @author Thys Michels
 */
public interface DataSourceConfiguration {
    DataSource dataSource() throws Exception;
}

1.2 Implement DataSource interface

package com.example.config;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;

import com.mongodb.Mongo;

import javax.inject.Inject;
import javax.sql.DataSource;
import java.sql.Driver;

/**
 * @author Thys Michels
 */
@PropertySource("classpath:/services.properties")
@Configuration
@Profile("default")
public class LocalDataSourceConfiguration implements DataSourceConfiguration {

    @Inject
    private Environment environment;

    @Bean
    public DataSource dataSource() throws Exception {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setPassword(environment.getProperty("dataSource.password"));
        dataSource.setUrl(environment.getProperty("dataSource.url"));
        dataSource.setUsername(environment.getProperty("dataSource.user"));
        dataSource.setDriverClassName(environment.getPropertyAsClass("dataSource.driverClass", Driver.class).getName());
        return dataSource;
    }
}

1.3 Test if DataSource is Connected

package com.example.config;

import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {

	public static void main(String[] args) throws SQLException {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.getEnvironment().setActiveProfiles("default");
        applicationContext.scan(LocalDataSourceConfiguration.class.getPackage().getName());
        applicationContext.refresh();
        
        DataSource newDataSource =applicationContext.getBean(DataSource.class);
       
        System.out.println("DataSource Connected: " + newDataSource.getConnection().isClosed());
        newDataSource.getConnection().close();
	}
}

2. JDBC
2.1 Define jdbc Configuration

package com.example.jdbc;

import javax.inject.Inject;
import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.example.config.DataSourceConfiguration;
import com.example.config.LocalDataSourceConfiguration;

@Configuration
@EnableTransactionManagement
@PropertySource("classpath:/services.properties")
@Import( { LocalDataSourceConfiguration.class })
public class JdbcConfiguration {
	
	  @Inject private DataSourceConfiguration dataSourceConfiguration;

	  @Inject private Environment environment;
	  
	  @Bean
	  public JdbcTemplate setupJdbcTemplate() throws Exception {
		 return new JdbcTemplate(dataSourceConfiguration.dataSource());
	  }
	  
	  @Bean
	  public PlatformTransactionManager transactionManager(DataSource dataSource) throws Exception {
	        return new DataSourceTransactionManager(dataSource);
	  }
	 
}

2.2 Define Jdbc Service

package com.example.jdbc;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.persistence.PersistenceContext;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.example.model.Customer;
import com.example.service.CustomerService;

@Repository
@Transactional
@Qualifier("jdbcRepository")
public class JdbcCustomerService implements CustomerService{

	@Inject
    private JdbcTemplate jdbcTemplate;
	
	@Override
	public Customer updateCustomer(long id, String fn, String ln) {
		Customer updateCustomer = new Customer();
		updateCustomer.setId(id);
		updateCustomer.setFirstName(fn);
		updateCustomer.setLastName(ln);
		jdbcTemplate.update("", updateCustomer);
		return null;
	}

	@Override
	public List<Customer> updateCustomers(List<Customer> customersToUpdate) {
		// TODO Auto-generated method stub
		return null;
	}
	
	public static final class CustomerMapper implements RowMapper<Customer>{
		@Override
		public Customer mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Customer customer = new Customer();
			customer.setId(resultSet.getLong("id"));
			customer.setFirstName(resultSet.getString("first_name"));
			customer.setLastName(resultSet.getString("last_name"));
			return customer;
		}
	}

	@Override
	public Customer getCustomerById(long id) {
		String sql = "Select * from customer where id = ?";
		return jdbcTemplate.queryForObject(sql, new Object[]{id},new CustomerMapper());
	}
}

2.3 Test Jdbc Service

package com.example.jdbc;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.example.service.CustomerService;

public class Main {

	public static void main(String[] args) {
		 	AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
	        applicationContext.getEnvironment().setActiveProfiles("default");
	        applicationContext.scan(JdbcConfiguration.class.getPackage().getName());
	        applicationContext.refresh();
	        
	        CustomerService customerService = applicationContext.getBean(CustomerService.class);
	        System.out.println(customerService.getCustomerById(new Long(14)));
	}

}

3. Hibernate
3.1 Define Hibernate Configration

package com.example.hibernate;

import java.util.Properties;

import javax.inject.Inject;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.hibernate.ejb.HibernateEntityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.example.config.DataSourceConfiguration;
import com.example.config.LocalDataSourceConfiguration;

@Configuration
@PropertySource("classpath:/services.properties")
@EnableTransactionManagement
@Import( { LocalDataSourceConfiguration.class })
public class HibernateConfiguration {
	
	 @Inject private DataSourceConfiguration dataSourceConfiguration;

	 @Inject private Environment environment;
	 
	 @Bean
	 public LocalSessionFactoryBean setupSessionFactory() throws Exception {
		  LocalSessionFactoryBean localSessionFactory = new LocalSessionFactoryBean();
		  localSessionFactory.setDataSource(dataSourceConfiguration.dataSource());
		  localSessionFactory.setPackagesToScan("com.example.model");
		  Properties hibernateProperties = new Properties();
		  hibernateProperties.setProperty("dialect", environment.getProperty("dataSource.dialect"));
		  localSessionFactory.setHibernateProperties(hibernateProperties);
		  return localSessionFactory;
	  }
	 
	  @Bean
	  public PlatformTransactionManager transactionManager(DataSource dataSource) throws Exception {
		  return new DataSourceTransactionManager(dataSource);
	  }
}

3.2 Define Hibernate Service

package com.example.hibernate;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.stereotype.Repository;

import com.example.model.Customer;
import com.example.service.CustomerService;

@Repository
@Qualifier("hibernateRepository")
public class HibernateCustomerService implements CustomerService{

	@Inject
	SessionFactory sessionFactory;
	
	@Override
	public Customer updateCustomer(long id, String fn, String ln) {
		Query query = sessionFactory.openSession().createQuery("update Customer set firstName=:fName, lastName=:lName where id=:id").setParameter("fName", fn).setParameter("lName", ln).setParameter("id", id);
		query.executeUpdate();
		return null;
	}

	@Override
	public Customer getCustomerById(long id) {
		return  (Customer) sessionFactory.openSession().createQuery("from Customer where id=?").setLong(0, id).list().get(0);
	}

	@Override
	public Collection<Customer> getAllCustomers() {
		return (Collection<Customer>)sessionFactory.openSession().createQuery("from Customer").list();
	}

	@Override
	public Customer createCustomer(String fn, String ln) {
		Session session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		Customer c = new Customer();
		c.setFirstName(fn);
		c.setLastName(ln);
		session.save(c);
		tx.commit();
		session.close();
		return c;
	}

	@Override
	public void deleteCustomer(long id) {
		Query query = sessionFactory.openSession().createQuery("delete Customer where id = :id").setParameter("id", id);
		query.executeUpdate();
	}

	@Override
	public Customer createCustomer(Customer newCustomer) {
		Session session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		session.save(newCustomer);
		tx.commit();
		session.close();
		return newCustomer;
	}

	@Override
	public int getTotalRecords() {
		String hql = "Select count(*) from Customer";
		Query query = sessionFactory.openSession().createQuery(hql);
		return ((Long)query.uniqueResult()).intValue();
	}
}

3.3 Test Hibernate Service

package com.example.hibernate;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.example.service.CustomerService;

public class Main {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.getEnvironment().setActiveProfiles("default");
        applicationContext.scan(HibernateConfiguration.class.getPackage().getName());
        applicationContext.refresh();
        
        CustomerService customerService = applicationContext.getBean(CustomerService.class);
        System.out.println(customerService.getAllCustomers());
        System.out.println(customerService.getCustomerById(new Long(14)));
        System.out.println(customerService.createCustomer("HibernateFName", "HibernateLName"));
        customerService.deleteCustomer(new Long(226));
        customerService.updateCustomer(new Long(225), "PName", "PLastName");
	}
}

4. Jpa
4.1 Define Jpa Configuration

package com.example.jpa;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.example.config.DataSourceConfiguration;
import com.example.config.LocalDataSourceConfiguration;
import com.example.model.Customer;

import javax.inject.Inject;
import javax.persistence.EntityManagerFactory;


@Configuration
@PropertySource("classpath:/services.properties")
@EnableTransactionManagement
@Import( { LocalDataSourceConfiguration.class })
public class JpaConfiguration {

    @Inject private DataSourceConfiguration dataSourceConfiguration;

    @Inject private Environment environment;

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws Exception {

        LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        localContainerEntityManagerFactoryBean.setDataSource(dataSourceConfiguration.dataSource());
        localContainerEntityManagerFactoryBean.setPackagesToScan(Customer.class.getPackage().getName());

        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        jpaVendorAdapter.setGenerateDdl(true);

        localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
        return localContainerEntityManagerFactoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager() throws Exception {
        EntityManagerFactory entityManagerFactory = entityManagerFactory().getObject();
        return new JpaTransactionManager(entityManagerFactory);
    }   
}

4.2 Define Jpa Service

package com.example.jpa;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.service.CustomerService;
import com.example.model.Customer;

@Repository
@Qualifier("jpaRepository")
@Transactional(readOnly = true)
public class JpaCustomerService implements CustomerService {

    @PersistenceContext
    private EntityManager entityManager;

    @Transactional(readOnly = true)
    public Customer getCustomerById(long id) {
        return this.entityManager.find(Customer.class, id);
    }

    public Customer createCustomer(String fn, String ln) {
        Customer newCustomer = new Customer();
        newCustomer.setFirstName(fn);
        newCustomer.setLastName(ln);
        this.entityManager.persist(newCustomer);
        return newCustomer;
    }
    
    @Transactional
    public Customer updateCustomer(long id, String fn, String ln) {
        Customer customer = this.getCustomerById(id);
        customer.setFirstName(fn);
        customer.setLastName(ln);
        this.entityManager.merge(customer);
        return getCustomerById(id);
    }

	public Collection<Customer> getAllCustomers() {
		 CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
	        CriteriaQuery<Customer> criteriaBuilderQuery = criteriaBuilder.createQuery(Customer.class);
	        CriteriaQuery<Customer> customerCriteriaQuery = criteriaBuilderQuery.select(
	                criteriaBuilderQuery.from(Customer.class));
	        return this.entityManager.createQuery(customerCriteriaQuery).getResultList();
	}

	@Transactional
	public void deleteCustomer(long id) {
		Customer customerToDelete = this.entityManager.find(Customer.class, id);
		this.entityManager.remove(customerToDelete);
	}

	public Customer createCustomer(Customer newCustomer) {
		 this.entityManager.persist(newCustomer);
	     return newCustomer;
	}

	@Transactional
	public Customer updateCustomer(long id, Customer updateCustomer) {
		Customer customer = this.getCustomerById(id);
		customer.setFirstName(updateCustomer.getFirstName());
	    customer.setLastName(updateCustomer.getLastName());
		this.entityManager.merge(customer);
        return getCustomerById(id);
	}

	@Override
	public List<Customer> bulkCreate(List<Customer> customers) {
		for (Customer customer : customers){
			this.entityManager.persist(customer);
		}
		return customers;
	}

	@Override
	public List<Customer> findCustomerByQuery(String query) {
		return this.entityManager.createNativeQuery(query, Customer.class).getResultList();
	}

	@Transactional
	public void deleteCustomers(List<Customer> customersToDelete) {
		for (Customer customer : customersToDelete){
			entityManager.remove(customer);
		}
	}

	@Override
	public List<Customer> getPaginatedCustomer(Integer currentPage,
			Integer totalPerPage) {
		CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
        CriteriaQuery<Customer> criteriaBuilderQuery = criteriaBuilder.createQuery(Customer.class);
        CriteriaQuery<Customer> customerCriteriaQuery = criteriaBuilderQuery.select(
                criteriaBuilderQuery.from(Customer.class));
        return this.entityManager.createQuery(customerCriteriaQuery).getResultList().subList(currentPage, totalPerPage);
	}

	@Transactional
	public List<Customer> updateCustomers(List<Customer> customersToUpdate) {
		List<Customer> listOfUpdatedCustomers = new ArrayList<Customer>();
		for (Customer customerToUpdate : customersToUpdate){
		 this.entityManager.merge(customerToUpdate);
		 listOfUpdatedCustomers.add(getCustomerById(customerToUpdate.getId()));
		}
		return listOfUpdatedCustomers;
	}

	@Override
	public int getTotalRecords() {
		CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
        CriteriaQuery<Customer> criteriaBuilderQuery = criteriaBuilder.createQuery(Customer.class);
        CriteriaQuery<Customer> customerCriteriaQuery = criteriaBuilderQuery.select(
                criteriaBuilderQuery.from(Customer.class));
        return this.entityManager.createQuery(customerCriteriaQuery).getResultList().size();
	}

	@Override
	public List<String> getPaginationSequence() {
		List<String> listOfPages = new ArrayList<String>();
		for (int k = 1; k < (int)Math.round((this.getTotalRecords()/10)+0.5)+1; k++){
			listOfPages.add(String.valueOf(k));
		}
		return listOfPages;
	}

	@Override
	public void createCustomersFromMap(Map<String, String> mapOfCustomers) {
		for (Map.Entry<String, String> customer : mapOfCustomers.entrySet()){
			Customer newCustomer = new Customer();
			newCustomer.setFirstName(customer.getKey());
			newCustomer.setLastName(customer.getValue());
			createCustomer(newCustomer);
		}
	}	
}

4.3 Test Jpa Service

package com.example.jpa;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.example.service.CustomerService;
import com.example.model.Customer;


public class Main {
    public static void main(String args[]) throws Throwable {

        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.getEnvironment().setActiveProfiles("default");
        applicationContext.scan(JpaConfiguration.class.getPackage().getName());
        applicationContext.refresh();

        Log log = LogFactory.getLog(Main.class);

        CustomerService customerService = applicationContext.getBean(CustomerService.class);

        Customer customer = customerService.createCustomer("Test", "Jpa");

        Customer retrievedCustomer = customerService.getCustomerById(customer.getId());

        log.info(String.format("customer.id (%s) == retreivedCustomer.id (%s)?  %s",
                customer.getId(), retrievedCustomer.getId(), customer.getId().equals(retrievedCustomer.getId())));

        Customer updatedCustomer = customerService.updateCustomer(customer.getId(), "JPA", "Lover");
        log.info(String.format("updated customer's firstName: %s", updatedCustomer.getFirstName()));
        
        Collection<Customer> listOfCustomers = customerService.getAllCustomers();
        for (Customer c : listOfCustomers){
        	System.out.println(c);
        }
        
        List<Customer> createDummyCustomers = new ArrayList<Customer>();
        for (int k = 0; k < 10; k++){
        	Customer dummy = new Customer();
        	dummy.setFirstName("FName"+k);
        	dummy.setLastName("LName"+k);
        	createDummyCustomers.add(dummy);
        }
        
        List<Customer> insertedCustomer = customerService.bulkCreate(createDummyCustomers);
        for (Customer c : insertedCustomer){
        	System.out.println(c);
        }
        
        
        List<Customer> customQueryCustomer = customerService.findCustomerByQuery("Select * from customer");
        for (Customer c : customQueryCustomer){
        	System.out.println(c);
        }
        
        List<Customer> customerPagination = customerService.getPaginatedCustomer(0, 10);
        for (Customer c : customerPagination){
        	System.out.println(c);
        }
       
        System.out.println((int)Math.round((customerService.getTotalRecords()/10)+0.5));
        System.out.println(customerService.getPaginationSequence());
    }
}

5. Spring Data
5.1 Configure Spring Data

package com.example.spring_data;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.example.config.DataSourceConfiguration;
import com.example.config.LocalDataSourceConfiguration;
import com.example.model.Customer;

import javax.inject.Inject;
import javax.persistence.EntityManagerFactory;


@Configuration
@EnableJpaRepositories
@PropertySource("classpath:/services.properties")
@EnableTransactionManagement
@Import( { LocalDataSourceConfiguration.class })
public class JpaCustomerConfiguration {

    @Inject private DataSourceConfiguration dataSourceConfiguration;

    @Inject private Environment environment;

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws Exception {

        LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        localContainerEntityManagerFactoryBean.setDataSource(dataSourceConfiguration.dataSource());
        localContainerEntityManagerFactoryBean.setPackagesToScan(Customer.class.getPackage().getName());

        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        jpaVendorAdapter.setGenerateDdl(true);

        localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
        
        return localContainerEntityManagerFactoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager() throws Exception {
        EntityManagerFactory entityManagerFactory = entityManagerFactory().getObject();
        return new JpaTransactionManager(entityManagerFactory);
    }   
}

5.2 Define Spring Data Service

package com.example.spring_data;

import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.data.repository.CrudRepository;

import com.example.model.Customer;

@EnableJpaRepositories
public interface CustomerCRUDRepository extends CrudRepository<Customer, Long>, QueryDslPredicateExecutor<Customer>{
}

5.3 Test Spring Data Service

package com.example.spring_data;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.example.model.Customer;

public class Main {
	
	public static void main(String[] args) {
		 	AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
	        applicationContext.getEnvironment().setActiveProfiles("default");
	        applicationContext.scan(JpaCustomerConfiguration.class.getPackage().getName());
	        applicationContext.refresh();

	        CustomerCRUDRepository cr = applicationContext.getBean(CustomerCRUDRepository.class);
	        System.out.println(cr.count());
	        //cr.delete(new Long(224));
	        Customer newCustomer = new Customer("DataJpaFName", "DataJpaLName");
	        cr.save(newCustomer);
	        System.out.println(cr.findAll());
	        System.out.println(cr.exists(new Long(224)));
	        System.out.println(cr.findOne(new Long(14)));
	}
}

All code can be found here:
https://github.com/thysmichels/cloudsole-database

Websphere MQ Cluster Tutorial

How to create a Websphere MQ Cluster:

Step 1: Open Websphere MQ Explorer and create two Queue Managers that will be part of the cluster.

Step 2: Right click on Queue Manager Cluster and Select New->Queue Manager Cluster

Step 3: Specify the following information:

  • Cluster Name
  • First Queue Manager
  • Second Queue Manager
  • Cluster Receiver Channel for First Queue Manager
  • Cluster Receiver Channel for Second Queue Manager

Active Full Repository Cluster:

Step 4: Create a new Queue and add it the Cluster (Specify the Cluster Name)

Step 5: Test Clustered Queue Manager by putting a message on both Queue Managers using a shared Queue (QIn)

amqsput QCluster1 QIn

amqsput QCluster2 QIn

Websphere Transformation Extender Launcher Tutorial

So how do you set up Websphere Transformation Extender Launcher to automatically transform incoming files with the correct transformation map en produce an output map. With this the launcher also comes with the Launcher Management Console which provides you detailed information on the status of transformed files. The Launcher Monitor provides you a graphical interface of your transformed maps. I will show how they all are used and how they can provide you with almost any level of detail on transformations in your enterprise.

Below is the steps to configure Websphere Transformation Extender Launcher:

1. Open Integration Flow Designer.

2. Click on the purple circle icon and drag it onto the pallet. It will ask to navigate to a .mms file, that is a map file already create in WTX Design Studio.

3. Double click on the newly imported .mms map to see the input and output cards respectively.

4. Confirm that the map executes without errors click on System -> Build Maps

5. If no errors occurred click on System->Deploy-> Definitions
6. Double click on ‘Generate and Transfer Launcher Control File’ and save it to the following directory: C:/IBM/Websphere Transformation Extender 8.3/system

7. After you have set your system file location close the Definition window and click on System Deploy->THE_NAME_OF_YOUR_MAP

You will see the following message if the map was deployed successfully.

8. Click on Yes to see the deployed map, it mus look something like this:

Deploy Results for System LauncherTest (Version 8.3(23))
Script:   DeployTest
Date:     Wed Sep 15 12:29:37 2010
File:     C:\TXTest\Launcher.msd
Deploy has completed successfully.
Total # of errors:  0
Map Building:
Number of maps processed:    1
Number of successful builds:  1
Number of maps with errors:   0
Number of maps with warnings:   0
The following map built successfully:
C:\Documents and Settings\Administrator\My Documents\LauncherLab_Verify\FiletoFile.mms: FileTest
Launcher File Generated For: LauncherTest
Map File Transfers:
Copied C:\Documents and Settings\Administrator\My Documents\LauncherLab_Verify\FileTest.mmc to C:\TXTest\FileTest.mmc.
Launcher File Transfer:
Copied C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\SE5C.tmp to C:\IBM\WebSphere Transformation Extender 8.3\systems\LauncherTest.msl.

Deploy Results for System LauncherTest (Version 8.3(23))
Script:   DeployTest Date:     Wed Sep 15 12:29:37 2010 File:     C:\TXTest\Launcher.msd

Deploy has completed successfully.
Total # of errors:  0

Map Building:
Number of maps processed:    1
Number of successful builds:  1Number of maps with errors:   0Number of maps with warnings:   0

The following map built successfully:
C:\Documents and Settings\Administrator\My Documents\LauncherLab_Verify\FiletoFile.mms: FileTest

Launcher File Generated For: LauncherTest

Map File Transfers:
Copied C:\Documents and Settings\Administrator\My Documents\LauncherLab_Verify\FileTest.mmc to C:\TXTest\FileTest.mmc.
Launcher File Transfer:
Copied C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\SE5C.tmp to C:\IBM\WebSphere Transformation Extender 8.3\systems\LauncherTest.msl.

9. Open up WTX Launcher Administrator

10. Click on the Access Tab and create a new user which you Grant access to All systems.

11. Click on the Deployment Directory tab and confirm that the Directory path is the same as where you created you msl file.

12. Now you are ready to start WTX service in your Windows service registry

13. Navigate to the file from which you imported the mms file in Step 2. Copy and paste the input the folder to see the output being created automatically by the launcher.