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