/* * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * 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 ScheduledExecutorService 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 = Executors.newScheduledThreadPool(1, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r, "Nuxeo-Administrative-Statuses-Notify-Scheduler"); } }); 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() { if (scheduler == null) { return; } try { scheduler.shutdown(); } finally { scheduler = null; } } 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; } }