Moving all files to root directory
[appc.git] / appc-dispatcher / appc-request-handler / appc-request-handler-core / src / main / java / org / openecomp / appc / workingstatemanager / impl / WorkingStateManagerImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : APP-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              reserved.
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
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
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=========================================================
20  */
21
22 package org.openecomp.appc.workingstatemanager.impl;
23
24 import java.sql.Connection;
25 import java.sql.PreparedStatement;
26 import java.sql.ResultSet;
27 import java.sql.SQLException;
28 import java.util.Map;
29 import java.util.concurrent.ConcurrentHashMap;
30
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;
42
43
44 public class WorkingStateManagerImpl extends JdbcWorkingStateManager {
45
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);
51
52     private static Map<String,VNFWorkingState> workingStateMap = new ConcurrentHashMap<>();
53     private static final EELFLogger logger = EELFManager.getInstance().getLogger(WorkingStateManagerImpl.class);
54
55
56     /**
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.
60      */
61     @Override
62     public boolean isVNFStable(String vnfId){
63         if (logger.isTraceEnabled()) {
64             logger.trace("Entering to isVNFStable with vnfId = "+ vnfId);
65         }
66         Connection connection = null;
67         boolean vnfStable = false;
68         try {
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);
75         } finally {
76             if(connection != null) {
77                 closeDbConnection(connection);
78         }
79         }
80         if (logger.isTraceEnabled()) {
81             logger.trace("Exiting from isVNFStable for vnfId = "+ vnfId+" with Result = "+vnfStable);
82         }
83         return vnfStable;
84     }
85
86     /**
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
92      * @param ownerId
93      * @param forceFlag - force to update also on case given onwerId is different then the registered one
94      */
95     @Override
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);
100         }
101         Connection connection = null;
102         try {
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);
108         } finally {
109             if(connection != null) {
110                 closeDbConnection(connection);
111             }
112         }
113
114         logger.trace("setWorkingState exit with output updated = "+updated);
115         return updated;
116     }
117
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);
120     }
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);
127
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);
130             String logMessage;
131             if(updated) {
132                 logMessage = MessageFormatter.format(RequestHandlerMessages.VNF_WORKING_STATE_UPDATED, params.getParams());
133             }else {
134                 logMessage = MessageFormatter.format(RequestHandlerMessages.VNF_WORKING_STATE_WAS_NOT_UPDATED, params.getParams());
135             }
136             logger.debug(logMessage);
137             if(!updated && attempt<maxAttempts){
138                 setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag,++attempt,maxAttempts);
139             }
140
141         }
142         return updated;
143     }
144
145
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);
150         } else {
151             stored = addVnfWorkingStateIfNotExists(connection, vnfId, ownerId, workingState.name());
152         }
153
154         return stored;
155     }
156
157     private boolean isVNFStable(VnfWorkingStateDto vnfWorkingStateDto) {
158         if( vnfWorkingStateDto == null || vnfWorkingStateDto.getState() ==VNFWorkingState.STABLE){
159             return true;
160         }
161         return false;
162     }
163
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);
174         }
175     }
176
177     protected VnfWorkingStateDto retrieveVnfWorkingState(Connection connection, String vnfId) throws SQLException {
178         VnfWorkingStateDto res = null;
179
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));
191                 }
192             }
193         }
194         return res;
195     }
196
197     private long getCurrentTime(Connection connection) throws SQLException {
198         long res = -1;
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();
204                     }
205                 }
206             }
207         }
208         if(res == -1) {
209             res = System.currentTimeMillis();
210         }
211         return res;
212         }
213
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;
224         }
225         return added;
226     }
227 }