Make Jedis return converted tx results
DATAREDIS-208
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.data.redis.connection.convert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.connection.FutureResult;
|
||||
|
||||
/**
|
||||
* Converts the results of transaction exec using a supplied Queue of {@link FutureResult}s.
|
||||
* Converts any Exception objects returned in the list as well, using the supplied Exception
|
||||
* {@link Converter}
|
||||
*
|
||||
* @author Jennifer Hickey
|
||||
*
|
||||
* @param <T>
|
||||
* The type of {@link FutureResult} of the individual tx operations
|
||||
*/
|
||||
public class TransactionResultConverter<T> implements Converter<List<Object>, List<Object>> {
|
||||
|
||||
private Queue<FutureResult<T>> txResults = new LinkedList<FutureResult<T>>();
|
||||
|
||||
private Converter<Exception, DataAccessException> exceptionConverter;
|
||||
|
||||
public TransactionResultConverter(Queue<FutureResult<T>> txResults,
|
||||
Converter<Exception, DataAccessException> exceptionConverter) {
|
||||
this.txResults = txResults;
|
||||
this.exceptionConverter = exceptionConverter;
|
||||
}
|
||||
|
||||
public List<Object> convert(List<Object> execResults) {
|
||||
if (execResults == null) {
|
||||
return null;
|
||||
}
|
||||
if (execResults.size() != txResults.size()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Incorrect number of transaction results. Expected: " + txResults.size()
|
||||
+ " Actual: " + execResults.size());
|
||||
}
|
||||
List<Object> convertedResults = new ArrayList<Object>();
|
||||
for (Object result : execResults) {
|
||||
FutureResult<T> futureResult = txResults.remove();
|
||||
if (result instanceof Exception) {
|
||||
throw exceptionConverter.convert((Exception) result);
|
||||
}
|
||||
if (!(futureResult.isStatus())) {
|
||||
convertedResults.add(futureResult.convert(result));
|
||||
}
|
||||
}
|
||||
return convertedResults;
|
||||
}
|
||||
}
|
||||
@@ -192,8 +192,7 @@ public class JedisConnection implements RedisConnection {
|
||||
});
|
||||
if(isPipelined()) {
|
||||
pipeline(new JedisResult(result));
|
||||
}
|
||||
if(isQueueing()) {
|
||||
}else {
|
||||
transaction(new JedisResult(result));
|
||||
}
|
||||
return null;
|
||||
@@ -314,6 +313,11 @@ public class JedisConnection implements RedisConnection {
|
||||
cause = dataAccessException;
|
||||
}
|
||||
results.add(dataAccessException);
|
||||
}catch(DataAccessException e) {
|
||||
if (cause == null) {
|
||||
cause = e;
|
||||
}
|
||||
results.add(e);
|
||||
}
|
||||
}
|
||||
if (cause != null) {
|
||||
@@ -425,7 +429,7 @@ public class JedisConnection implements RedisConnection {
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(new JedisResult(transaction.flushDB()));
|
||||
transaction(new JedisStatusResult(transaction.flushDB()));
|
||||
return;
|
||||
}
|
||||
jedis.flushDB();
|
||||
@@ -699,11 +703,13 @@ public class JedisConnection implements RedisConnection {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(new JedisResult(pipeline.exec(),
|
||||
new TransactionResultConverter<Response<?>>(new LinkedList<FutureResult<Response<?>>>(txResults))));
|
||||
new TransactionResultConverter<Response<?>>(new LinkedList<FutureResult<Response<?>>>(txResults),
|
||||
JedisConverters.exceptionConverter())));
|
||||
return null;
|
||||
}
|
||||
List<Object> results = transaction.exec();
|
||||
return convertPipelineAndTxResults ? new TransactionResultConverter<Response<?>>(txResults).convert(results) : results;
|
||||
return convertPipelineAndTxResults ? new TransactionResultConverter<Response<?>>(txResults,
|
||||
JedisConverters.exceptionConverter()).convert(results) : results;
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
} finally {
|
||||
|
||||
@@ -51,7 +51,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
|
||||
private JedisPool pool = null;
|
||||
private JedisPoolConfig poolConfig = new JedisPoolConfig();
|
||||
private int dbIndex = 0;
|
||||
private boolean convertPipelineResults = true;
|
||||
private boolean convertPipelineAndTxResults = true;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>JedisConnectionFactory</code> instance
|
||||
@@ -147,7 +147,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
|
||||
Jedis jedis = fetchJedisConnector();
|
||||
JedisConnection connection = (usePool ? new JedisConnection(jedis, pool, dbIndex) :
|
||||
new JedisConnection(jedis, null, dbIndex));
|
||||
connection.setConvertPipelineResults(convertPipelineResults);
|
||||
connection.setConvertPipelineAndTxResults(convertPipelineAndTxResults);
|
||||
return postProcessConnection(connection);
|
||||
}
|
||||
|
||||
@@ -304,23 +304,23 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
|
||||
|
||||
/**
|
||||
* Specifies if pipelined results should be converted to the expected data
|
||||
* type. If false, results of {@link #closePipeline()} will be of the
|
||||
* type returned by the Jedis driver
|
||||
* type. If false, results of {@link JedisConnection#closePipeline()} and
|
||||
* {@link JedisConnection#exec()} will be of the type returned by the Jedis driver
|
||||
*
|
||||
* @return Whether or not to convert pipeline results
|
||||
* @return Whether or not to convert pipeline and tx results
|
||||
*/
|
||||
public boolean getConvertPipelineResults() {
|
||||
return convertPipelineResults;
|
||||
public boolean getConvertPipelineAndTxResults() {
|
||||
return convertPipelineAndTxResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies if pipelined results should be converted to the expected data
|
||||
* type. If false, results of {@link #closePipeline()} will be of the
|
||||
* type returned by the Jedis driver
|
||||
* type. If false, results of {@link JedisConnection#closePipeline()} and
|
||||
* {@link JedisConnection#exec()} will be of the type returned by the Jedis driver
|
||||
*
|
||||
* @param convertPipelineResults Whether or not to convert pipeline results
|
||||
* @param convertPipelineAndTxResults Whether or not to convert pipeline and tx results
|
||||
*/
|
||||
public void setConvertPipelineResults(boolean convertPipelineResults) {
|
||||
this.convertPipelineResults = convertPipelineResults;
|
||||
public void setConvertPipelineAndTxResults(boolean convertPipelineAndTxResults) {
|
||||
this.convertPipelineAndTxResults = convertPipelineAndTxResults;
|
||||
}
|
||||
}
|
||||
@@ -15,22 +15,17 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection.jedis;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.redis.RedisConnectionFailureException;
|
||||
import org.springframework.data.redis.RedisSystemException;
|
||||
import org.springframework.data.redis.connection.DefaultTuple;
|
||||
import org.springframework.data.redis.connection.RedisListCommands.Position;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
|
||||
import org.springframework.data.redis.connection.SortParameters;
|
||||
import org.springframework.data.redis.connection.SortParameters.Order;
|
||||
import org.springframework.data.redis.connection.SortParameters.Range;
|
||||
import org.springframework.data.redis.connection.SortParameters;
|
||||
import org.springframework.data.redis.connection.convert.Converters;
|
||||
import org.springframework.data.redis.connection.convert.ListConverter;
|
||||
import org.springframework.data.redis.connection.convert.MapConverter;
|
||||
@@ -38,9 +33,6 @@ import org.springframework.data.redis.connection.convert.SetConverter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import redis.clients.jedis.BinaryClient.LIST_POSITION;
|
||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||
import redis.clients.jedis.exceptions.JedisDataException;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
import redis.clients.jedis.SortingParams;
|
||||
import redis.clients.util.SafeEncoder;
|
||||
|
||||
@@ -57,6 +49,7 @@ abstract public class JedisConverters extends Converters {
|
||||
private static final SetConverter<String, byte[]> STRING_SET_TO_BYTE_SET;
|
||||
private static final MapConverter<String, byte[]> STRING_MAP_TO_BYTE_MAP;
|
||||
private static final SetConverter<redis.clients.jedis.Tuple, Tuple> TUPLE_SET_TO_TUPLE_SET;
|
||||
private static final Converter<Exception,DataAccessException> EXCEPTION_CONVERTER = new JedisExceptionConverter();
|
||||
|
||||
static {
|
||||
STRING_TO_BYTES = new Converter<String, byte[]>() {
|
||||
@@ -96,6 +89,10 @@ abstract public class JedisConverters extends Converters {
|
||||
return TUPLE_SET_TO_TUPLE_SET;
|
||||
}
|
||||
|
||||
public static Converter<Exception,DataAccessException> exceptionConverter() {
|
||||
return EXCEPTION_CONVERTER;
|
||||
}
|
||||
|
||||
public static String[] toStrings(byte[][] source) {
|
||||
String[] result = new String[source.length];
|
||||
for (int i = 0; i < source.length; i++) {
|
||||
@@ -117,22 +114,7 @@ abstract public class JedisConverters extends Converters {
|
||||
}
|
||||
|
||||
public static DataAccessException toDataAccessException(Exception ex) {
|
||||
if (ex instanceof JedisDataException) {
|
||||
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof JedisConnectionException) {
|
||||
return new RedisConnectionFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof JedisException) {
|
||||
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof UnknownHostException) {
|
||||
return new RedisConnectionFailureException("Unknown host " + ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof IOException) {
|
||||
return new RedisConnectionFailureException("Could not connect to Redis server", ex);
|
||||
}
|
||||
return new RedisSystemException("Unknown jedis exception", ex);
|
||||
return EXCEPTION_CONVERTER.convert(ex);
|
||||
}
|
||||
|
||||
public static LIST_POSITION toListPosition(Position source) {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.data.redis.connection.jedis;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.redis.RedisConnectionFailureException;
|
||||
import org.springframework.data.redis.RedisSystemException;
|
||||
|
||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||
import redis.clients.jedis.exceptions.JedisDataException;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
|
||||
/**
|
||||
* Converts Exceptions thrown from Jedis to {@link DataAccessException}s
|
||||
*
|
||||
* @author Jennifer Hickey
|
||||
*
|
||||
*/
|
||||
public class JedisExceptionConverter implements Converter<Exception, DataAccessException> {
|
||||
|
||||
public DataAccessException convert(Exception ex) {
|
||||
if (ex instanceof DataAccessException) {
|
||||
return (DataAccessException) ex;
|
||||
}
|
||||
if (ex instanceof JedisDataException) {
|
||||
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof JedisConnectionException) {
|
||||
return new RedisConnectionFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof JedisException) {
|
||||
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof UnknownHostException) {
|
||||
return new RedisConnectionFailureException("Unknown host " + ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof IOException) {
|
||||
return new RedisConnectionFailureException("Could not connect to Redis server", ex);
|
||||
}
|
||||
return new RedisSystemException("Unknown jedis exception", ex);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user