|
Glassfish example source code file (GMSCallBack.java)
The Glassfish GMSCallBack.java source code/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package com.sun.enterprise.transaction.jts.recovery; import java.io.Serializable; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.logging.Logger; import java.util.logging.Level; import com.sun.jts.jta.TransactionServiceProperties; import com.sun.jts.CosTransactions.Configuration; import com.sun.jts.CosTransactions.DefaultTransactionService; import com.sun.enterprise.config.serverbeans.TransactionService; import com.sun.enterprise.config.serverbeans.Server; import com.sun.enterprise.config.serverbeans.Servers; import com.sun.enterprise.transaction.api.ResourceRecoveryManager; import com.sun.enterprise.transaction.api.RecoveryResourceRegistry; import com.sun.enterprise.transaction.spi.RecoveryEventListener; import com.sun.enterprise.transaction.jts.api.DelegatedTransactionRecoveryFence; import org.glassfish.gms.bootstrap.GMSAdapter; import org.glassfish.gms.bootstrap.GMSAdapterService; import com.sun.enterprise.ee.cms.core.CallBack; import com.sun.enterprise.ee.cms.core.DistributedStateCache; import com.sun.enterprise.ee.cms.core.GMSConstants; import com.sun.enterprise.ee.cms.core.GroupManagementService; import com.sun.enterprise.ee.cms.core.FailureRecoverySignal; import com.sun.enterprise.ee.cms.core.Signal; import com.sun.enterprise.util.i18n.StringManager; import com.sun.logging.LogDomains; import org.jvnet.hk2.component.Habitat; public class GMSCallBack implements CallBack { private static final String component = "TRANSACTION-RECOVERY-SERVICE"; private static final String TXLOGLOCATION = "TX_LOG_DIR"; private static final String MEMBER_DETAILS = "MEMBERDETAILS"; // Use a class from com.sun.jts subpackage static Logger _logger = LogDomains.getLogger(TransactionServiceProperties.class, LogDomains.TRANSACTION_LOGGER); private Servers servers; private Habitat habitat; private int waitTime; private DelegatedTransactionRecoveryFence fence; private GroupManagementService gms; private final long startTime; private final static Object lock = new Object(); public GMSCallBack(int waitTime, Habitat habitat) { GMSAdapterService gmsAdapterService = habitat.getComponent(GMSAdapterService.class); if (gmsAdapterService != null) { GMSAdapter gmsAdapter = gmsAdapterService.getGMSAdapter(); if (gmsAdapter != null) { gmsAdapter.registerFailureRecoveryListener(component, this); this.habitat = habitat; servers = habitat.getComponent(Servers.class); this.waitTime = waitTime; Properties props = TransactionServiceProperties.getJTSProperties(habitat, false); String instanceName = props.getProperty(Configuration.INSTANCE_NAME); String logdir = props.getProperty(Configuration.LOG_DIRECTORY); if (Configuration.getORB() == null) { // IIOP listeners are not setup yet, // Create recoveryfile file so that automatic recovery will find it even // if no XA transaction is envolved. DefaultTransactionService.setServerName(props); fence = RecoveryLockFile.getDelegatedTransactionRecoveryFence(this); } gms = gmsAdapter.getModule(); // Set the member details when GMS service is ready to store it try { gms.updateMemberDetails(instanceName, TXLOGLOCATION, logdir); } catch (Exception e) { _logger.log(Level.WARNING, "jts.error_updating_gms", e); } } } startTime = System.currentTimeMillis(); } @Override public void processNotification(Signal signal) { if (signal instanceof FailureRecoverySignal) { long timestamp = System.currentTimeMillis(); if (_logger.isLoggable(Level.INFO)) { _logger.log(Level.INFO, "[GMSCallBack] failure recovery signal: " + signal); } // Waiting for 1 minute (or the user set value) to ensure that indoubt xids are updated into // the database, otherwise while doing the recovery an instance may not // get all the correct indoubt xids. try { Thread.sleep(waitTime*1000); } catch(InterruptedException e) { e.printStackTrace(); } String instance = signal.getMemberToken(); String logdir = null; Map<Serializable, Serializable> failedMemberDetails = signal.getMemberDetails(); if (failedMemberDetails != null) { logdir = (String)failedMemberDetails.get(TXLOGLOCATION); } synchronized(lock) { _logger.log(Level.INFO, "[GMSCallBack] Recovering for instance: " + instance); doRecovery(logdir, instance, timestamp); // Find records of not finished delegated recovery and do delegated recovery on those instances. while (logdir != null) { logdir = finishDelegatedRecovery(logdir, timestamp); } _logger.log(Level.INFO, "[GMSCallBack] Finished recovery for instance: " + instance); } } else { if (_logger.isLoggable(Level.FINE)) { _logger.log(Level.FINE, "[GMSCallBack] ignoring signal: " + signal); } } } /** * Find records of not finished delegated recovery in the recovery lock file on * this path, and do delegated recovery if such record exists */ String finishDelegatedRecovery(String logdir) { return finishDelegatedRecovery(logdir, startTime); } /** * Find records of not finished delegated recovery in the recovery lock file on * this path and recorded before specified timestamp, and do delegated recovery if such record exists */ String finishDelegatedRecovery(String logdir, long timestamp) { String delegatedLogDir = null; String instance = fence.getInstanceRecoveredFor(logdir, timestamp); if (_logger.isLoggable(Level.INFO)) { _logger.log(Level.INFO, "[GMSCallBack] Instance " + instance + " need to finish delegated recovering"); } if (instance != null) { DistributedStateCache dsc=gms.getGroupHandle().getDistributedStateCache(); Map<Serializable, Serializable> memberDetails = dsc.getFromCacheForPattern(MEMBER_DETAILS, instance ); delegatedLogDir = (String)memberDetails.get(TXLOGLOCATION); if (_logger.isLoggable(Level.INFO)) { _logger.log(Level.INFO, "[GMSCallBack] Tx log dir for instance " + instance + " is " + delegatedLogDir); } doRecovery(delegatedLogDir, instance, timestamp); } return delegatedLogDir; } private void doRecovery(String logdir, String instance, long timestamp) { if (isInstanceRunning(instance)) { return; } if (logdir == null) { // Could happen if instance fails BEFORE actually getting this info into distributed state cache. // Could also be a gms distributed state cache bug. _logger.log(Level.WARNING, "jts.error_getting_member_details", instance); return; } if (fence.isFenceRaised(logdir, instance, timestamp)) { if (_logger.isLoggable(Level.INFO)) { _logger.log(Level.INFO, "Instance " + instance + " is already recovering"); } return; } try { fence.raiseFence(logdir, instance); if (_logger.isLoggable(Level.FINE)) { _logger.log(Level.FINE, "Transaction log directory for " + instance + " is " + logdir); _logger.log(Level.FINE, "Starting transaction recovery of " + instance); } ResourceRecoveryManager recoveryManager = habitat.getComponent(ResourceRecoveryManager.class); recoveryManager.recoverIncompleteTx(true, logdir, instance, true); if (_logger.isLoggable(Level.FINE)) { _logger.log(Level.FINE, "Transaction recovery of " + instance + " is completed"); } } catch (Throwable e) { _logger.log(Level.WARNING, "jts.recovery_error", e); } finally { fence.lowerFence(logdir, instance); } } private boolean isInstanceRunning(String instance) { boolean rs = false; for(Server server : servers.getServer()) { if(instance.equals(server.getName())) { rs = server.isRunning(); break; } } return rs; } } Other Glassfish examples (source code examples)Here is a short list of links related to this Glassfish GMSCallBack.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.