Spring Boot and RESTful API(6)Redis Advance and Cassandra Advance and Bean Mapper
Redis Configuration Upgrade
Last time, I set up the RedisTemplate in class and configuration in YAML. But they are not working together.
So here is some changes to make that working.
RedisConfig.java
package com.sillycat.jobsmonitorapi.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.sillycat.jobsmonitorapi.domain.User;
import com.sillycat.jobsmonitorapi.repository.RedisObjectSerializer;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "spring.redis")
public class RedisConfig {
private String database;
private String host;
private Integer port;
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(5);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
JedisConnectionFactory ob = new JedisConnectionFactory(poolConfig);
ob.setUsePool(true);
ob.setHostName(this.getHost());
ob.setPort(this.getPort());
return ob;
}
@Bean
public RedisTemplate<String, User> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, User> template = new RedisTemplate<String, User>();
template.setConnectionFactory(jedisConnectionFactory());
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new RedisObjectSerializer());
return template;
}
public String getDatabase() {
return database;
}
public void setDatabase(String database) {
this.database = database;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
}
Configuration in application.yaml or application-prod.yaml/application-dev.yaml/application-stage.yaml
spring:
profiles:
active: dev
redis:
database: 0
host: localhost
port: 6379
Cassandra and Hector
https://github.com/hector-client/hector
It seems that library is no longer active. But I want to set up that to check the columns usage in my old projects.
I have an old project called easycassandraserver. Try to set up the ENV to run it.
Exceptions
error: error while loading CharSequence, class file '/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/rt.jar(java/lang/CharSequence.class)' is broken
(bad constant pool tag 18 at byte 10)
Solution:
Roll back the JDK to 7
Limit 1 and Desc on the Time for Records
cassandra cql
>create table books ( brandCode text, deviceID text, unixtime bigint, notes text, primary key((brandCode, deviceID), unixtime)) with compact storage and compression = { 'sstable_compression' : '' } and compaction = { 'class' : 'LeveledCompactionStrategy', 'sstable_size_in_mb':10 } and clustering order by (unixtime desc) ;
>select * from books;
brandcode | deviceid | unixtime | notes
-----------+----------+----------+-------
>insert into books ( brandCode, deviceID, unixtime, notes) values ( 'sillycat', 'iphone5', 1, 'there is a book there');
>insert into books ( brandCode, deviceID, unixtime, notes) values ( 'sillycat', 'iphone5', 2, 'update to os 6.0’);
>insert into books ( brandCode, deviceID, unixtime, notes) values ( 'sillycat', 'iphone5', 3, 'update to os 7.0');
>insert into books ( brandCode, deviceID, unixtime, notes) values ( 'sillycat', 'android', 1, 'update to os 2.1');
>insert into books ( brandCode, deviceID, unixtime, notes) values ( 'sillycat', 'android', 2, 'update to os 2.2');
>select * from books where brandcode = 'sillycat' and deviceid='iphone5';
brandcode | deviceid | unixtime | notes
-----------+----------+----------+-----------------------
sillycat | iphone5 | 3 | update to os 7.0
sillycat | iphone5 | 2 | update to os 6.0
sillycat | iphone5 | 1 | there is a book there
>select * from books where brandcode = 'sillycat' and deviceid='iphone5' limit 1;
brandcode | deviceid | unixtime | notes
-----------+----------+----------+------------------
sillycat | iphone5 | 3 | update to os 7.0
Object Mapping - orika
http://orika-mapper.github.io/orika-docs/intro.html
Learn from org.springside.modules.utils.mapper.BeanMapper
I just copy the class from BeanMapper in springside, I do not want to include the whole library.
package com.j2c.jobsmonitorapi.dto;
import java.util.List;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import ma.glasnost.orika.metadata.Type;
import ma.glasnost.orika.metadata.TypeFactory;
public class BeanMapper {
private static MapperFacade mapper;
static {
MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
mapper = mapperFactory.getMapperFacade();
}
/**
* 简单的复制出新类型对象.
*
* 通过source.getClass() 获得源Class
*/
public static <S, D> D map(S source, Class<D> destinationClass) {
return mapper.map(source, destinationClass);
}
/**
* 极致性能的复制出新类型对象.
*
* 预先通过BeanMapper.getType() 静态获取并缓存Type类型,在此处传入
*/
public static <S, D> D map(S source, Type<S> sourceType, Type<D> destinationType) {
return mapper.map(source, sourceType, destinationType);
}
/**
* 简单的复制出新对象列表到ArrayList
*
* 不建议使用mapper.mapAsList(Iterable<S>,Class<D>)接口, sourceClass需要反射,实在有点慢
*/
public static <S, D> List<D> mapList(Iterable<S> sourceList, Class<S> sourceClass, Class<D> destinationClass) {
return mapper.mapAsList(sourceList, TypeFactory.valueOf(sourceClass), TypeFactory.valueOf(destinationClass));
}
/**
* 极致性能的复制出新类型对象到ArrayList.
*
* 预先通过BeanMapper.getType() 静态获取并缓存Type类型,在此处传入
*/
public static <S, D> List<D> mapList(Iterable<S> sourceList, Type<S> sourceType, Type<D> destinationType) {
return mapper.mapAsList(sourceList, sourceType, destinationType);
}
/**
* 简单复制出新对象列表到数组
*
* 通过source.getComponentType() 获得源Class
*/
public static <S, D> D[] mapArray(final D[] destination, final S[] source, final Class<D> destinationClass) {
return mapper.mapAsArray(destination, source, destinationClass);
}
/**
* 极致性能的复制出新类型对象到数组
*
* 预先通过BeanMapper.getType() 静态获取并缓存Type类型,在此处传入
*/
public static <S, D> D[] mapArray(D[] destination, S[] source, Type<S> sourceType, Type<D> destinationType) {
return mapper.mapAsArray(destination, source, sourceType, destinationType);
}
/**
* 预先获取orika转换所需要的Type,避免每次转换.
*/
public static <E> Type<E> getType(final Class<E> rawType) {
return TypeFactory.valueOf(rawType);
}
}
Include the third party jar pom.xml
<orika.version>1.5.1</orika.version>
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>${orika.version}</version>
</dependency>
In the Controller Layer
Job job = new Job("1", 1, "reference1", "fullstack engineer", "java, scala, python, grooyv","http://sillycat.iteye.com");
JobDto returnDto = BeanMapper.map(job, JobDto.class);
return Mono.just(returnDto);
Job job1 = new Job("1", 1, "reference1", "fullstack engineer", "java, scala, python, grooyv","http://sillycat.iteye.com");
Job job2 = new Job("2", 1, "reference2", "java engineer", "java, tomcat, weblogic”, "http://sillycat.iteye.com");
list.add(job1);
list.add(job2);
returnList = BeanMapper.mapList(list, Job.class, JobDto.class);
return Flux.fromArray(returnList.toArray(new JobDto[returnList.size()]));
References:
http://sillycat.iteye.com/blog/2384028
http://sillycat.iteye.com/blog/2011524
http://sillycat.iteye.com/blog/2383513
http://sillycat.iteye.com/blog/2383517
Redis Configuration Upgrade
Last time, I set up the RedisTemplate in class and configuration in YAML. But they are not working together.
So here is some changes to make that working.
RedisConfig.java
package com.sillycat.jobsmonitorapi.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.sillycat.jobsmonitorapi.domain.User;
import com.sillycat.jobsmonitorapi.repository.RedisObjectSerializer;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "spring.redis")
public class RedisConfig {
private String database;
private String host;
private Integer port;
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(5);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
JedisConnectionFactory ob = new JedisConnectionFactory(poolConfig);
ob.setUsePool(true);
ob.setHostName(this.getHost());
ob.setPort(this.getPort());
return ob;
}
@Bean
public RedisTemplate<String, User> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, User> template = new RedisTemplate<String, User>();
template.setConnectionFactory(jedisConnectionFactory());
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new RedisObjectSerializer());
return template;
}
public String getDatabase() {
return database;
}
public void setDatabase(String database) {
this.database = database;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
}
Configuration in application.yaml or application-prod.yaml/application-dev.yaml/application-stage.yaml
spring:
profiles:
active: dev
redis:
database: 0
host: localhost
port: 6379
Cassandra and Hector
https://github.com/hector-client/hector
It seems that library is no longer active. But I want to set up that to check the columns usage in my old projects.
I have an old project called easycassandraserver. Try to set up the ENV to run it.
Exceptions
error: error while loading CharSequence, class file '/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/rt.jar(java/lang/CharSequence.class)' is broken
(bad constant pool tag 18 at byte 10)
Solution:
Roll back the JDK to 7
Limit 1 and Desc on the Time for Records
cassandra cql
>create table books ( brandCode text, deviceID text, unixtime bigint, notes text, primary key((brandCode, deviceID), unixtime)) with compact storage and compression = { 'sstable_compression' : '' } and compaction = { 'class' : 'LeveledCompactionStrategy', 'sstable_size_in_mb':10 } and clustering order by (unixtime desc) ;
>select * from books;
brandcode | deviceid | unixtime | notes
-----------+----------+----------+-------
>insert into books ( brandCode, deviceID, unixtime, notes) values ( 'sillycat', 'iphone5', 1, 'there is a book there');
>insert into books ( brandCode, deviceID, unixtime, notes) values ( 'sillycat', 'iphone5', 2, 'update to os 6.0’);
>insert into books ( brandCode, deviceID, unixtime, notes) values ( 'sillycat', 'iphone5', 3, 'update to os 7.0');
>insert into books ( brandCode, deviceID, unixtime, notes) values ( 'sillycat', 'android', 1, 'update to os 2.1');
>insert into books ( brandCode, deviceID, unixtime, notes) values ( 'sillycat', 'android', 2, 'update to os 2.2');
>select * from books where brandcode = 'sillycat' and deviceid='iphone5';
brandcode | deviceid | unixtime | notes
-----------+----------+----------+-----------------------
sillycat | iphone5 | 3 | update to os 7.0
sillycat | iphone5 | 2 | update to os 6.0
sillycat | iphone5 | 1 | there is a book there
>select * from books where brandcode = 'sillycat' and deviceid='iphone5' limit 1;
brandcode | deviceid | unixtime | notes
-----------+----------+----------+------------------
sillycat | iphone5 | 3 | update to os 7.0
Object Mapping - orika
http://orika-mapper.github.io/orika-docs/intro.html
Learn from org.springside.modules.utils.mapper.BeanMapper
I just copy the class from BeanMapper in springside, I do not want to include the whole library.
package com.j2c.jobsmonitorapi.dto;
import java.util.List;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import ma.glasnost.orika.metadata.Type;
import ma.glasnost.orika.metadata.TypeFactory;
public class BeanMapper {
private static MapperFacade mapper;
static {
MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
mapper = mapperFactory.getMapperFacade();
}
/**
* 简单的复制出新类型对象.
*
* 通过source.getClass() 获得源Class
*/
public static <S, D> D map(S source, Class<D> destinationClass) {
return mapper.map(source, destinationClass);
}
/**
* 极致性能的复制出新类型对象.
*
* 预先通过BeanMapper.getType() 静态获取并缓存Type类型,在此处传入
*/
public static <S, D> D map(S source, Type<S> sourceType, Type<D> destinationType) {
return mapper.map(source, sourceType, destinationType);
}
/**
* 简单的复制出新对象列表到ArrayList
*
* 不建议使用mapper.mapAsList(Iterable<S>,Class<D>)接口, sourceClass需要反射,实在有点慢
*/
public static <S, D> List<D> mapList(Iterable<S> sourceList, Class<S> sourceClass, Class<D> destinationClass) {
return mapper.mapAsList(sourceList, TypeFactory.valueOf(sourceClass), TypeFactory.valueOf(destinationClass));
}
/**
* 极致性能的复制出新类型对象到ArrayList.
*
* 预先通过BeanMapper.getType() 静态获取并缓存Type类型,在此处传入
*/
public static <S, D> List<D> mapList(Iterable<S> sourceList, Type<S> sourceType, Type<D> destinationType) {
return mapper.mapAsList(sourceList, sourceType, destinationType);
}
/**
* 简单复制出新对象列表到数组
*
* 通过source.getComponentType() 获得源Class
*/
public static <S, D> D[] mapArray(final D[] destination, final S[] source, final Class<D> destinationClass) {
return mapper.mapAsArray(destination, source, destinationClass);
}
/**
* 极致性能的复制出新类型对象到数组
*
* 预先通过BeanMapper.getType() 静态获取并缓存Type类型,在此处传入
*/
public static <S, D> D[] mapArray(D[] destination, S[] source, Type<S> sourceType, Type<D> destinationType) {
return mapper.mapAsArray(destination, source, sourceType, destinationType);
}
/**
* 预先获取orika转换所需要的Type,避免每次转换.
*/
public static <E> Type<E> getType(final Class<E> rawType) {
return TypeFactory.valueOf(rawType);
}
}
Include the third party jar pom.xml
<orika.version>1.5.1</orika.version>
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>${orika.version}</version>
</dependency>
In the Controller Layer
Job job = new Job("1", 1, "reference1", "fullstack engineer", "java, scala, python, grooyv","http://sillycat.iteye.com");
JobDto returnDto = BeanMapper.map(job, JobDto.class);
return Mono.just(returnDto);
Job job1 = new Job("1", 1, "reference1", "fullstack engineer", "java, scala, python, grooyv","http://sillycat.iteye.com");
Job job2 = new Job("2", 1, "reference2", "java engineer", "java, tomcat, weblogic”, "http://sillycat.iteye.com");
list.add(job1);
list.add(job2);
returnList = BeanMapper.mapList(list, Job.class, JobDto.class);
return Flux.fromArray(returnList.toArray(new JobDto[returnList.size()]));
References:
http://sillycat.iteye.com/blog/2384028
http://sillycat.iteye.com/blog/2011524
http://sillycat.iteye.com/blog/2383513
http://sillycat.iteye.com/blog/2383517