Java tutorial
/* * R Service Bus * * Copyright (c) Copyright of Open Analytics NV, 2010-2015 * * =========================================================================== * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package eu.openanalytics.rsb.stats; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.HashMap; import java.util.Map; import java.util.TimeZone; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.pool.impl.GenericObjectPool; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import eu.openanalytics.rsb.Util; import eu.openanalytics.rsb.message.Job; /** * @author "OpenAnalytics <rsb.development@openanalytics.eu>" */ public class RedisJobStatisticsHandler implements JobStatisticsHandler { private static final Log LOGGER = LogFactory.getLog(RedisJobStatisticsHandler.class); private static final SimpleDateFormat MONTH_STAMP_FORMAT = new SimpleDateFormat("yyyy-MM"); private static final TimeZone UTC = TimeZone.getTimeZone("UTC"); private static final String RSB_STATS_KEY_PREFIX = "rsb:stats:"; private static final String RSB_STATS_APPLICATIONS_SET_KEY = RSB_STATS_KEY_PREFIX + "applications"; private JedisPool pool; private String redisHost; private int redisPort; private interface RedisAction { void run(Jedis jedis); } public void setConfiguration(final Map<String, Object> configuration) { redisHost = (String) configuration.get("host"); redisPort = (Integer) configuration.get("port"); } public void initialize() { final GenericObjectPool.Config poolConfig = new GenericObjectPool.Config(); poolConfig.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW; pool = new JedisPool(poolConfig, redisHost, redisPort); final boolean redisConfigurationOk = runWithJedis(new RedisAction() { public void run(final Jedis jedis) { final String pingResponse = jedis.ping(); Validate.isTrue("PONG".equals(pingResponse), "Unexpected response received from pinging Redis: " + pingResponse); LOGGER.info(String.format("%s successfully connected to Redis: %s:%d", getClass().getSimpleName(), redisHost, redisPort)); } }); Validate.isTrue(redisConfigurationOk, "Redis can't be contacted: please check parameter 'rsb.jobs.stats.handler' (set it to 'none' to disable statistics altogether)"); } public void destroy() { pool.destroy(); } public void storeJobStatistics(final Job job, final Calendar jobCompletionTime, final long millisecondsSpentProcessing, final String rServiAddress) { runWithJedis(new RedisAction() { public void run(final Jedis jedis) { // ensure application is registered as a statistics producer jedis.sadd(RSB_STATS_APPLICATIONS_SET_KEY, job.getApplicationName()); // add monthstamp to application's set of monthstamps jobCompletionTime.setTimeZone(UTC); final String monthStamp = MONTH_STAMP_FORMAT.format(jobCompletionTime.getTime()); jedis.sadd(RSB_STATS_KEY_PREFIX + job.getApplicationName() + ":monthstamps", monthStamp); // create persisted statistics JSON structure and store it in monthstamp list final Map<String, Object> statsMap = new HashMap<String, Object>(5); statsMap.put("application_name", job.getApplicationName()); statsMap.put("job_id", job.getJobId()); statsMap.put("utc_timestamp", jobCompletionTime.getTimeInMillis()); statsMap.put("time_spent", millisecondsSpentProcessing); statsMap.put("r_servi_address", rServiAddress); if (StringUtils.isNotBlank(job.getUserName())) { statsMap.put("user_name", job.getUserName()); } final String statsJson = Util.toJson(statsMap); jedis.lpush(RSB_STATS_KEY_PREFIX + job.getApplicationName() + ":" + monthStamp, statsJson); } }); } private boolean runWithJedis(final RedisAction action) { Jedis jedis = null; try { jedis = pool.getResource(); action.run(jedis); return true; } catch (final Throwable t) { LOGGER.warn("Failed to run action on Redis", t); return false; } finally { if (jedis != null) { try { pool.returnResource(jedis); } catch (final Throwable t) { LOGGER.warn("Failed to return Redis client to the pool", t); } } } } }