/**
*Copyright [2009-2010] [dennis zhuang(killme2008@gmail.com)]
*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
*/
/**
*Copyright [2009-2010] [dennis zhuang(killme2008@gmail.com)]
*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 net.rubyeye.xmemcached.utils;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.rubyeye.xmemcached.CommandFactory;
import net.rubyeye.xmemcached.KeyProvider;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.MemcachedSessionLocator;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.auth.AuthInfo;
import net.rubyeye.xmemcached.buffer.BufferAllocator;
import net.rubyeye.xmemcached.buffer.SimpleBufferAllocator;
import net.rubyeye.xmemcached.command.TextCommandFactory;
import net.rubyeye.xmemcached.impl.ArrayMemcachedSessionLocator;
import net.rubyeye.xmemcached.impl.DefaultKeyProvider;
import net.rubyeye.xmemcached.transcoders.SerializingTranscoder;
import net.rubyeye.xmemcached.transcoders.Transcoder;
import org.springframework.beans.factory.FactoryBean;
import com.google.code.yanf4j.config.Configuration;
/**
* Implement spring's factory bean,for integrating to spring framework.
*
* @author dennis
*
*/
public class XMemcachedClientFactoryBean implements FactoryBean {
private MemcachedSessionLocator sessionLocator = new ArrayMemcachedSessionLocator();
private BufferAllocator bufferAllocator = new SimpleBufferAllocator();
private String servers;
private List<Integer> weights;
@SuppressWarnings("unchecked")
private Transcoder transcoder = new SerializingTranscoder();
private Configuration configuration = XMemcachedClientBuilder
.getDefaultConfiguration();
private CommandFactory commandFactory = new TextCommandFactory();
private Map<InetSocketAddress, AuthInfo> authInfoMap = new HashMap<InetSocketAddress, AuthInfo>();
private String name;
private int connectionPoolSize = MemcachedClient.DEFAULT_CONNECTION_POOL_SIZE;
private MemcachedClient memcachedClient;
private boolean failureMode;
private long opTimeout = MemcachedClient.DEFAULT_OP_TIMEOUT;
private long connectTimeout = MemcachedClient.DEFAULT_CONNECT_TIMEOUT;
private KeyProvider keyProvider = DefaultKeyProvider.INSTANCE;
private int maxQueuedNoReplyOperations = MemcachedClient.DEFAULT_MAX_QUEUED_NOPS;
private long healSessionInterval = MemcachedClient.DEFAULT_HEAL_SESSION_INTERVAL;
private boolean enableHealSession = true;
public long getHealSessionInterval() {
return healSessionInterval;
}
public void setHealSessionInterval(long healSessionInterval) {
this.healSessionInterval = healSessionInterval;
}
public boolean isEnableHealSession() {
return enableHealSession;
}
public void setEnableHealSession(boolean enableHealSession) {
this.enableHealSession = enableHealSession;
}
public long getOpTimeout() {
return opTimeout;
}
public KeyProvider getKeyProvider() {
return keyProvider;
}
public void setKeyProvider(KeyProvider keyProvider) {
this.keyProvider = keyProvider;
}
public void setOpTimeout(long opTimeout) {
this.opTimeout = opTimeout;
}
public final CommandFactory getCommandFactory() {
return this.commandFactory;
}
public final void setCommandFactory(CommandFactory commandFactory) {
this.commandFactory = commandFactory;
}
public XMemcachedClientFactoryBean() {
}
public Map<InetSocketAddress, AuthInfo> getAuthInfoMap() {
return this.authInfoMap;
}
public void setAuthInfoMap(Map<InetSocketAddress, AuthInfo> authInfoMap) {
this.authInfoMap = authInfoMap;
}
public boolean isFailureMode() {
return this.failureMode;
}
public void setFailureMode(boolean failureMode) {
this.failureMode = failureMode;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getConnectionPoolSize() {
return this.connectionPoolSize;
}
public final void setConnectionPoolSize(int poolSize) {
this.connectionPoolSize = poolSize;
}
public void setSessionLocator(MemcachedSessionLocator sessionLocator) {
this.sessionLocator = sessionLocator;
}
public void setBufferAllocator(BufferAllocator bufferAllocator) {
this.bufferAllocator = bufferAllocator;
}
@SuppressWarnings("unchecked")
public void setTranscoder(Transcoder transcoder) {
this.transcoder = transcoder;
}
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
}
public String getServers() {
return this.servers;
}
public void setServers(String servers) {
this.servers = servers;
}
public MemcachedSessionLocator getSessionLocator() {
return this.sessionLocator;
}
public BufferAllocator getBufferAllocator() {
return this.bufferAllocator;
}
@SuppressWarnings("unchecked")
public Transcoder getTranscoder() {
return this.transcoder;
}
public List<Integer> getWeights() {
return this.weights;
}
/**
* Set max queued noreply operations number
*
* @see MemcachedClient#DEFAULT_MAX_QUEUED_NOPS
* @param maxQueuedNoReplyOperations
* @since 1.3.8
*/
public void setMaxQueuedNoReplyOperations(int maxQueuedNoReplyOperations) {
if (maxQueuedNoReplyOperations <= 1)
throw new IllegalArgumentException("maxQueuedNoReplyOperations<=1");
this.maxQueuedNoReplyOperations = maxQueuedNoReplyOperations;
}
public void setWeights(List<Integer> weights) {
this.weights = weights;
}
public Configuration getConfiguration() {
return this.configuration;
}
public Object getObject() throws Exception {
this.checkAttribute();
Map<InetSocketAddress, InetSocketAddress> serverMap = this
.getServerMap();
int[] weightsArray = this.getWeightsArray(serverMap);
MemcachedClientBuilder builder = this.newBuilder(serverMap,
weightsArray);
this.configBuilder(builder);
this.memcachedClient = builder.build();
this.memcachedClient.setOpTimeout(opTimeout);
return this.memcachedClient;
}
private MemcachedClientBuilder newBuilder(
Map<InetSocketAddress, InetSocketAddress> serverMap,
int[] weightsArray) {
MemcachedClientBuilder builder;
if (weightsArray == null) {
builder = new XMemcachedClientBuilder(serverMap);
} else {
builder = new XMemcachedClientBuilder(serverMap, weightsArray);
}
return builder;
}
private void configBuilder(MemcachedClientBuilder builder) {
builder.setConfiguration(this.configuration);
builder.setBufferAllocator(this.bufferAllocator);
builder.setSessionLocator(this.sessionLocator);
builder.setTranscoder(this.transcoder);
builder.setCommandFactory(this.commandFactory);
builder.setConnectionPoolSize(this.connectionPoolSize);
builder.setAuthInfoMap(this.authInfoMap);
builder.setFailureMode(this.failureMode);
builder.setKeyProvider(keyProvider);
builder.setMaxQueuedNoReplyOperations(this.maxQueuedNoReplyOperations);
builder.setName(this.name);
builder.setEnableHealSession(this.enableHealSession);
builder.setHealSessionInterval(this.healSessionInterval);
builder.setConnectTimeout(connectTimeout);
builder.setOpTimeout(opTimeout);
}
private int[] getWeightsArray(
Map<InetSocketAddress, InetSocketAddress> serverMap) {
int[] weightsArray = null;
if (serverMap != null && serverMap.size() > 0 && this.weights != null) {
if (this.weights.size() < serverMap.size()) {
throw new IllegalArgumentException(
"Weight list's size is less than server list's size");
}
weightsArray = new int[this.weights.size()];
for (int i = 0; i < weightsArray.length; i++) {
weightsArray[i] = this.weights.get(i);
}
}
return weightsArray;
}
private Map<InetSocketAddress, InetSocketAddress> getServerMap() {
Map<InetSocketAddress, InetSocketAddress> serverMap = null;
if (this.servers != null && this.servers.length() > 0) {
serverMap = AddrUtil.getAddressMap(this.servers);
}
return serverMap;
}
private void checkAttribute() {
if (this.bufferAllocator == null) {
throw new NullPointerException("Null BufferAllocator");
}
if (this.sessionLocator == null) {
throw new NullPointerException("Null MemcachedSessionLocator");
}
if (this.configuration == null) {
throw new NullPointerException("Null networking configuration");
}
if (this.commandFactory == null) {
throw new NullPointerException("Null command factory");
}
if (this.weights != null && this.servers == null) {
throw new NullPointerException("Empty server list");
}
}
public void shutdown() throws IOException {
if (this.memcachedClient != null) {
this.memcachedClient.shutdown();
}
}
@SuppressWarnings("rawtypes")
public Class getObjectType() {
return MemcachedClient.class;
}
public boolean isSingleton() {
return true;
}
public long getConnectTimeout() {
return connectTimeout;
}
public void setConnectTimeout(long connectTimeout) {
this.connectTimeout = connectTimeout;
}
}