001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Nuxeo - initial API and implementation 011 */ 012 013package org.nuxeo.ecm.core.management.statuses; 014 015import static org.nuxeo.ecm.core.management.api.AdministrativeStatus.ACTIVE; 016import static org.nuxeo.ecm.core.management.api.AdministrativeStatus.PASSIVE; 017 018import java.util.Calendar; 019import java.util.List; 020import java.util.concurrent.Executors; 021import java.util.concurrent.ScheduledExecutorService; 022import java.util.concurrent.ThreadFactory; 023import java.util.concurrent.TimeUnit; 024 025import org.nuxeo.ecm.core.management.CoreManagementService; 026import org.nuxeo.ecm.core.management.api.AdministrativeStatus; 027import org.nuxeo.ecm.core.management.api.AdministrativeStatusManager; 028import org.nuxeo.ecm.core.management.api.GlobalAdministrativeStatusManager; 029import org.nuxeo.ecm.core.management.storage.AdministrativeStatusPersister; 030import org.nuxeo.runtime.transaction.TransactionHelper; 031 032/** 033 * Implementation class for the {@link AdministrativeStatusManager} service. For each Nuxeo Instance in the cluster one 034 * instance of this class is created. 035 * 036 * @author tiry 037 */ 038public class AdministrativeStatusManagerImpl implements AdministrativeStatusManager, CoreManagementService { 039 040 protected final AdministrativeStatusPersister persister; 041 042 protected final GlobalAdministrativeStatusManager globalManager; 043 044 protected final String serverInstanceName; 045 046 protected final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, new ThreadFactory() { 047 @Override 048 public Thread newThread(Runnable r) { 049 return new Thread(r, "Nuxeo-Administrative-Statuses-Notify-Scheduler"); 050 } 051 }); 052 053 protected final Notifier[] notifiers = { new CoreEventNotifier(), new RuntimeEventNotifier() }; 054 055 public AdministrativeStatusManagerImpl(GlobalAdministrativeStatusManager globalManager, 056 AdministrativeStatusPersister persister) { 057 this.globalManager = globalManager; 058 this.persister = persister; 059 serverInstanceName = NuxeoInstanceIdentifierHelper.getServerInstanceName(); 060 } 061 062 public AdministrativeStatusManagerImpl(GlobalAdministrativeStatusManager globalManager, 063 AdministrativeStatusPersister persister, String instanceIdentifier) { 064 this.globalManager = globalManager; 065 this.persister = persister; 066 serverInstanceName = instanceIdentifier; 067 } 068 069 protected String getServerInstanceName() { 070 return serverInstanceName; 071 } 072 073 protected void notifyEvent(String eventName, String instanceIdentifier, String serviceIdentifier) { 074 for (Notifier notifier : notifiers) { 075 notifier.notifyEvent(eventName, instanceIdentifier, serviceIdentifier); 076 } 077 } 078 079 public void onNuxeoServerStartup() { 080 081 List<AdministrativeStatus> savedStatuses = persister.getAllStatuses(serverInstanceName); 082 083 // iterate throw declared services and init them if needed 084 List<AdministrableServiceDescriptor> descs = globalManager.listRegistredServices(); 085 086 for (AdministrableServiceDescriptor desc : descs) { 087 boolean serviceExist = false; 088 for (AdministrativeStatus status : savedStatuses) { 089 if (desc.getId().equals(status.getServiceIdentifier())) { 090 serviceExist = true; 091 break; 092 } 093 } 094 if (!serviceExist) { 095 AdministrativeStatus newStatus = new AdministrativeStatus(desc.getInitialState(), "", 096 Calendar.getInstance(), "system", serverInstanceName, desc.getId()); 097 persister.saveStatus(newStatus); 098 } 099 } 100 101 doNotifyAllStatuses(); 102 103 scheduler.scheduleAtFixedRate(new NotifyStatusesHandler(), 5, 5, TimeUnit.MINUTES); 104 } 105 106 protected void doNotifyAllStatuses() { 107 for (AdministrativeStatus status : persister.getAllStatuses(serverInstanceName)) { 108 notifyOnStatus(status); 109 } 110 } 111 112 public class NotifyStatusesHandler implements Runnable { 113 @Override 114 public void run() { 115 TransactionHelper.startTransaction(); 116 boolean notified = false; 117 try { 118 doNotifyAllStatuses(); 119 notified = true; 120 } finally { 121 if (!notified) { 122 TransactionHelper.setTransactionRollbackOnly(); 123 } 124 TransactionHelper.commitOrRollbackTransaction(); 125 } 126 } 127 } 128 129 public void onNuxeoServerShutdown() { 130 scheduler.shutdown(); 131 } 132 133 protected void notifyOnStatus(AdministrativeStatus status) { 134 if (status.isActive()) { 135 notifyEvent(ACTIVATED_EVENT, status.getInstanceIdentifier(), status.getServiceIdentifier()); 136 } else if (status.isPassive()) { 137 notifyEvent(PASSIVATED_EVENT, status.getInstanceIdentifier(), status.getServiceIdentifier()); 138 } 139 } 140 141 @Override 142 public AdministrativeStatus activateNuxeoInstance(String message, String login) { 143 return activate(GLOBAL_INSTANCE_AVAILABILITY, message, login); 144 } 145 146 @Override 147 public AdministrativeStatus deactivateNuxeoInstance(String message, String login) { 148 return deactivate(GLOBAL_INSTANCE_AVAILABILITY, message, login); 149 } 150 151 @Override 152 public AdministrativeStatus getNuxeoInstanceStatus() { 153 return getStatus(GLOBAL_INSTANCE_AVAILABILITY); 154 } 155 156 @Override 157 public AdministrativeStatus setNuxeoInstanceStatus(String state, String message, String login) { 158 return setStatus(GLOBAL_INSTANCE_AVAILABILITY, state, message, login); 159 } 160 161 @Override 162 public AdministrativeStatus activate(String serviceIdentifier, String message, String login) { 163 return setStatus(serviceIdentifier, ACTIVE, message, login); 164 } 165 166 @Override 167 public AdministrativeStatus deactivate(String serviceIdentifier, String message, String login) { 168 return setStatus(serviceIdentifier, PASSIVE, message, login); 169 } 170 171 @Override 172 public AdministrativeStatus setStatus(String serviceIdentifier, String state, String message, String login) { 173 AdministrativeStatus status = new AdministrativeStatus(state, message, Calendar.getInstance(), login, 174 serverInstanceName, serviceIdentifier); 175 status = persister.saveStatus(status); 176 notifyOnStatus(status); 177 return addLabelAndDescription(status); 178 } 179 180 @Override 181 public List<AdministrativeStatus> getAllStatuses() { 182 List<AdministrativeStatus> statuses = persister.getAllStatuses(serverInstanceName); 183 for (AdministrativeStatus status : statuses) { 184 addLabelAndDescription(status); 185 } 186 return statuses; 187 } 188 189 protected AdministrativeStatus addLabelAndDescription(AdministrativeStatus status) { 190 if (status == null) { 191 return null; 192 } 193 String id = status.getServiceIdentifier(); 194 AdministrableServiceDescriptor desc = globalManager.getServiceDescriptor(id); 195 if (desc != null) { 196 status.setLabelAndDescription(desc.getLabel(), desc.getDescription()); 197 } 198 return status; 199 } 200 201 @Override 202 public AdministrativeStatus getStatus(String serviceIdentifier) { 203 AdministrativeStatus status = persister.getStatus(serverInstanceName, serviceIdentifier); 204 addLabelAndDescription(status); 205 return status; 206 } 207 208}