IDEMPIERE-4056 Implement cluster support for idempiere Monitor and Server Manager

This commit is contained in:
Heng Sin Low 2019-10-02 12:58:48 +08:00
parent f579549cba
commit 2cecee1a0c
19 changed files with 1729 additions and 180 deletions

View File

@ -38,6 +38,8 @@ Import-Package: javax.jms;version="1.1.0",
Export-Package: org.adempiere.server, Export-Package: org.adempiere.server,
org.compiere.ldap, org.compiere.ldap,
org.compiere.server, org.compiere.server,
org.idempiere.server.cluster,
org.idempiere.server.cluster.callable,
org.idempiere.server.factory org.idempiere.server.factory
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Service-Component: OSGI-INF/*.xml Service-Component: OSGI-INF/*.xml

View File

@ -35,6 +35,7 @@ import org.compiere.model.MScheduler;
import org.compiere.model.MSession; import org.compiere.model.MSession;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.idempiere.server.cluster.ClusterServerMgr;
import org.osgi.framework.BundleEvent; import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener; import org.osgi.framework.BundleListener;
import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceReference;
@ -47,19 +48,15 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer;
* @author Jorg Janke * @author Jorg Janke
* @version $Id: AdempiereServerMgr.java,v 1.4 2006/10/09 00:23:26 jjanke Exp $ * @version $Id: AdempiereServerMgr.java,v 1.4 2006/10/09 00:23:26 jjanke Exp $
*/ */
public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFactory<AdempiereServer, AdempiereProcessor>, IServerFactory<AdempiereServer, AdempiereProcessor>>, BundleListener public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFactory<AdempiereServer, AdempiereProcessor>, IServerFactory<AdempiereServer, AdempiereProcessor>>, BundleListener, IServerManager
{ {
private static ServiceTracker<IServerFactory<AdempiereServer, AdempiereProcessor>, IServerFactory<AdempiereServer, AdempiereProcessor>> serviceTracker; private static ServiceTracker<IServerFactory<AdempiereServer, AdempiereProcessor>, IServerFactory<AdempiereServer, AdempiereProcessor>> serviceTracker;
public static int SERVER_STATE_NOT_SCHEDULE = 0;
public static int SERVER_STATE_STARTED = 1;
public static int SERVER_STATE_STOPPED = 2;
/** /**
* Get Adempiere Server Manager * Get Adempiere Server Manager
* @return mgr * @return mgr
*/ */
public synchronized static AdempiereServerMgr get() public synchronized static IServerManager get()
{ {
return get(true); return get(true);
} }
@ -68,7 +65,7 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
* Get Adempiere Server Manager * Get Adempiere Server Manager
* @return mgr * @return mgr
*/ */
public synchronized static AdempiereServerMgr get(boolean createNew) public synchronized static IServerManager get(boolean createNew)
{ {
if (m_serverMgr == null && createNew) if (m_serverMgr == null && createNew)
{ {
@ -93,12 +90,12 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
{ {
super(); super();
startEnvironment(); startEnvironment();
m_servers=new ArrayList<ServerWrapper>(); m_servers=new ArrayList<LocalServerController>();
processorClass = new HashSet<String>(); processorClass = new HashSet<String>();
} // AdempiereServerMgr } // AdempiereServerMgr
/** The Servers */ /** The Servers */
private ArrayList<ServerWrapper> m_servers = new ArrayList<ServerWrapper>(); private ArrayList<LocalServerController> m_servers = new ArrayList<LocalServerController>();
/** Context */ /** Context */
private Properties m_ctx = Env.getCtx(); private Properties m_ctx = Env.getCtx();
/** Start */ /** Start */
@ -129,14 +126,15 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
* @return true if started * @return true if started
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
public synchronized boolean reload() @Override
public synchronized String reload()
{ {
log.info(""); log.info("");
if (!stopAll()) if (stopAll() != null)
return false; return "Failed to stop all servers";
int noServers = 0; int noServers = 0;
m_servers=new ArrayList<ServerWrapper>(); m_servers=new ArrayList<LocalServerController>();
processorClass = new HashSet<String>(); processorClass = new HashSet<String>();
//osgi server //osgi server
@ -150,7 +148,7 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
} }
if (log.isLoggable(Level.FINE)) log.fine("#" + noServers); if (log.isLoggable(Level.FINE)) log.fine("#" + noServers);
return startAll(); return startAll() == null ? null : "Failed to restart all servers";
} // startEnvironment } // startEnvironment
private void createServers(IServerFactory<AdempiereServer, AdempiereProcessor> factory) { private void createServers(IServerFactory<AdempiereServer, AdempiereProcessor> factory) {
@ -164,13 +162,18 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
for (AdempiereServer server : servers) for (AdempiereServer server : servers)
{ {
AdempiereProcessor model = server.getModel(); AdempiereProcessor model = server.getModel();
if (AdempiereServer.isOKtoRunOnIP(model)) { if (canRunHere(server, model)) {
m_servers.add(new ServerWrapper(server)); m_servers.add(new LocalServerController(server));
} }
} }
} }
} }
} }
private boolean canRunHere(AdempiereServer server, AdempiereProcessor model) {
return AdempiereServer.isOKtoRunOnIP(model)
&& ClusterServerMgr.getInstance().getServerInstanceAtOtherMembers(server.getServerID())==null;
}
/** /**
* @param scheduler * @param scheduler
@ -179,7 +182,7 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
public boolean addScheduler(MScheduler scheduler) { public boolean addScheduler(MScheduler scheduler) {
String serverId = scheduler.getServerID(); String serverId = scheduler.getServerID();
if (getServer(serverId) != null) if (getServerInstance(serverId) != null)
return false; return false;
//osgi server //osgi server
@ -190,9 +193,9 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
{ {
if (factory.getProcessorClass().getName().equals(scheduler.getClass().getName())) { if (factory.getProcessorClass().getName().equals(scheduler.getClass().getName())) {
AdempiereServer server = factory.create(m_ctx, scheduler); AdempiereServer server = factory.create(m_ctx, scheduler);
if (server != null && AdempiereServer.isOKtoRunOnIP(scheduler)) { if (server != null && canRunHere(server, scheduler)) {
m_servers.add(new ServerWrapper(server)); m_servers.add(new LocalServerController(server));
return start(serverId); return start(serverId)==null;
} }
} }
} }
@ -214,13 +217,14 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
* Start all servers * Start all servers
* @return true if started * @return true if started
*/ */
public synchronized boolean startAll() @Override
public synchronized String startAll()
{ {
log.info (""); log.info ("");
ServerWrapper[] servers = getInActive(); LocalServerController[] servers = getInActive();
for (int i = 0; i < servers.length; i++) for (int i = 0; i < servers.length; i++)
{ {
ServerWrapper server = servers[i]; LocalServerController server = servers[i];
try try
{ {
if (server.scheduleFuture != null && !server.scheduleFuture.isDone()) if (server.scheduleFuture != null && !server.scheduleFuture.isDone())
@ -243,7 +247,7 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
int noStopped = 0; int noStopped = 0;
for (int i = 0; i < servers.length; i++) for (int i = 0; i < servers.length; i++)
{ {
ServerWrapper server = servers[i]; LocalServerController server = servers[i];
try try
{ {
if (server.scheduleFuture != null && !server.scheduleFuture.isDone()) if (server.scheduleFuture != null && !server.scheduleFuture.isDone())
@ -264,7 +268,7 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
} }
} }
if (log.isLoggable(Level.FINE)) log.fine("Running=" + noRunning + ", Stopped=" + noStopped); if (log.isLoggable(Level.FINE)) log.fine("Running=" + noRunning + ", Stopped=" + noStopped);
return noStopped == 0; return noStopped == 0 ? null : "Failed to start all servers";
} // startAll } // startAll
/** /**
@ -272,13 +276,14 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
* @param serverID server ID * @param serverID server ID
* @return true if started * @return true if started
*/ */
public synchronized boolean start (String serverID) @Override
public synchronized String start (String serverID)
{ {
ServerWrapper server = getServer(serverID); LocalServerController server = getLocalServerController(serverID);
if (server == null) if (server == null)
return false; return "Server not found";
if (server.scheduleFuture != null && !server.scheduleFuture.isDone()) if (server.scheduleFuture != null && !server.scheduleFuture.isDone())
return true; return "Server is already running";
try try
{ {
@ -290,28 +295,29 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
catch (Exception e) catch (Exception e)
{ {
log.log(Level.SEVERE, "Server=" + serverID, e); log.log(Level.SEVERE, "Server=" + serverID, e);
return false; return e.getMessage();
} }
finally finally
{ {
Env.setContext(Env.getCtx(), Env.AD_CLIENT_ID, 0); Env.setContext(Env.getCtx(), Env.AD_CLIENT_ID, 0);
} }
if (log.isLoggable(Level.INFO)) log.info(server.toString()); if (log.isLoggable(Level.INFO)) log.info(server.toString());
return (server.scheduleFuture != null && !server.scheduleFuture.isDone()); return (server.scheduleFuture != null && !server.scheduleFuture.isDone()) ? null : "Failed to start server";
} // startIt } // startIt
/** /**
* Stop all Servers * Stop all Servers
* @return true if stopped * @return true if stopped
*/ */
public synchronized boolean stopAll() @Override
public synchronized String stopAll()
{ {
log.info (""); log.info ("");
ServerWrapper[] servers = getActive(); LocalServerController[] servers = getActive();
// Interrupt // Interrupt
for (int i = 0; i < servers.length; i++) for (int i = 0; i < servers.length; i++)
{ {
ServerWrapper server = servers[i]; LocalServerController server = servers[i];
try try
{ {
if (server.scheduleFuture != null && !server.scheduleFuture.isDone()) if (server.scheduleFuture != null && !server.scheduleFuture.isDone())
@ -329,7 +335,7 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
// Wait for death // Wait for death
for (int i = 0; i < servers.length; i++) for (int i = 0; i < servers.length; i++)
{ {
ServerWrapper server = servers[i]; LocalServerController server = servers[i];
try try
{ {
int maxWait = 10; // 10 iterations = 1 sec int maxWait = 10; // 10 iterations = 1 sec
@ -354,7 +360,7 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
int noStopped = 0; int noStopped = 0;
for (int i = 0; i < servers.length; i++) for (int i = 0; i < servers.length; i++)
{ {
ServerWrapper server = servers[i]; LocalServerController server = servers[i];
try try
{ {
if (server.scheduleFuture != null && !server.scheduleFuture.isDone()) if (server.scheduleFuture != null && !server.scheduleFuture.isDone())
@ -376,7 +382,7 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
} }
if (log.isLoggable(Level.FINE)) log.fine("Running=" + noRunning + ", Stopped=" + noStopped); if (log.isLoggable(Level.FINE)) log.fine("Running=" + noRunning + ", Stopped=" + noStopped);
AdempiereServerGroup.get().dump(); AdempiereServerGroup.get().dump();
return noRunning == 0; return noRunning == 0 ? null : "Failed to stop all servers";
} // stopAll } // stopAll
/** /**
@ -384,13 +390,14 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
* @param serverID server ID * @param serverID server ID
* @return true if interrupted * @return true if interrupted
*/ */
public synchronized boolean stop (String serverID) @Override
public synchronized String stop (String serverID)
{ {
ServerWrapper server = getServer(serverID); LocalServerController server = getLocalServerController(serverID);
if (server == null) if (server == null)
return false; return "Server not found";
if (server.scheduleFuture == null || server.scheduleFuture.isDone()) if (server.scheduleFuture == null || server.scheduleFuture.isDone())
return true; return "Server is already stop";
try try
{ {
@ -400,10 +407,10 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
catch (Exception e) catch (Exception e)
{ {
log.log(Level.SEVERE, "stop", e); log.log(Level.SEVERE, "stop", e);
return false; return e.getMessage();
} }
if (log.isLoggable(Level.INFO)) log.info(server.toString()); if (log.isLoggable(Level.INFO)) log.info(server.toString());
return (server.scheduleFuture == null || server.scheduleFuture.isDone()); return (server.scheduleFuture == null || server.scheduleFuture.isDone()) ? null : "Failed to stop server";
} // stop } // stop
@ -421,16 +428,16 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
* Get Active Servers * Get Active Servers
* @return array of active servers * @return array of active servers
*/ */
protected synchronized ServerWrapper[] getActive() protected synchronized LocalServerController[] getActive()
{ {
ArrayList<ServerWrapper> list = new ArrayList<ServerWrapper>(); ArrayList<LocalServerController> list = new ArrayList<LocalServerController>();
for (int i = 0; i < m_servers.size(); i++) for (int i = 0; i < m_servers.size(); i++)
{ {
ServerWrapper server = (ServerWrapper)m_servers.get(i); LocalServerController server = (LocalServerController)m_servers.get(i);
if (server != null && server.scheduleFuture != null && !server.scheduleFuture.isDone()) if (server != null && server.scheduleFuture != null && !server.scheduleFuture.isDone())
list.add (server); list.add (server);
} }
ServerWrapper[] retValue = new ServerWrapper[list.size ()]; LocalServerController[] retValue = new LocalServerController[list.size ()];
list.toArray (retValue); list.toArray (retValue);
return retValue; return retValue;
} // getActive } // getActive
@ -439,16 +446,16 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
* Get InActive Servers * Get InActive Servers
* @return array of inactive servers * @return array of inactive servers
*/ */
protected synchronized ServerWrapper[] getInActive() protected synchronized LocalServerController[] getInActive()
{ {
ArrayList<ServerWrapper> list = new ArrayList<ServerWrapper>(); ArrayList<LocalServerController> list = new ArrayList<LocalServerController>();
for (int i = 0; i < m_servers.size(); i++) for (int i = 0; i < m_servers.size(); i++)
{ {
ServerWrapper server = m_servers.get(i); LocalServerController server = m_servers.get(i);
if (server != null && (server.scheduleFuture == null || server.scheduleFuture.isDone())) if (server != null && (server.scheduleFuture == null || server.scheduleFuture.isDone()))
list.add (server); list.add (server);
} }
ServerWrapper[] retValue = new ServerWrapper[list.size()]; LocalServerController[] retValue = new LocalServerController[list.size()];
list.toArray (retValue); list.toArray (retValue);
return retValue; return retValue;
} // getInActive } // getInActive
@ -457,33 +464,32 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
* Get all Servers * Get all Servers
* @return array of servers * @return array of servers
*/ */
public synchronized ServerWrapper[] getAll() private synchronized LocalServerController[] getLocalServerControllers()
{ {
ServerWrapper[] retValue = new ServerWrapper[m_servers.size()]; LocalServerController[] retValue = new LocalServerController[m_servers.size()];
m_servers.toArray (retValue); m_servers.toArray (retValue);
return retValue; return retValue;
} // getAll } // getAll
public synchronized int getStatus(AdempiereProcessor processor)
{ @Override
int status = SERVER_STATE_NOT_SCHEDULE; public ServerInstance[] getServerInstances() {
for (int i = 0; i < m_servers.size(); i++) List<ServerInstance> responses = new ArrayList<>();
{ LocalServerController[] controllers = getLocalServerControllers();
ServerWrapper server = m_servers.get(i); for (LocalServerController controller : controllers) {
AdempiereProcessor model = server.server.getModel(); if (controller.getServer() != null) {
if (model.getClass().getName().equals(processor.getClass().getName()) && model.getServerID().equals(processor.getServerID())) ServerInstance response = new ServerInstance(controller.getServer().getServerID(), controller.getServer().getModel(),
{ controller.isAlive(), controller.isInterrupted(), controller.getServer().isSleeping(),
if (server.scheduleFuture == null || server.scheduleFuture.isDone()) controller.getServer().getStartTime(), controller.getServer().getStatistics(), controller.getServer().getServerInfo());
{ responses.add(response);
status = SERVER_STATE_STOPPED;
}
else
{
status = SERVER_STATE_STARTED;
}
} }
} }
return status; return responses.toArray(new ServerInstance[0]);
}
public synchronized int getStatus(AdempiereProcessor processor)
{
return getServerStatus(processor.getServerID());
} }
/** /**
@ -491,13 +497,34 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
* @param serverID server id * @param serverID server id
* @return server or null * @return server or null
*/ */
public synchronized ServerWrapper getServer (String serverID) @Override
public synchronized ServerInstance getServerInstance(String serverID)
{ {
if (serverID == null) if (serverID == null)
return null; return null;
for (int i = 0; i < m_servers.size(); i++) for (int i = 0; i < m_servers.size(); i++)
{ {
ServerWrapper server = m_servers.get(i); LocalServerController server = m_servers.get(i);
if (serverID.equals(server.server.getServerID()))
return new ServerInstance(server.getServer().getServerID(), server.getServer().getModel(),
server.isAlive(), server.isInterrupted(), server.getServer().isSleeping(),
server.getServer().getStartTime(), server.getServer().getStatistics(), server.getServer().getServerInfo());
}
return null;
} // getServer
/**
* Get Server with ID
* @param serverID server id
* @return server or null
*/
private synchronized LocalServerController getLocalServerController (String serverID)
{
if (serverID == null)
return null;
for (int i = 0; i < m_servers.size(); i++)
{
LocalServerController server = m_servers.get(i);
if (serverID.equals(server.server.getServerID())) if (serverID.equals(server.server.getServerID()))
return server; return server;
} }
@ -522,49 +549,48 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
* Get Description * Get Description
* @return description * @return description
*/ */
@Override
public String getDescription() public String getDescription()
{ {
return "$Revision: 1.4 $"; return Adempiere.getVersion();
} // getDescription } // getDescription
/** /**
* Get Number Servers * Get Number Servers
* @return no of servers * @return no of servers
*/ */
public synchronized String getServerCount() @Override
public synchronized ServerCount getServerCount()
{ {
int noRunning = 0; ServerCount serverCount = new ServerCount();
int noStopped = 0;
for (int i = 0; i < m_servers.size(); i++) for (int i = 0; i < m_servers.size(); i++)
{ {
ServerWrapper server = m_servers.get(i); LocalServerController server = m_servers.get(i);
if (server.scheduleFuture != null && !server.scheduleFuture.isDone()) if (server.scheduleFuture != null && !server.scheduleFuture.isDone())
noRunning++; serverCount.addStarted(1);
else else
noStopped++; serverCount.addStopped(1);
} }
String info = String.valueOf(m_servers.size()) return serverCount;
+ " - Running=" + noRunning
+ " - Stopped=" + noStopped;
return info;
} // getServerCount } // getServerCount
/** /**
* Get start date * Get start date
* @return start date * @return start date
*/ */
@Override
public Timestamp getStartTime() public Timestamp getStartTime()
{ {
return m_start; return m_start;
} // getStartTime } // getStartTime
public static class ServerWrapper implements Runnable private class LocalServerController implements Runnable
{ {
protected AdempiereServer server; protected AdempiereServer server;
protected volatile ScheduledFuture<?> scheduleFuture; protected volatile ScheduledFuture<?> scheduleFuture;
public ServerWrapper(AdempiereServer server) { public LocalServerController(AdempiereServer server) {
this.server = server; this.server = server;
start(); start();
} }
@ -633,12 +659,12 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
} }
public Boolean remove(String serverID) { public Boolean remove(String serverID) {
ServerWrapper server = getServer(serverID); LocalServerController server = getLocalServerController(serverID);
if (server == null) if (server == null)
return false; return false;
if (server.scheduleFuture != null && !server.scheduleFuture.isDone()) { if (server.scheduleFuture != null && !server.scheduleFuture.isDone()) {
if (!stop(serverID)) { if (stop(serverID) != null) {
return false; return false;
} }
} }
@ -653,4 +679,38 @@ public class AdempiereServerMgr implements ServiceTrackerCustomizer<IServerFacto
return false; return false;
} }
@Override
public String runNow(String serverId) {
LocalServerController serverInstance = getLocalServerController(serverId);
if (serverInstance == null || serverInstance.getServer() == null) {
return "Server " + serverId + " not found";
}
if (serverInstance.getServer().isSleeping())
{
serverInstance.getServer().runNow();
}
else
{
int count = 0;
while(!serverInstance.getServer().isSleeping() && count < 5)
{
count++;
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
if (serverInstance.getServer().isSleeping())
serverInstance.getServer().runNow();
else
{
return "Timeout waiting for server process to be available for execution.";
}
}
return null;
}
} // AdempiereServerMgr } // AdempiereServerMgr

View File

@ -27,7 +27,6 @@ import java.util.Collection;
import java.util.logging.Level; import java.util.logging.Level;
import org.adempiere.impexp.ArrayExcelExporter; import org.adempiere.impexp.ArrayExcelExporter;
import org.compiere.Adempiere;
import org.compiere.model.MAlert; import org.compiere.model.MAlert;
import org.compiere.model.MAlertProcessor; import org.compiere.model.MAlertProcessor;
import org.compiere.model.MAlertProcessorLog; import org.compiere.model.MAlertProcessorLog;
@ -457,21 +456,5 @@ public class AlertProcessor extends AdempiereServer
public String getServerInfo() public String getServerInfo()
{ {
return "#" + p_runCount + " - Last=" + m_summary.toString(); return "#" + p_runCount + " - Last=" + m_summary.toString();
} // getServerInfo } // getServerInfo
/***************************************************************************
* Test
* @param args ignored
*/
public static void main (String[] args)
{
Adempiere.startup(true);
MAlertProcessor model = new MAlertProcessor (Env.getCtx(), 100, null);
AlertProcessor ap = new AlertProcessor(model);
AdempiereServerMgr.ServerWrapper wrapper = new AdempiereServerMgr.ServerWrapper(ap);
wrapper.start();
}
} }

View File

@ -0,0 +1,121 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.compiere.server;
import java.sql.Timestamp;
/**
*
* @author hengsin
*
*/
public interface IServerManager {
public static int SERVER_STATE_NOT_SCHEDULE = 0;
public static int SERVER_STATE_STARTED = 1;
public static int SERVER_STATE_STOPPED = 2;
/**
* Get server instance by id
* @param serverId
* @return ServerInstance or null if not found
*/
public ServerInstance getServerInstance(String serverId);
/**
*
* @param serverId
* @return server status
*/
public default int getServerStatus(String serverId) {
ServerInstance instance = getServerInstance(serverId);
if (instance == null || instance.getServerId() == null) {
return SERVER_STATE_NOT_SCHEDULE;
} else if (instance.isStarted()) {
return SERVER_STATE_STARTED;
} else {
return SERVER_STATE_STOPPED;
}
}
/**
*
* @param serverId
* @return error
*/
public String runNow(String serverId);
/**
*
* @param serverId
* @return error
*/
public String start(String serverId);
/**
*
* @param serverId
* @return error
*/
public String stop(String serverId);
/**
* @return error
*/
public String startAll();
/**
* @return error
*/
public String stopAll();
/**
* @return error
*/
public String reload();
/**
* @return start time stamp
*/
public Timestamp getStartTime();
/**
*
* @return ServerCount
*/
public ServerCount getServerCount();
/**
* @return all server instances
*/
public ServerInstance[] getServerInstances();
/**
* @return description
*/
public String getDescription();
}

View File

@ -0,0 +1,73 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.compiere.server;
import java.io.Serializable;
/**
*
* @author hengsin
*
*/
public class ServerCount implements Serializable {
/**
* generated serial id
*/
private static final long serialVersionUID = -5064676550658918430L;
private int noStarted = 0;
private int noStopped = 0;
/**
* @return no of started instance
*/
public int getStarted() {
return noStarted;
}
/**
* @return no of stopped instance
*/
public int getStopped() {
return noStopped;
}
/**
* increase no of started count
* @param started
*/
public void addStarted(int started) {
noStarted += started;
}
/**
* increase no of stopped count
* @param stopped
*/
public void addStopped(int stopped) {
noStopped += stopped;
}
}

View File

@ -0,0 +1,146 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.compiere.server;
import java.io.Serializable;
import java.sql.Timestamp;
import org.compiere.model.AdempiereProcessor;
import org.idempiere.distributed.IClusterMember;
/**
*
* @author hengsin
*
*/
public class ServerInstance implements Serializable {
/**
* generated serial id
*/
private static final long serialVersionUID = -6332080326921128215L;
private String serverId;
private AdempiereProcessor model;
private boolean started = false;
private boolean interrupted = false;
private boolean sleeping = false;
private Timestamp startTime;
private String statistics;
private String serverInfo;
private IClusterMember clusterMember;
/**
*
* @param server
* @param started
* @param interrupted
*/
public ServerInstance(String serverId, AdempiereProcessor model, boolean started, boolean interrupted,
boolean sleeping, Timestamp startTime, String statistics, String serverInfo) {
this.serverId = serverId;
this.model = model;
this.started = started;
this.sleeping = sleeping;
this.startTime = startTime;
this.statistics = statistics;
this.serverInfo = serverInfo;
}
/**
* @return is instance started
*/
public boolean isStarted() {
return started;
}
/**
* @return is instance interrupted/stopped
*/
public boolean isInterrupted() {
return interrupted;
}
/**
* is instance idle waiting for next run (at the time of getting this ServerInstance reference)
* @return true if instance is idle, false otherwise
*/
public boolean isSleeping() {
return sleeping;
}
/**
* @return latest start time
*/
public Timestamp getStartTime() {
return startTime;
}
/**
* Get Run Statistics
* @return Statistic info
*/
public String getStatistics() {
return statistics;
}
/**
* Get Server Info
* @return info
*/
public String getServerInfo() {
return serverInfo;
}
/**
* @return server id
*/
public String getServerId() {
return serverId;
}
/**
*
* @return {@link AdempiereProcessor}
*/
public AdempiereProcessor getModel() {
return model;
}
/**
*
* @param clusterMember
*/
public void setClusterMember(IClusterMember clusterMember) {
this.clusterMember = clusterMember;
}
/**
* @return {@link IClusterMember}
*/
public IClusterMember getClusterMember() {
return clusterMember;
}
}

View File

@ -0,0 +1,421 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.idempiere.server.cluster;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.adempiere.base.IServiceHolder;
import org.adempiere.base.Service;
import org.compiere.Adempiere;
import org.compiere.server.IServerManager;
import org.compiere.server.ServerCount;
import org.compiere.server.ServerInstance;
import org.idempiere.distributed.IClusterMember;
import org.idempiere.distributed.IClusterService;
import org.idempiere.server.cluster.callable.GetAllCallable;
import org.idempiere.server.cluster.callable.GetServerCallable;
import org.idempiere.server.cluster.callable.GetServerCountCallable;
import org.idempiere.server.cluster.callable.GetStartTimeCallable;
import org.idempiere.server.cluster.callable.ReloadCallable;
import org.idempiere.server.cluster.callable.Response;
import org.idempiere.server.cluster.callable.RunNowCallable;
import org.idempiere.server.cluster.callable.StartAllCallable;
import org.idempiere.server.cluster.callable.StartCallable;
import org.idempiere.server.cluster.callable.StopAllCallable;
import org.idempiere.server.cluster.callable.StopCallable;
/**
*
* @author hengsin
*
*/
public class ClusterServerMgr implements IServerManager {
private final static ClusterServerMgr INSTANCE = new ClusterServerMgr();
/**
*
* @return share instance
*/
public static ClusterServerMgr getInstance() {
return INSTANCE;
}
private ClusterServerMgr() {
}
private IClusterService getClusterService() {
IServiceHolder<IClusterService> holder = Service.locator().locate(IClusterService.class);
IClusterService service = holder != null ? holder.getService() : null;
return service;
}
@Override
public ServerInstance getServerInstance(String serverId) {
IClusterService service = getClusterService();
if (service == null)
return null;
GetServerCallable callable = new GetServerCallable(serverId);
Map<IClusterMember, Future<ServerInstance>> futureMap = service.execute(callable, service.getMembers());
if (futureMap != null) {
try {
Set<Entry<IClusterMember, Future<ServerInstance>>> results = futureMap.entrySet();
for(Entry<IClusterMember, Future<ServerInstance>> f : results) {
ServerInstance i = f.getValue().get();
if (i != null) {
i.setClusterMember(f.getKey());
return i;
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (ExecutionException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
return null;
}
@Override
public String runNow(String serverId) {
IClusterService service = getClusterService();
if (service == null)
return "Cluster service not available";
RunNowCallable callable = new RunNowCallable(serverId);
Map<IClusterMember, Future<Response>> futureMap = service.execute(callable, service.getMembers());
if (futureMap != null) {
try {
Collection<Future<Response>> results = futureMap.values();
for(Future<Response> f : results) {
Response response = f.get();
if (response.getServerId() != null) {
return response.getError();
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (ExecutionException e) {
throw new RuntimeException(e.getMessage(), e);
}
return "Server " + serverId + " not found";
}
return null;
}
@Override
public String start(String serverId) {
IClusterService service = getClusterService();
if (service == null)
return "Cluster service not available";
StartCallable callable = new StartCallable(serverId);
Map<IClusterMember, Future<Response>> futureMap = service.execute(callable, service.getMembers());
if (futureMap != null) {
try {
Collection<Future<Response>> results = futureMap.values();
for(Future<Response> f : results) {
Response response = f.get();
if (response != null && response.getServerId() != null) {
return response.getError();
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (ExecutionException e) {
throw new RuntimeException(e.getMessage(), e);
}
return "Server " + serverId + " not found";
} else {
return "Failed to send start request through cluster service";
}
}
@Override
public String stop(String serverId) {
IClusterService service = getClusterService();
if (service == null)
return "Cluster service not available";
StopCallable callable = new StopCallable(serverId);
Map<IClusterMember, Future<Response>> futureMap = service.execute(callable, service.getMembers());
if (futureMap != null) {
try {
Collection<Future<Response>> results = futureMap.values();
for(Future<Response> f : results) {
Response response = f.get();
if (response != null && response.getServerId() != null) {
return response.getError();
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (ExecutionException e) {
throw new RuntimeException(e.getMessage(), e);
}
return "Server " + serverId + " not found";
} else {
return "Failed to send stop request through cluster service";
}
}
@Override
public String reload() {
IClusterService service = getClusterService();
if (service == null)
return "Cluster service not available";
ReloadCallable callable = new ReloadCallable();
Map<IClusterMember, Future<String>> futureMap = service.execute(callable, service.getMembers());
if (futureMap != null) {
try {
Collection<Future<String>> results = futureMap.values();
for(Future<String> f : results) {
String response = f.get();
if (response != null) {
return response;
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (ExecutionException e) {
throw new RuntimeException(e.getMessage(), e);
}
return null;
} else {
return "Failed to send reload request through cluster service";
}
}
@Override
public Timestamp getStartTime() {
IClusterService service = getClusterService();
if (service == null)
return null;
Timestamp earliest = null;
GetStartTimeCallable callable = new GetStartTimeCallable();
Map<IClusterMember, Future<Timestamp>> futureMap = service.execute(callable, service.getMembers());
if (futureMap != null) {
try {
Collection<Future<Timestamp>> results = futureMap.values();
for(Future<Timestamp> f : results) {
Timestamp response = f.get();
if (response != null) {
if (earliest == null)
earliest = response;
else if (response.before(earliest))
earliest = response;
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (ExecutionException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
return earliest;
}
@Override
public ServerCount getServerCount() {
IClusterService service = getClusterService();
if (service == null)
return null;
ServerCount serverCount = null;
GetServerCountCallable callable = new GetServerCountCallable();
Map<IClusterMember, Future<ServerCount>> futureMap = service.execute(callable, service.getMembers());
if (futureMap != null) {
try {
Collection<Future<ServerCount>> results = futureMap.values();
for(Future<ServerCount> f : results) {
ServerCount response = f.get();
if (response != null) {
if (serverCount == null) {
serverCount = response;
} else {
serverCount.addStarted(response.getStarted());
serverCount.addStopped(response.getStopped());
}
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (ExecutionException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
return serverCount;
}
@Override
public ServerInstance[] getServerInstances() {
IClusterService service = getClusterService();
if (service == null)
return null;
List<ServerInstance> servers = new ArrayList<>();
GetAllCallable callable = new GetAllCallable();
Map<IClusterMember, Future<ServerInstance[]>> futureMap = service.execute(callable, service.getMembers());
if (futureMap != null) {
try {
Set<Entry<IClusterMember, Future<ServerInstance[]>>> results = futureMap.entrySet();
for(Entry<IClusterMember, Future<ServerInstance[]>> f : results) {
ServerInstance[] response = f.getValue().get();
if (response != null) {
Arrays.stream(response).forEach(e -> {
e.setClusterMember(f.getKey());
servers.add(e);
});
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (ExecutionException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
return servers.toArray(new ServerInstance[0]);
}
@Override
public String getDescription() {
return Adempiere.getVersion();
}
@Override
public String startAll() {
IClusterService service = getClusterService();
if (service == null)
return "Cluster service not available";
StartAllCallable callable = new StartAllCallable();
Map<IClusterMember, Future<String>> futureMap = service.execute(callable, service.getMembers());
if (futureMap != null) {
try {
Collection<Future<String>> results = futureMap.values();
for(Future<String> f : results) {
String response = f.get();
if (response != null) {
return response;
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (ExecutionException e) {
throw new RuntimeException(e.getMessage(), e);
}
return null;
} else {
return "Failed to send start all request through cluster servie";
}
}
@Override
public String stopAll() {
IClusterService service = getClusterService();
if (service == null)
return "Cluster service not available";
StopAllCallable callable = new StopAllCallable();
Map<IClusterMember, Future<String>> futureMap = service.execute(callable, service.getMembers());
if (futureMap != null) {
try {
Collection<Future<String>> results = futureMap.values();
for(Future<String> f : results) {
String response = f.get();
if (response != null) {
return response;
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (ExecutionException e) {
throw new RuntimeException(e.getMessage(), e);
}
return null;
} else {
return "Failed to send stop all request through cluster servie";
}
}
/**
* find server instance from non-local nodes
* @param serverId
* @return ServerInstance
*/
public ServerInstance getServerInstanceAtOtherMembers(String serverId) {
IClusterService service = getClusterService();
if (service == null)
return null;
GetServerCallable callable = new GetServerCallable(serverId);
Collection<IClusterMember> members = service.getMembers();
if (members == null || members.isEmpty())
return null;
final IClusterMember local = service.getLocalMember();
if (local == null)
return null;
List<IClusterMember> others = new ArrayList<>();
members.forEach(e -> {
if (!e.getId().equals(local.getId())) {
others.add(e);
}
});
if (others.size() > 0) {
Map<IClusterMember, Future<ServerInstance>> futureMap = service.execute(callable, others);
if (futureMap != null) {
try {
Set<Entry<IClusterMember, Future<ServerInstance>>> results = futureMap.entrySet();
for(Entry<IClusterMember, Future<ServerInstance>> f : results) {
ServerInstance i = f.getValue().get();
if (i != null) {
i.setClusterMember(f.getKey());
return i;
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (ExecutionException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
return null;
}
}

View File

@ -0,0 +1,66 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.idempiere.server.cluster.callable;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import org.compiere.server.AdempiereServerMgr;
import org.compiere.server.IServerManager;
import org.compiere.server.ServerInstance;
/**
* @author hengsin
*
*/
public class GetAllCallable implements Callable<ServerInstance[]>, Serializable {
/**
* generated serial
*/
private static final long serialVersionUID = -2658045266402067579L;
/**
* default constructor
*/
public GetAllCallable() {
}
@Override
public ServerInstance[] call() throws Exception {
List<ServerInstance> responses = new ArrayList<>();
IServerManager serverMgr = AdempiereServerMgr.get(false);
if (serverMgr != null) {
ServerInstance[] servers = serverMgr.getServerInstances();
for (ServerInstance server : servers) {
responses.add(server);
}
}
return responses.toArray(new ServerInstance[0]);
}
}

View File

@ -0,0 +1,63 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.idempiere.server.cluster.callable;
import java.io.Serializable;
import java.util.concurrent.Callable;
import org.compiere.server.AdempiereServerMgr;
import org.compiere.server.IServerManager;
import org.compiere.server.ServerInstance;
/**
* @author hengsin
*
*/
public class GetServerCallable implements Callable<ServerInstance>, Serializable {
/**
* generated serial
*/
private static final long serialVersionUID = -2658045266402067579L;
private String serverId;
/**
* @param serverId
*/
public GetServerCallable(String serverId) {
this.serverId = serverId;
}
@Override
public ServerInstance call() throws Exception {
IServerManager serverMgr = AdempiereServerMgr.get(false);
if (serverMgr != null) {
return serverMgr.getServerInstance(serverId);
}
return null;
}
}

View File

@ -0,0 +1,69 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.idempiere.server.cluster.callable;
import java.io.Serializable;
import java.util.concurrent.Callable;
import org.compiere.server.AdempiereServerMgr;
import org.compiere.server.IServerManager;
import org.compiere.server.ServerCount;
import org.compiere.server.ServerInstance;
/**
* @author hengsin
*
*/
public class GetServerCountCallable implements Callable<ServerCount>, Serializable {
/**
* generated serial
*/
private static final long serialVersionUID = 3496041492358893501L;
/**
* default constructor
*/
public GetServerCountCallable() {
}
@Override
public ServerCount call() throws Exception {
ServerCount serverCount = new ServerCount();
IServerManager serverMgr = AdempiereServerMgr.get(false);
if (serverMgr != null) {
ServerInstance[] servers = serverMgr.getServerInstances();
for (ServerInstance server : servers) {
if (server.isStarted())
serverCount.addStarted(1);
else
serverCount.addStopped(1);
}
}
return serverCount;
}
}

View File

@ -0,0 +1,62 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.idempiere.server.cluster.callable;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.concurrent.Callable;
import org.compiere.server.AdempiereServerMgr;
import org.compiere.server.IServerManager;
/**
* @author hengsin
*
*/
public class GetStartTimeCallable implements Callable<Timestamp>, Serializable {
/**
* generated serial
*/
private static final long serialVersionUID = 3496041492358893501L;
/**
* default constructor
*/
public GetStartTimeCallable() {
}
@Override
public Timestamp call() throws Exception {
IServerManager serverMgr = AdempiereServerMgr.get(false);
if (serverMgr != null) {
return serverMgr.getStartTime();
}
return null;
}
}

View File

@ -0,0 +1,62 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.idempiere.server.cluster.callable;
import java.io.Serializable;
import java.util.concurrent.Callable;
import org.compiere.server.AdempiereServerMgr;
import org.compiere.server.IServerManager;
/**
* @author hengsin
*
*/
public class ReloadCallable implements Callable<String>, Serializable {
/**
* generated serial
*/
private static final long serialVersionUID = -477156440432070776L;
/**
* default constructor
*/
public ReloadCallable() {
}
@Override
public String call() throws Exception {
IServerManager serverMgr = AdempiereServerMgr.get(false);
if (serverMgr != null) {
return serverMgr.reload();
}
return null;
}
}

View File

@ -0,0 +1,51 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.idempiere.server.cluster.callable;
import java.io.Serializable;
/**
*
* @author hengsin
*
*/
public class Response implements Serializable {
/**
* generated serial id
*/
private static final long serialVersionUID = -62222370378270354L;
protected String error = null;
protected String serverId = null;
public String getError() {
return error;
}
public String getServerId() {
return serverId;
}
}

View File

@ -0,0 +1,68 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.idempiere.server.cluster.callable;
import java.io.Serializable;
import java.util.concurrent.Callable;
import org.compiere.server.AdempiereServerMgr;
import org.compiere.server.IServerManager;
import org.compiere.server.ServerInstance;
/**
* @author hengsin
*
*/
public class RunNowCallable implements Callable<Response>, Serializable {
/**
* generated serial
*/
private static final long serialVersionUID = 3629305666372614289L;
private String serverId;
/**
* @param serverId
*/
public RunNowCallable(String serverId) {
this.serverId = serverId;
}
@Override
public Response call() throws Exception {
Response response = new Response();
IServerManager serverMgr = AdempiereServerMgr.get(false);
if (serverMgr != null) {
ServerInstance serverInstance = serverMgr.getServerInstance(serverId);
if (serverInstance != null) {
response.serverId = serverInstance.getServerId();
response.error = serverMgr.runNow(serverId);
}
}
return response;
}
}

View File

@ -0,0 +1,61 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.idempiere.server.cluster.callable;
import java.io.Serializable;
import java.util.concurrent.Callable;
import org.compiere.server.AdempiereServerMgr;
import org.compiere.server.IServerManager;
/**
* @author hengsin
*
*/
public class StartAllCallable implements Callable<String>, Serializable {
/**
* generated serial
*/
private static final long serialVersionUID = 3496041492358893501L;
/**
* default constructor
*/
public StartAllCallable() {
}
@Override
public String call() throws Exception {
IServerManager serverMgr = AdempiereServerMgr.get(false);
if (serverMgr != null) {
return serverMgr.startAll();
}
return null;
}
}

View File

@ -0,0 +1,69 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.idempiere.server.cluster.callable;
import java.io.Serializable;
import java.util.concurrent.Callable;
import org.compiere.server.AdempiereServerMgr;
import org.compiere.server.IServerManager;
import org.compiere.server.ServerInstance;
/**
* @author hengsin
*
*/
public class StartCallable implements Callable<Response>, Serializable {
/**
* generated serial
*/
private static final long serialVersionUID = 3496041492358893501L;
private String serverId;
/**
* @param serverId
*/
public StartCallable(String serverId) {
this.serverId = serverId;
}
@Override
public Response call() throws Exception {
Response response = new Response();
IServerManager serverMgr = AdempiereServerMgr.get(false);
if (serverMgr != null) {
ServerInstance server = serverMgr.getServerInstance(serverId);
if (server != null) {
response.error = serverMgr.start(serverId);
response.serverId = server.getServerId();
}
}
return response;
}
}

View File

@ -0,0 +1,61 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.idempiere.server.cluster.callable;
import java.io.Serializable;
import java.util.concurrent.Callable;
import org.compiere.server.AdempiereServerMgr;
import org.compiere.server.IServerManager;
/**
* @author hengsin
*
*/
public class StopAllCallable implements Callable<String>, Serializable {
/**
* generated serial
*/
private static final long serialVersionUID = 3496041492358893501L;
/**
* default constructor
*/
public StopAllCallable() {
}
@Override
public String call() throws Exception {
IServerManager serverMgr = AdempiereServerMgr.get(false);
if (serverMgr != null) {
return serverMgr.stopAll();
}
return null;
}
}

View File

@ -0,0 +1,68 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Trek Global Corporation *
* - Heng Sin Low *
**********************************************************************/
package org.idempiere.server.cluster.callable;
import java.io.Serializable;
import java.util.concurrent.Callable;
import org.compiere.server.AdempiereServerMgr;
import org.compiere.server.IServerManager;
import org.compiere.server.ServerInstance;
/**
* @author hengsin
*
*/
public class StopCallable implements Callable<Response>, Serializable {
/**
* generated serial
*/
private static final long serialVersionUID = 3496041492358893501L;
private String serverId;
/**
* @param serverId
*/
public StopCallable(String serverId) {
this.serverId = serverId;
}
@Override
public Response call() throws Exception {
Response response = new Response();
IServerManager serverMgr = AdempiereServerMgr.get(false);
if (serverMgr != null) {
ServerInstance server = serverMgr.getServerInstance(serverId);
if (server != null) {
response.error = serverMgr.stop(serverId);
response.serverId = server.getServerId();
}
}
return response;
}
}

View File

@ -26,6 +26,7 @@ import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean; import java.lang.management.MemoryMXBean;
import java.lang.management.RuntimeMXBean; import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean; import java.lang.management.ThreadMXBean;
import java.net.InetAddress;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -39,6 +40,8 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.adempiere.base.IServiceHolder;
import org.adempiere.base.Service;
import org.adempiere.util.LogAuthFailure; import org.adempiere.util.LogAuthFailure;
import org.apache.ecs.HtmlColor; import org.apache.ecs.HtmlColor;
import org.apache.ecs.xhtml.a; import org.apache.ecs.xhtml.a;
@ -69,10 +72,11 @@ import org.compiere.model.MStore;
import org.compiere.model.MSysConfig; import org.compiere.model.MSysConfig;
import org.compiere.model.MSystem; import org.compiere.model.MSystem;
import org.compiere.model.Query; import org.compiere.model.Query;
import org.compiere.server.AdempiereServer;
import org.compiere.server.AdempiereServerGroup; import org.compiere.server.AdempiereServerGroup;
import org.compiere.server.AdempiereServerMgr; import org.compiere.server.AdempiereServerMgr;
import org.compiere.server.AdempiereServerMgr.ServerWrapper; import org.compiere.server.IServerManager;
import org.compiere.server.ServerCount;
import org.compiere.server.ServerInstance;
import org.compiere.util.CLogFile; import org.compiere.util.CLogFile;
import org.compiere.util.CLogMgt; import org.compiere.util.CLogMgt;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
@ -83,9 +87,12 @@ import org.compiere.util.Env;
import org.compiere.util.Ini; import org.compiere.util.Ini;
import org.compiere.util.TimeUtil; import org.compiere.util.TimeUtil;
import org.compiere.util.Trx; import org.compiere.util.Trx;
import org.compiere.util.Util;
import org.compiere.util.WebDoc; import org.compiere.util.WebDoc;
import org.compiere.util.WebEnv; import org.compiere.util.WebEnv;
import org.compiere.util.WebUtil; import org.compiere.util.WebUtil;
import org.idempiere.distributed.IClusterService;
import org.idempiere.server.cluster.ClusterServerMgr;
/** /**
* Adempiere Server Monitor * Adempiere Server Monitor
@ -103,7 +110,7 @@ public class AdempiereMonitor extends HttpServlet
/** Logger */ /** Logger */
private static CLogger log = CLogger.getCLogger(AdempiereMonitor.class); private static CLogger log = CLogger.getCLogger(AdempiereMonitor.class);
/** The Server */ /** The Server */
private static AdempiereServerMgr m_serverMgr = null; private static IServerManager m_serverMgr = null;
/** Message */ /** Message */
private static p m_message = null; private static p m_message = null;
@ -189,8 +196,8 @@ public class AdempiereMonitor extends HttpServlet
return false; return false;
if (log.isLoggable(Level.INFO)) log.info ("ServerID=" + serverID); if (log.isLoggable(Level.INFO)) log.info ("ServerID=" + serverID);
ServerWrapper server = m_serverMgr.getServer(serverID); ServerInstance server = m_serverMgr.getServerInstance(serverID);
if (server == null || server.getServer() == null) if (server == null)
{ {
m_message = new p(); m_message = new p();
m_message.addElement(new strong("Server not found: ")); m_message.addElement(new strong("Server not found: "));
@ -207,7 +214,7 @@ public class AdempiereMonitor extends HttpServlet
para.addElement(link); para.addElement(link);
b.addElement(para); b.addElement(para);
// //
b.addElement(new h2(server.getServer().getName())); b.addElement(new h2(server.getModel().getName()));
// //
table table = new table(); table table = new table();
table.setBorder(1); table.setBorder(1);
@ -224,7 +231,7 @@ public class AdempiereMonitor extends HttpServlet
// line.addElement(new th().addElement("Description")); // line.addElement(new th().addElement("Description"));
table.addElement(line); table.addElement(line);
AdempiereProcessorLog[] logs = server.getServer().getLogs(); AdempiereProcessorLog[] logs = server.getModel().getLogs();
for (int i = 0; i < logs.length; i++) for (int i = 0; i < logs.length; i++)
{ {
AdempiereProcessorLog pLog = logs[i]; AdempiereProcessorLog pLog = logs[i];
@ -260,8 +267,8 @@ public class AdempiereMonitor extends HttpServlet
return false; return false;
if (log.isLoggable(Level.INFO)) log.info ("ServerID=" + serverID); if (log.isLoggable(Level.INFO)) log.info ("ServerID=" + serverID);
ServerWrapper server = m_serverMgr.getServer(serverID); ServerInstance server = m_serverMgr.getServerInstance(serverID);
if (server == null || server.getServer() == null) if (server == null)
{ {
m_message = new p(); m_message = new p();
m_message.addElement(new strong("Server not found: ")); m_message.addElement(new strong("Server not found: "));
@ -269,32 +276,14 @@ public class AdempiereMonitor extends HttpServlet
return false; return false;
} }
// //
AdempiereServer serverInstance = server.getServer(); String error = m_serverMgr.runNow(serverID);
if (serverInstance.isSleeping()) if (!Util.isEmpty(error, true))
{ {
serverInstance.runNow(); m_message = new p();
} m_message.addElement(new strong(error));
else m_message.addElement(serverID);
{
int count = 0;
while(!serverInstance.isSleeping() && count < 5)
{
count++;
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
if (serverInstance.isSleeping())
serverInstance.runNow();
else
{
m_message = new p();
m_message.addElement(new strong("Timeout waiting for server process to be available for execution."));
m_message.addElement(serverID);
}
} }
// //
return true; return true;
} // processRunParameter } // processRunParameter
@ -323,9 +312,9 @@ public class AdempiereMonitor extends HttpServlet
{ {
if (start) if (start)
{ {
ok = m_serverMgr.startAll(); ok = m_serverMgr.startAll()==null;
} else{ } else{
ok = m_serverMgr.stopAll(); ok = m_serverMgr.stopAll()==null;
} }
m_message.addElement("All"); m_message.addElement("All");
@ -334,22 +323,22 @@ public class AdempiereMonitor extends HttpServlet
{ {
if (reload) if (reload)
{ {
ok=m_serverMgr.reload(); ok=m_serverMgr.reload()==null;
this.createSummaryPage(request, response,true); this.createSummaryPage(request, response,true);
m_dirAccessList = getDirAcessList(); m_dirAccessList = getDirAcessList();
} else { } else {
ServerWrapper server = m_serverMgr.getServer(serverID); ServerInstance server = m_serverMgr.getServerInstance(serverID);
if (server == null || server.getServer() == null) { if (server == null) {
m_message = new p(); m_message = new p();
m_message.addElement(new strong("Server not found: ")); m_message.addElement(new strong("Server not found: "));
m_message.addElement(serverID); m_message.addElement(serverID);
return; return;
} else { } else {
if (start) if (start)
ok = m_serverMgr.start(serverID); ok = m_serverMgr.start(serverID)==null;
else else
ok = m_serverMgr.stop(serverID); ok = m_serverMgr.stop(serverID)==null;
m_message.addElement(server.getServer().getName()); m_message.addElement(server.getModel().getName());
} }
} }
} }
@ -631,13 +620,24 @@ public class AdempiereMonitor extends HttpServlet
table.addElement(line); table.addElement(line);
line = new tr(); line = new tr();
line.addElement(new th().addElement("Servers")); line.addElement(new th().addElement("Servers"));
line.addElement(new td().addElement(WebEnv.getCellContent(m_serverMgr.getServerCount()))); line.addElement(new td().addElement(WebEnv.getCellContent(createServerCountMessage(m_serverMgr.getServerCount()))));
table.addElement(line); table.addElement(line);
line = new tr(); line = new tr();
line.addElement(new th().addElement("Last Updated")); line.addElement(new th().addElement("Last Updated"));
line.addElement(new td().addElement(new Timestamp(System.currentTimeMillis()).toString())); line.addElement(new td().addElement(new Timestamp(System.currentTimeMillis()).toString()));
table.addElement(line); table.addElement(line);
bb.addElement(table); bb.addElement(table);
IServiceHolder<IClusterService> holder = Service.locator().locate(IClusterService.class);
IClusterService service = holder != null ? holder.getService() : null;
if (service != null && service.getLocalMember() != null)
{
line = new tr();
line.addElement(new th().addElement("Cluster Node Id"));
line.addElement(new td().addElement(WebEnv.getCellContent(service.getLocalMember().getId())));
table.addElement(line);
bb.addElement(table);
}
// //
p para = new p(); p para = new p();
a link = new a ("idempiereMonitor?Action=Start_All", "Start All"); a link = new a ("idempiereMonitor?Action=Start_All", "Start All");
@ -656,16 +656,16 @@ public class AdempiereMonitor extends HttpServlet
// ***** Server Links ***** // ***** Server Links *****
bb.addElement(new hr()); bb.addElement(new hr());
para = new p(); para = new p();
ServerWrapper[] servers = m_serverMgr.getAll(); ServerInstance[] servers = m_serverMgr.getServerInstances();
for (int i = 0; i < servers.length; i++) for (int i = 0; i < servers.length; i++)
{ {
if (i > 0) if (i > 0)
para.addElement(new br()); para.addElement(new br());
ServerWrapper server = servers[i]; ServerInstance server = servers[i];
link = new a ("#" + server.getServer().getServerID(), server.getServer().getName()); link = new a ("#" + server.getServerId(), server.getModel().getName());
para.addElement(link); para.addElement(link);
font status = null; font status = null;
if (server.isAlive()) if (server.isStarted())
status = new font().setColor(HtmlColor.GREEN).addElement(" (Running)"); status = new font().setColor(HtmlColor.GREEN).addElement(" (Running)");
else else
status = new font().setColor(HtmlColor.RED).addElement(" (Stopped)"); status = new font().setColor(HtmlColor.RED).addElement(" (Stopped)");
@ -680,10 +680,10 @@ public class AdempiereMonitor extends HttpServlet
bb.removeEndEndModifier(); bb.removeEndEndModifier();
for (int i = 0; i < servers.length; i++) for (int i = 0; i < servers.length; i++)
{ {
ServerWrapper server = servers[i]; ServerInstance server = servers[i];
bb.addElement(new hr()); bb.addElement(new hr());
bb.addElement(new a().setName(server.getServer().getServerID())); bb.addElement(new a().setName(server.getServerId()));
bb.addElement(new h2(server.getServer().getName())); bb.addElement(new h2(server.getModel().getName()));
// //
table = new table(); table = new table();
table.setBorder(1); table.setBorder(1);
@ -691,11 +691,11 @@ public class AdempiereMonitor extends HttpServlet
table.setCellPadding(2); table.setCellPadding(2);
// Status // Status
line = new tr(); line = new tr();
if (server.isAlive()) if (server.isStarted())
{ {
String msg = "Stop"; String msg = "Stop";
link = new a ("idempiereMonitor?Action=Stop_" + server.getServer().getServerID(), msg); link = new a ("idempiereMonitor?Action=Stop_" + server.getServerId(), msg);
if (server.getServer().isSleeping()) if (server.isSleeping())
{ {
line.addElement(new th().addElement("Sleeping")); line.addElement(new th().addElement("Sleeping"));
line.addElement(new td().addElement(link)); line.addElement(new td().addElement(link));
@ -708,54 +708,74 @@ public class AdempiereMonitor extends HttpServlet
table.addElement(line); table.addElement(line);
line = new tr(); line = new tr();
line.addElement(new th().addElement("Start - Elapsed")); line.addElement(new th().addElement("Start - Elapsed"));
line.addElement(new td().addElement(WebEnv.getCellContent(server.getServer().getStartTime()) line.addElement(new td().addElement(WebEnv.getCellContent(server.getStartTime())
+ " - " + TimeUtil.formatElapsed(server.getServer().getStartTime()))); + " - " + TimeUtil.formatElapsed(server.getStartTime())));
} }
else else
{ {
String msg = "Start"; String msg = "Start";
line.addElement(new th().addElement("Not Started")); line.addElement(new th().addElement("Not Started"));
link = new a ("idempiereMonitor?Action=Start_" + server.getServer().getServerID(), msg); link = new a ("idempiereMonitor?Action=Start_" + server.getServerId(), msg);
line.addElement(new td().addElement(link)); line.addElement(new td().addElement(link));
} }
table.addElement(line); table.addElement(line);
// //
line = new tr(); line = new tr();
line.addElement(new th().addElement("Description")); line.addElement(new th().addElement("Description"));
line.addElement(new td().addElement(WebEnv.getCellContent(server.getServer().getDescription()))); line.addElement(new td().addElement(WebEnv.getCellContent(server.getModel().getDescription())));
table.addElement(line); table.addElement(line);
// //
line = new tr(); line = new tr();
line.addElement(new th().addElement("Last Run")); line.addElement(new th().addElement("Last Run"));
line.addElement(new td().addElement(WebEnv.getCellContent(server.getServer().getDateLastRun()))); line.addElement(new td().addElement(WebEnv.getCellContent(server.getModel().getDateLastRun())));
table.addElement(line); table.addElement(line);
line = new tr(); line = new tr();
line.addElement(new th().addElement("Info")); line.addElement(new th().addElement("Info"));
line.addElement(new td().addElement(WebEnv.getCellContent(server.getServer().getServerInfo()))); line.addElement(new td().addElement(WebEnv.getCellContent(server.getServerInfo())));
table.addElement(line); table.addElement(line);
// //
line = new tr(); line = new tr();
line.addElement(new th().addElement("Next Run")); line.addElement(new th().addElement("Next Run"));
td td = new td(); td td = new td();
td.addElement(WebEnv.getCellContent(server.getServer().getDateNextRun(false))); td.addElement(WebEnv.getCellContent(server.getModel().getDateNextRun(false)));
td.addElement(" - "); td.addElement(" - ");
link = new a ("idempiereMonitor?RunNow=" + server.getServer().getServerID(), "(Run Now)"); link = new a ("idempiereMonitor?RunNow=" + server.getServerId(), "(Run Now)");
td.addElement(link); td.addElement(link);
line.addElement(td); line.addElement(td);
table.addElement(line); table.addElement(line);
// //
line = new tr(); line = new tr();
line.addElement(new th().addElement("Statistics")); line.addElement(new th().addElement("Statistics"));
line.addElement(new td().addElement(server.getServer().getStatistics())); line.addElement(new td().addElement(server.getStatistics()));
table.addElement(line); table.addElement(line);
// //
if (server.getClusterMember() != null)
{
InetAddress address = server.getClusterMember().getAddress();
String ip = address != null ? address.getHostAddress() : null;
if (ip != null &&
(ip.startsWith("10.") ||
ip.startsWith("172.16") ||
ip.startsWith("192.168")))
{
line = new tr();
line.addElement(new th().addElement("Cluster Node IP"));
line.addElement(new td().addElement(ip));
}
table.addElement(line);
line = new tr();
line.addElement(new th().addElement("Cluster Node Id"));
line.addElement(new td().addElement(server.getClusterMember().getId()));
table.addElement(line);
}
// Add table to Body // Add table to Body
bb.addElement(table); bb.addElement(table);
link = new a ("#top", "Top"); link = new a ("#top", "Top");
bb.addElement(link); bb.addElement(link);
bb.addElement(" - "); bb.addElement(" - ");
link = new a ("idempiereMonitor?Log=" + server.getServer().getServerID(), "Log"); link = new a ("idempiereMonitor?Log=" + server.getServerId(), "Log");
bb.addElement(link); bb.addElement(link);
bb.addElement(" - "); bb.addElement(" - ");
link = new a ("idempiereMonitor", "Refresh"); link = new a ("idempiereMonitor", "Refresh");
@ -766,6 +786,20 @@ public class AdempiereMonitor extends HttpServlet
WebUtil.createResponse (request, response, this, null, doc, false); WebUtil.createResponse (request, response, this, null, doc, false);
} // createSummaryPage } // createSummaryPage
private String createServerCountMessage(ServerCount serverCount) {
StringBuilder builder = new StringBuilder();
if (serverCount != null) {
builder.append(serverCount.getStarted()+serverCount.getStopped())
.append(" - Running=")
.append(serverCount.getStarted())
.append(" - Stopped=")
.append(serverCount.getStopped());
}
return builder.toString();
}
/************************************************************************** /**************************************************************************
* Create & Return Summary Page * Create & Return Summary Page
* @param request request * @param request request
@ -817,29 +851,29 @@ public class AdempiereMonitor extends HttpServlet
writer.print(m_serverMgr.getServerCount()); writer.print(m_serverMgr.getServerCount());
writer.println("</server-count>"); writer.println("</server-count>");
ServerWrapper[] servers = m_serverMgr.getAll(); ServerInstance[] servers = m_serverMgr.getServerInstances();
for (int i = 0; i < servers.length; i++) for (int i = 0; i < servers.length; i++)
{ {
ServerWrapper server = servers[i]; ServerInstance server = servers[i];
writer.println("\t\t<server>"); writer.println("\t\t<server>");
writer.print("\t\t\t<id>"); writer.print("\t\t\t<id>");
writer.print(server.getServer().getServerID()); writer.print(server.getServerId());
writer.println("</id>"); writer.println("</id>");
writer.print("\t\t\t<name>"); writer.print("\t\t\t<name>");
writer.print(server.getServer().getName()); writer.print(server.getModel().getName());
writer.println("</name>"); writer.println("</name>");
writer.print("\t\t\t<description>"); writer.print("\t\t\t<description>");
writer.print(server.getServer().getDescription()); writer.print(server.getModel().getDescription());
writer.println("</description>"); writer.println("</description>");
writer.print("\t\t\t<info>"); writer.print("\t\t\t<info>");
writer.print(server.getServer().getServerInfo()); writer.print(server.getServerInfo());
writer.println("</info>"); writer.println("</info>");
writer.print("\t\t\t<status>"); writer.print("\t\t\t<status>");
if (server.isAlive()) if (server.isStarted())
{ {
if (server.isInterrupted()) if (server.isInterrupted())
writer.print("Interrupted"); writer.print("Interrupted");
else if (server.getServer().isSleeping()) else if (server.isSleeping())
writer.print("Sleeping"); writer.print("Sleeping");
else else
writer.print("Running"); writer.print("Running");
@ -848,16 +882,16 @@ public class AdempiereMonitor extends HttpServlet
writer.print("Stopped"); writer.print("Stopped");
writer.println("</status>"); writer.println("</status>");
writer.print("\t\t\t<start-time>"); writer.print("\t\t\t<start-time>");
writer.print(server.getServer().getStartTime()); writer.print(server.getStartTime());
writer.println("</start-time>"); writer.println("</start-time>");
writer.print("\t\t\t<last-run>"); writer.print("\t\t\t<last-run>");
writer.print(server.getServer().getDateLastRun()); writer.print(server.getModel().getDateLastRun());
writer.println("</last-run>"); writer.println("</last-run>");
writer.print("\t\t\t<next-run>"); writer.print("\t\t\t<next-run>");
writer.print(server.getServer().getDateNextRun(false)); writer.print(server.getModel().getDateNextRun(false));
writer.println("</next-run>"); writer.println("</next-run>");
writer.print("\t\t\t<statistics>"); writer.print("\t\t\t<statistics>");
writer.print(server.getServer().getStatistics()); writer.print(server.getStatistics());
writer.println("</statistics>"); writer.println("</statistics>");
writer.println("\t\t</server>"); writer.println("\t\t</server>");
} }
@ -1148,7 +1182,16 @@ public class AdempiereMonitor extends HttpServlet
{ {
WebEnv.initWeb(config); WebEnv.initWeb(config);
log.info (""); log.info ("");
//always create the local server manager instance
m_serverMgr = AdempiereServerMgr.get(); m_serverMgr = AdempiereServerMgr.get();
//switch to cluster manager if cluster service is available
IServiceHolder<IClusterService> holder = Service.locator().locate(IClusterService.class);
IClusterService service = holder != null ? holder.getService() : null;
if (service != null)
m_serverMgr = ClusterServerMgr.getInstance();
m_dirAccessList = getDirAcessList(); m_dirAccessList = getDirAcessList();
} // init } // init