com.sun.xml.ws.tx.at.internal.WSATGatewayRM Maven / Gradle / Ivy
/*
* Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package com.sun.xml.ws.tx.at.internal;
import com.sun.istack.logging.Logger;
import com.sun.xml.ws.tx.at.localization.LocalizationMessages;
import com.sun.xml.ws.tx.at.WSATHelper;
import com.sun.xml.ws.tx.at.WSATXAResource;
import com.sun.xml.ws.tx.at.common.TransactionImportManager;
import com.sun.xml.ws.tx.dev.WSATRuntimeConfig;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
import jakarta.transaction.*;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import jakarta.xml.ws.WebServiceException;
/**
* Gateway XAResource for managing outbound WS-AT transaction branches.
*/
public class WSATGatewayRM implements XAResource, WSATRuntimeConfig.RecoveryEventListener {
private static final Logger LOGGER = Logger.getLogger(WSATGatewayRM.class);
private static final String WSAT = "wsat";
private static final String OUTBOUND = "outbound";
private static final String INBOUND = "inbound";
private static WSATGatewayRM singleton;
static private String resourceRegistrationName; // JTA resource registration name
static private Map branches; // xid to Branch
static List pendingXids; // collection of Xids
private final Object currentXidLock = new Object();
private Xid currentXid;
static boolean isReadyForRecovery = false;
public static boolean isReadyForRuntime = false;
public static String txlogdir;
static String txlogdirInbound;
private static String txlogdirOutbound;
static boolean isStoreInit = false;
private volatile int counter = 0;
private Map activityXidToInternalXidMap = new HashMap<>();
private Map internalXidToActivityXidMap = new HashMap<>();
// package access for test instantiation only, this is a singleton
WSATGatewayRM(String serverName) {
resourceRegistrationName = "RM_NAME_PREFIX" + serverName;
branches = Collections.synchronizedMap(new HashMap<>());
pendingXids = Collections.synchronizedList(new ArrayList<>());
singleton = this;
}
/**
* called by transaction services for enlistment and used by HA delegation
*/
public static synchronized WSATGatewayRM getInstance() {
if(singleton==null) {
create("server");
}
return singleton;
}
/**
* Called during tube/web service init
*/
public static synchronized WSATGatewayRM create() {
return create("server");
}
/**
* Called as part of WSATTransactionService start
* @param serverName this server's name
* @return the WSATGatewayRM singleton that WSATTransactionService will call stop on during stop/shutdown
*/
private static synchronized WSATGatewayRM create(String serverName)
{
if (singleton == null) {
new WSATGatewayRM(serverName);
isReadyForRecovery = setupRecovery();
}
return singleton;
}
private static boolean setupRecovery() {
if (!WSATRuntimeConfig.getInstance().isWSATRecoveryEnabled()) return true;
TransactionImportManager.registerRecoveryResourceHandler(singleton);
WSATRuntimeConfig.getInstance().setWSATRecoveryEventListener(singleton);
setTxLogDirs();
try {
initStore();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* Called for create of WSATGatewayRM
*/
static void initStore() throws Exception {
if (isStoreInit) return;
if (WSATHelper.isDebugEnabled()) debug("WSATGatewayRM.initStore path:"+txlogdirInbound);
createFile(txlogdirInbound, true);
if (WSATHelper.isDebugEnabled()) debug("WSATGatewayRM.initStore path:"+txlogdirOutbound);
createFile(txlogdirOutbound, true);
isStoreInit = true;
}
static private File createFile(String logFilePath, boolean isDir) throws Exception {
File file = new File(logFilePath);
if (!file.exists()) {
if (isDir && !file.mkdirs()) {
throw new Exception("Could not create directory : " + file.getAbsolutePath());
} else if (!isDir) {
try {
file.createNewFile();
} catch (IOException ioe) {
Exception storeEx = new Exception("Could not create file : " + file.getAbsolutePath());
storeEx.initCause(ioe);
throw storeEx;
}
}
}
return file;
}
/**
* Called for XAResource.recover
*/
void recoverPendingBranches(String outboundRecoveryDir, String inboundRecoveryDir) {
if (WSATHelper.isDebugEnabled()) debug("recoverPendingBranches outbound directory:"+outboundRecoveryDir);
FileInputStream fis;
ObjectInputStream in;
File[] files = new File(outboundRecoveryDir).listFiles();
if(files!=null) for (int i=0;i