2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
 
   7  * ================================================================================
 
   8  * Licensed under the Apache License, Version 2.0 (the "License");
 
   9  * you may not use this file except in compliance with the License.
 
  10  * You may obtain a copy of the License at
 
  12  *      http://www.apache.org/licenses/LICENSE-2.0
 
  14  * Unless required by applicable law or agreed to in writing, software
 
  15  * distributed under the License is distributed on an "AS IS" BASIS,
 
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  17  * See the License for the specific language governing permissions and
 
  18  * limitations under the License.
 
  19  * ============LICENSE_END=========================================================
 
  22 package org.openecomp.appc.workingstatemanager.impl;
 
  24 import java.sql.Connection;
 
  25 import java.sql.PreparedStatement;
 
  26 import java.sql.ResultSet;
 
  27 import java.sql.SQLException;
 
  29 import java.util.concurrent.ConcurrentHashMap;
 
  31 import org.apache.commons.lang.ObjectUtils;
 
  32 import org.apache.commons.lang3.StringUtils;
 
  33 import org.openecomp.appc.configuration.ConfigurationFactory;
 
  34 import org.openecomp.appc.executor.objects.Params;
 
  35 import org.openecomp.appc.message.RequestHandlerMessages;
 
  36 import org.openecomp.appc.util.MessageFormatter;
 
  37 import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState;
 
  38 import org.openecomp.appc.workingstatemanager.objects.VnfWorkingStateDto;
 
  39 import com.att.eelf.configuration.EELFLogger;
 
  40 import com.att.eelf.configuration.EELFManager;
 
  41 import org.apache.commons.lang3.StringUtils;
 
  44 public class WorkingStateManagerImpl extends JdbcWorkingStateManager {
 
  46     private static final String SQL_RETRIEVE_VNF_STATE_MANAGEMENT = "SELECT VNF_ID,STATE,OWNER_ID,UPDATED,VER FROM VNF_STATE_MANAGEMENT WHERE VNF_ID=?";
 
  47     private static final String SQL_INSERT_VNF_STATE_MANAGEMENT = "INSERT IGNORE INTO VNF_STATE_MANAGEMENT (VNF_ID,STATE,OWNER_ID,UPDATED,VER) VALUES (?, ?, ?, ?, ?)";
 
  48     private static final String SQL_UPDATE_VNF_STATE_MANAGEMENT = "UPDATE VNF_STATE_MANAGEMENT SET OWNER_ID=?, UPDATED=?, STATE=?, VER=? WHERE VNF_ID=? AND VER=?";
 
  49     private static final String SQL_CURRENT_TIMESTAMP = "SELECT CURRENT_TIMESTAMP()";
 
  50     private static int maxAttempts = ConfigurationFactory.getConfiguration().getIntegerProperty("org.openecomp.appc.workingstatemanager.maxAttempts",20);
 
  52     private static Map<String,VNFWorkingState> workingStateMap = new ConcurrentHashMap<>();
 
  53     private static final EELFLogger logger = EELFManager.getInstance().getLogger(WorkingStateManagerImpl.class);
 
  57      * Return true if vnf state exists in working state map and state is STABLE else return false. If vnf does not exists in working state map throws vnf not found  exception.
 
  58      * @param vnfId vnf Id to be verified for stable state
 
  59      * @return True if vnf Exists and state is STABLE else False.
 
  62     public boolean isVNFStable(String vnfId){
 
  63         if (logger.isTraceEnabled()) {
 
  64             logger.trace("Entering to isVNFStable with vnfId = "+ vnfId);
 
  66         Connection connection = null;
 
  67         boolean vnfStable = false;
 
  69             connection = openDbConnection();
 
  70             VnfWorkingStateDto vnfWorkingStateDto = retrieveVnfWorkingState(connection, vnfId);
 
  71             vnfStable = isVNFStable(vnfWorkingStateDto);
 
  72         } catch (SQLException e) {
 
  73             String errMsg = StringUtils.isEmpty(e.getMessage())? e.toString() :e.getMessage();
 
  74             throw new RuntimeException(errMsg);
 
  76             if(connection != null) {
 
  77                 closeDbConnection(connection);
 
  80         if (logger.isTraceEnabled()) {
 
  81             logger.trace("Exiting from isVNFStable for vnfId = "+ vnfId+" with Result = "+vnfStable);
 
  87      * Updates working state for given vnf Id. Returns true if update was allowed and succeeded. Update will success only if the existing vnf state is 'STABLE' or
 
  88      * if the registered ownerId is equal to the given ownerId or if the forceFlag is true.
 
  89      * Note on case of simultaneously updates the latest updates will be failed, and another attempts will be done after refetching the updated data from persistent store.
 
  90      * @param vnfId vnf Id to be updated
 
  91      * @param workingState new working state
 
  93      * @param forceFlag - force to update also on case given onwerId is different then the registered one
 
  96     public boolean setWorkingState(String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag){
 
  97         boolean updated = false;
 
  98         if (logger.isTraceEnabled()) {
 
  99             logger.trace("Entering to setWorkingState with vnfId = "+ ObjectUtils.toString(vnfId)+ ", VNFWorkingState = " +  workingState.name() + ", ownerId = "+ownerId+", forceFlag = "+forceFlag);
 
 101         Connection connection = null;
 
 103             connection = openDbConnection();
 
 104             updated = setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag, maxAttempts);
 
 105         } catch (SQLException e) {
 
 106             String errMsg = StringUtils.isEmpty(e.getMessage())? e.toString() :e.getMessage();
 
 107             throw new RuntimeException(errMsg);
 
 109             if(connection != null) {
 
 110                 closeDbConnection(connection);
 
 114         logger.trace("setWorkingState exit with output updated = "+updated);
 
 118     public boolean setWorkingStateIfStableOrSameOwnerIdOrForce(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag, int maxAttempts) throws SQLException {
 
 119         return setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag,1,maxAttempts);
 
 121     public boolean setWorkingStateIfStableOrSameOwnerIdOrForce(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag,int attempt, int maxAttempts) throws SQLException {
 
 122         boolean updated = false;
 
 123         VnfWorkingStateDto vnfWorkingStateDto = retrieveVnfWorkingState(connection, vnfId);
 
 124         Long currentVersion = vnfWorkingStateDto != null ? vnfWorkingStateDto.getVer() : null;
 
 125         if(forceFlag || isVNFStable(vnfWorkingStateDto) || vnfWorkingStateDto.getOwnerId().equals(ownerId)){
 
 126             updated = storeWorkingStateIfSameVersion(connection, vnfId, workingState, ownerId, currentVersion);
 
 128             Params params = new Params().addParam("vnfId", vnfId).addParam("workingState",workingState.name())
 
 129                     .addParam("attempt",attempt).addParam("maxAttempts",maxAttempts).addParam("ownerId",ownerId).addParam("forceFlag",forceFlag);
 
 132                 logMessage = MessageFormatter.format(RequestHandlerMessages.VNF_WORKING_STATE_UPDATED, params.getParams());
 
 134                 logMessage = MessageFormatter.format(RequestHandlerMessages.VNF_WORKING_STATE_WAS_NOT_UPDATED, params.getParams());
 
 136             logger.debug(logMessage);
 
 137             if(!updated && attempt<maxAttempts){
 
 138                 setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag,++attempt,maxAttempts);
 
 146     public boolean storeWorkingStateIfSameVersion(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, Long currentVersion) throws SQLException {
 
 147         boolean stored = false;
 
 148         if (currentVersion != null) {
 
 149             stored = updateStateIfSameVersion(connection, vnfId, ownerId, workingState.name(), currentVersion);
 
 151             stored = addVnfWorkingStateIfNotExists(connection, vnfId, ownerId, workingState.name());
 
 157     private boolean isVNFStable(VnfWorkingStateDto vnfWorkingStateDto) {
 
 158         if( vnfWorkingStateDto == null || vnfWorkingStateDto.getState() ==VNFWorkingState.STABLE){
 
 164     public boolean updateStateIfSameVersion(Connection connection, String vnfId, String ownerId, String state, long currentVer) throws SQLException {
 
 165         try(PreparedStatement statement = connection.prepareStatement(SQL_UPDATE_VNF_STATE_MANAGEMENT)) {
 
 166             long newVer = (currentVer >= Long.MAX_VALUE) ? 1 : (currentVer + 1);
 
 167             statement.setString(1, ownerId);
 
 168             statement.setLong(2, getCurrentTime(connection));
 
 169             statement.setString(3, state);
 
 170             statement.setLong(4, newVer);
 
 171             statement.setString(5, vnfId);
 
 172             statement.setLong(6, currentVer);
 
 173             return (statement.executeUpdate() != 0);
 
 177     protected VnfWorkingStateDto retrieveVnfWorkingState(Connection connection, String vnfId) throws SQLException {
 
 178         VnfWorkingStateDto res = null;
 
 180         try(PreparedStatement statement = connection.prepareStatement(SQL_RETRIEVE_VNF_STATE_MANAGEMENT)) { //VNF_ID,STATE,OWNER_ID,UPDATED,VER
 
 181             statement.setString(1, vnfId);
 
 182             try(ResultSet resultSet = statement.executeQuery()) {
 
 183                 if(resultSet.next()) {
 
 184                     res = new VnfWorkingStateDto(vnfId);
 
 185                     String stateString = resultSet.getString(2);
 
 186                     VNFWorkingState vnfWorkingState = VNFWorkingState.valueOf(stateString);
 
 187                     res.setState(vnfWorkingState);
 
 188                     res.setOwnerId(resultSet.getString(3));
 
 189                     res.setUpdated(resultSet.getLong(4));
 
 190                     res.setVer(resultSet.getLong(5));
 
 197     private long getCurrentTime(Connection connection) throws SQLException {
 
 199         if(connection != null) {
 
 200             try(PreparedStatement statement = connection.prepareStatement(SQL_CURRENT_TIMESTAMP)) {
 
 201                 try(ResultSet resultSet = statement.executeQuery()) {
 
 202                     if(resultSet.next()) {
 
 203                         res = resultSet.getTimestamp(1).getTime();
 
 209             res = System.currentTimeMillis();
 
 214     protected boolean addVnfWorkingStateIfNotExists(Connection connection, String vnfId, String ownerId, String state) throws SQLException {
 
 215         boolean added = false;
 
 216         try(PreparedStatement statement = connection.prepareStatement(SQL_INSERT_VNF_STATE_MANAGEMENT)) { //VNF_ID,STATE,OWNER_ID,UPDATED,VER
 
 217             statement.setString(1, vnfId);
 
 218             statement.setString(2, state);
 
 219             statement.setString(3, ownerId);
 
 220             statement.setLong(4, getCurrentTime(connection));
 
 221             statement.setLong(5, 1L);
 
 222             int rowCount = statement.executeUpdate();
 
 223             added = rowCount != 0 ? true : false;