/* ********************************************************************
Licensed to Jasig under one or more contributor license
agreements. See the NOTICE file distributed with this work
for additional information regarding copyright ownership.
Jasig licenses this file to you 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.bedework.calsvc.jmx;
import org.bedework.calfacade.BwStats;
import org.bedework.calfacade.configs.SystemProperties;
import org.bedework.calfacade.exc.CalFacadeException;
import org.bedework.calfacade.ifs.IfInfo;
import org.bedework.calsvci.CalSvcFactoryDefault;
import org.bedework.calsvci.CalSvcI;
import org.bedework.calsvci.CalSvcIPars;
import org.bedework.util.config.ConfInfo;
import org.bedework.util.jmx.ConfBase;
import org.bedework.util.jmx.ConfigHolder;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
/**
* @author douglm
*
*/
public class SystemConf extends ConfBase<SystemPropertiesImpl>
implements SystemConfMBean, ConfigHolder<SystemPropertiesImpl> {
/** Name of the property holding the location of the config data */
public static final String confuriPname = "org.bedework.bwengine.confuri";
private CalSvcI svci;
private boolean running;
private static final Set<String> dontKill = new TreeSet<>();
static {
dontKill.add(CalSvcIPars.logIdIndexer);
dontKill.add(CalSvcIPars.logIdRestore);
}
private class AutoKillThread extends Thread {
int ctr;
boolean showedTrace;
int terminated;
int failedTerminations;
AutoKillThread() {
super("Bedework AutoKill");
}
@Override
public void run() {
while (running) {
final int waitMins = getAutoKillMinutes();
try {
if (waitMins == 0) {
// Display every 10 mins
ctr++;
if (ctr == 10) {
info(listOpenIfs());
ctr = 0;
}
} else {
if (debug) {
debug("About to check interfaces");
}
checkIfs(waitMins * 60);
}
} catch (final Throwable t) {
if (!showedTrace) {
error(t);
showedTrace = true;
} else {
error(t.getMessage());
}
}
if (running) {
// Wait a bit before restarting
try {
synchronized (this) {
final int wait;
if (waitMins == 0) {
// Autokill disabled - go to sleep for a minute
wait = 60 * 1000;
} else {
wait = waitMins * 60 * 1000;
}
this.wait(wait);
}
} catch (final Throwable t) {
error(t.getMessage());
}
}
}
}
private void checkIfs(final int waitSecs) {
try {
getSvci();
if (svci != null) {
for (final IfInfo ifInfo: svci.getActiveIfInfos()) {
if (ifInfo.getSeconds() > waitSecs) {
if (dontKill.contains(ifInfo.getLogid())) {
warn("Skipping long running task: " + ifInfo.getId());
continue;
}
try {
if (debug) {
debug("About to shut down interface " +
ifInfo.getId());
}
svci.kill(ifInfo);
terminated++;
} catch (final Throwable t) {
warn("Failed to terminate " +
ifInfo.getId());
error(t);
failedTerminations++;
}
}
}
}
} catch (final Throwable t) {
error(t);
} finally {
closeSvci();
}
}
}
private AutoKillThread autoKiller;
/**
* @param name of config
*/
public SystemConf(final String name) {
super(getServiceName(name));
setConfigName(name);
setConfigPname(confuriPname);
}
/**
* @param name of config
* @return service name for the mbean with this name
*/
public static String getServiceName(final String name) {
return "org.bedework.bwengine:service=" + name;
}
/* ========================================================================
* Attributes
* ======================================================================== */
@Override
public void setTzid(final String val) {
getConfig().setTzid(val);
}
@Override
public String getTzid() {
return getConfig().getTzid();
}
@Override
public void setTzServeruri(final String val) {
getConfig().setTzServeruri(val);
}
@Override
public String getTzServeruri() {
return getConfig().getTzServeruri();
}
@Override
public void setSystemid(final String val) {
getConfig().setSystemid(val);
}
@Override
public String getSystemid() {
return getConfig().getSystemid();
}
@Override
public void setRootUsers(final String val) {
getConfig().setRootUsers(val);
}
@Override
public String getRootUsers() {
return getConfig().getRootUsers();
}
@Override
public void setFeatureFlags(final String val) {
getConfig().setFeatureFlags(val);
}
@Override
public String getFeatureFlags() {
return getConfig().getFeatureFlags();
}
@Override
public void setAdminContact(final String val) {
getConfig().setAdminContact(val);
}
@Override
public String getAdminContact() {
return getConfig().getAdminContact();
}
@Override
public void setIscheduleURI(final String val) {
getConfig().setIscheduleURI(val);
}
@Override
public String getIscheduleURI() {
return getConfig().getIscheduleURI();
}
@Override
public void setFburlServiceURI(final String val) {
getConfig().setFburlServiceURI(val);
}
@Override
public String getFburlServiceURI() {
return getConfig().getFburlServiceURI();
}
/** Set the web calendar service uri - null for no web calendar service
*
* @param val String
*/
@Override
public void setWebcalServiceURI(final String val) {
getConfig().setWebcalServiceURI(val);
}
/** get the web calendar service uri - null for no web calendar service
*
* @return String
*/
@Override
public String getWebcalServiceURI() {
return getConfig().getWebcalServiceURI();
}
/** Set the calws soap web service uri - null for no service
*
* @param val String
*/
@Override
public void setCalSoapWsURI(final String val) {
getConfig().setCalSoapWsURI(val);
}
/** Get the calws soap web service uri - null for no service
*
* @return String
*/
@Override
public String getCalSoapWsURI() {
return getConfig().getCalSoapWsURI();
}
/** Set the calws soap web service WSDL uri - null for no service
*
* @param val String
*/
@Override
public void setCalSoapWsWSDLURI(final String val) {
getConfig().setCalSoapWsWSDLURI(val);
}
@Override
public String getCalSoapWsWSDLURI() {
return getConfig().getCalSoapWsWSDLURI();
}
@Override
public void setTimezonesByReference(final boolean val) {
getConfig().setTimezonesByReference(val);
}
@Override
public boolean getTimezonesByReference() {
return getConfig().getTimezonesByReference();
}
@Override
public void setUserauthClass(final String val) {
getConfig().setUserauthClass(val);
}
@Override
public String getUserauthClass() {
return getConfig().getUserauthClass();
}
@Override
public void setMailerClass(final String val) {
getConfig().setMailerClass(val);
}
/**
*
* @return String
*/
@Override
public String getMailerClass() {
return getConfig().getMailerClass();
}
/** Set the admingroups class
*
* @param val String admingroups class
*/
@Override
public void setAdmingroupsClass(final String val) {
getConfig().setAdmingroupsClass(val);
}
@Override
public String getAdmingroupsClass() {
return getConfig().getAdmingroupsClass();
}
@Override
public void setUsergroupsClass(final String val) {
getConfig().setUsergroupsClass(val);
}
@Override
public String getUsergroupsClass() {
return getConfig().getUsergroupsClass();
}
@Override
public void setLocaleList(final String val) {
getConfig().setLocaleList(val);
}
@Override
public String getLocaleList() {
return getConfig().getLocaleList();
}
@Override
public void setEventregAdminToken(final String val) {
getConfig().setEventregAdminToken(val);
}
@Override
public String getEventregAdminToken() {
return getConfig().getEventregAdminToken();
}
@Override
public void setEventregUrl(final String val) {
getConfig().setEventregUrl(val);
}
@Override
public String getEventregUrl() {
return getConfig().getEventregUrl();
}
@Override
public void setCacheUrlPrefix(final String val) {
getConfig().setCacheUrlPrefix(val);
}
@Override
public String getCacheUrlPrefix() {
return getConfig().getCacheUrlPrefix();
}
@Override
public void setAutoKillMinutes(final int val) {
getConfig().setAutoKillMinutes(val);
}
@Override
public int getAutoKillMinutes() {
return getConfig().getAutoKillMinutes();
}
@Override
public void setSuggestionEnabled(final boolean val) {
getConfig().setSuggestionEnabled(val);
}
@Override
public boolean getSuggestionEnabled() {
return getConfig().getSuggestionEnabled();
}
@Override
public void setWorkflowEnabled(final boolean val) {
getConfig().setWorkflowEnabled(val);
}
@Override
public boolean getWorkflowEnabled() {
return getConfig().getWorkflowEnabled();
}
@Override
public void setWorkflowRoot(final String val) {
getConfig().setWorkflowRoot(val);
}
@Override
public String getWorkflowRoot() {
return getConfig().getWorkflowRoot();
}
@Override
public void setUserSubscriptionsOnly(final boolean val) {
getConfig().setUserSubscriptionsOnly(val);
}
@Override
public boolean getUserSubscriptionsOnly() {
return getConfig().getUserSubscriptionsOnly();
}
@Override
public int getAutoKillTerminated() {
return autoKiller.terminated;
}
@Override
public int getAutoKillFailedTerminations() {
return autoKiller.failedTerminations;
}
@Override
public void setVpollMaxItems(final Integer val) {
getConfig().setVpollMaxItems(val);
}
@Override
public Integer getVpollMaxItems() {
return getConfig().getVpollMaxItems();
}
@Override
public void setVpollMaxActive(final Integer val) {
getConfig().setVpollMaxActive(val);
}
@Override
public Integer getVpollMaxActive() {
return getConfig().getVpollMaxActive();
}
@Override
public void setVpollMaxVoters(final Integer val) {
getConfig().setVpollMaxVoters(val);
}
@Override
public Integer getVpollMaxVoters() {
return getConfig().getVpollMaxVoters();
}
@Override
public void setSyseventsProperties(final List<String> val) {
getConfig().setSyseventsProperties(val);
}
@Override
@ConfInfo(collectionElementName = "syseventsProperty" ,
elementType = "java.lang.String")
public List<String> getSyseventsProperties() {
return getConfig().getSyseventsProperties();
}
@Override
public void addSyseventsProperty(final String name,
final String val) {
getConfig().addSyseventsProperty(name, val);
}
@Override
public String getSyseventsProperty(final String name) {
return getConfig().getSyseventsProperty(name);
}
@Override
public void removeSyseventsProperty(final String name) {
getConfig().removeSyseventsProperty(name);
}
@Override
public void setSyseventsProperty(final String name,
final String val) {
getConfig().setSyseventsProperty(name, val);
}
@Override
public void setDbStatsEnabled(final boolean enable) {
try {
getSvci();
if (svci != null) {
svci.setDbStatsEnabled(enable);
}
} catch (final Throwable t) {
error(t);
} finally {
closeSvci();
}
}
@Override
public boolean getDbStatsEnabled() {
try {
getSvci();
return svci != null && svci.getDbStatsEnabled();
} catch (final Throwable t) {
error(t);
return false;
} finally {
closeSvci();
}
}
/* ========================================================================
* Operations
* ======================================================================== */
@Override
public BwStats getStats() {
try {
getSvci();
if (svci == null) {
return null;
}
return svci.getStats();
} catch (final Throwable t) {
error(t);
return null;
} finally {
closeSvci();
}
}
@Override
public void dumpDbStats() {
try {
getSvci();
if (svci != null) {
svci.dumpDbStats();
}
} catch (final Throwable t) {
error(t);
} finally {
closeSvci();
}
}
@Override
public String listOpenIfs() {
final StringBuilder sb = new StringBuilder();
try {
getSvci();
if (svci != null) {
for (final IfInfo ifInfo: svci.getActiveIfInfos()) {
sb.append(ifInfo.getId());
sb.append("\t");
sb.append(ifInfo.getLastStateTime());
sb.append("\t");
sb.append(ifInfo.getState());
sb.append("\t");
sb.append(ifInfo.getSeconds());
sb.append("\n");
}
}
} catch (final Throwable t) {
error(t);
} finally {
closeSvci();
}
return sb.toString();
}
@Override
public String loadConfig() {
final String res = loadConfig(SystemPropertiesImpl.class);
try {
autoKiller = new AutoKillThread();
running = true;
autoKiller.start();
} catch (final Throwable t) {
error(t);
error("Unable to start autokill process");
}
return res;
}
/** Save the configuration.
*
*/
@Override
public void putConfig() {
saveConfig();
}
@Override
public SystemProperties cloneIt() {
return null;
}
/* ====================================================================
* Private methods
* ==================================================================== */
/** Get an svci object and return it. Also embed it in this object.
*
* @return svci object
* @throws org.bedework.calfacade.exc.CalFacadeException
*/
private CalSvcI getSvci() throws CalFacadeException {
if (getConfig() == null) {
return null;
}
if ((svci != null) && svci.isOpen()) {
return svci;
}
/* Extract a root user */
if (getRootUsers() == null) {
return null;
}
final String[] rootUsers = getRootUsers().split(",");
if ((rootUsers.length == 0) || (rootUsers[0] == null)) {
return null;
}
final CalSvcIPars pars = CalSvcIPars.getServicePars(getServiceName(),
rootUsers[0],
true, // publicAdmin
true); // Allow super user
svci = new CalSvcFactoryDefault().getSvc(pars);
svci.open();
svci.beginTransaction();
return svci;
}
/**
*/
private void closeSvci() {
if ((svci == null) || !svci.isOpen()) {
return;
}
try {
svci.endTransaction();
} catch (final Throwable t) {
try {
svci.close();
} catch (final Throwable ignored) {
}
}
try {
svci.close();
} catch (final Throwable ignored) {
}
}
/* ========================================================================
* Lifecycle
* ======================================================================== */
}