Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/NonActivatableMahaloImpl.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/NonActivatableMahaloImpl.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/NonActivatableMahaloImpl.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/NonActivatableMahaloImpl.java Sun Jul 5 11:41:39 2020 @@ -1,56 +1,56 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ -package org.apache.river.mahalo; - -import org.apache.river.start.LifeCycle; - -/** - * Convenience class intended for use with the - * {@link org.apache.river.start.ServiceStarter} framework to start - * an implementation of Mahalo that is not activatable, but which - * will log its state information to persistent storage. - * - * @author Sun Microsystems, Inc. - * @since 2.0 - */ -class NonActivatableMahaloImpl extends TxnManagerImpl { - - /** - * Constructs a new instance of <code>TxnManagerImpl</code> that is not - * activatable, but which will persist its state. - * - * @param configArgs <code>String</code> array whose elements are - * the arguments to use when creating the server. - * @param lifeCycle instance of <code>LifeCycle</code> that, if - * non-<code>null</code>, will cause this object's - * <code>unregister</code> method to be invoked during - * shutdown to notify the service starter framework that - * the reference to this service's implementation can be - * 'released' for garbage collection. A value of - * <code>null</code> for this argument is allowed. - * - * @throws Exception If there was a problem initializing the service. - */ - NonActivatableMahaloImpl(String[] configArgs, LifeCycle lifeCycle) - throws Exception - { - super(configArgs, lifeCycle, true);//true ==> persistent - }//end constructor - -}//end class NonActivatableMahaloImpl - +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +package org.apache.river.mahalo; + +import org.apache.river.start.lifecycle.LifeCycle; + +/** + * Convenience class intended for use with the + * {@link org.apache.river.start.ServiceStarter} framework to start + * an implementation of Mahalo that is not activatable, but which + * will log its state information to persistent storage. + * + * @author Sun Microsystems, Inc. + * @since 2.0 + */ +class NonActivatableMahaloImpl extends TxnManagerImpl { + + /** + * Constructs a new instance of <code>TxnManagerImpl</code> that is not + * activatable, but which will persist its state. + * + * @param configArgs <code>String</code> array whose elements are + * the arguments to use when creating the server. + * @param lifeCycle instance of <code>LifeCycle</code> that, if + * non-<code>null</code>, will cause this object's + * <code>unregister</code> method to be invoked during + * shutdown to notify the service starter framework that + * the reference to this service's implementation can be + * 'released' for garbage collection. A value of + * <code>null</code> for this argument is allowed. + * + * @throws Exception If there was a problem initializing the service. + */ + NonActivatableMahaloImpl(String[] configArgs, LifeCycle lifeCycle) + throws Exception + { + super(configArgs, lifeCycle, true);//true ==> persistent + }//end constructor + +}//end class NonActivatableMahaloImpl +
Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/ParticipantTask.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/ParticipantTask.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/ParticipantTask.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/ParticipantTask.java Sun Jul 5 11:41:39 2020 @@ -17,8 +17,8 @@ */ package org.apache.river.mahalo; -import org.apache.river.thread.RetryTask; -import org.apache.river.thread.WakeupManager; +import org.apache.river.thread.wakeup.RetryTask; +import org.apache.river.thread.wakeup.WakeupManager; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.logging.Level; Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareAndCommitJob.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareAndCommitJob.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareAndCommitJob.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareAndCommitJob.java Sun Jul 5 11:41:39 2020 @@ -20,7 +20,7 @@ package org.apache.river.mahalo; import org.apache.river.logging.Levels; import org.apache.river.mahalo.log.ClientLog; import org.apache.river.thread.TaskManager; -import org.apache.river.thread.WakeupManager; +import org.apache.river.thread.wakeup.WakeupManager; import java.rmi.RemoteException; import java.util.concurrent.ExecutorService; import java.util.logging.Level; Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareJob.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareJob.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareJob.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/PrepareJob.java Sun Jul 5 11:41:39 2020 @@ -19,7 +19,7 @@ package org.apache.river.mahalo; import org.apache.river.mahalo.log.ClientLog; -import org.apache.river.thread.WakeupManager; +import org.apache.river.thread.wakeup.WakeupManager; import java.rmi.RemoteException; import java.util.Iterator; import java.util.concurrent.ExecutorService; Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/SettlerTask.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/SettlerTask.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/SettlerTask.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/SettlerTask.java Sun Jul 5 11:41:39 2020 @@ -18,8 +18,8 @@ package org.apache.river.mahalo; import org.apache.river.logging.Levels; -import org.apache.river.thread.RetryTask; -import org.apache.river.thread.WakeupManager; +import org.apache.river.thread.wakeup.RetryTask; +import org.apache.river.thread.wakeup.WakeupManager; import java.rmi.NoSuchObjectException; import java.rmi.RemoteException; import java.util.concurrent.ExecutorService; Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TransientMahaloImpl.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TransientMahaloImpl.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TransientMahaloImpl.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TransientMahaloImpl.java Sun Jul 5 11:41:39 2020 @@ -1,56 +1,56 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ -package org.apache.river.mahalo; - -import org.apache.river.start.LifeCycle; - -/** - * Convenience class intended for use with the - * {@link org.apache.river.start.ServiceStarter} framework to start - * a <i>transient</i> (non-activatable, non-persistent) implementation - * of Mahalo. - * - * @author Sun Microsystems, Inc. - * @since 2.0 - */ -class TransientMahaloImpl extends TxnManagerImpl { - - /** - * Constructs a new instance of <code>TxnManagerImpl</code> that is not - * activatable, and which will not persist its state. - * - * @param configArgs <code>String</code> array whose elements are - * the arguments to use when creating the server. - * @param lifeCycle instance of <code>LifeCycle</code> that, if - * non-<code>null</code>, will cause this object's - * <code>unregister</code> method to be invoked during - * shutdown to notify the service starter framework that - * the reference to this service's implementation can be - * 'released' for garbage collection. A value of - * <code>null</code> for this argument is allowed. - * - * @throws Exception If there was a problem initializing the service. - */ - TransientMahaloImpl(String[] configArgs, LifeCycle lifeCycle) - throws Exception - { - super(configArgs, lifeCycle, false);//false ==> not persistent - }//end constructor - -}//end class TransientMahaloImpl - +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +package org.apache.river.mahalo; + +import org.apache.river.start.lifecycle.LifeCycle; + +/** + * Convenience class intended for use with the + * {@link org.apache.river.start.ServiceStarter} framework to start + * a <i>transient</i> (non-activatable, non-persistent) implementation + * of Mahalo. + * + * @author Sun Microsystems, Inc. + * @since 2.0 + */ +class TransientMahaloImpl extends TxnManagerImpl { + + /** + * Constructs a new instance of <code>TxnManagerImpl</code> that is not + * activatable, and which will not persist its state. + * + * @param configArgs <code>String</code> array whose elements are + * the arguments to use when creating the server. + * @param lifeCycle instance of <code>LifeCycle</code> that, if + * non-<code>null</code>, will cause this object's + * <code>unregister</code> method to be invoked during + * shutdown to notify the service starter framework that + * the reference to this service's implementation can be + * 'released' for garbage collection. A value of + * <code>null</code> for this argument is allowed. + * + * @throws Exception If there was a problem initializing the service. + */ + TransientMahaloImpl(String[] configArgs, LifeCycle lifeCycle) + throws Exception + { + super(configArgs, lifeCycle, false);//false ==> not persistent + }//end constructor + +}//end class TransientMahaloImpl + Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImpl.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImpl.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImpl.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImpl.java Sun Jul 5 11:41:39 2020 @@ -31,11 +31,11 @@ import org.apache.river.mahalo.log.LogRe import org.apache.river.mahalo.log.LogRecovery; import org.apache.river.mahalo.log.MultiLogManager; import org.apache.river.mahalo.log.MultiLogManagerAdmin; -import org.apache.river.start.LifeCycle; +import org.apache.river.start.lifecycle.LifeCycle; import org.apache.river.api.util.Startable; import org.apache.river.thread.InterruptedStatusThread; import org.apache.river.thread.ReadyState; -import org.apache.river.thread.WakeupManager; +import org.apache.river.thread.wakeup.WakeupManager; import java.io.File; import java.io.IOException; @@ -100,6 +100,11 @@ import net.jini.security.TrustVerifier; import org.apache.river.thread.ExtensibleExecutorService; import org.apache.river.thread.ExtensibleExecutorService.RunnableFutureFactory; +import org.apache.river.mahalo.proxy.TxnManager; +import org.apache.river.mahalo.proxy.TxnMgrProxy; +import org.apache.river.mahalo.proxy.TxnMgrAdminProxy; +import org.apache.river.mahalo.proxy.ProxyVerifier; + /** * An implementation of the Jini Transaction Specification. * Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImplInitializer.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImplInitializer.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImplInitializer.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerImplInitializer.java Sun Jul 5 11:41:39 2020 @@ -22,7 +22,7 @@ import org.apache.river.constants.TimeCo import org.apache.river.landlord.FixedLeasePeriodPolicy; import org.apache.river.landlord.LeasePeriodPolicy; import org.apache.river.thread.InterruptedStatusThread; -import org.apache.river.thread.WakeupManager; +import org.apache.river.thread.wakeup.WakeupManager; import java.io.IOException; import java.rmi.RemoteException; import java.rmi.activation.ActivationException; @@ -52,6 +52,8 @@ import net.jini.jeri.tcp.TcpServerEndpoi import net.jini.security.BasicProxyPreparer; import net.jini.security.ProxyPreparer; import org.apache.river.thread.NamedThreadFactory; +import org.apache.river.mahalo.proxy.TxnManager; + /** * Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerTransaction.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerTransaction.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerTransaction.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/TxnManagerTransaction.java Sun Jul 5 11:41:39 2020 @@ -25,7 +25,7 @@ import org.apache.river.logging.Levels; import org.apache.river.mahalo.log.ClientLog; import org.apache.river.mahalo.log.LogException; import org.apache.river.mahalo.log.LogManager; -import org.apache.river.thread.WakeupManager; +import org.apache.river.thread.wakeup.WakeupManager; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.Collections; @@ -50,6 +50,7 @@ import net.jini.core.transaction.server. import net.jini.core.transaction.server.TransactionParticipant; import net.jini.id.Uuid; import net.jini.security.ProxyPreparer; +import org.apache.river.mahalo.proxy.InternalManagerException; /** * TxnManagerTransaction is a class which Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/MultiLogManager.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/MultiLogManager.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/MultiLogManager.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/MultiLogManager.java Sun Jul 5 11:41:39 2020 @@ -1,386 +1,386 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -package org.apache.river.mahalo.log; - -import org.apache.river.logging.Levels; -import org.apache.river.mahalo.TxnManager; -import org.apache.river.system.FileSystem; -import java.io.File; -import java.io.FilenameFilter; - -import net.jini.admin.Administrable; - -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * - * @author Sun Microsystems, Inc. - * - */ -public class MultiLogManager - implements LogManager, FileModes, Administrable, MultiLogManagerAdmin { - private static final String LOG_FILE = "Log."; - - /** Logger for persistence related messages */ - private static final Logger persistenceLogger = - Logger.getLogger(TxnManager.MAHALO + ".persistence"); - - /** Logger for operations related messages */ - private static final Logger operationsLogger = - Logger.getLogger(TxnManager.MAHALO + ".operations"); - - /** Logger for initialization related messages */ - private static final Logger initLogger = - Logger.getLogger(TxnManager.MAHALO + ".init"); - - /** Client called during log recovery to process log objects */ - private final LogRecovery client; - - /** Map of log files keyed by their associated cookie */ - private final Map logByID = new HashMap(); - - /** Lock object used for coordinating access to logByID */ - private final Object logByIDLock = new Object(); - - /** Flag that is set to true upon destruction */ - private boolean destroyed = false; - - /** Persistence directory */ - private String directory = null; - - private final static FilenameFilter filter = - new FilenameFilter() { - public boolean accept(File dir, String name) { - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.entering(FilenameFilter.class.getName(), - "accept", new Object[] {dir, name}); - } - final boolean isLog = name.startsWith(LOG_FILE); - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.exiting(FilenameFilter.class.getName(), - "accept", Boolean.valueOf(isLog)); - } - return isLog; - }; - }; - - /** - * Callback interface for log files to remove themselves from - * this manager - */ - public static interface LogRemovalManager { - public void release(long cookie); - } - - /** - * Capability object passed to log files, which is called back upon - * log removal. - */ - final LogRemovalManager logMgrRef = new LogRemovalManager() { - public void release(long cookie) { - MultiLogManager.this.release(cookie); - } - }; - - /** - * Create a non-persistent <code>MultiLogManager</code>. - */ - public MultiLogManager() { - directory = null; // just for insurance - client = null; - } - - /** - * Create a <code>MultiLogManager</code>. - * - * @param client who to inform during recovery. - * - * @param path where to store logging information. - */ - public MultiLogManager(LogRecovery client, String path) { - if (path == null) - throw new IllegalArgumentException("MultiLogManager: must use " + - "non-null path"); - if (client == null) - throw new IllegalArgumentException("MultiLogManager: must use " + - "non-null recovery client"); - this.client = client; - directory = path; - - if (!directory.endsWith(File.separator)) - directory = directory.concat(File.separator); - - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "directory = {0}", directory); - } - - File tmpfile = new File(directory); - - //If you attempt to access the Version file and - //it does not exist, start with zero. - try { - if (!tmpfile.exists()) - if (!tmpfile.mkdirs()) - if (persistenceLogger.isLoggable(Level.SEVERE)) { - persistenceLogger.log(Level.SEVERE, - "Could not create {0}", tmpfile); - } -//TODO - ignore??? - } catch (SecurityException se) { - if (persistenceLogger.isLoggable(Level.SEVERE)) { - persistenceLogger.log(Level.SEVERE, - "Error accessing Version File", se); - } -//TODO ignore? throw (SecurityException)se.fillInStackTrace(); - } - } - - // javadoc inherited from supertype - public ClientLog logFor(long cookie) throws LogException { - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.entering(MultiLogManager.class.getName(), - "logFor", Long.valueOf(cookie)); - } - ClientLog cl = null; - Long key = Long.valueOf(cookie); - Object prev = null; - - synchronized(logByIDLock) { - if (destroyed) - throw new LogException("Manger has been destroyed"); - - cl = (ClientLog)logByID.get(key); - if (cl == null) { - cl = (directory==null)? - (ClientLog)new TransientLogFile(cookie, logMgrRef): - (ClientLog)new SimpleLogFile( - directory + LOG_FILE + cookie, - cookie, logMgrRef); - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "Created ClientLog: {0}", - directory + LOG_FILE + cookie); - } - prev = logByID.put(key, cl); - } - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "Currently managing {0} logs.", - Integer.valueOf(logByID.size())); - } - - } - if (prev != null) - throw new LogException("Previous mapping for cookie(" - + cookie + ") -- internal table corrupt?"); - - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "Using ClientLog {0} for cookie {1}", - new Object[] {cl, Long.valueOf(cookie)}); - } - - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.exiting(MultiLogManager.class.getName(), - "logFor", cl); - } - return cl; - } - - // javadoc inherited from supertype - private void release(long cookie) { - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.entering(MultiLogManager.class.getName(), - "release", Long.valueOf(cookie)); - } - Object prev = null; - synchronized(logByIDLock) { - if (destroyed) - return; - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "Releasing ClientLog for cookie {0}", - Long.valueOf(cookie)); - } - prev = logByID.remove(Long.valueOf(cookie)); - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "Currently managing {0} logs.", - Integer.valueOf(logByID.size())); - } - } - - if (persistenceLogger.isLoggable(Level.FINEST)) { - if (prev == null) { - persistenceLogger.log(Level.FINEST, - "Note: ClientLog already removed"); - } - } - - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.exiting(MultiLogManager.class.getName(), - "release"); - } - } - - /** - * Consumes the log file and re-constructs a system's - * state. - */ - public void recover() throws LogException { - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.entering(MultiLogManager.class.getName(), - "recover"); - } - // Short-circuit for non-persistent mode - if (directory == null) return; - - Log log = null; - File tmpfile = null; - String [] filenames = null; - - /* Called by initialization thread only, - * so don't need to check for destroyed. - */ - - try { - tmpfile = new File(directory); - filenames = tmpfile.list(filter); - - if (filenames == null || filenames.length == 0) - return; - - String logName; - for (int i = 0; i < filenames.length; i++ ) { - logName = directory + filenames[i]; - log = new SimpleLogFile(logName, logMgrRef); - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "Recovering log: {0}", logName); - } - try { - log.recover(client); - - /* Called by initialization thread only, - * so doesn't need to be synchronized here. - */ - logByID.put(Long.valueOf(log.cookie()),log); - } catch (LogException le) { - if(persistenceLogger.isLoggable(Level.WARNING)) { - persistenceLogger.log(Level.WARNING, - "Unable to recover log state", le); - } - } - } - } catch (SecurityException se) { // TODO - shouldn't this percolate back up? - if(persistenceLogger.isLoggable(Level.WARNING)) { - persistenceLogger.log(Level.WARNING, - "Unable to recover log state", se); - } - } - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.exiting(MultiLogManager.class.getName(), - "recover"); - } - } - - - /** - * Retrieves the administration interface for the - * <code>MultiLogManager</code> - * - */ - public Object getAdmin() { - // TBD - pass capability object instead? - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.entering(MultiLogManager.class.getName(), - "getAdmin"); - } - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.exiting(MultiLogManager.class.getName(), - "getAdmin", this); - } - return (MultiLogManagerAdmin)this; - } - - - /** - * Clean up all <code>LogFile</code> objects on behalf of caller. - * - * @see org.apache.river.admin.DestroyAdmin - * @see org.apache.river.system.FileSystem - */ - public void destroy() { - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.entering(MultiLogManager.class.getName(), - "destroy"); - } - - // TBD - Set destroy flag? used by logFor()/release() - // TBD - Loop over values enum? - /** - * Loop over know logs and invalidate them. - */ - synchronized(logByIDLock) { - if (destroyed) // return silently to avoids retries - return; - if (logByID.size() > 0) { - /* Can't use iterator because slf.invalidate() calls back into - * this.release() in order to remove itself from logByID, - * which would cause a concurrent modification exception. - */ - Object [] vals = logByID.values().toArray(); - Log slf = null; - for (int i=0; i<vals.length; i++) { - try { - slf = (Log)vals[i]; - if (slf != null) - slf.invalidate(); - else { - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "Observed a null log file entry at: {0}", i); - } - } - } catch (LogException le) { - if(persistenceLogger.isLoggable(Levels.HANDLED)) { - persistenceLogger.log(Levels.HANDLED, - "Unable to recover log state", le); - } - } catch (java.util.NoSuchElementException nsee) { - if(persistenceLogger.isLoggable(Levels.HANDLED)) { - persistenceLogger.log(Levels.HANDLED, - "Problem enumerating internal log state", nsee); - } - } - } - logByID.clear(); - destroyed = true; - } - } - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.exiting(MultiLogManager.class.getName(), - "destroy"); - } - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.river.mahalo.log; + +import org.apache.river.logging.Levels; +import org.apache.river.mahalo.proxy.TxnManager; +import org.apache.river.system.FileSystem; +import java.io.File; +import java.io.FilenameFilter; + +import net.jini.admin.Administrable; + +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author Sun Microsystems, Inc. + * + */ +public class MultiLogManager + implements LogManager, FileModes, Administrable, MultiLogManagerAdmin { + private static final String LOG_FILE = "Log."; + + /** Logger for persistence related messages */ + private static final Logger persistenceLogger = + Logger.getLogger(TxnManager.MAHALO + ".persistence"); + + /** Logger for operations related messages */ + private static final Logger operationsLogger = + Logger.getLogger(TxnManager.MAHALO + ".operations"); + + /** Logger for initialization related messages */ + private static final Logger initLogger = + Logger.getLogger(TxnManager.MAHALO + ".init"); + + /** Client called during log recovery to process log objects */ + private final LogRecovery client; + + /** Map of log files keyed by their associated cookie */ + private final Map logByID = new HashMap(); + + /** Lock object used for coordinating access to logByID */ + private final Object logByIDLock = new Object(); + + /** Flag that is set to true upon destruction */ + private boolean destroyed = false; + + /** Persistence directory */ + private String directory = null; + + private final static FilenameFilter filter = + new FilenameFilter() { + public boolean accept(File dir, String name) { + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.entering(FilenameFilter.class.getName(), + "accept", new Object[] {dir, name}); + } + final boolean isLog = name.startsWith(LOG_FILE); + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.exiting(FilenameFilter.class.getName(), + "accept", Boolean.valueOf(isLog)); + } + return isLog; + }; + }; + + /** + * Callback interface for log files to remove themselves from + * this manager + */ + public static interface LogRemovalManager { + public void release(long cookie); + } + + /** + * Capability object passed to log files, which is called back upon + * log removal. + */ + final LogRemovalManager logMgrRef = new LogRemovalManager() { + public void release(long cookie) { + MultiLogManager.this.release(cookie); + } + }; + + /** + * Create a non-persistent <code>MultiLogManager</code>. + */ + public MultiLogManager() { + directory = null; // just for insurance + client = null; + } + + /** + * Create a <code>MultiLogManager</code>. + * + * @param client who to inform during recovery. + * + * @param path where to store logging information. + */ + public MultiLogManager(LogRecovery client, String path) { + if (path == null) + throw new IllegalArgumentException("MultiLogManager: must use " + + "non-null path"); + if (client == null) + throw new IllegalArgumentException("MultiLogManager: must use " + + "non-null recovery client"); + this.client = client; + directory = path; + + if (!directory.endsWith(File.separator)) + directory = directory.concat(File.separator); + + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "directory = {0}", directory); + } + + File tmpfile = new File(directory); + + //If you attempt to access the Version file and + //it does not exist, start with zero. + try { + if (!tmpfile.exists()) + if (!tmpfile.mkdirs()) + if (persistenceLogger.isLoggable(Level.SEVERE)) { + persistenceLogger.log(Level.SEVERE, + "Could not create {0}", tmpfile); + } +//TODO - ignore??? + } catch (SecurityException se) { + if (persistenceLogger.isLoggable(Level.SEVERE)) { + persistenceLogger.log(Level.SEVERE, + "Error accessing Version File", se); + } +//TODO ignore? throw (SecurityException)se.fillInStackTrace(); + } + } + + // javadoc inherited from supertype + public ClientLog logFor(long cookie) throws LogException { + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.entering(MultiLogManager.class.getName(), + "logFor", Long.valueOf(cookie)); + } + ClientLog cl = null; + Long key = Long.valueOf(cookie); + Object prev = null; + + synchronized(logByIDLock) { + if (destroyed) + throw new LogException("Manger has been destroyed"); + + cl = (ClientLog)logByID.get(key); + if (cl == null) { + cl = (directory==null)? + (ClientLog)new TransientLogFile(cookie, logMgrRef): + (ClientLog)new SimpleLogFile( + directory + LOG_FILE + cookie, + cookie, logMgrRef); + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "Created ClientLog: {0}", + directory + LOG_FILE + cookie); + } + prev = logByID.put(key, cl); + } + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "Currently managing {0} logs.", + Integer.valueOf(logByID.size())); + } + + } + if (prev != null) + throw new LogException("Previous mapping for cookie(" + + cookie + ") -- internal table corrupt?"); + + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "Using ClientLog {0} for cookie {1}", + new Object[] {cl, Long.valueOf(cookie)}); + } + + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.exiting(MultiLogManager.class.getName(), + "logFor", cl); + } + return cl; + } + + // javadoc inherited from supertype + private void release(long cookie) { + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.entering(MultiLogManager.class.getName(), + "release", Long.valueOf(cookie)); + } + Object prev = null; + synchronized(logByIDLock) { + if (destroyed) + return; + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "Releasing ClientLog for cookie {0}", + Long.valueOf(cookie)); + } + prev = logByID.remove(Long.valueOf(cookie)); + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "Currently managing {0} logs.", + Integer.valueOf(logByID.size())); + } + } + + if (persistenceLogger.isLoggable(Level.FINEST)) { + if (prev == null) { + persistenceLogger.log(Level.FINEST, + "Note: ClientLog already removed"); + } + } + + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.exiting(MultiLogManager.class.getName(), + "release"); + } + } + + /** + * Consumes the log file and re-constructs a system's + * state. + */ + public void recover() throws LogException { + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.entering(MultiLogManager.class.getName(), + "recover"); + } + // Short-circuit for non-persistent mode + if (directory == null) return; + + Log log = null; + File tmpfile = null; + String [] filenames = null; + + /* Called by initialization thread only, + * so don't need to check for destroyed. + */ + + try { + tmpfile = new File(directory); + filenames = tmpfile.list(filter); + + if (filenames == null || filenames.length == 0) + return; + + String logName; + for (int i = 0; i < filenames.length; i++ ) { + logName = directory + filenames[i]; + log = new SimpleLogFile(logName, logMgrRef); + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "Recovering log: {0}", logName); + } + try { + log.recover(client); + + /* Called by initialization thread only, + * so doesn't need to be synchronized here. + */ + logByID.put(Long.valueOf(log.cookie()),log); + } catch (LogException le) { + if(persistenceLogger.isLoggable(Level.WARNING)) { + persistenceLogger.log(Level.WARNING, + "Unable to recover log state", le); + } + } + } + } catch (SecurityException se) { // TODO - shouldn't this percolate back up? + if(persistenceLogger.isLoggable(Level.WARNING)) { + persistenceLogger.log(Level.WARNING, + "Unable to recover log state", se); + } + } + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.exiting(MultiLogManager.class.getName(), + "recover"); + } + } + + + /** + * Retrieves the administration interface for the + * <code>MultiLogManager</code> + * + */ + public Object getAdmin() { + // TBD - pass capability object instead? + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.entering(MultiLogManager.class.getName(), + "getAdmin"); + } + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.exiting(MultiLogManager.class.getName(), + "getAdmin", this); + } + return (MultiLogManagerAdmin)this; + } + + + /** + * Clean up all <code>LogFile</code> objects on behalf of caller. + * + * @see org.apache.river.admin.DestroyAdmin + * @see org.apache.river.system.FileSystem + */ + public void destroy() { + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.entering(MultiLogManager.class.getName(), + "destroy"); + } + + // TBD - Set destroy flag? used by logFor()/release() + // TBD - Loop over values enum? + /** + * Loop over know logs and invalidate them. + */ + synchronized(logByIDLock) { + if (destroyed) // return silently to avoids retries + return; + if (logByID.size() > 0) { + /* Can't use iterator because slf.invalidate() calls back into + * this.release() in order to remove itself from logByID, + * which would cause a concurrent modification exception. + */ + Object [] vals = logByID.values().toArray(); + Log slf = null; + for (int i=0; i<vals.length; i++) { + try { + slf = (Log)vals[i]; + if (slf != null) + slf.invalidate(); + else { + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "Observed a null log file entry at: {0}", i); + } + } + } catch (LogException le) { + if(persistenceLogger.isLoggable(Levels.HANDLED)) { + persistenceLogger.log(Levels.HANDLED, + "Unable to recover log state", le); + } + } catch (java.util.NoSuchElementException nsee) { + if(persistenceLogger.isLoggable(Levels.HANDLED)) { + persistenceLogger.log(Levels.HANDLED, + "Problem enumerating internal log state", nsee); + } + } + } + logByID.clear(); + destroyed = true; + } + } + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.exiting(MultiLogManager.class.getName(), + "destroy"); + } + } +} Modified: river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/SimpleLogFile.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/SimpleLogFile.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/SimpleLogFile.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/mahalo/mahalo-service/src/main/java/org/apache/river/mahalo/log/SimpleLogFile.java Sun Jul 5 11:41:39 2020 @@ -1,464 +1,464 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -package org.apache.river.mahalo.log; - -import org.apache.river.logging.Levels; -import org.apache.river.mahalo.log.MultiLogManager.LogRemovalManager; -import org.apache.river.mahalo.TxnManager; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.EOFException; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InvalidClassException; -import java.io.NotSerializableException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; - -import java.util.ArrayList; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * An implementation of a re-usable <code>Log</code>. - * - * @author Sun Microsystems, Inc. - * - * @see org.apache.river.mahalo.log.Log - */ -public class SimpleLogFile implements Log { - /** Unique ID associated with this log */ - private /*final*/ long cookie; - /** Output stream for writing log objects */ - private /*final*/ ObjectOutputStream out; - /** - * File output stream associated with <code>out</code>. - * Used to get a handle to underlying file descriptor object. - */ - private /*final*/ FileOutputStream outfile; - /** (Relative) File name of the log file */ - private final String name; - /** - * Reference to <code>LogRemovalManager</code>, which is called - * to remove this log from the managed set of logs. - */ - private final LogRemovalManager logMgr; - /** - * Flag that indicates validity of this log. Set to false - * by call to <code>invalidate()</code>. - */ - private boolean valid = true; - /** - * Flag to indicate that the log file has been created via - * the read-only constructor. This flag is set to false via - * the non-read-only constructor or a call to <code>recover()</code> - */ - private boolean readonly = false; - - /** Logger for persistence related messages */ - private static final Logger persistenceLogger = - Logger.getLogger(TxnManager.MAHALO + ".persistence"); - - /** Logger for operations related messages */ - private static final Logger operationsLogger = - Logger.getLogger(TxnManager.MAHALO + ".operations"); - - /** Logger for initialization related messages */ - private static final Logger initLogger = - Logger.getLogger(TxnManager.MAHALO + ".init"); - - /** - * This class extends <tt>ObjectInputStream</tt> and overrides the - * <code>readStreamHeader</code> method to a no-op operation. This class - * is intended to work in conjunction with - * <code>HeaderlessObjectOutputStream</code>. - */ - private static class HeaderlessObjectInputStream extends ObjectInputStream { - - /** - * Simple constructor that passes its argument to the superclass - * - * @exception IOException if an I/O error occurs - */ - public HeaderlessObjectInputStream(InputStream in) throws IOException { - super(in); - } - - /** - * Overrides <tt>ObjectInputStream</tt>'s method with no-op - * functionality. - * @see HeaderlessObjectOutputStream#writeStreamHeader - * @exception IOException if an I/O error occurs - */ - protected void readStreamHeader() throws IOException { - // Do nothing - } - } - - /** - * This class extends <tt>ObjectOutputStream</tt> and overrides the - * <code>writeStreamHeader</code> method to a no-op operation. This - * class is intended to be used in conjunction with - * <code>HeaderlessObjectInputStream</code>. - */ - private static class HeaderlessObjectOutputStream extends ObjectOutputStream { - - /** - * Simple constructor that passes its argument to the superclass - * - * @exception IOException if an I/O error occurs - */ - public HeaderlessObjectOutputStream(OutputStream out) throws IOException { - super(out); - } - - /** - * Overrides <tt>ObjectOutputStream</tt>'s method with no-op - * functionality. This prevents header information from being - * sent to the stream, which makes appending to existing log files - * easier. Otherwise, appending header info to an existing log file - * would cause a corresponding <code>ObjectInputStream</code> to - * throw a <code>StreamCorruptedException</code> when it encountered - * the header information instead of the class/object type code - * information it was expecting. - * - * @exception IOException if an I/O error occurs - */ - protected void writeStreamHeader() throws IOException { - // Do nothing - } - } - - /** - * Creates a read-only <code>SimpleLogFile</code> - * - * To be used for read-only access to a named <code>Log</code>. This is - * desired when recovering information from a <code>Log</code>. - * - * @param name names the file in which information is stored. - * - * @param logMgr <code>LogRemovalManager</code> managing this log. - * This object is called back to remove this log - * from the manager's managed set of log files. - * - * @see org.apache.river.mahalo.log.Log - * @see org.apache.river.mahalo.log.LogManager - * @see org.apache.river.mahalo.log.MultiLogManager - * @see org.apache.river.mahalo.log.MultiLogManager.LogRemovalManager - */ - public SimpleLogFile(String name, LogRemovalManager logMgr) { - this(name, 0, logMgr); - readonly = true; - } - - /** - * Creates a <code>SimpleLogFile</code>. - * - * @param name names the file in which information is stored. - * - * @param cookie identifier representing information being stored. - * - * @param logMgr <code>LogRemovalManager</code> managing this log. - * This object is called back to remove this log - * from the manager's responsibility. - * - * @see org.apache.river.mahalo.log.Log - * @see org.apache.river.mahalo.log.LogManager - * @see org.apache.river.mahalo.log.MultiLogManager - * @see org.apache.river.mahalo.log.MultiLogManager.LogRemovalManager - */ - public SimpleLogFile(String name, long cookie, LogRemovalManager logMgr) { - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.entering(SimpleLogFile.class.getName(), - "init", new Object[] {name, Long.valueOf(cookie), logMgr}); - } - if (name == null) - throw new IllegalArgumentException("SimpleLogFile: null name"); - - if (logMgr == null) - throw new IllegalArgumentException( - "SimpleLogFile: null log manager"); - - this.name = name; - this.cookie = cookie; - this.logMgr = logMgr; - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.exiting(SimpleLogFile.class.getName(), - "init"); - } - } - - - /** - * Returns the identifier associated with information in - * this <code>Log</code>. - * - * @see org.apache.river.mahalo.log.Log - */ - public synchronized long cookie() { - return cookie; - } - - /** - * Add a <code>LogRecord</code> to the <code>Log</code>. - * - * @param rec the record to be logged. - * - * @see org.apache.river.mahalo.log.LogRecord - */ - public synchronized void write(LogRecord rec) throws LogException { - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.entering(SimpleLogFile.class.getName(), - "write", rec); - } - try { - if (!valid) - throw new InvalidatedLogException("Cannot write to to " + - "invalidated log"); - if (readonly) - throw new LogException("Unable to write to read only log"); - - if (out == null) { - boolean append = true; - File log = new File(name); - outfile = new FileOutputStream(name, append); - out = - new HeaderlessObjectOutputStream( - new BufferedOutputStream(outfile)); - if (log.length() == 0) { - out.writeLong(cookie); - } - out.reset(); - } - - out.writeObject(rec); - out.flush(); - outfile.getFD().sync(); - - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "Wrote: {0}", rec); - } - } catch (InvalidClassException ice) { - if (persistenceLogger.isLoggable(Level.WARNING)) { - persistenceLogger.log(Level.WARNING, - "Problem persisting LogRecord", ice); - } -// TODO - assertion error? ... should not happen - } catch (NotSerializableException nse) { - if (persistenceLogger.isLoggable(Level.WARNING)) { - persistenceLogger.log(Level.WARNING, - "Problem persisting LogRecord", nse); - } -// TODO - assertion error? ... should not happen - } catch (IOException ioe) { - if (persistenceLogger.isLoggable(Level.WARNING)) { - persistenceLogger.log(Level.WARNING, - "Problem persisting LogRecord", ioe); - } -// TODO - throw LogException? - } catch (SecurityException se) { - if (persistenceLogger.isLoggable(Level.WARNING)) { - persistenceLogger.log(Level.WARNING, - "Problem persisting LogRecord", se); - } -// TODO - assertion error? ... should not happen - } - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.exiting(SimpleLogFile.class.getName(), - "write", rec); - } - } - - /** - * Invalidate the log. - */ - public synchronized void invalidate() throws LogException { - // No short circuit check because we allow repeat calls - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.entering(MultiLogManager.class.getName(), - "invalidate"); - } - - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "Invalidating log for cookie: {0}", Long.valueOf(cookie)); - } - - if (valid) { - // Set validity flag to false - valid = false; - - // Ask log manager to remove us from its managed set - logMgr.release(cookie); - } - - try { - if (out != null) { - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "Closing log file for: {0}", Long.valueOf(cookie)); - } - out.close(); // calls outfile.close() - } - } catch (IOException ioe) { // just log it - if (persistenceLogger.isLoggable(Levels.HANDLED)) { - persistenceLogger.log(Levels.HANDLED, - "Problem closing log file", ioe); - } - } - - try { - File fl = new File(name); - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "Deleting log file for: {0}", Long.valueOf(cookie)); - } - if(!fl.delete()) { - if (persistenceLogger.isLoggable(Levels.HANDLED)) { - persistenceLogger.log(Levels.HANDLED, - "Could not delete log file"); - } - } - } catch (SecurityException se) { // notify caller - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "SecurityException on log deletion", se); - } - throw new LogException("SimpleLogFile: invalidate: " - + "cannot delete log file."); - } - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.exiting(MultiLogManager.class.getName(), - "invalidate"); - } - } - - /** - * Recover information from the log. - * - * @param client who to inform with information from the log. - * - * @see org.apache.river.mahalo.log.LogRecovery - */ - public synchronized void recover(LogRecovery client) throws LogException { - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.entering(MultiLogManager.class.getName(), - "recover", client); - } - if (!valid) - throw new InvalidatedLogException("Cannot recover from " + - "invalidated log"); - if (client == null) - throw new IllegalArgumentException("Cannot have a <null> " - + "client argument."); - - ObjectInputStream in = null; - ArrayList recList = new ArrayList(); - try { - if (persistenceLogger.isLoggable(Level.FINEST)) { - persistenceLogger.log(Level.FINEST, - "Recovering from: {0}", name); - } - in = new HeaderlessObjectInputStream( - new BufferedInputStream( - new FileInputStream(name))); - - this.cookie = in.readLong(); - LogRecord rec = null; - boolean done = false; - boolean update = true; - try { - while (!done) { - // try to catch cast exceptions here - rec = (LogRecord)in.readObject(); - if (rec != null) { - recList.add(rec); - } else { //TBD - ignore? - update = false; - done = true; // bad log ... skip it - if (persistenceLogger.isLoggable(Levels.HANDLED)) { - persistenceLogger.log(Levels.HANDLED, - "Log for cookie {0} contained a null " - + "record object", Long.valueOf(cookie)); - } - } - } - } catch (ClassNotFoundException cnfe) { - update = false; - if (persistenceLogger.isLoggable(Level.WARNING)) { - persistenceLogger.log(Level.WARNING, - "Problem recovering log file", cnfe); - } -// TODO - assertion error? ... should not happen - } catch (ClassCastException cce) { - update = false; - if (persistenceLogger.isLoggable(Level.WARNING)) { - persistenceLogger.log(Level.WARNING, - "Problem recovering log file", cce); - } -// TODO - assertion error? ... should not happen - } catch (EOFException eofe) { - // OK. Assume we've hit the end of the log file - } catch (IOException ioe) { - update = false; - if (persistenceLogger.isLoggable(Level.WARNING)) { - persistenceLogger.log(Level.WARNING, - "Problem recovering log file", ioe); - } - } - - if (update) { - for (int i=0; i<recList.size(); i++) { - client.recover(cookie, (LogRecord)recList.get(i)); - } - } else { - if (persistenceLogger.isLoggable(Level.WARNING)) { - persistenceLogger.log(Level.WARNING, - "Skipping log recovery for", name); - } - } - } catch (IOException ioe) { - // bogus log file -- skip it - if (persistenceLogger.isLoggable(Level.WARNING)) { - persistenceLogger.log(Level.WARNING, - "Problem recovering log file", ioe); - } - } finally { - try { - if (in != null) in.close(); // calls fin.close() - } catch (IOException ioe) { - if (persistenceLogger.isLoggable(Levels.HANDLED)) { - persistenceLogger.log(Levels.HANDLED, - "Problem closing recovered log file", ioe); - } - } - readonly = false; - } - if (operationsLogger.isLoggable(Level.FINER)) { - operationsLogger.exiting(MultiLogManager.class.getName(), - "recover"); - } - } - // TBD - add a toString() method for debugging purposes -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.river.mahalo.log; + +import org.apache.river.logging.Levels; +import org.apache.river.mahalo.log.MultiLogManager.LogRemovalManager; +import org.apache.river.mahalo.proxy.TxnManager; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.NotSerializableException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * An implementation of a re-usable <code>Log</code>. + * + * @author Sun Microsystems, Inc. + * + * @see org.apache.river.mahalo.log.Log + */ +public class SimpleLogFile implements Log { + /** Unique ID associated with this log */ + private /*final*/ long cookie; + /** Output stream for writing log objects */ + private /*final*/ ObjectOutputStream out; + /** + * File output stream associated with <code>out</code>. + * Used to get a handle to underlying file descriptor object. + */ + private /*final*/ FileOutputStream outfile; + /** (Relative) File name of the log file */ + private final String name; + /** + * Reference to <code>LogRemovalManager</code>, which is called + * to remove this log from the managed set of logs. + */ + private final LogRemovalManager logMgr; + /** + * Flag that indicates validity of this log. Set to false + * by call to <code>invalidate()</code>. + */ + private boolean valid = true; + /** + * Flag to indicate that the log file has been created via + * the read-only constructor. This flag is set to false via + * the non-read-only constructor or a call to <code>recover()</code> + */ + private boolean readonly = false; + + /** Logger for persistence related messages */ + private static final Logger persistenceLogger = + Logger.getLogger(TxnManager.MAHALO + ".persistence"); + + /** Logger for operations related messages */ + private static final Logger operationsLogger = + Logger.getLogger(TxnManager.MAHALO + ".operations"); + + /** Logger for initialization related messages */ + private static final Logger initLogger = + Logger.getLogger(TxnManager.MAHALO + ".init"); + + /** + * This class extends <tt>ObjectInputStream</tt> and overrides the + * <code>readStreamHeader</code> method to a no-op operation. This class + * is intended to work in conjunction with + * <code>HeaderlessObjectOutputStream</code>. + */ + private static class HeaderlessObjectInputStream extends ObjectInputStream { + + /** + * Simple constructor that passes its argument to the superclass + * + * @exception IOException if an I/O error occurs + */ + public HeaderlessObjectInputStream(InputStream in) throws IOException { + super(in); + } + + /** + * Overrides <tt>ObjectInputStream</tt>'s method with no-op + * functionality. + * @see HeaderlessObjectOutputStream#writeStreamHeader + * @exception IOException if an I/O error occurs + */ + protected void readStreamHeader() throws IOException { + // Do nothing + } + } + + /** + * This class extends <tt>ObjectOutputStream</tt> and overrides the + * <code>writeStreamHeader</code> method to a no-op operation. This + * class is intended to be used in conjunction with + * <code>HeaderlessObjectInputStream</code>. + */ + private static class HeaderlessObjectOutputStream extends ObjectOutputStream { + + /** + * Simple constructor that passes its argument to the superclass + * + * @exception IOException if an I/O error occurs + */ + public HeaderlessObjectOutputStream(OutputStream out) throws IOException { + super(out); + } + + /** + * Overrides <tt>ObjectOutputStream</tt>'s method with no-op + * functionality. This prevents header information from being + * sent to the stream, which makes appending to existing log files + * easier. Otherwise, appending header info to an existing log file + * would cause a corresponding <code>ObjectInputStream</code> to + * throw a <code>StreamCorruptedException</code> when it encountered + * the header information instead of the class/object type code + * information it was expecting. + * + * @exception IOException if an I/O error occurs + */ + protected void writeStreamHeader() throws IOException { + // Do nothing + } + } + + /** + * Creates a read-only <code>SimpleLogFile</code> + * + * To be used for read-only access to a named <code>Log</code>. This is + * desired when recovering information from a <code>Log</code>. + * + * @param name names the file in which information is stored. + * + * @param logMgr <code>LogRemovalManager</code> managing this log. + * This object is called back to remove this log + * from the manager's managed set of log files. + * + * @see org.apache.river.mahalo.log.Log + * @see org.apache.river.mahalo.log.LogManager + * @see org.apache.river.mahalo.log.MultiLogManager + * @see org.apache.river.mahalo.log.MultiLogManager.LogRemovalManager + */ + public SimpleLogFile(String name, LogRemovalManager logMgr) { + this(name, 0, logMgr); + readonly = true; + } + + /** + * Creates a <code>SimpleLogFile</code>. + * + * @param name names the file in which information is stored. + * + * @param cookie identifier representing information being stored. + * + * @param logMgr <code>LogRemovalManager</code> managing this log. + * This object is called back to remove this log + * from the manager's responsibility. + * + * @see org.apache.river.mahalo.log.Log + * @see org.apache.river.mahalo.log.LogManager + * @see org.apache.river.mahalo.log.MultiLogManager + * @see org.apache.river.mahalo.log.MultiLogManager.LogRemovalManager + */ + public SimpleLogFile(String name, long cookie, LogRemovalManager logMgr) { + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.entering(SimpleLogFile.class.getName(), + "init", new Object[] {name, Long.valueOf(cookie), logMgr}); + } + if (name == null) + throw new IllegalArgumentException("SimpleLogFile: null name"); + + if (logMgr == null) + throw new IllegalArgumentException( + "SimpleLogFile: null log manager"); + + this.name = name; + this.cookie = cookie; + this.logMgr = logMgr; + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.exiting(SimpleLogFile.class.getName(), + "init"); + } + } + + + /** + * Returns the identifier associated with information in + * this <code>Log</code>. + * + * @see org.apache.river.mahalo.log.Log + */ + public synchronized long cookie() { + return cookie; + } + + /** + * Add a <code>LogRecord</code> to the <code>Log</code>. + * + * @param rec the record to be logged. + * + * @see org.apache.river.mahalo.log.LogRecord + */ + public synchronized void write(LogRecord rec) throws LogException { + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.entering(SimpleLogFile.class.getName(), + "write", rec); + } + try { + if (!valid) + throw new InvalidatedLogException("Cannot write to to " + + "invalidated log"); + if (readonly) + throw new LogException("Unable to write to read only log"); + + if (out == null) { + boolean append = true; + File log = new File(name); + outfile = new FileOutputStream(name, append); + out = + new HeaderlessObjectOutputStream( + new BufferedOutputStream(outfile)); + if (log.length() == 0) { + out.writeLong(cookie); + } + out.reset(); + } + + out.writeObject(rec); + out.flush(); + outfile.getFD().sync(); + + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "Wrote: {0}", rec); + } + } catch (InvalidClassException ice) { + if (persistenceLogger.isLoggable(Level.WARNING)) { + persistenceLogger.log(Level.WARNING, + "Problem persisting LogRecord", ice); + } +// TODO - assertion error? ... should not happen + } catch (NotSerializableException nse) { + if (persistenceLogger.isLoggable(Level.WARNING)) { + persistenceLogger.log(Level.WARNING, + "Problem persisting LogRecord", nse); + } +// TODO - assertion error? ... should not happen + } catch (IOException ioe) { + if (persistenceLogger.isLoggable(Level.WARNING)) { + persistenceLogger.log(Level.WARNING, + "Problem persisting LogRecord", ioe); + } +// TODO - throw LogException? + } catch (SecurityException se) { + if (persistenceLogger.isLoggable(Level.WARNING)) { + persistenceLogger.log(Level.WARNING, + "Problem persisting LogRecord", se); + } +// TODO - assertion error? ... should not happen + } + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.exiting(SimpleLogFile.class.getName(), + "write", rec); + } + } + + /** + * Invalidate the log. + */ + public synchronized void invalidate() throws LogException { + // No short circuit check because we allow repeat calls + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.entering(MultiLogManager.class.getName(), + "invalidate"); + } + + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "Invalidating log for cookie: {0}", Long.valueOf(cookie)); + } + + if (valid) { + // Set validity flag to false + valid = false; + + // Ask log manager to remove us from its managed set + logMgr.release(cookie); + } + + try { + if (out != null) { + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "Closing log file for: {0}", Long.valueOf(cookie)); + } + out.close(); // calls outfile.close() + } + } catch (IOException ioe) { // just log it + if (persistenceLogger.isLoggable(Levels.HANDLED)) { + persistenceLogger.log(Levels.HANDLED, + "Problem closing log file", ioe); + } + } + + try { + File fl = new File(name); + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "Deleting log file for: {0}", Long.valueOf(cookie)); + } + if(!fl.delete()) { + if (persistenceLogger.isLoggable(Levels.HANDLED)) { + persistenceLogger.log(Levels.HANDLED, + "Could not delete log file"); + } + } + } catch (SecurityException se) { // notify caller + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "SecurityException on log deletion", se); + } + throw new LogException("SimpleLogFile: invalidate: " + + "cannot delete log file."); + } + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.exiting(MultiLogManager.class.getName(), + "invalidate"); + } + } + + /** + * Recover information from the log. + * + * @param client who to inform with information from the log. + * + * @see org.apache.river.mahalo.log.LogRecovery + */ + public synchronized void recover(LogRecovery client) throws LogException { + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.entering(MultiLogManager.class.getName(), + "recover", client); + } + if (!valid) + throw new InvalidatedLogException("Cannot recover from " + + "invalidated log"); + if (client == null) + throw new IllegalArgumentException("Cannot have a <null> " + + "client argument."); + + ObjectInputStream in = null; + ArrayList recList = new ArrayList(); + try { + if (persistenceLogger.isLoggable(Level.FINEST)) { + persistenceLogger.log(Level.FINEST, + "Recovering from: {0}", name); + } + in = new HeaderlessObjectInputStream( + new BufferedInputStream( + new FileInputStream(name))); + + this.cookie = in.readLong(); + LogRecord rec = null; + boolean done = false; + boolean update = true; + try { + while (!done) { + // try to catch cast exceptions here + rec = (LogRecord)in.readObject(); + if (rec != null) { + recList.add(rec); + } else { //TBD - ignore? + update = false; + done = true; // bad log ... skip it + if (persistenceLogger.isLoggable(Levels.HANDLED)) { + persistenceLogger.log(Levels.HANDLED, + "Log for cookie {0} contained a null " + + "record object", Long.valueOf(cookie)); + } + } + } + } catch (ClassNotFoundException cnfe) { + update = false; + if (persistenceLogger.isLoggable(Level.WARNING)) { + persistenceLogger.log(Level.WARNING, + "Problem recovering log file", cnfe); + } +// TODO - assertion error? ... should not happen + } catch (ClassCastException cce) { + update = false; + if (persistenceLogger.isLoggable(Level.WARNING)) { + persistenceLogger.log(Level.WARNING, + "Problem recovering log file", cce); + } +// TODO - assertion error? ... should not happen + } catch (EOFException eofe) { + // OK. Assume we've hit the end of the log file + } catch (IOException ioe) { + update = false; + if (persistenceLogger.isLoggable(Level.WARNING)) { + persistenceLogger.log(Level.WARNING, + "Problem recovering log file", ioe); + } + } + + if (update) { + for (int i=0; i<recList.size(); i++) { + client.recover(cookie, (LogRecord)recList.get(i)); + } + } else { + if (persistenceLogger.isLoggable(Level.WARNING)) { + persistenceLogger.log(Level.WARNING, + "Skipping log recovery for", name); + } + } + } catch (IOException ioe) { + // bogus log file -- skip it + if (persistenceLogger.isLoggable(Level.WARNING)) { + persistenceLogger.log(Level.WARNING, + "Problem recovering log file", ioe); + } + } finally { + try { + if (in != null) in.close(); // calls fin.close() + } catch (IOException ioe) { + if (persistenceLogger.isLoggable(Levels.HANDLED)) { + persistenceLogger.log(Levels.HANDLED, + "Problem closing recovered log file", ioe); + } + } + readonly = false; + } + if (operationsLogger.isLoggable(Level.FINER)) { + operationsLogger.exiting(MultiLogManager.class.getName(), + "recover"); + } + } + // TBD - add a toString() method for debugging purposes +}
