diff options
Diffstat (limited to 'feature-state-management/src/main/java/org')
7 files changed, 990 insertions, 1066 deletions
diff --git a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/DbAudit.java b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/DbAudit.java index 33f672c5..108ee6b0 100644 --- a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/DbAudit.java +++ b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/DbAudit.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * feature-state-management * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -31,212 +31,203 @@ import java.util.UUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * This class audits the database +/** This class audits the database. */ -public class DbAudit extends DroolsPDPIntegrityMonitor.AuditBase -{ - // get an instance of logger - private static Logger logger = LoggerFactory.getLogger(DbAudit.class); - // single global instance of this audit object - private static final DbAudit instance = new DbAudit(); - - // This indicates if 'CREATE TABLE IF NOT EXISTS Audit ...' should be - // invoked -- doing this avoids the need to create the table in advance. - private static boolean createTableNeeded = true; - - private static boolean isJunit = false; - - /** - * Constructor - set the name to 'Database' - */ - private DbAudit() - { - super("Database"); - } - - private static synchronized void setCreateTableNeeded(boolean b) { - DbAudit.createTableNeeded = b; - } - - public static synchronized void setIsJunit(boolean b) { - DbAudit.isJunit = b; - } - - public static boolean isJunit(){ - return DbAudit.isJunit; - } - - - /** - * @return the single 'DbAudit' instance - */ - public static DroolsPDPIntegrityMonitor.AuditBase getInstance() - { - return instance; - } - - /** - * Invoke the audit - * - * @param properties properties to be passed to the audit - */ - @Override - public void invoke(Properties properties) - { - logger.debug("Running 'DbAudit.invoke'"); - boolean doCreate = createTableNeeded && !isJunit; - - if(!isActive()){ - logger.info("DbAudit.invoke: exiting because isActive = false"); - return; - } - - // fetch DB properties from properties file -- they are already known - // to exist, because they were verified by the 'IntegrityMonitor' - // constructor - String url = properties.getProperty(StateManagementProperties.DB_URL); - String user = properties.getProperty(StateManagementProperties.DB_USER); - String password = properties.getProperty(StateManagementProperties.DB_PWD); - - // operation phase currently running -- used to construct an error - // message, if needed - String phase = null; - - // create connection to DB - phase = "creating connection"; - logger.debug("DbAudit: Creating connection to {}", url); - try (Connection connection = DriverManager.getConnection(url, user, password)) - { - - // create audit table, if needed - if (doCreate) - { - phase = "create table"; - createTable(connection); - } - - // insert an entry into the table - phase = "insert entry"; - String key = UUID.randomUUID().toString(); - insertEntry(connection, key); - - phase = "fetch entry"; - findEntry(connection, key); - - phase = "delete entry"; - deleteEntry(connection, key); - } - catch (Exception e) - { - String message = "DbAudit: Exception during audit, phase = " + phase; - logger.error(message, e); - setResponse(message); - } - } - - /** - * Determines if the DbAudit is active, based on properties. Defaults to - * {@code true}, if not found in the properties. - * @return {@code true} if DbAudit is active, {@code false} otherwise - */ - private boolean isActive() { - String dbAuditIsActive = StateManagementProperties.getProperty("db.audit.is.active"); - logger.debug("DbAudit.invoke: dbAuditIsActive = {}", dbAuditIsActive); - - if (dbAuditIsActive != null) { - try { - return Boolean.parseBoolean(dbAuditIsActive.trim()); - } catch (NumberFormatException e) { - logger.warn("DbAudit.invoke: Ignoring invalid property: db.audit.is.active = {}", dbAuditIsActive); - } - } - - return true; - } - - /** - * Creates the table. - * @param connection - * @throws SQLException - */ - private void createTable(Connection connection) throws SQLException { - logger.info("DbAudit: Creating 'Audit' table, if needed"); - try (PreparedStatement statement = connection.prepareStatement - ("CREATE TABLE IF NOT EXISTS Audit (\n" - + " name varchar(64) DEFAULT NULL,\n" - + " UNIQUE KEY name (name)\n" - + ") DEFAULT CHARSET=latin1;")) { - statement.execute(); - DbAudit.setCreateTableNeeded(false); - } - } - - /** - * Inserts an entry. - * @param connection - * @param key - * @throws SQLException - */ - private void insertEntry(Connection connection, String key) throws SQLException { - try (PreparedStatement statement = connection.prepareStatement - ("INSERT INTO Audit (name) VALUES (?)")) { - statement.setString(1, key); - statement.executeUpdate(); - } - } - - /** - * Finds an entry. - * @param connection - * @param key - * @throws SQLException - */ - private void findEntry(Connection connection, String key) throws SQLException { - try (PreparedStatement statement = connection.prepareStatement - ("SELECT name FROM Audit WHERE name = ?")) { - statement.setString(1, key); - getEntry(statement, key); - } - } - - /** - * Executes the query to determine if the entry exists. Sets the response - * if it fails. - * @param statement - * @param key - * @throws SQLException - */ - private void getEntry(PreparedStatement statement, String key) throws SQLException { - try (ResultSet rs = statement.executeQuery()) { - if (rs.first()) - { - // found entry - if(logger.isDebugEnabled()){ - logger.debug("DbAudit: Found key {}", rs.getString(1)); - } - } - else - { - logger.error - ("DbAudit: can't find newly-created entry with key {}", key); - setResponse("Can't find newly-created entry"); - } - } - } - - /** - * Deletes an entry. - * @param connection - * @param key - * @throws SQLException - */ - private void deleteEntry(Connection connection, String key) throws SQLException { - try (PreparedStatement statement = connection.prepareStatement - ("DELETE FROM Audit WHERE name = ?")) { - statement.setString(1, key); - statement.executeUpdate(); - } - } - +public class DbAudit extends DroolsPDPIntegrityMonitor.AuditBase { + // get an instance of logger + private static Logger logger = LoggerFactory.getLogger(DbAudit.class); + // single global instance of this audit object + private static final DbAudit instance = new DbAudit(); + + // This indicates if 'CREATE TABLE IF NOT EXISTS Audit ...' should be + // invoked -- doing this avoids the need to create the table in advance. + private static boolean createTableNeeded = true; + + private static boolean isJunit = false; + + /** Constructor - set the name to 'Database'. */ + private DbAudit() { + super("Database"); + } + + private static synchronized void setCreateTableNeeded(boolean isNeeded) { + DbAudit.createTableNeeded = isNeeded; + } + + public static synchronized void setIsJunit(boolean isJUnit) { + DbAudit.isJunit = isJUnit; + } + + public static boolean isJunit() { + return DbAudit.isJunit; + } + + /** + * Get the instance. + * + * @return the single 'DbAudit' instance. */ + public static DroolsPDPIntegrityMonitor.AuditBase getInstance() { + return instance; + } + + /** + * Invoke the audit. + * + * @param properties properties to be passed to the audit + */ + @Override + public void invoke(Properties properties) { + logger.debug("Running 'DbAudit.invoke'"); + boolean doCreate = createTableNeeded && !isJunit; + + if (!isActive()) { + logger.info("DbAudit.invoke: exiting because isActive = false"); + return; + } + + // fetch DB properties from properties file -- they are already known + // to exist, because they were verified by the 'IntegrityMonitor' + // constructor + String url = properties.getProperty(StateManagementProperties.DB_URL); + String user = properties.getProperty(StateManagementProperties.DB_USER); + String password = properties.getProperty(StateManagementProperties.DB_PWD); + + // operation phase currently running -- used to construct an error + // message, if needed + String phase = null; + + // create connection to DB + phase = "creating connection"; + logger.debug("DbAudit: Creating connection to {}", url); + try (Connection connection = DriverManager.getConnection(url, user, password)) { + + // create audit table, if needed + if (doCreate) { + phase = "create table"; + createTable(connection); + } + + // insert an entry into the table + phase = "insert entry"; + String key = UUID.randomUUID().toString(); + insertEntry(connection, key); + + phase = "fetch entry"; + findEntry(connection, key); + + phase = "delete entry"; + deleteEntry(connection, key); + } catch (Exception e) { + String message = "DbAudit: Exception during audit, phase = " + phase; + logger.error(message, e); + setResponse(message); + } + } + + /** + * Determines if the DbAudit is active, based on properties. Defaults to {@code true}, if not + * found in the properties. + * + * @return {@code true} if DbAudit is active, {@code false} otherwise + */ + private boolean isActive() { + String dbAuditIsActive = StateManagementProperties.getProperty("db.audit.is.active"); + logger.debug("DbAudit.invoke: dbAuditIsActive = {}", dbAuditIsActive); + + if (dbAuditIsActive != null) { + try { + return Boolean.parseBoolean(dbAuditIsActive.trim()); + } catch (NumberFormatException e) { + logger.warn( + "DbAudit.invoke: Ignoring invalid property: db.audit.is.active = {}", dbAuditIsActive); + } + } + + return true; + } + + /** + * Creates the table. + * + * @param connection connection + * @throws SQLException exception + */ + private void createTable(Connection connection) throws SQLException { + logger.info("DbAudit: Creating 'Audit' table, if needed"); + try (PreparedStatement statement = + connection.prepareStatement( + "CREATE TABLE IF NOT EXISTS Audit (\n" + + " name varchar(64) DEFAULT NULL,\n" + + " UNIQUE KEY name (name)\n" + + ") DEFAULT CHARSET=latin1;")) { + statement.execute(); + DbAudit.setCreateTableNeeded(false); + } + } + + /** + * Inserts an entry. + * + * @param connection connection + * @param key key + * @throws SQLException exception + */ + private void insertEntry(Connection connection, String key) throws SQLException { + try (PreparedStatement statement = + connection.prepareStatement("INSERT INTO Audit (name) VALUES (?)")) { + statement.setString(1, key); + statement.executeUpdate(); + } + } + + /** + * Finds an entry. + * + * @param connection connection + * @param key key + * @throws SQLException exception + */ + private void findEntry(Connection connection, String key) throws SQLException { + try (PreparedStatement statement = + connection.prepareStatement("SELECT name FROM Audit WHERE name = ?")) { + statement.setString(1, key); + getEntry(statement, key); + } + } + + /** + * Executes the query to determine if the entry exists. Sets the response if it fails. + * + * @param statement statement + * @param key key + * @throws SQLException exception + */ + private void getEntry(PreparedStatement statement, String key) throws SQLException { + try (ResultSet rs = statement.executeQuery()) { + if (rs.first()) { + // found entry + if (logger.isDebugEnabled()) { + logger.debug("DbAudit: Found key {}", rs.getString(1)); + } + } else { + logger.error("DbAudit: can't find newly-created entry with key {}", key); + setResponse("Can't find newly-created entry"); + } + } + } + + /** + * Deletes an entry. + * + * @param connection connection + * @param key key + * @throws SQLException exception + */ + private void deleteEntry(Connection connection, String key) throws SQLException { + try (PreparedStatement statement = + connection.prepareStatement("DELETE FROM Audit WHERE name = ?")) { + statement.setString(1, key); + statement.executeUpdate(); + } + } } diff --git a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/DroolsPDPIntegrityMonitor.java b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/DroolsPDPIntegrityMonitor.java index a7606eb2..3cb99f23 100644 --- a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/DroolsPDPIntegrityMonitor.java +++ b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/DroolsPDPIntegrityMonitor.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * feature-state-management * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,7 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { private static final String PROPERTIES_NAME = "feature-state-management.properties"; /** - * Constructor - pass arguments to superclass, but remember properties + * Constructor - pass arguments to superclass, but remember properties. * * @param resourceName unique name of this Integrity Monitor * @param url the JMX URL of the MBean server @@ -81,10 +81,10 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { /** * Static initialization -- create Drools Integrity Monitor, and an HTTP server to handle REST - * 'test' requests + * 'test' requests. * - * @throws StateManagementPropertiesException - * @throws IntegrityMonitorException + * @throws StateManagementPropertiesException exception + * @throws IntegrityMonitorException exception */ public static DroolsPDPIntegrityMonitor init(String configDir) throws IntegrityMonitorException { @@ -125,9 +125,9 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { checkPropError(stateManagementProperties, StateManagementProperties.DB_USER); checkPropError(stateManagementProperties, StateManagementProperties.DB_PWD); - String testHost = stateManagementProperties.getProperty(StateManagementProperties.TEST_HOST); - String testPort = stateManagementProperties.getProperty(StateManagementProperties.TEST_PORT); - String resourceName = stateManagementProperties.getProperty(StateManagementProperties.RESOURCE_NAME); + final String testHost = stateManagementProperties.getProperty(StateManagementProperties.TEST_HOST); + final String testPort = stateManagementProperties.getProperty(StateManagementProperties.TEST_PORT); + final String resourceName = stateManagementProperties.getProperty(StateManagementProperties.RESOURCE_NAME); subsystemTestProperties = stateManagementProperties; @@ -148,8 +148,8 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { * * @param resourceName unique name of this Integrity Monitor * @param properties properties used to configure the Integrity Monitor - * @return - * @throws IntegrityMonitorException + * @return monitor object + * @throws IntegrityMonitorException exception */ private static DroolsPDPIntegrityMonitor makeMonitor(String resourceName, Properties properties) throws IntegrityMonitorException { @@ -168,7 +168,7 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { * @param testHost host name * @param testPort port * @param properties properties used to configure the rest server - * @throws IntegrityMonitorException + * @throws IntegrityMonitorException exception */ private static void makeRestServer(String testHost, String testPort, Properties properties) throws IntegrityMonitorException { @@ -190,7 +190,7 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { * * @param configDir directory containing the property file * @return the properties - * @throws IntegrityMonitorException + * @throws IntegrityMonitorException exception */ private static Properties getProperties(String configDir) throws IntegrityMonitorException { try { @@ -206,7 +206,7 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { * * @param props set of properties * @param name name of the property to check - * @throws IntegrityMonitorException + * @throws IntegrityMonitorException exception */ private static void checkPropError(Properties props, String name) throws IntegrityMonitorException { String val = props.getProperty(name); @@ -260,7 +260,7 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { } /** - * Run tests (audits) unique to Drools PDP VM (Database + Repository) + * Run tests (audits) unique to Drools PDP VM (Database + Repository). */ @Override public void subsystemTest() throws IntegrityMonitorException { @@ -308,7 +308,7 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { /* ============================================================ */ /** - * This is the base class for audits invoked in 'subsystemTest' + * This is the base class for audits invoked in 'subsystemTest'. */ public abstract static class AuditBase { // name of the audit @@ -318,7 +318,7 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { protected String response; /** - * Constructor - initialize the name, and clear the initial response + * Constructor - initialize the name, and clear the initial response. * * @param name name of the audit */ @@ -328,6 +328,8 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { } /** + * Get the name. + * * @return the name of this audit */ public String getName() { @@ -335,6 +337,8 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { } /** + * Get the response. + * * @return the response String (non-null indicates the error message) */ public String getResponse() { @@ -342,7 +346,7 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { } /** - * Set the response string to the specified value + * Set the response string to the specified value. * * @param value the new value of the response string (null = no errors) */ @@ -351,7 +355,7 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { } /** - * Abstract method to invoke the audit + * Abstract method to invoke the audit. * * @param persistenceProperties Used for DB access * @throws Exception passed in by the audit @@ -416,6 +420,12 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor { } } + /** + * Returns the instance. + * + * @return DroolsPDPIntegrityMonitor object + * @throws IntegrityMonitorException exception + */ public static DroolsPDPIntegrityMonitor getInstance() throws IntegrityMonitorException { if (logger.isDebugEnabled()) { logger.debug("getInstance() called"); diff --git a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/IntegrityMonitorRestManager.java b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/IntegrityMonitorRestManager.java index b6491e7a..49e4577c 100644 --- a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/IntegrityMonitorRestManager.java +++ b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/IntegrityMonitorRestManager.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * feature-state-management * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,11 @@ package org.onap.policy.drools.statemanagement; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; + import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Response; @@ -27,84 +32,82 @@ import javax.ws.rs.core.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; @Api(value = "test") - @Path("/") +@Path("/") public class IntegrityMonitorRestManager { - private static Logger logger = LoggerFactory.getLogger(IntegrityMonitorRestManager.class); - private DroolsPDPIntegrityMonitor im; - - /** - * Test interface for Integrity Monitor - * - * @return Exception message if exception, otherwise empty - */ - @ApiOperation( - value = "Test endpoint for integrity monitor", - notes = "The TEST command is used to request data from a subcomponent " - + "instance that can be used to determine its operational state. " - + "A 200/success response status code should be returned if the " - + "subcomponent instance is functioning properly and able to respond to requests.", - response = String.class) - @ApiResponses(value = { - @ApiResponse( - code = 200, - message = "Integrity monitor sanity check passed"), - @ApiResponse( - code = 500, - message = "Integrity monitor sanity check encountered an exception. This can indicate operational state disabled or administrative state locked") - }) - @GET - @Path("test") - public Response test() { - if(logger.isDebugEnabled()){ - logger.debug("integrity monitor /test accessed"); - } - // The responses are stored within the audit objects, so we need to - // invoke the audits and get responses before we handle another - // request. - synchronized (IntegrityMonitorRestManager.class) { - // will include messages associated with subsystem failures - StringBuilder body = new StringBuilder(); + private static Logger logger = LoggerFactory.getLogger(IntegrityMonitorRestManager.class); + private DroolsPDPIntegrityMonitor im; + + /** + * Test interface for Integrity Monitor. + * + * @return Exception message if exception, otherwise empty + */ + @ApiOperation( + value = "Test endpoint for integrity monitor", + notes = "The TEST command is used to request data from a subcomponent " + + "instance that can be used to determine its operational state. " + + "A 200/success response status code should be returned if the " + + "subcomponent instance is functioning properly and able to respond to requests.", + response = String.class) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "Integrity monitor sanity check passed"), + @ApiResponse( + code = 500, + message = "Integrity monitor sanity check encountered an exception. " + + "This can indicate operational state disabled or administrative state locked") + }) + @GET + @Path("test") + public Response test() { + if (logger.isDebugEnabled()) { + logger.debug("integrity monitor /test accessed"); + } + // The responses are stored within the audit objects, so we need to + // invoke the audits and get responses before we handle another + // request. + synchronized (IntegrityMonitorRestManager.class) { + // will include messages associated with subsystem failures + StringBuilder body = new StringBuilder(); - // 200=SUCCESS, 500=failure - int responseValue = 200; + // 200=SUCCESS, 500=failure + int responseValue = 200; - if (im == null) { - try { - im = DroolsPDPIntegrityMonitor.getInstance(); - } catch (Exception e) { - logger.error("IntegrityMonitorRestManager: test() interface caught an exception", e); - body.append("\nException: " + e + "\n"); - responseValue = 500; - } - } + if (im == null) { + try { + im = DroolsPDPIntegrityMonitor.getInstance(); + } catch (Exception e) { + logger.error("IntegrityMonitorRestManager: test() interface caught an exception", e); + body.append("\nException: " + e + "\n"); + responseValue = 500; + } + } - if (im != null) { - try { - // call 'IntegrityMonitor.evaluateSanity()' - im.evaluateSanity(); - } catch (Exception e) { - // this exception isn't coming from one of the audits, - // because those are caught in 'subsystemTest()' - logger.error("DroolsPDPIntegrityMonitor.evaluateSanity()", e); + if (im != null) { + try { + // call 'IntegrityMonitor.evaluateSanity()' + im.evaluateSanity(); + } catch (Exception e) { + // this exception isn't coming from one of the audits, + // because those are caught in 'subsystemTest()' + logger.error("DroolsPDPIntegrityMonitor.evaluateSanity()", e); - // include exception in HTTP response - body.append("\nException: " + e + "\n"); - responseValue = 500; - } - } + // include exception in HTTP response + body.append("\nException: " + e + "\n"); + responseValue = 500; + } + } - // send response, including the contents of 'body' - // (which is empty if everything is successful) - if (responseValue == 200) - return Response.status(Response.Status.OK).build(); - else - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(body.toString()).build(); - } - } + // send response, including the contents of 'body' + // (which is empty if everything is successful) + if (responseValue == 200) { + return Response.status(Response.Status.OK).build(); + } else { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(body.toString()).build(); + } + } + } } diff --git a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/RepositoryAudit.java b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/RepositoryAudit.java index 6ddf0c78..92ec2ac0 100644 --- a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/RepositoryAudit.java +++ b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/RepositoryAudit.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * feature-state-management * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,529 +37,456 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * This class audits the Maven repository + * This class audits the Maven repository. */ -public class RepositoryAudit extends DroolsPDPIntegrityMonitor.AuditBase -{ - private static final long DEFAULT_TIMEOUT = 60; // timeout in 60 seconds - - // get an instance of logger - private static Logger logger = LoggerFactory.getLogger(RepositoryAudit.class); - // single global instance of this audit object - private static RepositoryAudit instance = new RepositoryAudit(); - - /** - * Constructor - set the name to 'Repository' - */ - private RepositoryAudit() - { - super("Repository"); - } - - /** - * @return the single 'RepositoryAudit' instance - */ - public static DroolsPDPIntegrityMonitor.AuditBase getInstance() - { - return instance; - } - - /** - * Invoke the audit - * - * @param properties properties to be passed to the audit - */ - @Override - public void invoke(Properties properties) - throws IOException, InterruptedException - { - if(logger.isDebugEnabled()){ - logger.debug("Running 'RepositoryAudit.invoke'"); - } - - boolean isActive = true; - boolean ignoreErrors = true; // ignore errors by default - String repoAuditIsActive = StateManagementProperties.getProperty("repository.audit.is.active"); - String repoAuditIgnoreErrors = - StateManagementProperties.getProperty("repository.audit.ignore.errors"); - logger.debug("RepositoryAudit.invoke: repoAuditIsActive = {}" - + ", repoAuditIgnoreErrors = {}",repoAuditIsActive, repoAuditIgnoreErrors); - - if (repoAuditIsActive != null) { - try { - isActive = Boolean.parseBoolean(repoAuditIsActive.trim()); - } catch (NumberFormatException e) { - logger.warn("RepositoryAudit.invoke: Ignoring invalid property: repository.audit.is.active = {}", repoAuditIsActive); - } - } - - if(!isActive){ - logger.info("RepositoryAudit.invoke: exiting because isActive = {}", isActive); - return; - } - - if (repoAuditIgnoreErrors != null) - { - try - { - ignoreErrors = Boolean.parseBoolean(repoAuditIgnoreErrors.trim()); - } - catch (NumberFormatException e) - { - ignoreErrors = true; - logger.warn("RepositoryAudit.invoke: Ignoring invalid property: repository.audit.ignore.errors = {}", repoAuditIgnoreErrors); - } - }else{ - ignoreErrors = true; - } - - // Fetch repository information from 'IntegrityMonitorProperties' - String repositoryId = - StateManagementProperties.getProperty("repository.audit.id"); - String repositoryUrl = - StateManagementProperties.getProperty("repository.audit.url"); - String repositoryUsername = - StateManagementProperties.getProperty("repository.audit.username"); - String repositoryPassword = - StateManagementProperties.getProperty("repository.audit.password"); - boolean upload = - repositoryId != null && repositoryUrl != null - && repositoryUsername != null && repositoryPassword != null; - - // used to incrementally construct response as problems occur - // (empty = no problems) - StringBuilder response = new StringBuilder(); - - long timeoutInSeconds = DEFAULT_TIMEOUT; - String timeoutString = - StateManagementProperties.getProperty("repository.audit.timeout"); - if (timeoutString != null && !timeoutString.isEmpty()) - { - try - { - timeoutInSeconds = Long.valueOf(timeoutString); - } - catch (NumberFormatException e) - { - logger.error - ("RepositoryAudit: Invalid 'repository.audit.timeout' value: '{}'", timeoutString, e); - if (!ignoreErrors) - { - response.append("Invalid 'repository.audit.timeout' value: '") - .append(timeoutString).append("'\n"); - setResponse(response.toString()); - } - } - } - - // artifacts to be downloaded - LinkedList<Artifact> artifacts = new LinkedList<>(); - - /* - * 1) create temporary directory - */ - Path dir = Files.createTempDirectory("auditRepo"); - logger.info("RepositoryAudit: temporary directory = {}", dir); - - // nested 'pom.xml' file and 'repo' directory - Path pom = dir.resolve("pom.xml"); - Path repo = dir.resolve("repo"); - - /* - * 2) Create test file, and upload to repository - * (only if repository information is specified) - */ - String groupId = null; - String artifactId = null; - String version = null; - if (upload) - { - groupId = "org.onap.policy.audit"; - artifactId = "repository-audit"; - version = "0." + System.currentTimeMillis(); - - if (repositoryUrl.toLowerCase().contains("snapshot")) - { - // use SNAPSHOT version - version += "-SNAPSHOT"; - } - - // create text file to write - FileOutputStream fos = - new FileOutputStream(dir.resolve("repository-audit.txt").toFile()); - try - { - fos.write(version.getBytes()); - } - finally - { - fos.close(); - } - - // try to install file in repository - if (runProcess - (timeoutInSeconds, dir.toFile(), null, - "mvn", "deploy:deploy-file", - "-DrepositoryId=" + repositoryId, - "-Durl=" + repositoryUrl, - "-Dfile=repository-audit.txt", - "-DgroupId=" + groupId, - "-DartifactId=" + artifactId, - "-Dversion=" + version, - "-Dpackaging=txt", - "-DgeneratePom=false") != 0) - { - logger.error - ("RepositoryAudit: 'mvn deploy:deploy-file' failed"); - if (!ignoreErrors) - { - response.append("'mvn deploy:deploy-file' failed\n"); - setResponse(response.toString()); - } - } - else - { - logger.info - ("RepositoryAudit: 'mvn deploy:deploy-file succeeded"); - - // we also want to include this new artifact in the download - // test (steps 3 and 4) - artifacts.add(new Artifact(groupId, artifactId, version, "txt")); - } - } - - /* - * 3) create 'pom.xml' file in temporary directory - */ - artifacts.add(new Artifact("org.apache.maven/maven-embedder/3.2.2")); - - StringBuilder sb = new StringBuilder(); - sb.append - ("<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" - + " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n" - + "\n" - + " <modelVersion>4.0.0</modelVersion>\n" - + " <groupId>empty</groupId>\n" - + " <artifactId>empty</artifactId>\n" - + " <version>1.0-SNAPSHOT</version>\n" - + " <packaging>pom</packaging>\n" - + "\n" - + " <build>\n" - + " <plugins>\n" - + " <plugin>\n" - + " <groupId>org.apache.maven.plugins</groupId>\n" - + " <artifactId>maven-dependency-plugin</artifactId>\n" - + " <version>2.10</version>\n" - + " <executions>\n" - + " <execution>\n" - + " <id>copy</id>\n" - + " <goals>\n" - + " <goal>copy</goal>\n" - + " </goals>\n" - + " <configuration>\n" - + " <localRepositoryDirectory>") - .append(repo) - .append("</localRepositoryDirectory>\n") - .append(" <artifactItems>\n"); - for (Artifact artifact : artifacts) - { - // each artifact results in an 'artifactItem' element - sb.append - (" <artifactItem>\n" - + " <groupId>") - .append(artifact.groupId) - .append - ("</groupId>\n" - + " <artifactId>") - .append(artifact.artifactId) - .append - ("</artifactId>\n" - + " <version>") - .append(artifact.version) - .append - ("</version>\n" - + " <type>") - .append(artifact.type) - .append - ("</type>\n" - + " </artifactItem>\n"); - } - sb.append - (" </artifactItems>\n" - + " </configuration>\n" - + " </execution>\n" - + " </executions>\n" - + " </plugin>\n" - + " </plugins>\n" - + " </build>\n" - + "</project>\n"); - FileOutputStream fos = new FileOutputStream(pom.toFile()); - try - { - fos.write(sb.toString().getBytes()); - } - finally - { - fos.close(); - } - - /* - * 4) Invoke external 'mvn' process to do the downloads - */ - - // output file = ${dir}/out (this supports step '4a') - File output = dir.resolve("out").toFile(); - - // invoke process, and wait for response - int rval = runProcess - (timeoutInSeconds, dir.toFile(), output, "mvn", "compile"); - logger.info("RepositoryAudit: 'mvn' return value = {}", rval); - if (rval != 0) - { - logger.error - ("RepositoryAudit: 'mvn compile' invocation failed"); - if (!ignoreErrors) - { - response.append("'mvn compile' invocation failed\n"); - setResponse(response.toString()); - } - } - - /* - * 4a) Check attempted and successful downloads from output file - * Note: at present, this step just generates log messages, - * but doesn't do any verification. - */ - if (rval == 0 && output != null) - { - // place output in 'fileContents' (replacing the Return characters - // with Newline) - byte[] outputData = new byte[(int)output.length()]; - String fileContents; - try (FileInputStream fis = new FileInputStream(output)) { - // - // Ideally this should be in a loop or even better use - // Java 8 nio functionality. - // - int bytesRead = fis.read(outputData); - logger.info("fileContents read {} bytes", bytesRead); - fileContents = new String(outputData).replace('\r','\n'); - } - - // generate log messages from 'Downloading' and 'Downloaded' - // messages within the 'mvn' output - int index = 0; - while ((index = fileContents.indexOf("\nDown", index)) > 0) - { - index += 5; - if (fileContents.regionMatches(index, "loading: ", 0, 9)) - { - index += 9; - int endIndex = fileContents.indexOf('\n', index); - logger.info - ("RepositoryAudit: Attempted download: '{}'", fileContents.substring(index, endIndex)); - index = endIndex; - } - else if (fileContents.regionMatches(index, "loaded: ", 0, 8)) - { - index += 8; - int endIndex = fileContents.indexOf(' ', index); - logger.info - ("RepositoryAudit: Successful download: '{}'",fileContents.substring(index, endIndex)); - index = endIndex; - } - } - } - - /* - * 5) Check the contents of the directory to make sure the downloads - * were successful - */ - for (Artifact artifact : artifacts) - { - if (repo.resolve(artifact.groupId.replace('.','/')) - .resolve(artifact.artifactId) - .resolve(artifact.version) - .resolve(artifact.artifactId + "-" + artifact.version + "." - + artifact.type).toFile().exists()) - { - // artifact exists, as expected - logger.info("RepositoryAudit: {} : exists", artifact.toString()); - } - else - { - // Audit ERROR: artifact download failed for some reason - logger.error("RepositoryAudit: {}: does not exist", artifact.toString()); - if (!ignoreErrors) - { - response.append("Failed to download artifact: ") - .append(artifact).append('\n'); - setResponse(response.toString()); - } - } - } - - /* - * 6) Use 'curl' to delete the uploaded test file - * (only if repository information is specified) - */ - if (upload) - { - if (runProcess - (timeoutInSeconds, dir.toFile(), null, - "curl", - "--request", "DELETE", - "--user", repositoryUsername + ":" + repositoryPassword, - repositoryUrl + "/" + groupId.replace('.', '/') + "/" + - artifactId + "/" + version) - != 0) - { - logger.error - ("RepositoryAudit: delete of uploaded artifact failed"); - if (!ignoreErrors) - { - response.append("delete of uploaded artifact failed\n"); - setResponse(response.toString()); - } - } - else - { - logger.info - ("RepositoryAudit: delete of uploaded artifact succeeded"); - artifacts.add(new Artifact(groupId, artifactId, version, "txt")); - } - } - - /* - * 7) Remove the temporary directory - */ - Files.walkFileTree(dir, new RecursivelyDeleteDirectory()); - } - - /** - * Run a process, and wait for the response - * - * @param timeoutInSeconds the number of seconds to wait for the - * process to terminate - * @param directory the execution directory of the process - * (null = current directory) - * @param stdout the file to contain the standard output - * (null = discard standard output) - * @param command command and arguments - * @return the return value of the process - * @throws IOException, InterruptedException - */ - static int runProcess(long timeoutInSeconds, - File directory, File stdout, String... command) - throws IOException, InterruptedException - { - ProcessBuilder pb = new ProcessBuilder(command); - if (directory != null) - { - pb.directory(directory); - } - if (stdout != null) - { - pb.redirectOutput(stdout); - } - - Process process = pb.start(); - if (process.waitFor(timeoutInSeconds, TimeUnit.SECONDS)) - { - // process terminated before the timeout - return process.exitValue(); - } - - // process timed out -- kill it, and return -1 - process.destroyForcibly(); - return -1; - } - - /** - * This class is used to recursively delete a directory and all of its - * contents. - */ - private final class RecursivelyDeleteDirectory extends SimpleFileVisitor<Path> { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - { - file.toFile().delete(); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path file, IOException e) - throws IOException - { - if (e == null) - { - file.toFile().delete(); - return FileVisitResult.CONTINUE; - } - else - { - throw e; - } - } - } - -/* ============================================================ */ - - /** - * An instance of this class exists for each artifact that we are trying - * to download. - */ - static class Artifact - { - String groupId; - String artifactId; - String version; - String type; - - /** - * Constructor - populate the 'Artifact' instance - * - * @param groupId groupId of artifact - * @param artifactId artifactId of artifact - * @param version version of artifact - * @param type type of the artifact (e.g. "jar") - */ - Artifact(String groupId, String artifactId, String version, String type) - { - this.groupId = groupId; - this.artifactId = artifactId; - this.version = version; - this.type = type; - } - - /** - * Constructor - populate an 'Artifact' instance - * - * @param artifact a string of the form: - * "<groupId>/<artifactId>/<version>[/<type>]" - * @throws IllegalArgumentException if 'artifact' has the incorrect format - */ - Artifact(String artifact) - { - String[] segments = artifact.split("/"); - if (segments.length != 4 && segments.length != 3) - { - throw new IllegalArgumentException("groupId/artifactId/version/type"); - } - groupId = segments[0]; - artifactId = segments[1]; - version = segments[2]; - type = segments.length == 4 ? segments[3] : "jar"; - } - - /** - * @return the artifact id in the form: - * "<groupId>/<artifactId>/<version>/<type>" - */ - @Override - public String toString() - { - return groupId + "/" + artifactId + "/" + version + "/" + type; - } - } +public class RepositoryAudit extends DroolsPDPIntegrityMonitor.AuditBase { + private static final long DEFAULT_TIMEOUT = 60; //timeout in 60 seconds + + // get an instance of logger + private static Logger logger = LoggerFactory.getLogger(RepositoryAudit.class); + // single global instance of this audit object + private static RepositoryAudit instance = new RepositoryAudit(); + + /** + * Constructor - set the name to 'Repository'. + */ + private RepositoryAudit() { + super("Repository"); + } + + /** + * Get the integrity monitor instance. + * + * @return the single 'RepositoryAudit' instance + */ + public static DroolsPDPIntegrityMonitor.AuditBase getInstance() { + return instance; + } + + /** + * Invoke the audit. + * + * @param properties properties to be passed to the audit + */ + @Override + public void invoke(Properties properties) + throws IOException, InterruptedException { + if (logger.isDebugEnabled()) { + logger.debug("Running 'RepositoryAudit.invoke'"); + } + + boolean isActive = true; + // ignore errors by default + boolean ignoreErrors = true; + String repoAuditIsActive = StateManagementProperties.getProperty("repository.audit.is.active"); + String repoAuditIgnoreErrors = + StateManagementProperties.getProperty("repository.audit.ignore.errors"); + logger.debug("RepositoryAudit.invoke: repoAuditIsActive = {}" + + ", repoAuditIgnoreErrors = {}",repoAuditIsActive, repoAuditIgnoreErrors); + + if (repoAuditIsActive != null) { + try { + isActive = Boolean.parseBoolean(repoAuditIsActive.trim()); + } catch (NumberFormatException e) { + logger.warn("RepositoryAudit.invoke: Ignoring invalid property: repository.audit.is.active = {}", + repoAuditIsActive); + } + } + + if (!isActive) { + logger.info("RepositoryAudit.invoke: exiting because isActive = {}", isActive); + return; + } + + if (repoAuditIgnoreErrors != null) { + try { + ignoreErrors = Boolean.parseBoolean(repoAuditIgnoreErrors.trim()); + } catch (NumberFormatException e) { + ignoreErrors = true; + logger.warn("RepositoryAudit.invoke: Ignoring invalid property: repository.audit.ignore.errors = {}", + repoAuditIgnoreErrors); + } + } else { + ignoreErrors = true; + } + + // Fetch repository information from 'IntegrityMonitorProperties' + String repositoryId = + StateManagementProperties.getProperty("repository.audit.id"); + String repositoryUrl = + StateManagementProperties.getProperty("repository.audit.url"); + String repositoryUsername = + StateManagementProperties.getProperty("repository.audit.username"); + String repositoryPassword = + StateManagementProperties.getProperty("repository.audit.password"); + boolean upload = + repositoryId != null && repositoryUrl != null + && repositoryUsername != null && repositoryPassword != null; + + // used to incrementally construct response as problems occur + // (empty = no problems) + StringBuilder response = new StringBuilder(); + + long timeoutInSeconds = DEFAULT_TIMEOUT; + String timeoutString = + StateManagementProperties.getProperty("repository.audit.timeout"); + if (timeoutString != null && !timeoutString.isEmpty()) { + try { + timeoutInSeconds = Long.valueOf(timeoutString); + } catch (NumberFormatException e) { + logger.error("RepositoryAudit: Invalid 'repository.audit.timeout' value: '{}'", + timeoutString, e); + if (!ignoreErrors) { + response.append("Invalid 'repository.audit.timeout' value: '") + .append(timeoutString).append("'\n"); + setResponse(response.toString()); + } + } + } + + // artifacts to be downloaded + LinkedList<Artifact> artifacts = new LinkedList<>(); + + /* + * 1) create temporary directory + */ + Path dir = Files.createTempDirectory("auditRepo"); + logger.info("RepositoryAudit: temporary directory = {}", dir); + + // nested 'pom.xml' file and 'repo' directory + final Path pom = dir.resolve("pom.xml"); + final Path repo = dir.resolve("repo"); + + /* + * 2) Create test file, and upload to repository + * (only if repository information is specified) + */ + String groupId = null; + String artifactId = null; + String version = null; + if (upload) { + groupId = "org.onap.policy.audit"; + artifactId = "repository-audit"; + version = "0." + System.currentTimeMillis(); + + if (repositoryUrl.toLowerCase().contains("snapshot")) { + // use SNAPSHOT version + version += "-SNAPSHOT"; + } + + // create text file to write + try (FileOutputStream fos = + new FileOutputStream(dir.resolve("repository-audit.txt").toFile())) { + fos.write(version.getBytes()); + } + + // try to install file in repository + if (runProcess(timeoutInSeconds, dir.toFile(), null, + "mvn", "deploy:deploy-file", + "-DrepositoryId=" + repositoryId, + "-Durl=" + repositoryUrl, + "-Dfile=repository-audit.txt", + "-DgroupId=" + groupId, + "-DartifactId=" + artifactId, + "-Dversion=" + version, + "-Dpackaging=txt", + "-DgeneratePom=false") != 0) { + logger.error("RepositoryAudit: 'mvn deploy:deploy-file' failed"); + if (!ignoreErrors) { + response.append("'mvn deploy:deploy-file' failed\n"); + setResponse(response.toString()); + } + } + else { + logger.info("RepositoryAudit: 'mvn deploy:deploy-file succeeded"); + + // we also want to include this new artifact in the download + // test (steps 3 and 4) + artifacts.add(new Artifact(groupId, artifactId, version, "txt")); + } + } + + /* + * 3) create 'pom.xml' file in temporary directory + */ + artifacts.add(new Artifact("org.apache.maven/maven-embedder/3.2.2")); + + StringBuilder sb = new StringBuilder(); + sb.append("<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + + " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n" + + "\n" + + " <modelVersion>4.0.0</modelVersion>\n" + + " <groupId>empty</groupId>\n" + + " <artifactId>empty</artifactId>\n" + + " <version>1.0-SNAPSHOT</version>\n" + + " <packaging>pom</packaging>\n" + + "\n" + + " <build>\n" + + " <plugins>\n" + + " <plugin>\n" + + " <groupId>org.apache.maven.plugins</groupId>\n" + + " <artifactId>maven-dependency-plugin</artifactId>\n" + + " <version>2.10</version>\n" + + " <executions>\n" + + " <execution>\n" + + " <id>copy</id>\n" + + " <goals>\n" + + " <goal>copy</goal>\n" + + " </goals>\n" + + " <configuration>\n" + + " <localRepositoryDirectory>") + .append(repo) + .append("</localRepositoryDirectory>\n") + .append(" <artifactItems>\n"); + + for (Artifact artifact : artifacts) { + // each artifact results in an 'artifactItem' element + sb.append(" <artifactItem>\n" + + " <groupId>") + .append(artifact.groupId) + .append("</groupId>\n" + + " <artifactId>") + .append(artifact.artifactId) + .append("</artifactId>\n" + + " <version>") + .append(artifact.version) + .append("</version>\n" + + " <type>") + .append(artifact.type) + .append("</type>\n" + + " </artifactItem>\n"); + } + sb.append(" </artifactItems>\n" + + " </configuration>\n" + + " </execution>\n" + + " </executions>\n" + + " </plugin>\n" + + " </plugins>\n" + + " </build>\n" + + "</project>\n"); + + try (FileOutputStream fos = new FileOutputStream(pom.toFile())) { + fos.write(sb.toString().getBytes()); + } + + /* + * 4) Invoke external 'mvn' process to do the downloads + */ + + // output file = ${dir}/out (this supports step '4a') + File output = dir.resolve("out").toFile(); + + // invoke process, and wait for response + int rval = runProcess(timeoutInSeconds, dir.toFile(), output, "mvn", "compile"); + logger.info("RepositoryAudit: 'mvn' return value = {}", rval); + if (rval != 0) { + logger.error("RepositoryAudit: 'mvn compile' invocation failed"); + if (!ignoreErrors) { + response.append("'mvn compile' invocation failed\n"); + setResponse(response.toString()); + } + } + + /* + * 4a) Check attempted and successful downloads from output file + * Note: at present, this step just generates log messages, + * but doesn't do any verification. + */ + if (rval == 0 && output != null) { + // place output in 'fileContents' (replacing the Return characters + // with Newline) + byte[] outputData = new byte[(int)output.length()]; + String fileContents; + try (FileInputStream fis = new FileInputStream(output)) { + // + // Ideally this should be in a loop or even better use + // Java 8 nio functionality. + // + int bytesRead = fis.read(outputData); + logger.info("fileContents read {} bytes", bytesRead); + fileContents = new String(outputData).replace('\r','\n'); + } + + // generate log messages from 'Downloading' and 'Downloaded' + // messages within the 'mvn' output + int index = 0; + while ((index = fileContents.indexOf("\nDown", index)) > 0) { + index += 5; + if (fileContents.regionMatches(index, "loading: ", 0, 9)) { + index += 9; + int endIndex = fileContents.indexOf('\n', index); + logger.info("RepositoryAudit: Attempted download: '{}'", + fileContents.substring(index, endIndex)); + index = endIndex; + } else if (fileContents.regionMatches(index, "loaded: ", 0, 8)) { + index += 8; + int endIndex = fileContents.indexOf(' ', index); + logger.info("RepositoryAudit: Successful download: '{}'",fileContents.substring(index, endIndex)); + index = endIndex; + } + } + } + + /* + * 5) Check the contents of the directory to make sure the downloads + * were successful + */ + for (Artifact artifact : artifacts) { + if (repo.resolve(artifact.groupId.replace('.','/')) + .resolve(artifact.artifactId) + .resolve(artifact.version) + .resolve(artifact.artifactId + "-" + artifact.version + "." + + artifact.type).toFile().exists()) { + // artifact exists, as expected + logger.info("RepositoryAudit: {} : exists", artifact.toString()); + } else { + // Audit ERROR: artifact download failed for some reason + logger.error("RepositoryAudit: {}: does not exist", artifact.toString()); + if (!ignoreErrors) { + response.append("Failed to download artifact: ") + .append(artifact).append('\n'); + setResponse(response.toString()); + } + } + } + + /* + * 6) Use 'curl' to delete the uploaded test file + * (only if repository information is specified) + */ + if (upload) { + if (runProcess(timeoutInSeconds, dir.toFile(), null, + "curl", + "--request", "DELETE", + "--user", repositoryUsername + ":" + repositoryPassword, + repositoryUrl + "/" + groupId.replace('.', '/') + "/" + + artifactId + "/" + version) + != 0) { + logger.error("RepositoryAudit: delete of uploaded artifact failed"); + if (!ignoreErrors) { + response.append("delete of uploaded artifact failed\n"); + setResponse(response.toString()); + } + } else { + logger.info("RepositoryAudit: delete of uploaded artifact succeeded"); + artifacts.add(new Artifact(groupId, artifactId, version, "txt")); + } + } + + /* + * 7) Remove the temporary directory + */ + Files.walkFileTree(dir, new RecursivelyDeleteDirectory()); + } + + /** + * Run a process, and wait for the response. + * + * @param timeoutInSeconds the number of seconds to wait for the process to terminate + * @param directory the execution directory of the process (null = current directory) + * @param stdout the file to contain the standard output (null = discard standard output) + * @param command command and arguments + * @return the return value of the process + * @throws IOException InterruptedException + */ + static int runProcess(long timeoutInSeconds, + File directory, File stdout, String... command) + throws IOException, InterruptedException { + ProcessBuilder pb = new ProcessBuilder(command); + if (directory != null) { + pb.directory(directory); + } + if (stdout != null) { + pb.redirectOutput(stdout); + } + + Process process = pb.start(); + if (process.waitFor(timeoutInSeconds, TimeUnit.SECONDS)) { + // process terminated before the timeout + return process.exitValue(); + } + + // process timed out -- kill it, and return -1 + process.destroyForcibly(); + return -1; + } + + /** + * This class is used to recursively delete a directory and all of its + * contents. + */ + private final class RecursivelyDeleteDirectory extends SimpleFileVisitor<Path> { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + file.toFile().delete(); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path file, IOException ex) + throws IOException { + if (ex == null) { + file.toFile().delete(); + return FileVisitResult.CONTINUE; + } else { + throw ex; + } + } + } + + /* ============================================================ */ + + /** + * An instance of this class exists for each artifact that we are trying + * to download. + */ + static class Artifact { + String groupId; + String artifactId; + String version; + String type; + + /** + * Constructor - populate the 'Artifact' instance. + * + * @param groupId groupId of artifact + * @param artifactId artifactId of artifact + * @param version version of artifact + * @param type type of the artifact (e.g. "jar") + */ + Artifact(String groupId, String artifactId, String version, String type) { + this.groupId = groupId; + this.artifactId = artifactId; + this.version = version; + this.type = type; + } + + /** + * Constructor - populate an 'Artifact' instance. + * + * @param artifact a string of the form: + * {@code"<groupId>/<artifactId>/<version>[/<type>]"} + * @throws IllegalArgumentException if 'artifact' has the incorrect format + */ + Artifact(String artifact) { + String[] segments = artifact.split("/"); + if (segments.length != 4 && segments.length != 3) { + throw new IllegalArgumentException("groupId/artifactId/version/type"); + } + groupId = segments[0]; + artifactId = segments[1]; + version = segments[2]; + type = segments.length == 4 ? segments[3] : "jar"; + } + + /** + * Returns string representation. + * + * @return the artifact id in the form: {@code"<groupId>/<artifactId>/<version>/<type>"} + */ + @Override + public String toString() { + return groupId + "/" + artifactId + "/" + version + "/" + type; + } + } } diff --git a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/StateManagementFeature.java b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/StateManagementFeature.java index cb1700e4..d7f9d108 100644 --- a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/StateManagementFeature.java +++ b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/StateManagementFeature.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * feature-state-management * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,227 +38,218 @@ import org.slf4j.LoggerFactory; * active/standby state management and IntegrityMonitor. For now, they are * all treated as a single feature, but it would be nice to separate them. * - * The bulk of the code here was once in other classes, such as + * <p>The bulk of the code here was once in other classes, such as * 'PolicyContainer' and 'Main'. It was moved here as part of making this * a separate optional feature. */ public class StateManagementFeature implements StateManagementFeatureAPI, - PolicySessionFeatureAPI, PolicyEngineFeatureAPI -{ - // get an instance of logger - private static final Logger logger = - LoggerFactory.getLogger(StateManagementFeature.class); - - private DroolsPDPIntegrityMonitor droolsPdpIntegrityMonitor = null; - private StateManagement stateManagement = null; - - /**************************/ - /* 'FeatureAPI' interface */ - /**************************/ - - public StateManagementFeature(){ - logger.debug("StateManagementFeature() constructor"); - } - - @Override - public void globalInit(String[] args, String configDir) - { - // Initialization code associated with 'PolicyContainer' - logger.debug("StateManagementFeature.globalInit({}) entry", configDir); - - try - { - droolsPdpIntegrityMonitor = DroolsPDPIntegrityMonitor.init(configDir); - } - catch (Exception e) - { - logger.debug("DroolsPDPIntegrityMonitor initialization exception: ", e); - logger.error("DroolsPDPIntegrityMonitor.init()", e); - } - - initializeProperties(configDir); - - //At this point the DroolsPDPIntegrityMonitor instance must exist. Let's check it. - try { - droolsPdpIntegrityMonitor = DroolsPDPIntegrityMonitor.getInstance(); - stateManagement = droolsPdpIntegrityMonitor.getStateManager(); - - if (stateManagement == null) { - logger.debug("StateManagementFeature.globalInit(): stateManagement is NULL!"); - } - else { - logger.debug("StateManagementFeature.globalInit(): " - + "stateManagement.getAdminState(): {}", stateManagement.getAdminState()); - } - } catch (Exception e1) { - logger.debug("StateManagementFeature.globalInit(): DroolsPDPIntegrityMonitor" - + " initialization failed with exception:", e1); - logger.error("DroolsPDPIntegrityMonitor.init(): StateManagementFeature startup failed " - + "to get DroolsPDPIntegrityMonitor instance:", e1); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void addObserver(Observer stateChangeObserver) { - logger.debug("StateManagementFeature.addObserver() entry\n" - + "StateManagementFeature.addObserver(): " - + "stateManagement.getAdminState(): {}", stateManagement.getAdminState()); - - stateManagement.addObserver(stateChangeObserver); - - logger.debug("StateManagementFeature.addObserver() exit"); - } - - /** - * {@inheritDoc} - */ - @Override - public String getAdminState() { - return stateManagement.getAdminState(); - } - - /** - * {@inheritDoc} - */ - @Override - public String getOpState() { - return stateManagement.getOpState(); - } - - /** - * {@inheritDoc} - */ - @Override - public String getAvailStatus() { - return stateManagement.getAvailStatus(); - } - - /** - * {@inheritDoc} - */ - @Override - public String getStandbyStatus() { - return stateManagement.getStandbyStatus(); - } - - /** - * {@inheritDoc} - */ - @Override - public String getStandbyStatus(String resourceName) { - return stateManagement.getStandbyStatus(resourceName); - } - - /** - * {@inheritDoc} - */ - @Override - public void disableFailed(String resourceName) throws Exception { - stateManagement.disableFailed(resourceName); - - } - - /** - * {@inheritDoc} - */ - @Override - public void disableFailed() throws Exception { - stateManagement.disableFailed(); - } - - /** - * {@inheritDoc} - */ - @Override - public void promote() throws Exception { - stateManagement.promote(); - } - - /** - * {@inheritDoc} - */ - @Override - public void demote() throws Exception { - stateManagement.demote(); - } - - /** - * {@inheritDoc} - */ - @Override - public String getResourceName() { - return StateManagementProperties.getProperty(StateManagementProperties.NODE_NAME); - } - - /** - * {@inheritDoc} - * @return - */ - @Override - public boolean lock(){ - try{ - stateManagement.lock(); - }catch(Exception e){ - logger.error("StateManagementFeature.lock() failed with exception: {}", e); - return false; - } - return true; - } - - /** - * {@inheritDoc} - * @throws Exception - */ - @Override - public boolean unlock(){ - try{ - stateManagement.unlock(); - }catch(Exception e){ - logger.error("StateManagementFeature.unlock() failed with exception: {}", e); - return false; - } - return true; - } - - /** - * {@inheritDoc} - * @throws Exception - */ - @Override - public boolean isLocked(){ - return StateManagement.LOCKED.equals(stateManagement.getAdminState()); - } - - @Override - public int getSequenceNumber() { - return SEQ_NUM; - } - - /** - * Read in the properties and initialize the StateManagementProperties. - */ - private static void initializeProperties(String configDir) - { - //Get the state management properties - try { - Properties pIm = - PropertyUtil.getProperties(configDir + "/feature-state-management.properties"); - StateManagementProperties.initProperties(pIm); - logger.info("initializeProperties: resourceName= {}", StateManagementProperties.getProperty(StateManagementProperties.NODE_NAME)); - } catch (IOException e1) { - logger.error("initializeProperties", e1); - } - } - - @Override - public void allSeemsWell(String key, Boolean asw, String msg) - throws AllSeemsWellException { - - droolsPdpIntegrityMonitor.allSeemsWell(key, asw, msg); - - } + PolicySessionFeatureAPI, PolicyEngineFeatureAPI { + // get an instance of logger + private static final Logger logger = + LoggerFactory.getLogger(StateManagementFeature.class); + + private DroolsPDPIntegrityMonitor droolsPdpIntegrityMonitor = null; + private StateManagement stateManagement = null; + + public StateManagementFeature() { + logger.debug("StateManagementFeature() constructor"); + } + + @Override + public void globalInit(String[] args, String configDir) { + // Initialization code associated with 'PolicyContainer' + logger.debug("StateManagementFeature.globalInit({}) entry", configDir); + + try { + droolsPdpIntegrityMonitor = DroolsPDPIntegrityMonitor.init(configDir); + } catch (Exception e) { + logger.debug("DroolsPDPIntegrityMonitor initialization exception: ", e); + logger.error("DroolsPDPIntegrityMonitor.init()", e); + } + + initializeProperties(configDir); + + //At this point the DroolsPDPIntegrityMonitor instance must exist. Let's check it. + try { + droolsPdpIntegrityMonitor = DroolsPDPIntegrityMonitor.getInstance(); + stateManagement = droolsPdpIntegrityMonitor.getStateManager(); + + if (stateManagement == null) { + logger.debug("StateManagementFeature.globalInit(): stateManagement is NULL!"); + } + else { + logger.debug("StateManagementFeature.globalInit(): " + + "stateManagement.getAdminState(): {}", stateManagement.getAdminState()); + } + } catch (Exception e1) { + logger.debug("StateManagementFeature.globalInit(): DroolsPDPIntegrityMonitor" + + " initialization failed with exception:", e1); + logger.error("DroolsPDPIntegrityMonitor.init(): StateManagementFeature startup failed " + + "to get DroolsPDPIntegrityMonitor instance:", e1); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void addObserver(Observer stateChangeObserver) { + logger.debug("StateManagementFeature.addObserver() entry\n" + + "StateManagementFeature.addObserver(): " + + "stateManagement.getAdminState(): {}", stateManagement.getAdminState()); + + stateManagement.addObserver(stateChangeObserver); + + logger.debug("StateManagementFeature.addObserver() exit"); + } + + /** + * {@inheritDoc} + */ + @Override + public String getAdminState() { + return stateManagement.getAdminState(); + } + + /** + * {@inheritDoc} + */ + @Override + public String getOpState() { + return stateManagement.getOpState(); + } + + /** + * {@inheritDoc} + */ + @Override + public String getAvailStatus() { + return stateManagement.getAvailStatus(); + } + + /** + * {@inheritDoc} + */ + @Override + public String getStandbyStatus() { + return stateManagement.getStandbyStatus(); + } + + /** + * {@inheritDoc} + */ + @Override + public String getStandbyStatus(String resourceName) { + return stateManagement.getStandbyStatus(resourceName); + } + + /** + * {@inheritDoc} + */ + @Override + public void disableFailed(String resourceName) throws Exception { + stateManagement.disableFailed(resourceName); + + } + + /** + * {@inheritDoc} + */ + @Override + public void disableFailed() throws Exception { + stateManagement.disableFailed(); + } + + /** + * {@inheritDoc} + */ + @Override + public void promote() throws Exception { + stateManagement.promote(); + } + + /** + * {@inheritDoc} + */ + @Override + public void demote() throws Exception { + stateManagement.demote(); + } + + /** + * {@inheritDoc} + */ + @Override + public String getResourceName() { + return StateManagementProperties.getProperty(StateManagementProperties.NODE_NAME); + } + + /** + * {@inheritDoc} + * @return + */ + @Override + public boolean lock() { + try { + stateManagement.lock(); + } catch (Exception e) { + logger.error("StateManagementFeature.lock() failed with exception: {}", e); + return false; + } + return true; + } + + /** + * {@inheritDoc} + * @throws Exception exception + */ + @Override + public boolean unlock() { + try { + stateManagement.unlock(); + } catch (Exception e) { + logger.error("StateManagementFeature.unlock() failed with exception: {}", e); + return false; + } + return true; + } + + /** + * {@inheritDoc} + * @throws Exception exception + */ + @Override + public boolean isLocked() { + return StateManagement.LOCKED.equals(stateManagement.getAdminState()); + } + + @Override + public int getSequenceNumber() { + return SEQ_NUM; + } + + /** + * Read in the properties and initialize the StateManagementProperties. + */ + private static void initializeProperties(String configDir) { + //Get the state management properties + try { + Properties props = + PropertyUtil.getProperties(configDir + "/feature-state-management.properties"); + StateManagementProperties.initProperties(props); + logger.info("initializeProperties: resourceName= {}", + StateManagementProperties.getProperty(StateManagementProperties.NODE_NAME)); + } catch (IOException e1) { + logger.error("initializeProperties", e1); + } + } + + @Override + public void allSeemsWell(String key, Boolean asw, String msg) + throws AllSeemsWellException { + + droolsPdpIntegrityMonitor.allSeemsWell(key, asw, msg); + + } } diff --git a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/StateManagementProperties.java b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/StateManagementProperties.java index 38356226..471745d4 100644 --- a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/StateManagementProperties.java +++ b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/StateManagementProperties.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * feature-state-management * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,15 +65,16 @@ public class StateManagementProperties { private StateManagementProperties() {} - /* - * Initialize the parameter values from the feature-state-management.properties file values + /** + * Initialize the parameter values from the feature-state-management.properties file values. * - * This is designed so that the Properties object is obtained from the + * <p>This is designed so that the Properties object is obtained from the * feature-state-management.properties file and then is passed to this method to initialize the * value of the parameters. This allows the flexibility of JUnit tests using * getProperties(filename) to get the properties while runtime methods can use * getPropertiesFromClassPath(filename). * + * @param prop properties */ public static void initProperties(Properties prop) { logger.info("StateManagementProperties.initProperties(Properties): entry"); diff --git a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/StateManagementPropertiesException.java b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/StateManagementPropertiesException.java index 59802ebd..a88bcf25 100644 --- a/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/StateManagementPropertiesException.java +++ b/feature-state-management/src/main/java/org/onap/policy/drools/statemanagement/StateManagementPropertiesException.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * Feature-State-Management * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,22 +20,23 @@ package org.onap.policy.drools.statemanagement; -public class StateManagementPropertiesException extends Exception{ - private static final long serialVersionUID = 1L; - - public StateManagementPropertiesException() { - super(); - } - - public StateManagementPropertiesException(String message) { - super(message); - } +public class StateManagementPropertiesException extends Exception { + private static final long serialVersionUID = 1L; - public StateManagementPropertiesException(Throwable cause) { - super(cause); - } - public StateManagementPropertiesException(String message, Throwable cause) { - super(message, cause); - } + public StateManagementPropertiesException() { + super(); + } + + public StateManagementPropertiesException(String message) { + super(message); + } + + public StateManagementPropertiesException(Throwable cause) { + super(cause); + } + + public StateManagementPropertiesException(String message, Throwable cause) { + super(message, cause); + } } |