10a775c522a63e6094785dc5503d568d9309eb28
[appc.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * APPC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright (C) 2017 Amdocs
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  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  */
22
23 package org.openecomp.appc.workingstatemanager.impl;
24
25 import java.sql.Connection;
26 import java.sql.PreparedStatement;
27 import java.sql.ResultSet;
28 import java.sql.SQLException;
29 import java.util.Map;
30 import java.util.concurrent.ConcurrentHashMap;
31
32 import org.apache.commons.lang.ObjectUtils;
33 import org.apache.commons.lang3.StringUtils;
34 import org.openecomp.appc.configuration.ConfigurationFactory;
35 import org.openecomp.appc.executor.objects.Params;
36 import org.openecomp.appc.message.RequestHandlerMessages;
37 import org.openecomp.appc.util.MessageFormatter;
38 import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState;
39 import org.openecomp.appc.workingstatemanager.objects.VnfWorkingStateDto;
40 import com.att.eelf.configuration.EELFLogger;
41 import com.att.eelf.configuration.EELFManager;
42 import org.apache.commons.lang3.StringUtils;
43
44
45 public class WorkingStateManagerImpl extends JdbcWorkingStateManager {
46
47     private static final String SQL_RETRIEVE_VNF_STATE_MANAGEMENT = "SELECT VNF_ID,STATE,OWNER_ID,UPDATED,VER FROM VNF_STATE_MANAGEMENT WHERE VNF_ID=?";
48     private static final String SQL_INSERT_VNF_STATE_MANAGEMENT = "INSERT IGNORE INTO VNF_STATE_MANAGEMENT (VNF_ID,STATE,OWNER_ID,UPDATED,VER) VALUES (?, ?, ?, ?, ?)";
49     private static final String SQL_UPDATE_VNF_STATE_MANAGEMENT = "UPDATE VNF_STATE_MANAGEMENT SET OWNER_ID=?, UPDATED=?, STATE=?, VER=? WHERE VNF_ID=? AND VER=?";
50     private static final String SQL_CURRENT_TIMESTAMP = "SELECT CURRENT_TIMESTAMP()";
51     private static int maxAttempts = ConfigurationFactory.getConfiguration().getIntegerProperty("org.openecomp.appc.workingstatemanager.maxAttempts",20);
52
53     private static Map<String,VNFWorkingState> workingStateMap = new ConcurrentHashMap<>();
54     private static final EELFLogger logger = EELFManager.getInstance().getLogger(WorkingStateManagerImpl.class);
55
56
57     /**
58      * 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.
59      * @param vnfId vnf Id to be verified for stable state
60      * @return True if vnf Exists and state is STABLE else False.
61      */
62     @Override
63     public boolean isVNFStable(String vnfId){
64         if (logger.isTraceEnabled()) {
65             logger.trace("Entering to isVNFStable with vnfId = "+ vnfId);
66         }
67         Connection connection = null;
68         boolean vnfStable = false;
69         try {
70             connection = openDbConnection();
71             VnfWorkingStateDto vnfWorkingStateDto = retrieveVnfWorkingState(connection, vnfId);
72             vnfStable = isVNFStable(vnfWorkingStateDto);
73         } catch (SQLException e) {
74             String errMsg = StringUtils.isEmpty(e.getMessage())? e.toString() :e.getMessage();
75             throw new RuntimeException(errMsg);
76         } finally {
77             if(connection != null) {
78                 closeDbConnection(connection);
79         }
80         }
81         if (logger.isTraceEnabled()) {
82             logger.trace("Exiting from isVNFStable for vnfId = "+ vnfId+" with Result = "+vnfStable);
83         }
84         return vnfStable;
85     }
86
87     /**
88      * 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
89      * if the registered ownerId is equal to the given ownerId or if the forceFlag is true.
90      * 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.
91      * @param vnfId vnf Id to be updated
92      * @param workingState new working state
93      * @param ownerId
94      * @param forceFlag - force to update also on case given onwerId is different then the registered one
95      */
96     @Override
97     public boolean setWorkingState(String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag){
98         boolean updated = false;
99         if (logger.isTraceEnabled()) {
100             logger.trace("Entering to setWorkingState with vnfId = "+ ObjectUtils.toString(vnfId)+ ", VNFWorkingState = " +  workingState.name() + ", ownerId = "+ownerId+", forceFlag = "+forceFlag);
101         }
102         Connection connection = null;
103         try {
104             connection = openDbConnection();
105             updated = setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag, maxAttempts);
106         } catch (SQLException e) {
107             String errMsg = StringUtils.isEmpty(e.getMessage())? e.toString() :e.getMessage();
108             throw new RuntimeException(errMsg);
109         } finally {
110             if(connection != null) {
111                 closeDbConnection(connection);
112             }
113         }
114
115         logger.trace("setWorkingState exit with output updated = "+updated);
116         return updated;
117     }
118
119     public boolean setWorkingStateIfStableOrSameOwnerIdOrForce(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag, int maxAttempts) throws SQLException {
120         return setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag,1,maxAttempts);
121     }
122     public boolean setWorkingStateIfStableOrSameOwnerIdOrForce(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag,int attempt, int maxAttempts) throws SQLException {
123         boolean updated = false;
124         VnfWorkingStateDto vnfWorkingStateDto = retrieveVnfWorkingState(connection, vnfId);
125         Long currentVersion = vnfWorkingStateDto != null ? vnfWorkingStateDto.getVer() : null;
126         if(forceFlag || isVNFStable(vnfWorkingStateDto) || vnfWorkingStateDto.getOwnerId().equals(ownerId)){
127             updated = storeWorkingStateIfSameVersion(connection, vnfId, workingState, ownerId, currentVersion);
128
129             Params params = new Params().addParam("vnfId", vnfId).addParam("workingState",workingState.name())
130                     .addParam("attempt",attempt).addParam("maxAttempts",maxAttempts).addParam("ownerId",ownerId).addParam("forceFlag",forceFlag);
131             String logMessage;
132             if(updated) {
133                 logMessage = MessageFormatter.format(RequestHandlerMessages.VNF_WORKING_STATE_UPDATED, params.getParams());
134             }else {
135                 logMessage = MessageFormatter.format(RequestHandlerMessages.VNF_WORKING_STATE_WAS_NOT_UPDATED, params.getParams());
136             }
137             logger.debug(logMessage);
138             if(!updated && attempt<maxAttempts){
139                 setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag,++attempt,maxAttempts);
140             }
141
142         }
143         return updated;
144     }
145
146
147     public boolean storeWorkingStateIfSameVersion(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, Long currentVersion) throws SQLException {
148         boolean stored = false;
149         if (currentVersion != null) {
150             stored = updateStateIfSameVersion(connection, vnfId, ownerId, workingState.name(), currentVersion);
151         } else {
152             stored = addVnfWorkingStateIfNotExists(connection, vnfId, ownerId, workingState.name());
153         }
154
155         return stored;
156     }
157
158     private boolean isVNFStable(VnfWorkingStateDto vnfWorkingStateDto) {
159         if( vnfWorkingStateDto == null || vnfWorkingStateDto.getState() ==VNFWorkingState.STABLE){
160             return true;
161         }
162         return false;
163     }
164
165     public boolean updateStateIfSameVersion(Connection connection, String vnfId, String ownerId, String state, long currentVer) throws SQLException {
166         try(PreparedStatement statement = connection.prepareStatement(SQL_UPDATE_VNF_STATE_MANAGEMENT)) {
167             long newVer = (currentVer >= Long.MAX_VALUE) ? 1 : (currentVer + 1);
168             statement.setString(1, ownerId);
169             statement.setLong(2, getCurrentTime(connection));
170             statement.setString(3, state);
171             statement.setLong(4, newVer);
172             statement.setString(5, vnfId);
173             statement.setLong(6, currentVer);
174             return (statement.executeUpdate() != 0);
175         }
176     }
177
178     protected VnfWorkingStateDto retrieveVnfWorkingState(Connection connection, String vnfId) throws SQLException {
179         VnfWorkingStateDto res = null;
180
181         try(PreparedStatement statement = connection.prepareStatement(SQL_RETRIEVE_VNF_STATE_MANAGEMENT)) { //VNF_ID,STATE,OWNER_ID,UPDATED,VER
182             statement.setString(1, vnfId);
183             try(ResultSet resultSet = statement.executeQuery()) {
184                 if(resultSet.next()) {
185                     res = new VnfWorkingStateDto(vnfId);
186                     String stateString = resultSet.getString(2);
187                     VNFWorkingState vnfWorkingState = VNFWorkingState.valueOf(stateString);
188                     res.setState(vnfWorkingState);
189                     res.setOwnerId(resultSet.getString(3));
190                     res.setUpdated(resultSet.getLong(4));
191                     res.setVer(resultSet.getLong(5));
192                 }
193             }
194         }
195         return res;
196     }
197
198     private long getCurrentTime(Connection connection) throws SQLException {
199         long res = -1;
200         if(connection != null) {
201             try(PreparedStatement statement = connection.prepareStatement(SQL_CURRENT_TIMESTAMP)) {
202                 try(ResultSet resultSet = statement.executeQuery()) {
203                     if(resultSet.next()) {
204                         res = resultSet.getTimestamp(1).getTime();
205                     }
206                 }
207             }
208         }
209         if(res == -1) {
210             res = System.currentTimeMillis();
211         }
212         return res;
213         }
214
215     protected boolean addVnfWorkingStateIfNotExists(Connection connection, String vnfId, String ownerId, String state) throws SQLException {
216         boolean added = false;
217         try(PreparedStatement statement = connection.prepareStatement(SQL_INSERT_VNF_STATE_MANAGEMENT)) { //VNF_ID,STATE,OWNER_ID,UPDATED,VER
218             statement.setString(1, vnfId);
219             statement.setString(2, state);
220             statement.setString(3, ownerId);
221             statement.setLong(4, getCurrentTime(connection));
222             statement.setLong(5, 1L);
223             int rowCount = statement.executeUpdate();
224             added = rowCount != 0 ? true : false;
225         }
226         return added;
227     }
228 }