All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.atmosphere.plugin.redis.RedisUtil Maven / Gradle / Ivy
/*
* Copyright 2013 Jeanfrancois Arcand
*
* 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.atmosphere.plugin.redis;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.atmosphere.cpr.AtmosphereConfig;
import com.vaadin.external.org.slf4j.Logger;
import com.vaadin.external.org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.exceptions.JedisException;
import java.net.URI;
import java.util.concurrent.atomic.AtomicBoolean;
public class RedisUtil {
private static final Logger logger = LoggerFactory.getLogger(RedisBroadcaster.class);
private static final String REDIS_AUTH = RedisBroadcaster.class.getName() + ".authorization";
private static final String REDIS_SERVER = RedisBroadcaster.class.getName() + ".server";
private static final String REDIS_SHARED_POOL = RedisBroadcaster.class.getName() + ".sharedPool";
private Jedis jedisSubscriber;
private Jedis jedisPublisher;
private String authToken = null;
private boolean sharedPool = false;
private JedisPool jedisPool;
private final AtmosphereConfig config;
private URI uri;
private final AtomicBoolean destroyed = new AtomicBoolean();
private final Callback callback;
public RedisUtil(URI uri, AtmosphereConfig config, Callback callback) {
this.config = config;
this.callback = callback;
this.uri = uri;
}
public String getAuth() {
return authToken;
}
public void setAuth(String auth) {
authToken = auth;
}
public void configure() {
if (config.getServletConfig().getInitParameter(REDIS_AUTH) != null) {
authToken = config.getServletConfig().getInitParameter(REDIS_AUTH);
}
if (config.getServletConfig().getInitParameter(REDIS_SERVER) != null) {
uri = URI.create(config.getServletConfig().getInitParameter(REDIS_SERVER));
} else if (uri == null) {
throw new NullPointerException("uri cannot be null");
}
if (config.getServletConfig().getInitParameter(REDIS_SHARED_POOL) != null) {
sharedPool = Boolean.parseBoolean(config.getServletConfig().getInitParameter(REDIS_SHARED_POOL));
}
logger.info("{} shared connection pool {}", getClass().getName(), sharedPool);
if (sharedPool) {
if (config.properties().get(REDIS_SHARED_POOL) != null) {
jedisPool = (JedisPool) config.properties().get(REDIS_SHARED_POOL);
}
// setup is synchronized, no need to sync here as well.
if (jedisPool == null) {
GenericObjectPool.Config gConfig = new GenericObjectPool.Config();
gConfig.testOnBorrow = true;
gConfig.testWhileIdle = true;
jedisPool = new JedisPool(gConfig, uri.getHost(), uri.getPort());
config.properties().put(REDIS_SHARED_POOL, jedisPool);
} else {
disconnectSubscriber();
}
}
// We use the pool only for publishing
jedisSubscriber = new Jedis(uri.getHost(), uri.getPort());
try {
jedisSubscriber.connect();
auth(jedisSubscriber);
} catch (JedisException e) {
logger.error("failed to connect subscriber", e);
disconnectSubscriber();
}
jedisPublisher = sharedPool ? null : new Jedis(uri.getHost(), uri.getPort());
if (!sharedPool) {
try {
jedisPublisher.connect();
auth(jedisPublisher);
} catch (JedisException e) {
logger.error("failed to connect publisher", e);
disconnectPublisher();
}
}
}
public synchronized void setID(String id) {
disconnectPublisher();
disconnectSubscriber();
}
/**
* {@inheritDoc}
*/
public void destroy() {
if (!sharedPool) {
Object lockingObject = getLockingObject();
synchronized (lockingObject) {
try {
disconnectPublisher();
disconnectSubscriber();
if (jedisPool != null) {
jedisPool.destroy();
}
} catch (Throwable t) {
logger.warn("Jedis error on close", t);
} finally {
config.properties().put(REDIS_SHARED_POOL, null);
}
}
}
}
public boolean isShared(){
return sharedPool;
}
/**
* {@inheritDoc}
*/
public void incomingBroadcast() {
logger.info("Subscribing to: {}", callback.getID());
jedisSubscriber.subscribe(new JedisPubSub() {
public void onMessage(String channel, String message) {
callback.broadcastReceivedMessage(message);
}
public void onSubscribe(String channel, int subscribedChannels) {
logger.debug("onSubscribe: {}", channel);
}
public void onUnsubscribe(String channel, int subscribedChannels) {
logger.debug("onUnsubscribe: {}", channel);
}
public void onPSubscribe(String pattern, int subscribedChannels) {
logger.debug("onPSubscribe: {}", pattern);
}
public void onPUnsubscribe(String pattern, int subscribedChannels) {
logger.debug("onPUnsubscribe: {}", pattern);
}
public void onPMessage(String pattern, String channel, String message) {
logger.debug("onPMessage: pattern: {}, channel: {}, message: {}",
new Object[]{pattern, channel, message});
}
}, callback.getID());
}
public void outgoingBroadcast(Object message) {
// Marshal the message outside of the sync block.
String contents = message.toString();
Object lockingObject = getLockingObject();
synchronized (lockingObject) {
if (destroyed.get()) {
logger.debug("JedisPool closed. Re-opening");
setID(callback.getID());
}
if (sharedPool) {
for (int i = 0; i < 10; ++i) {
boolean valid = true;
Jedis jedis = jedisPool.getResource();
try {
auth(jedis);
jedis.publish(callback.getID(), contents);
} catch (JedisException e) {
valid = false;
logger.warn("outgoingBroadcast exception", e);
} finally {
if (valid) {
jedisPool.returnResource(jedis);
} else {
jedisPool.returnBrokenResource(jedis);
}
}
if (valid) {
break;
}
}
} else {
try {
jedisPublisher.publish(callback.getID(), contents);
} catch (JedisException e) {
logger.warn("outgoingBroadcast exception", e);
}
}
}
}
private void auth(Jedis jedis) {
if (authToken != null) {
jedis.auth(authToken);
}
}
private void disconnectSubscriber() {
if (jedisSubscriber == null) return;
synchronized (jedisSubscriber) {
try {
jedisSubscriber.disconnect();
} catch (JedisException e) {
logger.error("failed to disconnect subscriber", e);
}
}
}
private void disconnectPublisher() {
if (jedisPublisher == null) return;
synchronized (jedisPublisher) {
try {
jedisPublisher.disconnect();
} catch (JedisException e) {
logger.error("failed to disconnect publisher", e);
}
}
}
private Object getLockingObject() {
return sharedPool ? jedisPool : jedisPublisher;
}
public static interface Callback {
String getID();
void broadcastReceivedMessage(String message);
}
}