2 * ============LICENSE_START=======================================================
3 * feature-state-management
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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 * ============LICENSE_END=========================================================
21 package org.onap.policy.drools.statemanagement;
23 import java.sql.Connection;
24 import java.sql.DriverManager;
25 import java.sql.PreparedStatement;
26 import java.sql.ResultSet;
27 import java.sql.SQLException;
28 import java.util.Properties;
29 import java.util.UUID;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
35 * This class audits the database
37 public class DbAudit extends DroolsPDPIntegrityMonitor.AuditBase
39 // get an instance of logger
40 private static Logger logger = LoggerFactory.getLogger(DbAudit.class);
41 // single global instance of this audit object
42 private static final DbAudit instance = new DbAudit();
44 // This indicates if 'CREATE TABLE IF NOT EXISTS Audit ...' should be
45 // invoked -- doing this avoids the need to create the table in advance.
46 private static boolean createTableNeeded = true;
48 private static boolean isJunit = false;
51 * Constructor - set the name to 'Database'
58 private static synchronized void setCreateTableNeeded(boolean b) {
59 DbAudit.createTableNeeded = b;
62 public static synchronized void setIsJunit(boolean b) {
66 public static boolean isJunit(){
67 return DbAudit.isJunit;
72 * @return the single 'DbAudit' instance
74 public static DroolsPDPIntegrityMonitor.AuditBase getInstance()
82 * @param properties properties to be passed to the audit
85 public void invoke(Properties properties)
87 logger.debug("Running 'DbAudit.invoke'");
88 boolean doCreate = createTableNeeded && !isJunit;
91 logger.info("DbAudit.invoke: exiting because isActive = false");
95 // fetch DB properties from properties file -- they are already known
96 // to exist, because they were verified by the 'IntegrityMonitor'
98 String url = properties.getProperty(StateManagementProperties.DB_URL);
99 String user = properties.getProperty(StateManagementProperties.DB_USER);
100 String password = properties.getProperty(StateManagementProperties.DB_PWD);
102 // operation phase currently running -- used to construct an error
103 // message, if needed
106 // create connection to DB
107 phase = "creating connection";
108 logger.debug("DbAudit: Creating connection to {}", url);
109 try (Connection connection = DriverManager.getConnection(url, user, password))
112 // create audit table, if needed
115 phase = "create table";
116 createTable(connection);
119 // insert an entry into the table
120 phase = "insert entry";
121 String key = UUID.randomUUID().toString();
122 insertEntry(connection, key);
124 phase = "fetch entry";
125 findEntry(connection, key);
127 phase = "delete entry";
128 deleteEntry(connection, key);
132 String message = "DbAudit: Exception during audit, phase = " + phase;
133 logger.error(message, e);
134 setResponse(message);
139 * Determines if the DbAudit is active, based on properties. Defaults to
140 * {@code true}, if not found in the properties.
141 * @return {@code true} if DbAudit is active, {@code false} otherwise
143 private boolean isActive() {
144 String dbAuditIsActive = StateManagementProperties.getProperty("db.audit.is.active");
145 logger.debug("DbAudit.invoke: dbAuditIsActive = {}", dbAuditIsActive);
147 if (dbAuditIsActive != null) {
149 return Boolean.parseBoolean(dbAuditIsActive.trim());
150 } catch (NumberFormatException e) {
151 logger.warn("DbAudit.invoke: Ignoring invalid property: db.audit.is.active = {}", dbAuditIsActive);
161 * @throws SQLException
163 private void createTable(Connection connection) throws SQLException {
164 logger.info("DbAudit: Creating 'Audit' table, if needed");
165 try (PreparedStatement statement = connection.prepareStatement
166 ("CREATE TABLE IF NOT EXISTS Audit (\n"
167 + " name varchar(64) DEFAULT NULL,\n"
168 + " UNIQUE KEY name (name)\n"
169 + ") DEFAULT CHARSET=latin1;")) {
171 DbAudit.setCreateTableNeeded(false);
179 * @throws SQLException
181 private void insertEntry(Connection connection, String key) throws SQLException {
182 try (PreparedStatement statement = connection.prepareStatement
183 ("INSERT INTO Audit (name) VALUES (?)")) {
184 statement.setString(1, key);
185 statement.executeUpdate();
193 * @throws SQLException
195 private void findEntry(Connection connection, String key) throws SQLException {
196 try (PreparedStatement statement = connection.prepareStatement
197 ("SELECT name FROM Audit WHERE name = ?")) {
198 statement.setString(1, key);
199 getEntry(statement, key);
204 * Executes the query to determine if the entry exists. Sets the response
208 * @throws SQLException
210 private void getEntry(PreparedStatement statement, String key) throws SQLException {
211 try (ResultSet rs = statement.executeQuery()) {
215 if(logger.isDebugEnabled()){
216 logger.debug("DbAudit: Found key {}", rs.getString(1));
222 ("DbAudit: can't find newly-created entry with key {}", key);
223 setResponse("Can't find newly-created entry");
232 * @throws SQLException
234 private void deleteEntry(Connection connection, String key) throws SQLException {
235 try (PreparedStatement statement = connection.prepareStatement
236 ("DELETE FROM Audit WHERE name = ?")) {
237 statement.setString(1, key);
238 statement.executeUpdate();