ASM #629 - GFE: when runProcedure terminates unexpectedly locks remain in gfelocktable.
Change-Id: Ife5ecb2c5823d4d34c1b4af6dc53fa360074b7bb Former-commit-id:bae8d9ea3f
[formerlybae8d9ea3f
[formerly 38eabd6196df1576970019f2b0255d3f39a825a9]] Former-commit-id:e007fac30f
Former-commit-id:f034b8dab1
This commit is contained in:
parent
5bd95b83c7
commit
85a439fb39
5 changed files with 301 additions and 0 deletions
|
@ -231,6 +231,9 @@
|
|||
<constructor-arg value="com.raytheon.uf.common.dataplugin.gfe.request.GetTopoDataRequest"/>
|
||||
<constructor-arg ref="getTopoDataHandler"/>
|
||||
</bean>
|
||||
<bean id="ClearGfeOrphanedLocks" class="com.raytheon.edex.plugin.gfe.server.lock.ClearGfeOrphanedLocks">
|
||||
<property name="provider" ref="brokerConnectionsProvider" />
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- Service Backup Handlers -->
|
||||
|
@ -426,6 +429,7 @@
|
|||
<endpoint id="gfeProductPurgeCron" uri="clusteredquartz://gfe/purgeGfeProducts/?cron=${purge.gfe.products.cron}"/>
|
||||
<endpoint id="svcbuLogPurgeCron" uri="clusteredquartz://gfe/purgeSvcbuLogs/?cron=${purge.svcbu.logs.cron}"/>
|
||||
<endpoint id="iscSendLauncher" uri="quartz://iscSendThread?trigger.repeatCount=0&trigger.repeatInterval=1"/>
|
||||
<endpoint id="gfeClearOrphanedLocksCron" uri="clusteredquartz://gfe/clearGfeOrhpanedLocks/?cron=${clear.gfe.orphaned.locks.cron}"/>
|
||||
|
||||
<route id="exportDigitalData">
|
||||
<from uri="exportDigitalDataCron"/>
|
||||
|
@ -495,6 +499,21 @@
|
|||
</doCatch>
|
||||
</doTry>
|
||||
</route>
|
||||
|
||||
<route id="clearGfeOrphanedLocks">
|
||||
<from uri="gfeClearOrphanedLocksCron"/>
|
||||
<to uri="jms-generic:queue:clearOrphanedLocksWork"/>
|
||||
</route>
|
||||
<route id="clearOrphanedLocksWork">
|
||||
<from uri="jms-generic:queue:clearOrphanedLocksWork"/>
|
||||
<doTry>
|
||||
<bean ref="ClearGfeOrphanedLocks" method="clearLocksCron"/>
|
||||
<doCatch>
|
||||
<exception>java.lang.Throwable</exception>
|
||||
<to uri="log:svcBackup?level=ERROR"/>
|
||||
</doCatch>
|
||||
</doTry>
|
||||
</route>
|
||||
|
||||
<!-- ISC Data Receive route -->
|
||||
<route id="iscReceiveRoute">
|
||||
|
|
|
@ -12,3 +12,6 @@ purge.svcbu.logs.cron=0+30+0+*+*+?
|
|||
|
||||
# Interval at which the gfe products are purged
|
||||
purge.gfe.products.cron=0+45+0+*+*+?
|
||||
|
||||
# Interval at which the gfe orphaned locks are cleared
|
||||
clear.gfe.orphaned.locks.cron = 0+0/10+*+*+*+?
|
|
@ -53,6 +53,7 @@ import com.raytheon.uf.edex.database.dao.DaoConfig;
|
|||
* 04/19/13 #1949 rjpeter Normalized GFE Database.
|
||||
* 06/20/13 #2127 rjpeter Set session to read only.
|
||||
* 10/16/2014 3454 bphillip Upgrading to Hibernate 4
|
||||
* 01/07/15 629 mgamazaychikov Add getAllLocks method.
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
|
@ -192,4 +193,55 @@ public class GFELockDao extends CoreDao {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<ParmID, LockTable> getAllLocks() throws DataAccessLayerException{
|
||||
Map<ParmID, LockTable> lockMap = new HashMap<ParmID, LockTable>();
|
||||
Session sess = null;
|
||||
Transaction tx = null;
|
||||
|
||||
try {
|
||||
sess = getSession();
|
||||
sess.setDefaultReadOnly(true);
|
||||
tx = sess.beginTransaction();
|
||||
|
||||
Query query = sess
|
||||
.createQuery("FROM Lock");
|
||||
List<Lock> locks = query.list();
|
||||
tx.commit();
|
||||
|
||||
// populate Lock table
|
||||
for (Lock lock : locks) {
|
||||
WsId wid = lock.getWsId();
|
||||
ParmID pid = lock.getParmId();
|
||||
LockTable lockTable = lockMap.get(pid);
|
||||
if (lockTable == null) {
|
||||
lockTable = new LockTable(pid, new ArrayList<Lock>(), wid);
|
||||
lockMap.put(pid, lockTable);
|
||||
}
|
||||
lockTable.addLock(lock);
|
||||
}
|
||||
return lockMap;
|
||||
} catch (Exception e) {
|
||||
if (tx != null) {
|
||||
try {
|
||||
tx.rollback();
|
||||
} catch (Exception e1) {
|
||||
logger.error("Error occurred rolling back transaction", e1);
|
||||
}
|
||||
}
|
||||
|
||||
throw new DataAccessLayerException(
|
||||
"Unable to look up locks ", e);
|
||||
} finally {
|
||||
if (sess != null) {
|
||||
try {
|
||||
sess.close();
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Error occurred closing database session", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.edex.plugin.gfe.server.lock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.edex.plugin.gfe.server.IFPServer;
|
||||
import com.raytheon.edex.plugin.gfe.server.lock.LockManager;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.server.lock.Lock;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.server.lock.LockTable;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.server.lock.LockTable.LockMode;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.server.request.LockRequest;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.common.time.TimeRange;
|
||||
import com.raytheon.uf.edex.core.EDEXUtil;
|
||||
import com.raytheon.uf.edex.esb.camel.jms.IBrokerConnectionsProvider;
|
||||
|
||||
/**
|
||||
* GFE task to clear orphaned locks from the database table. Orphaned
|
||||
* locks are locks whose session ID is not in the list of current Qpid
|
||||
* sessions.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 07, 2015 629 mgamazaychikov Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mgamazaychikov
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class ClearGfeOrphanedLocks {
|
||||
private static IBrokerConnectionsProvider provider;
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(ClearGfeOrphanedLocks.class);
|
||||
public final String CAVE = "CAVE";
|
||||
|
||||
public static void setProvider(IBrokerConnectionsProvider provider) {
|
||||
ClearGfeOrphanedLocks.provider = provider;
|
||||
}
|
||||
|
||||
private Set<String> breakAllLocks(List<LockTable> lockTables,
|
||||
LockManager lockMgr) {
|
||||
Set<String> inactives = new HashSet<String>();
|
||||
for (LockTable lockTable : lockTables) {
|
||||
for (Lock lock : lockTable.getLocks()) {
|
||||
TimeRange tr = lock.getTimeRange();
|
||||
List<LockRequest> lreq = new ArrayList<LockRequest>();
|
||||
lreq.add(new LockRequest(lock.getParmId(), tr,
|
||||
LockMode.BREAK_LOCK));
|
||||
lockMgr.requestLockChange(lreq, lock.getWsId());
|
||||
if (!inactives.contains(lock.getWsId().toPrettyString())
|
||||
&& !inactives.contains(lock.getParmId().toString())) {
|
||||
String message = " Breaking orphaned lock on "
|
||||
+ lock.getParmId().toString() + " owned by "
|
||||
+ lock.getWsId().toPrettyString() + ".";
|
||||
inactives.add(message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return inactives;
|
||||
}
|
||||
|
||||
private Set<String> breakLocks(Set<String> clients,
|
||||
List<LockTable> lockTables, LockManager lockMgr) {
|
||||
Set<String> inactives = new HashSet<String>();
|
||||
for (LockTable lockTable : lockTables) {
|
||||
for (Lock lock : lockTable.getLocks()) {
|
||||
String lockedWsid = lock.getWsId().toString();
|
||||
for (String client : clients) {
|
||||
if (!lockedWsid.equals(client)) {
|
||||
// Inactive CAVE clients found - break its lock
|
||||
List<LockRequest> lreq = new ArrayList<LockRequest>();
|
||||
lreq.add(new LockRequest(lock.getParmId(), lock
|
||||
.getTimeRange(), LockMode.BREAK_LOCK));
|
||||
lockMgr.requestLockChange(lreq, lock.getWsId());
|
||||
if (!inactives
|
||||
.contains(lock.getWsId().toPrettyString())
|
||||
&& !inactives.contains(lock.getParmId()
|
||||
.toString())) {
|
||||
String message = " Breaking orphaned lock on "
|
||||
+ lock.getParmId().toString()
|
||||
+ " owned by "
|
||||
+ lock.getWsId().toPrettyString() + ".";
|
||||
inactives.add(message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return inactives;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void clearLocksCron() throws Exception {
|
||||
|
||||
Date executionTime = new Date(System.currentTimeMillis());
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
String msg = "Started at " + executionTime;
|
||||
statusHandler.info(msg);
|
||||
}
|
||||
|
||||
Set<String> clients = new HashSet<String>(provider.getConnections());
|
||||
Set<String> inactives = new HashSet<String>();
|
||||
|
||||
String siteId = EDEXUtil.getEdexSite();
|
||||
IFPServer ifpServer = IFPServer.getActiveServer(siteId);
|
||||
if (ifpServer == null) {
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
String msg = "No active IFPServer for site " + siteId;
|
||||
statusHandler.info(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
LockManager lockMgr = ifpServer.getLockMgr();
|
||||
|
||||
List<LockTable> lockTables = (List<LockTable>) lockMgr.getAllLocks()
|
||||
.getPayload();
|
||||
|
||||
/*
|
||||
* There are no locks in the db.
|
||||
*/
|
||||
if (lockTables.size() == 0) {
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
String msg = "No locks found for site " + siteId;
|
||||
statusHandler.info(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Filter out non-CAVE clients.
|
||||
*/
|
||||
for (Iterator<String> iterator = clients.iterator(); iterator.hasNext();) {
|
||||
String client = iterator.next();
|
||||
if (!client.contains(CAVE)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If there are no active CAVE clients but the locks exist, they all
|
||||
* must be orphaned -> break the locks.
|
||||
*/
|
||||
if (clients.isEmpty() && lockTables.size() > 0) {
|
||||
inactives = breakAllLocks(lockTables, lockMgr);
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String in : inactives) {
|
||||
sb.append(in);
|
||||
}
|
||||
statusHandler.info(sb.toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* There are active CAVE clients, find orphaned locks and break the
|
||||
* locks.
|
||||
*/
|
||||
inactives = breakLocks(clients, lockTables, lockMgr);
|
||||
if (inactives.isEmpty()) {
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
String msg = "No orphaned locks found for site " + siteId;
|
||||
statusHandler.info(msg);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String in : inactives) {
|
||||
sb.append(in);
|
||||
}
|
||||
statusHandler.info(sb.toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -67,6 +67,7 @@ import com.raytheon.uf.edex.database.DataAccessLayerException;
|
|||
* fixed inefficiencies in querying/merging
|
||||
* 06/13/13 #2044 randerso Converted from singleton to instance per
|
||||
* site managed by IFPServer
|
||||
* 01/07/15 629 mgamazaychikov Add getAllLocks method.
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
|
@ -915,4 +916,20 @@ public class LockManager {
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public ServerResponse <?> getAllLocks() {
|
||||
ServerResponse<List<LockTable>> sr = new ServerResponse<List<LockTable>>();
|
||||
try {
|
||||
List<LockTable> payLoad = null;
|
||||
Map<ParmID, LockTable> lockMap = dao.getAllLocks();
|
||||
payLoad = new ArrayList<LockTable>(lockMap.size());
|
||||
payLoad.addAll(lockMap.values());
|
||||
sr.setPayload(payLoad);
|
||||
} catch (Exception e) {
|
||||
sr.addMessage("Error getting lock tables for");
|
||||
sr.setPayload(new ArrayList<LockTable>(0));
|
||||
}
|
||||
|
||||
return sr;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue