lowered some code smells
[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                 e.printStackTrace();
60             }
61         }
62     }
63
64     private void cleanupStaleLocks() throws MusicServiceException {
65         Set<String> lockQTables = getLockQTables();
66         logger.info(EELFLoggerDelegate.applicationLogger, "Lock q tables found: " + lockQTables);
67         for(String lockTable: lockQTables) {
68             try {
69                 cleanUpLocksFromTable(lockTable);
70             } catch (MusicServiceException e) {
71                 logger.warn(EELFLoggerDelegate.applicationLogger, "Unable to clear locks on table " + lockTable, e);
72             }
73         }
74     }
75
76
77     private Set<String> getLockQTables() throws MusicServiceException {
78         Set<String> keyspacesToCleanUp = MusicUtil.getKeyspacesToCleanLocks();
79         Set<String> lockQTables = new HashSet<>();
80         
81         PreparedQueryObject query = new PreparedQueryObject();
82         query.appendQueryString("SELECT keyspace_name, table_name FROM system_schema.tables;");
83         ResultSet results = MusicCore.get(query);
84         
85         for (Row row: results) {
86             if (keyspacesToCleanUp.contains(row.getString("keyspace_name"))
87                     && row.getString("table_name").toLowerCase().startsWith(CassaLockStore.table_prepend_name.toLowerCase()) ) {
88                 lockQTables.add(row.getString("keyspace_name") + "." + row.getString("table_name"));
89             }
90         }
91         return lockQTables;
92     }
93
94     private void cleanUpLocksFromTable(String lockTable) throws MusicServiceException {
95         PreparedQueryObject query = new PreparedQueryObject();
96         query.appendQueryString("SELECT * from " + lockTable);
97         ResultSet results = MusicCore.get(query);
98         for (Row lock: results) {
99             if (!lock.isNull("lockreference")) {
100                 try {
101                     deleteLockIfStale(lockTable, lock);
102                 } catch (MusicServiceException e) {
103                     logger.warn(EELFLoggerDelegate.applicationLogger, "Unable to delete a potentially stale lock " + lock, e);
104                 }
105             }
106         }
107     }
108     
109     
110     private void deleteLockIfStale(String lockTable, Row lock) throws MusicServiceException {
111         if (lock.isNull("createtime") && lock.isNull("acquiretime")) {
112             return;
113         }
114
115         long createTime = lock.isNull("createtime") ? 0 : Long.parseLong(lock.getString("createtime"));
116         long acquireTime = lock.isNull("acquiretime") ? 0 : Long.parseLong(lock.getString("acquiretime"));
117         long row_access_time = Math.max(createTime, acquireTime);
118         if (System.currentTimeMillis() > row_access_time + MusicUtil.getDefaultLockLeasePeriod()) {
119             logger.info(EELFLoggerDelegate.applicationLogger, "Stale lock detected and being removed: " + lock);
120             PreparedQueryObject query = new PreparedQueryObject();
121             query.appendQueryString("DELETE FROM " + lockTable + " WHERE key='" + lock.getString("key") + "' AND " +
122                     "lockreference=" + lock.getLong("lockreference") + " IF EXISTS;");
123             MusicDataStoreHandle.getDSHandle().getSession().execute(query.getQuery());
124         }
125     }
126
127     public void terminate() {
128         terminated = true;
129     }
130 }