1 16 package org.outerj.daisy.backuplock.impl; 17 18 import org.outerj.daisy.backuplock.SuspendForBackupRegistrar; 19 import org.outerj.daisy.backuplock.SuspendableProcess; 20 import org.outerj.daisy.blobstore.BlobStore; 21 import org.outerj.daisy.jms.JmsClient; 22 import org.apache.avalon.framework.service.Serviceable; 23 import org.apache.avalon.framework.service.ServiceManager; 24 import org.apache.avalon.framework.service.ServiceException; 25 import org.apache.avalon.framework.activity.Initializable; 26 import org.apache.avalon.framework.activity.Disposable; 27 28 import javax.management.MBeanServer ; 29 import javax.management.ObjectName ; 30 import java.util.ArrayList ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 34 42 public class BackupLockerImpl implements SuspendForBackupRegistrar, Serviceable, Initializable, BackupLockerImplMBean, 43 Disposable { 44 private BlobStore blobStore; 45 private JmsClient jmsClient; 46 private List suspendableProcesses = new ArrayList (); 47 private ServiceManager serviceManager; 48 private boolean locked = false; 49 50 55 public void service(ServiceManager serviceManager) throws ServiceException { 56 this.serviceManager = serviceManager; 57 this.blobStore = (BlobStore)serviceManager.lookup("blobstore"); 58 this.jmsClient = (JmsClient)serviceManager.lookup("jmsclient"); 59 } 60 61 public void initialize() throws Exception { 62 MBeanServer mbeanServer = (MBeanServer )serviceManager.lookup("mbeanserver"); 63 try { 64 mbeanServer.registerMBean(this, new ObjectName ("Daisy:name=BackupLocker")); 65 } finally { 66 serviceManager.release(mbeanServer); 67 } 68 69 suspendableProcesses.add(new ProcessInfo("JMS client", new SuspendableProcess() { 72 public boolean suspendExecution(long msecs) throws InterruptedException { 73 return jmsClient.suspend(msecs); 74 } 75 76 public void resumeExecution() { 77 jmsClient.resume(); 78 } 79 })); 80 suspendableProcesses.add(new ProcessInfo("Blob store", new SuspendableProcess() { 83 public boolean suspendExecution(long msecs) throws InterruptedException { 84 return blobStore.suspendWrites(msecs); 85 } 86 87 public void resumeExecution() { 88 blobStore.resumeWrites(); 89 } 90 })); 91 } 92 93 public synchronized void dispose() { 94 suspendableProcesses.clear(); 95 serviceManager.release(blobStore); 96 serviceManager.release(jmsClient); 97 } 98 99 public synchronized void register(String descriptiveName, SuspendableProcess process) { 100 suspendableProcesses.add(0, new ProcessInfo(descriptiveName, process)); 102 } 103 104 public synchronized void unregister(SuspendableProcess process) { 105 for (int i = 0; i < suspendableProcesses.size(); i++) { 106 ProcessInfo processInfo = (ProcessInfo)suspendableProcesses.get(i); 107 if (processInfo.process == process) { 108 suspendableProcesses.remove(i); 109 return; 110 } 111 } 112 } 113 114 static class ProcessInfo { 115 String name; 116 SuspendableProcess process; 117 118 public ProcessInfo(String name, SuspendableProcess process) { 119 this.name = name; 120 this.process = process; 121 } 122 } 123 124 public synchronized void lock(long msecs) throws Exception { 125 if (locked) 126 throw new Exception ("Already locked for backup."); 127 128 Iterator suspendableProcessesIt = suspendableProcesses.iterator(); 129 while (suspendableProcessesIt.hasNext()) { 130 ProcessInfo processInfo = (ProcessInfo)suspendableProcessesIt.next(); 131 boolean success = false; 132 try { 133 success = processInfo.process.suspendExecution(msecs); 134 } catch (InterruptedException e) { 135 } 137 if (!success) { 138 unlock(true); 140 throw new Exception ("Failed to suspend execution of " + processInfo.name + " within the given time out of " + msecs + " msecs."); 141 } 142 } 143 locked = true; 144 } 145 146 public synchronized void unlock() throws Exception { 147 unlock(false); 148 } 149 150 private synchronized void unlock(boolean force) throws Exception { 151 if (!force && !locked) 152 throw new Exception ("Cannot unlock, because currently not locked."); 153 154 Iterator suspendableProcessesIt = suspendableProcesses.iterator(); 155 while (suspendableProcessesIt.hasNext()) { 156 ProcessInfo processInfo = (ProcessInfo)suspendableProcessesIt.next(); 157 processInfo.process.resumeExecution(); 158 } 159 locked = false; 160 } 161 162 public synchronized boolean isLocked() { 163 return locked; 164 } 165 } 166 | Popular Tags |