/*
* Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nuxeo - initial API and implementation
*/
package org.nuxeo.ecm.core.management.statuses;
import static org.nuxeo.ecm.core.management.api.AdministrativeStatus.ACTIVE;
import static org.nuxeo.ecm.core.management.api.AdministrativeStatus.PASSIVE;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import org.nuxeo.ecm.core.management.CoreManagementService;
import org.nuxeo.ecm.core.management.api.AdministrativeStatus;
import org.nuxeo.ecm.core.management.api.AdministrativeStatusManager;
import org.nuxeo.ecm.core.management.api.GlobalAdministrativeStatusManager;
import org.nuxeo.ecm.core.management.storage.AdministrativeStatusPersister;
import org.nuxeo.runtime.transaction.TransactionHelper;
/**
* Implementation class for the {@link AdministrativeStatusManager} service.
* For each Nuxeo Instance in the cluster one instance of this class is
* created.
*
* @author tiry
*/
public class AdministrativeStatusManagerImpl implements
AdministrativeStatusManager, CoreManagementService {
protected final AdministrativeStatusPersister persister;
protected final GlobalAdministrativeStatusManager globalManager;
protected final String serverInstanceName;
protected final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "Nuxeo-Administrative-Statuses-Notify-Scheduler");
}
});
protected final Notifier[] notifiers = { new CoreEventNotifier(),
new RuntimeEventNotifier() };
public AdministrativeStatusManagerImpl(
GlobalAdministrativeStatusManager globalManager,
AdministrativeStatusPersister persister) {
this.globalManager = globalManager;
this.persister = persister;
serverInstanceName = NuxeoInstanceIdentifierHelper.getServerInstanceName();
}
public AdministrativeStatusManagerImpl(
GlobalAdministrativeStatusManager globalManager,
AdministrativeStatusPersister persister, String instanceIdentifier) {
this.globalManager = globalManager;
this.persister = persister;
serverInstanceName = instanceIdentifier;
}
protected String getServerInstanceName() {
return serverInstanceName;
}
protected void notifyEvent(String eventName, String instanceIdentifier,
String serviceIdentifier) {
for (Notifier notifier : notifiers) {
notifier.notifyEvent(eventName, instanceIdentifier,
serviceIdentifier);
}
}
public void onNuxeoServerStartup() {
List<AdministrativeStatus> savedStatuses = persister.getAllStatuses(serverInstanceName);
// iterate throw declared services and init them if needed
List<AdministrableServiceDescriptor> descs = globalManager.listRegistredServices();
for (AdministrableServiceDescriptor desc : descs) {
boolean serviceExist = false;
for (AdministrativeStatus status : savedStatuses) {
if (desc.getId().equals(status.getServiceIdentifier())) {
serviceExist = true;
break;
}
}
if (!serviceExist) {
AdministrativeStatus newStatus = new AdministrativeStatus(
desc.getInitialState(), "", Calendar.getInstance(),
"system", serverInstanceName, desc.getId());
persister.saveStatus(newStatus);
}
}
doNotifyAllStatuses();
scheduler.scheduleAtFixedRate(new NotifyStatusesHandler(), 5, 5, TimeUnit.MINUTES);
}
protected void doNotifyAllStatuses() {
for (AdministrativeStatus status : persister.getAllStatuses(serverInstanceName)) {
notifyOnStatus(status);
}
}
public class NotifyStatusesHandler implements Runnable {
@Override
public void run() {
TransactionHelper.startTransaction();
boolean notified = false;
try {
doNotifyAllStatuses();
notified = true;
} finally {
if (!notified) {
TransactionHelper.setTransactionRollbackOnly();
}
TransactionHelper.commitOrRollbackTransaction();
}
}
}
public void onNuxeoServerShutdown() {
scheduler.shutdown();
}
protected void notifyOnStatus(AdministrativeStatus status) {
if (status.isActive()) {
notifyEvent(ACTIVATED_EVENT,
status.getInstanceIdentifier(),
status.getServiceIdentifier());
} else if (status.isPassive()) {
notifyEvent(PASSIVATED_EVENT,
status.getInstanceIdentifier(),
status.getServiceIdentifier());
}
}
@Override
public AdministrativeStatus activateNuxeoInstance(String message,
String login) {
return activate(GLOBAL_INSTANCE_AVAILABILITY,
message, login);
}
@Override
public AdministrativeStatus deactivateNuxeoInstance(String message,
String login) {
return deactivate(GLOBAL_INSTANCE_AVAILABILITY,
message, login);
}
@Override
public AdministrativeStatus getNuxeoInstanceStatus() {
return getStatus(GLOBAL_INSTANCE_AVAILABILITY);
}
@Override
public AdministrativeStatus setNuxeoInstanceStatus(String state,
String message, String login) {
return setStatus(GLOBAL_INSTANCE_AVAILABILITY,
state, message, login);
}
@Override
public AdministrativeStatus activate(String serviceIdentifier,
String message, String login) {
return setStatus(serviceIdentifier, ACTIVE,
message, login);
}
@Override
public AdministrativeStatus deactivate(String serviceIdentifier,
String message, String login) {
return setStatus(serviceIdentifier, PASSIVE,
message, login);
}
@Override
public AdministrativeStatus setStatus(String serviceIdentifier,
String state, String message, String login) {
AdministrativeStatus status = new AdministrativeStatus(state, message,
Calendar.getInstance(), login, serverInstanceName,
serviceIdentifier);
status = persister.saveStatus(status);
notifyOnStatus(status);
return addLabelAndDescription(status);
}
@Override
public List<AdministrativeStatus> getAllStatuses() {
List<AdministrativeStatus> statuses = persister.getAllStatuses(serverInstanceName);
for (AdministrativeStatus status : statuses) {
addLabelAndDescription(status);
}
return statuses;
}
protected AdministrativeStatus addLabelAndDescription(
AdministrativeStatus status) {
if (status == null) {
return null;
}
String id = status.getServiceIdentifier();
AdministrableServiceDescriptor desc = globalManager.getServiceDescriptor(id);
if (desc != null) {
status.setLabelAndDescription(desc.getLabel(),
desc.getDescription());
}
return status;
}
@Override
public AdministrativeStatus getStatus(String serviceIdentifier) {
AdministrativeStatus status = persister.getStatus(serverInstanceName,
serviceIdentifier);
addLabelAndDescription(status);
return status;
}
}