/* * Copyright 2010 NCHOVY * * 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.krakenapps.sentry.impl; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.apache.felix.ipojo.annotations.Component; import org.apache.felix.ipojo.annotations.Invalidate; import org.apache.felix.ipojo.annotations.Provides; import org.apache.felix.ipojo.annotations.Requires; import org.apache.felix.ipojo.annotations.Validate; import org.krakenapps.sentry.process.ProcessCheck; import org.krakenapps.sentry.process.ProcessCheckEventListener; import org.krakenapps.sentry.process.ProcessCheckOption; import org.krakenapps.sentry.process.ProcessMonitor; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; import org.osgi.service.prefs.PreferencesService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Component(name = "process-monitor") @Provides public class ProcessMonitorImpl implements ProcessMonitor { private static final String PROCESS_CHECK_KEY = "process_check"; private final Logger logger = LoggerFactory.getLogger(ProcessMonitorImpl.class.getName()); private Map<String, ProcessCheck> checklist; private Set<ProcessCheckEventListener> callbacks; @Requires private PreferencesService prefsvc; @Validate public void start() { checklist = new ConcurrentHashMap<String, ProcessCheck>(); callbacks = Collections.newSetFromMap(new ConcurrentHashMap<ProcessCheckEventListener, Boolean>()); // load saved checklist try { Preferences root = getConfig(); for (String name : root.childrenNames()) { String policy = root.node(name).get("policy", null); ProcessCheckOption option = ProcessCheckOption.valueOf(policy); checklist.put(name, new ProcessCheck(name, option)); } } catch (BackingStoreException e) { logger.error("kraken sentry: cannot load process checklist", e); } } @Invalidate public void stop() { checklist.clear(); } @Override public Collection<ProcessCheck> getProcessChecklist() { return checklist.values(); } @Override public void addProcess(String processName, ProcessCheckOption option) { if (processName == null) throw new IllegalArgumentException("process name must be not null"); // add to persistent config try { Preferences p = getConfig(); Preferences node = p.node(processName.toLowerCase()); node.put("policy", option.toString()); p.flush(); p.sync(); // add to checklist checklist.put(processName, new ProcessCheck(processName, option)); } catch (BackingStoreException e) { logger.error("kraken sentry: cannot save process check", e); } } @Override public void removeProcess(String processName) { // remove persistent config try { Preferences p = getConfig(); if (!p.nodeExists(processName.toLowerCase())) throw new IllegalStateException(processName + " not found"); p.node(processName.toLowerCase()).removeNode(); p.flush(); p.sync(); // remove from checklist checklist.remove(processName); } catch (BackingStoreException e) { logger.error("kraken sentry: cannot remove process check", e); } } @Override public void addListener(ProcessCheckEventListener callback) { callbacks.add(callback); } @Override public void removeListener(ProcessCheckEventListener callback) { callbacks.remove(callback); } @Override public void dispatch(String processName, ProcessCheckOption option, boolean isRunning) { for (ProcessCheckEventListener callback : callbacks) { try { callback.onCheck(processName, option, isRunning); } catch (Exception e) { logger.warn("kraken sentry: process check event listener should not throw any exception", e); } } } private Preferences getConfig() { try { Preferences root = prefsvc.getSystemPreferences(); if (!root.nodeExists(PROCESS_CHECK_KEY)) { Preferences p = root.node(PROCESS_CHECK_KEY); p.flush(); p.sync(); } return root.node(PROCESS_CHECK_KEY); } catch (BackingStoreException e) { logger.error("kraken sentry: cannot fetch config store", e); throw new IllegalStateException("cannot fetch process check config"); } } }