mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-20 03:24:55 +00:00
Refactored service monitor to perform on-demand checks when service status is unknown
This commit is contained in:
parent
f4bc81f93e
commit
c9f2863e27
@ -38,7 +38,6 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
|||||||
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
||||||
import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo;
|
import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo;
|
||||||
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
|
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
|
||||||
import org.sleuthkit.datamodel.CaseDbConnectionInfo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class periodically checks availability of collaboration resources -
|
* This class periodically checks availability of collaboration resources -
|
||||||
@ -61,7 +60,8 @@ public class ServicesMonitor {
|
|||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The service monitor maintains a mapping of each service to it's last status update.
|
* The service monitor maintains a mapping of each service to it's last
|
||||||
|
* status update.
|
||||||
*/
|
*/
|
||||||
private final ConcurrentHashMap<String, String> statusByService;
|
private final ConcurrentHashMap<String, String> statusByService;
|
||||||
|
|
||||||
@ -77,13 +77,12 @@ public class ServicesMonitor {
|
|||||||
* New value is set to updated ServiceStatus, old value is null.
|
* New value is set to updated ServiceStatus, old value is null.
|
||||||
*/
|
*/
|
||||||
REMOTE_CASE_DATABASE,
|
REMOTE_CASE_DATABASE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Property change event fired when remote keyword search service status changes.
|
* Property change event fired when remote keyword search service status
|
||||||
* New value is set to updated ServiceStatus, old value is null.
|
* changes. New value is set to updated ServiceStatus, old value is
|
||||||
|
* null.
|
||||||
*/
|
*/
|
||||||
REMOTE_KEYWORD_SEARCH,
|
REMOTE_KEYWORD_SEARCH,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Property change event fired when messaging service status changes.
|
* Property change event fired when messaging service status changes.
|
||||||
* New value is set to updated ServiceStatus, old value is null.
|
* New value is set to updated ServiceStatus, old value is null.
|
||||||
@ -100,11 +99,14 @@ public class ServicesMonitor {
|
|||||||
* Service is currently up.
|
* Service is currently up.
|
||||||
*/
|
*/
|
||||||
UP,
|
UP,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service is currently down.
|
* Service is currently down.
|
||||||
*/
|
*/
|
||||||
DOWN
|
DOWN,
|
||||||
|
/**
|
||||||
|
* Service status is unknown.
|
||||||
|
*/
|
||||||
|
UNKNOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
public synchronized static ServicesMonitor getInstance() {
|
public synchronized static ServicesMonitor getInstance() {
|
||||||
@ -118,10 +120,8 @@ public class ServicesMonitor {
|
|||||||
|
|
||||||
this.eventPublisher = new AutopsyEventPublisher();
|
this.eventPublisher = new AutopsyEventPublisher();
|
||||||
this.statusByService = new ConcurrentHashMap<>();
|
this.statusByService = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
// Services are assumed to be "UP" by default. See CrashDetectionTask class for more info.
|
|
||||||
for (String serviceName : serviceNames) {
|
for (String serviceName : serviceNames) {
|
||||||
this.statusByService.put(serviceName, ServiceStatus.UP.toString());
|
this.statusByService.put(serviceName, ServiceStatus.UNKNOWN.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,7 +138,7 @@ public class ServicesMonitor {
|
|||||||
* @param service Name of the service.
|
* @param service Name of the service.
|
||||||
* @param status Updated status for the service.
|
* @param status Updated status for the service.
|
||||||
*/
|
*/
|
||||||
private void setServiceStatus(String service, String status){
|
private void setServiceStatus(String service, String status) {
|
||||||
this.statusByService.put(service, status);
|
this.statusByService.put(service, status);
|
||||||
publishServiceStatusUpdate(service, status);
|
publishServiceStatusUpdate(service, status);
|
||||||
}
|
}
|
||||||
@ -152,21 +152,65 @@ public class ServicesMonitor {
|
|||||||
*/
|
*/
|
||||||
public String getServiceStatus(String service) throws UnknownServiceException {
|
public String getServiceStatus(String service) throws UnknownServiceException {
|
||||||
|
|
||||||
if (service == null){
|
if (service == null) {
|
||||||
// TODO NbBundle.getMessage(Case.class, "Case.createCaseDir.exception.existNotDir"));
|
// TODO NbBundle.getMessage(Case.class, "Case.createCaseDir.exception.existNotDir"));
|
||||||
throw new UnknownServiceException("Requested service name is null");
|
throw new UnknownServiceException("Requested service name is null");
|
||||||
}
|
}
|
||||||
|
|
||||||
String status = this.statusByService.get(service);
|
String status = this.statusByService.get(service);
|
||||||
if (status == null){
|
if (status == null) {
|
||||||
// no such service
|
// no such service
|
||||||
throw new UnknownServiceException("Requested service name " + service + " is unknown");
|
throw new UnknownServiceException("Requested service name " + service + " is unknown");
|
||||||
|
|
||||||
|
} else if (status.equals(ServiceStatus.UNKNOWN.toString())) {
|
||||||
|
// status for the service is not known. This is likely because we haven't
|
||||||
|
// checked it's status yet. Perform an on-demand check of the service status.
|
||||||
|
status = checkServiceStatusStatus(service);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publish an event signifying change in service status. Event is published locally.
|
* Performs on-demand check of service availability.
|
||||||
|
*
|
||||||
|
* @param service Name of the service.
|
||||||
|
* @return String Status for the service.
|
||||||
|
*/
|
||||||
|
private String checkServiceStatusStatus(String service) {
|
||||||
|
|
||||||
|
if (service.equals(ServiceName.REMOTE_CASE_DATABASE.toString())) {
|
||||||
|
if (canConnectToRemoteDb()) {
|
||||||
|
setServiceStatus(ServiceName.REMOTE_CASE_DATABASE.toString(), ServiceStatus.UP.toString());
|
||||||
|
return ServiceStatus.UP.toString();
|
||||||
|
} else {
|
||||||
|
setServiceStatus(ServiceName.REMOTE_CASE_DATABASE.toString(), ServiceStatus.DOWN.toString());
|
||||||
|
return ServiceStatus.DOWN.toString();
|
||||||
|
}
|
||||||
|
} else if (service.equals(ServiceName.REMOTE_KEYWORD_SEARCH.toString())){
|
||||||
|
KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class);
|
||||||
|
// TODO - do I need to check for kwsService == null?
|
||||||
|
if (kwsService.canConnectToRemoteSolrServer()) {
|
||||||
|
setServiceStatus(ServiceName.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.UP.toString());
|
||||||
|
return ServiceStatus.UP.toString();
|
||||||
|
} else {
|
||||||
|
setServiceStatus(ServiceName.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.DOWN.toString());
|
||||||
|
return ServiceStatus.DOWN.toString();
|
||||||
|
}
|
||||||
|
} else if (service.equals(ServiceName.MESSAGING.toString())) {
|
||||||
|
if (canConnectToMessagingService()) {
|
||||||
|
setServiceStatus(ServiceName.MESSAGING.toString(), ServiceStatus.UP.toString());
|
||||||
|
return ServiceStatus.UP.toString();
|
||||||
|
} else {
|
||||||
|
setServiceStatus(ServiceName.MESSAGING.toString(), ServiceStatus.DOWN.toString());
|
||||||
|
return ServiceStatus.DOWN.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ServiceStatus.UNKNOWN.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish an event signifying change in service status. Event is published
|
||||||
|
* locally.
|
||||||
*
|
*
|
||||||
* @param service Name of the service.
|
* @param service Name of the service.
|
||||||
* @param status Updated status for the event.
|
* @param status Updated status for the event.
|
||||||
@ -246,20 +290,41 @@ public class ServicesMonitor {
|
|||||||
eventPublisher.removeSubscriber(serviceNames, subscriber);
|
eventPublisher.removeSubscriber(serviceNames, subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies connection to remote database.
|
||||||
|
*
|
||||||
|
* @return True if connection can be established, false otherwise.
|
||||||
|
*/
|
||||||
|
private boolean canConnectToRemoteDb() {
|
||||||
|
return UserPreferences.getDatabaseConnectionInfo().canConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies connection to messaging service.
|
||||||
|
*
|
||||||
|
* @return True if connection can be established, false otherwise.
|
||||||
|
*/
|
||||||
|
private boolean canConnectToMessagingService() {
|
||||||
|
MessageServiceConnectionInfo msgInfo = UserPreferences.getMessageServiceConnectionInfo();
|
||||||
|
try {
|
||||||
|
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(msgInfo.getUserName(), msgInfo.getPassword(), msgInfo.getURI());
|
||||||
|
Connection connection = connectionFactory.createConnection();
|
||||||
|
connection.start();
|
||||||
|
connection.close();
|
||||||
|
return true;
|
||||||
|
} catch (URISyntaxException | JMSException ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Runnable task that periodically checks the availability of
|
* A Runnable task that periodically checks the availability of
|
||||||
* collaboration resources (PostgreSQL server, Solr server, Active MQ
|
* collaboration resources (remote database, remote keyword search service,
|
||||||
* message broker) and reports status to the user in case of a gap in
|
* message broker) and reports status to the user in case of a gap in
|
||||||
* service.
|
* service.
|
||||||
*/
|
*/
|
||||||
private final class CrashDetectionTask implements Runnable {
|
private final class CrashDetectionTask implements Runnable {
|
||||||
|
|
||||||
// Services are assumed to be "UP" by default. Change default value in ServicesMonitor()
|
|
||||||
// constructor if this assumption changes.
|
|
||||||
private boolean dbServerIsRunning = true;
|
|
||||||
private boolean solrServerIsRunning = true;
|
|
||||||
private boolean messageServerIsRunning = true;
|
|
||||||
|
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -268,60 +333,53 @@ public class ServicesMonitor {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
CaseDbConnectionInfo dbInfo = UserPreferences.getDatabaseConnectionInfo();
|
|
||||||
if (dbInfo.canConnect()) {
|
|
||||||
if (!dbServerIsRunning) {
|
|
||||||
dbServerIsRunning = true;
|
|
||||||
logger.log(Level.INFO, "Connection to PostgreSQL server restored"); //NON-NLS
|
|
||||||
MessageNotifyUtil.Notify.info(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredService.notify.title"), NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredDbService.notify.msg"));
|
|
||||||
setServiceStatus(ServiceName.REMOTE_CASE_DATABASE.toString(), ServiceStatus.UP.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (dbServerIsRunning) {
|
|
||||||
dbServerIsRunning = false;
|
|
||||||
logger.log(Level.SEVERE, "Failed to connect to PostgreSQL server"); //NON-NLS
|
|
||||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedService.notify.title"), NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedDbService.notify.msg"));
|
|
||||||
setServiceStatus(ServiceName.REMOTE_CASE_DATABASE.toString(), ServiceStatus.DOWN.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class);
|
|
||||||
// TODO - do I need to check for kwsService == null?
|
|
||||||
if (kwsService.canConnectToRemoteSolrServer()) {
|
|
||||||
if (!solrServerIsRunning) {
|
|
||||||
solrServerIsRunning = true;
|
|
||||||
logger.log(Level.INFO, "Connection to Solr server restored"); //NON-NLS
|
|
||||||
MessageNotifyUtil.Notify.info(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredService.notify.title"), NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredSolrService.notify.msg"));
|
|
||||||
setServiceStatus(ServiceName.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.UP.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (solrServerIsRunning) {
|
|
||||||
solrServerIsRunning = false;
|
|
||||||
logger.log(Level.SEVERE, "Failed to connect to Solr server"); //NON-NLS
|
|
||||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedService.notify.title"), NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedSolrService.notify.msg"));
|
|
||||||
setServiceStatus(ServiceName.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.DOWN.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageServiceConnectionInfo msgInfo = UserPreferences.getMessageServiceConnectionInfo();
|
|
||||||
try {
|
try {
|
||||||
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(msgInfo.getUserName(), msgInfo.getPassword(), msgInfo.getURI());
|
if (canConnectToRemoteDb()) {
|
||||||
Connection connection = connectionFactory.createConnection();
|
if (!getServiceStatus(ServiceName.REMOTE_CASE_DATABASE.toString()).equals(ServiceStatus.UP.toString())) {
|
||||||
connection.start();
|
logger.log(Level.INFO, "Connection to PostgreSQL server restored"); //NON-NLS
|
||||||
connection.close();
|
MessageNotifyUtil.Notify.info(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredService.notify.title"), NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredDbService.notify.msg"));
|
||||||
if (!messageServerIsRunning) {
|
setServiceStatus(ServiceName.REMOTE_CASE_DATABASE.toString(), ServiceStatus.UP.toString());
|
||||||
messageServerIsRunning = true;
|
}
|
||||||
logger.log(Level.INFO, "Connection to ActiveMQ server restored"); //NON-NLS
|
} else {
|
||||||
MessageNotifyUtil.Notify.info(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredService.notify.title"), NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredMessageService.notify.msg"));
|
if (!getServiceStatus(ServiceName.REMOTE_CASE_DATABASE.toString()).equals(ServiceStatus.DOWN.toString())) {
|
||||||
setServiceStatus(ServiceName.MESSAGING.toString(), ServiceStatus.UP.toString());
|
logger.log(Level.SEVERE, "Failed to connect to PostgreSQL server"); //NON-NLS
|
||||||
|
MessageNotifyUtil.Notify.error(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedService.notify.title"), NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedDbService.notify.msg"));
|
||||||
|
setServiceStatus(ServiceName.REMOTE_CASE_DATABASE.toString(), ServiceStatus.DOWN.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (URISyntaxException | JMSException ex) {
|
|
||||||
if (messageServerIsRunning) {
|
KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class);
|
||||||
messageServerIsRunning = false;
|
// TODO - do I need to check for kwsService == null?
|
||||||
logger.log(Level.SEVERE, "Failed to connect to ActiveMQ server", ex); //NON-NLS
|
if (kwsService.canConnectToRemoteSolrServer()) {
|
||||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedService.notify.title"), NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedMessageService.notify.msg"));
|
if (!getServiceStatus(ServiceName.REMOTE_KEYWORD_SEARCH.toString()).equals(ServiceStatus.UP.toString())) {
|
||||||
setServiceStatus(ServiceName.MESSAGING.toString(), ServiceStatus.DOWN.toString());
|
logger.log(Level.INFO, "Connection to Solr server restored"); //NON-NLS
|
||||||
|
MessageNotifyUtil.Notify.info(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredService.notify.title"), NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredSolrService.notify.msg"));
|
||||||
|
setServiceStatus(ServiceName.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.UP.toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!getServiceStatus(ServiceName.REMOTE_KEYWORD_SEARCH.toString()).equals(ServiceStatus.DOWN.toString())) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to connect to Solr server"); //NON-NLS
|
||||||
|
MessageNotifyUtil.Notify.error(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedService.notify.title"), NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedSolrService.notify.msg"));
|
||||||
|
setServiceStatus(ServiceName.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.DOWN.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (canConnectToMessagingService()) {
|
||||||
|
if (!getServiceStatus(ServiceName.MESSAGING.toString()).equals(ServiceStatus.UP.toString())) {
|
||||||
|
logger.log(Level.INFO, "Connection to ActiveMQ server restored"); //NON-NLS
|
||||||
|
MessageNotifyUtil.Notify.info(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredService.notify.title"), NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredMessageService.notify.msg"));
|
||||||
|
setServiceStatus(ServiceName.MESSAGING.toString(), ServiceStatus.UP.toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!getServiceStatus(ServiceName.MESSAGING.toString()).equals(ServiceStatus.DOWN.toString())) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to connect to ActiveMQ server"); //NON-NLS
|
||||||
|
MessageNotifyUtil.Notify.error(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedService.notify.title"), NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedMessageService.notify.msg"));
|
||||||
|
setServiceStatus(ServiceName.MESSAGING.toString(), ServiceStatus.DOWN.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (UnknownServiceException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Exception while checking current service status", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user