/* * The MIT License * * Copyright 2012 Sony Mobile Communications AB. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.sonyericsson.jenkins.plugins.bfa.db; import com.mongodb.MongoException; import com.sonyericsson.jenkins.plugins.bfa.model.FailureCause; import net.vz.mongodb.jackson.DBCursor; import net.vz.mongodb.jackson.JacksonDBCollection; import java.util.LinkedList; import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.logging.Level; import java.util.logging.Logger; import static com.sonyericsson.jenkins.plugins.bfa.db.MongoDBKnowledgeBase.NOT_REMOVED_QUERY; /** * Cache for the MongoDBKnowledgeBase. * * @author Tomas Westling <tomas.westling@sonyericsson.com> */ public class MongoDBKnowledgeBaseCache { private Semaphore shouldUpdate; private UpdateThread updaterThread; private Timer timer; private TimerTask timerTask; private List<FailureCause> cachedFailureCauses; private List<String> categories; private JacksonDBCollection<FailureCause, String> jacksonCollection; private static final long CACHE_UPDATE_INTERVAL = 60000; private static final Logger logger = Logger.getLogger(MongoDBKnowledgeBase.class.getName()); /** * Standard constructor. * @param jacksonCollection the JacksonDBCollection, used for accessing the database. */ public MongoDBKnowledgeBaseCache(JacksonDBCollection<FailureCause, String> jacksonCollection) { this.jacksonCollection = jacksonCollection; } /** * Run when the cache, including the update mechanism, should start running. */ public void start() { shouldUpdate = new Semaphore(); updaterThread = new UpdateThread(); updaterThread.start(); timer = new Timer(); timerTask = new TimerTask() { @Override public void run() { shouldUpdate.release(); } }; timer.scheduleAtFixedRate(timerTask, 0, CACHE_UPDATE_INTERVAL); } /** * Run when we want to shut down the cache. */ public void stop() { timer.cancel(); timer = null; timerTask = null; updaterThread.stopThread(); updaterThread = null; } /** * Signal that an update of the Cache should be made. */ public void updateCache() { if (shouldUpdate != null) { shouldUpdate.release(); } } /** * Getter for the cachedFailureCauses. * @return the causes. */ public List<FailureCause> getCauses() { return cachedFailureCauses; } /** * Getter for the categories of all FailureCauses. * @return the categories. */ public List<String> getCategories() { return categories; } /** * The thread responsible for updating the MongoDB cache. */ protected class UpdateThread extends Thread { private volatile boolean stop = false; @Override public void run() { while (!stop) { try { shouldUpdate.acquire(); if (stop) { break; } List<FailureCause> list = new LinkedList<FailureCause>(); DBCursor<FailureCause> dbCauses = jacksonCollection.find(NOT_REMOVED_QUERY); while (dbCauses.hasNext()) { list.add(dbCauses.next()); } cachedFailureCauses = list; categories = jacksonCollection.distinct("categories"); } catch (MongoException e) { logger.log(Level.SEVERE, "MongoException caught when updating cache: " + e); } catch (InterruptedException e) { logger.log(Level.WARNING, "Updater thread interrupted", e); } } } /** * Stops the execution of this thread. */ protected void stopThread() { stop = true; shouldUpdate.release(); } } }