Sonar issue fix in LockCleanUpDaemon
[music.git] / music-core / src / main / java / org / onap / music / lockingservice / cassandra / LockCleanUpDaemon.java
1 /*
2  * ============LICENSE_START==========================================
3  * org.onap.music
4  * ===================================================================
5  *  Copyright (c) 2019 AT&T Intellectual Property
6  * ===================================================================
7  *  Licensed under the Apache License, Version 2.0 (the "License");
8  *  you may not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at
10  * 
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  *  Unless required by applicable law or agreed to in writing, software
14  *  distributed under the License is distributed on an "AS IS" BASIS,
15  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *  See the License for the specific language governing permissions and
17  *  limitations under the License.
18  * 
19  * ============LICENSE_END=============================================
20  * ====================================================================
21  */
22
23 package org.onap.music.lockingservice.cassandra;
24
25 import java.util.HashSet;
26 import java.util.Set;
27 import org.onap.music.datastore.MusicDataStoreHandle;
28 import org.onap.music.datastore.PreparedQueryObject;
29 import org.onap.music.eelf.logging.EELFLoggerDelegate;
30 import org.onap.music.exceptions.MusicServiceException;
31 import org.onap.music.main.MusicCore;
32 import org.onap.music.main.MusicUtil;
33 import com.datastax.driver.core.ResultSet;
34 import com.datastax.driver.core.Row;
35
36 public class LockCleanUpDaemon extends Thread {
37     
38     boolean terminated = false;
39     private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(LockCleanUpDaemon.class);
40
41     
42     public LockCleanUpDaemon() {
43     }
44     
45     @Override
46     public void run() {
47         if (MusicUtil.getLockDaemonSleepTimeMs()<0) {
48             terminate();
49         }
50         while (!terminated) {
51             try {
52                 cleanupStaleLocks();
53             } catch (MusicServiceException e) {
54                 logger.warn(EELFLoggerDelegate.applicationLogger, "Unable to clean up locks", e);
55             }
56             try {
57                 Thread.sleep(MusicUtil.getLockDaemonSleepTimeMs());
58             } catch (InterruptedException e) {
59                 logger.warn(EELFLoggerDelegate.applicationLogger, "Interrupted exception", e);
60
61             }
62         }
63     }
64
65     private void cleanupStaleLocks() throws MusicServiceException {
66         Set<String> lockQTables = getLockQTables();
67         logger.info(EELFLoggerDelegate.applicationLogger, "Lock q tables found: " + lockQTables);
68         for(String lockTable: lockQTables) {
69             try {
70                 cleanUpLocksFromTable(lockTable);
71             } catch (MusicServiceException e) {
72                 logger.warn(EELFLoggerDelegate.applicationLogger, "Unable to clear locks on table " + lockTable, e);
73             }
74         }
75     }
76
77
78     private Set<String> getLockQTables() throws MusicServiceException {
79         Set<String> keyspacesToCleanUp = MusicUtil.getKeyspacesToCleanLocks();
80         Set<String> lockQTables = new HashSet<>();
81         
82         PreparedQueryObject query = new PreparedQueryObject();
83         query.appendQueryString("SELECT keyspace_name, table_name FROM system_schema.tables;");
84         ResultSet results = MusicCore.get(query);
85         
86         for (Row row: results) {
87             if (keyspacesToCleanUp.contains(row.getString("keyspace_name"))
88                     && row.getString("table_name").toLowerCase().startsWith(CassaLockStore.table_prepend_name.toLowerCase()) ) {
89                 lockQTables.add(row.getString("keyspace_name") + "." + row.getString("table_name"));
90             }
91         }
92         return lockQTables;
93     }
94
95     private void cleanUpLocksFromTable(String lockTable) throws MusicServiceException {
96         PreparedQueryObject query = new PreparedQueryObject();
97         query.appendQueryString("SELECT * from " + lockTable);
98         ResultSet results = MusicCore.get(query);
99         for (Row lock: results) {
100             if (!lock.isNull("lockreference")) {
101                 try {
102                     deleteLockIfStale(lockTable, lock);
103                 } catch (MusicServiceException e) {
104                     logger.warn(EELFLoggerDelegate.applicationLogger, "Unable to delete a potentially stale lock " + lock, e);
105                 }
106             }
107         }
108     }
109     
110     
111     private void deleteLockIfStale(String lockTable, Row lock) throws MusicServiceException {
112         final String CREATETIME="createtime";
113         final String ACQUIRETIME="acquiretime";
114         if (lock.isNull(CREATETIME) && lock.isNull("acquiretime")) {
115             return;
116         }
117
118         long createTime = lock.isNull(CREATETIME) ? 0 : Long.parseLong(lock.getString(CREATETIME));
119         long acquireTime = lock.isNull(ACQUIRETIME) ? 0 : Long.parseLong(lock.getString(ACQUIRETIME));
120         long row_access_time = Math.max(createTime, acquireTime);
121         if (System.currentTimeMillis() > row_access_time + MusicUtil.getDefaultLockLeasePeriod()) {
122             logger.info(EELFLoggerDelegate.applicationLogger, "Stale lock detected and being removed: " + lock);
123             PreparedQueryObject query = new PreparedQueryObject();
124             query.appendQueryString("DELETE FROM " + lockTable + " WHERE key='" + lock.getString("key") + "' AND " +
125                     "lockreference=" + lock.getLong("lockreference") + " IF EXISTS;");
126             MusicDataStoreHandle.getDSHandle().getSession().execute(query.getQuery());
127         }
128     }
129
130     public void terminate() {
131         terminated = true;
132     }
133 }