Change code in appc dispatcher for new LCMs in R6
[appc.git] / appc-dispatcher / appc-dispatcher-common / transaction-recorder / src / test / java / org / onap / appc / transactionrecorder / impl / TransactionRecorderImplTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * ================================================================================
9  * Modifications Copyright (C) 2019 Ericsson
10  * =============================================================================
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.onap.appc.transactionrecorder.impl;
26
27 import com.sun.rowset.CachedRowSetImpl;
28 import org.junit.After;
29 import org.junit.Assert;
30 import org.junit.Before;
31 import org.junit.Rule;
32 import org.junit.Test;
33 import org.junit.rules.ExpectedException;
34 import org.mockito.Mockito;
35
36 import static org.mockito.Matchers.anyObject;
37 import static org.mockito.Matchers.anyString;
38 import static org.hamcrest.CoreMatchers.isA;
39
40 import org.onap.appc.dao.util.dbcp.DBConnectionPool;
41 import org.onap.appc.dao.util.helper.DBHelper;
42 import org.onap.appc.domainmodel.lcm.Flags;
43 import org.onap.appc.domainmodel.lcm.RequestStatus;
44 import org.onap.appc.domainmodel.lcm.TransactionRecord;
45 import org.onap.appc.domainmodel.lcm.VNFOperation;
46 import org.onap.appc.exceptions.APPCException;
47 import org.onap.appc.transactionrecorder.objects.TransactionConstants;
48 import org.onap.appc.transactionrecorder.objects.TransactionConstants.TRANSACTION_ATTRIBUTES;
49 import org.onap.ccsdk.sli.core.dblib.DbLibService;
50
51 import javax.sql.rowset.CachedRowSet;
52 import java.sql.Connection;
53 import java.sql.PreparedStatement;
54 import java.sql.ResultSet;
55 import java.sql.SQLException;
56 import java.sql.Statement;
57 import java.time.Instant;
58 import java.time.ZoneOffset;
59 import java.time.format.DateTimeFormatter;
60 import java.time.temporal.ChronoUnit;
61 import java.util.ArrayList;
62 import java.util.HashMap;
63 import java.util.List;
64 import java.util.Map;
65 import java.util.UUID;
66
67 /**
68  * Test class for TransactionRecorder
69  */
70 public class TransactionRecorderImplTest {
71
72     private String dbUrl = "jdbc:h2:mem:test;MODE=MYSQL;DB_CLOSE_DELAY=-1";
73     private String username = "sa";
74     private String password = "sa";
75     private String driver = "org.h2.Driver";
76
77     private TransactionRecorderImpl transactionRecorderImpl;
78     private DbLibService dbLibService;
79
80     private DBConnectionPool dbConnectionPool;
81
82
83     /**
84      * Ideally JUnit should grab the SQL to create the transaction table from the same source used in deployments;
85      * however, at the time of writing this that was not possible.  Should it become possible in the future please
86      * update this JUnit test to use the deployment source.
87      * <p>
88      * Please ensure this table create script is identical to the source script used in a deployment.
89      */
90     private String TRANSACTION_CREATE_TABLE =
91             "CREATE TABLE TRANSACTIONS ("
92             + "  TRANSACTION_ID VARCHAR(75) NOT NULL PRIMARY KEY,"
93             + "  ORIGIN_TIMESTAMP DATETIME(3) NOT NULL,"
94             + "  REQUEST_ID VARCHAR(256) NOT NULL,"
95             + "  SUBREQUEST_ID VARCHAR(256) DEFAULT NULL,"
96             + "  ORIGINATOR_ID VARCHAR(256) DEFAULT NULL,"
97             + "  START_TIME DATETIME(3) NOT NULL,"
98             + "  END_TIME DATETIME(3) DEFAULT NULL,"
99             + "  TARGET_ID VARCHAR(256) NOT NULL,"
100             + "  TARGET_TYPE VARCHAR(256) DEFAULT NULL,"
101             + "  OPERATION VARCHAR(256) NOT NULL,"
102             + "  RESULT_CODE INT(11) DEFAULT NULL,"
103             + "  DESCRIPTION TEXT,"
104             + "  STATE VARCHAR(50) NOT NULL,"
105             + "  SERVICE_INSTANCE_ID VARCHAR(256) DEFAULT NULL,"
106             + "  VNFC_NAME VARCHAR(256) DEFAULT NULL,"
107             + "  VSERVER_ID VARCHAR(256) DEFAULT NULL,"
108             + "  VF_MODULE_ID VARCHAR(256) DEFAULT NULL,"
109             + "  MODE VARCHAR(50) NOT NULL,"
110             + ")";
111     private String TRANSACTION_DROP_TABLE = "DROP TABLE IF EXISTS TRANSACTIONS";
112
113     @Rule
114     public ExpectedException expectedEx = ExpectedException.none();
115
116     @Before
117     public void setUp() throws Exception {
118         transactionRecorderImpl = new TransactionRecorderImpl();
119         transactionRecorderImpl.setAppcInstanceId("123");
120         dbLibService = Mockito.mock(DbLibService.class);
121         transactionRecorderImpl.setDbLibService(dbLibService);
122         dbConnectionPool = new DBConnectionPool(dbUrl, username, password, driver);
123         executeUpdate(TRANSACTION_CREATE_TABLE);
124     }
125
126
127     @After
128     public void shutdown() {
129         if (dbConnectionPool != null) {
130             executeUpdate(TRANSACTION_DROP_TABLE);
131             dbConnectionPool.shutdown();
132         }
133     }
134
135     private void executeUpdate(String updateSQL) {
136         Connection connection = null;
137         Statement stmt = null;
138         try {
139             connection = dbConnectionPool.getConnection();
140             stmt = connection.createStatement();
141             stmt.executeUpdate(updateSQL);
142         } catch (SQLException e) {
143             throw new RuntimeException(e);
144         } finally {
145             DBHelper.close(null, stmt, connection);
146         }
147     }
148
149     /**
150      * Verify the transactionRecorderImpl.store() store the TransactionRecord correctly in the database.
151      */
152     @Test
153     public void testStore() throws Exception {
154
155         TransactionRecord input = prepareTransactionsInput();
156         Mockito.when(dbLibService.writeData(anyString(), anyObject(), anyString()))
157                 .thenAnswer(invocation -> testStoreInMemory(invocation.getArguments()));
158         transactionRecorderImpl.store(input);
159
160     }
161
162     @Test
163     public void testStoreExceptionFlow() throws SQLException, APPCException {
164
165         TransactionRecord input = prepareTransactionsInput();
166         Mockito.when(dbLibService.writeData(anyString(), anyObject(), anyString())).thenThrow(new SQLException());
167         expectedEx.expect(APPCException.class);
168         expectedEx.expectMessage(TransactionConstants.ERROR_ACCESSING_DATABASE);
169         expectedEx.expectCause(isA(SQLException.class));
170         transactionRecorderImpl.store(input);
171
172     }
173
174     @Test
175     public void testGetInProgressRequests() throws SQLException, APPCException {
176         TransactionRecord record1 = prepareTransactionsInput();
177         insertRecord(record1);
178         TransactionRecord input = prepareTransactionsInput();
179         input.setStartTime(Instant.now());
180         Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString()))
181                 .thenAnswer(invocation -> inMemoryExecutionWithResultSet(invocation.getArguments()));
182         Assert.assertEquals(1, transactionRecorderImpl.getInProgressRequests(input, 0).size());
183
184     }
185
186     @Test
187     public void testGetInProgressRequestsSqlException() throws SQLException, APPCException {
188         TransactionRecord record1 = prepareTransactionsInput();
189         insertRecord(record1);
190         TransactionRecord input = prepareTransactionsInput();
191         input.setStartTime(Instant.now());
192         Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString())).thenThrow(new SQLException());
193         expectedEx.expect(APPCException.class);
194         expectedEx.expectMessage(TransactionConstants.ERROR_ACCESSING_DATABASE);
195         expectedEx.expectCause(isA(SQLException.class));
196         transactionRecorderImpl.getInProgressRequests(input, 0);
197     }
198
199     @Test
200     public void testGetInProgressRequestsWithinTimeInterval() throws SQLException, APPCException {
201         TransactionRecord record1 = prepareTransactionsInput();
202         record1.setStartTime(Instant.now().minus(4, ChronoUnit.HOURS));
203         insertRecord(record1);
204         TransactionRecord input = prepareTransactionsInput();
205         input.setStartTime(Instant.now());
206         Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString()))
207                 .thenAnswer(invocation -> inMemoryExecutionWithResultSet(invocation.getArguments()));
208         List<TransactionRecord> aList = transactionRecorderImpl.getInProgressRequests(input, 12);
209         Assert.assertEquals(1, transactionRecorderImpl.getInProgressRequests(input, 12).size());
210
211     }
212
213     @Test
214     public void testIsTransactionDuplicate() throws SQLException, APPCException {
215         TransactionRecord input = prepareTransactionsInput();
216         Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString()))
217                 .thenAnswer(invocation -> inMemoryExecutionWithResultSet(invocation.getArguments()));
218         Assert.assertFalse(transactionRecorderImpl.isTransactionDuplicate(input));
219
220     }
221
222     @Test
223     public void testIsTransactionDuplicateExceptionFlow() throws SQLException, APPCException {
224         TransactionRecord input = prepareTransactionsInput();
225         Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString())).thenThrow(new SQLException());
226         expectedEx.expect(APPCException.class);
227         expectedEx.expectMessage(TransactionConstants.ERROR_ACCESSING_DATABASE);
228         expectedEx.expectCause(isA(SQLException.class));
229         transactionRecorderImpl.isTransactionDuplicate(input);
230     }
231
232     @Test
233     public void testIsTransactionDuplicateAlternativeFlow() throws SQLException, APPCException {
234         TransactionRecord input = prepareTransactionsInput();
235         input.setSubRequestId(null);
236         input.setOriginatorId(null);
237         CachedRowSetImpl rowset = Mockito.mock(CachedRowSetImpl.class);
238         Mockito.when(rowset.first()).thenReturn(true);
239         Mockito.when(rowset.getString(TransactionConstants.TRANSACTION_ATTRIBUTES.TRANSACTION_ID.getColumnName()))
240             .thenReturn(null);
241         Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString())).thenReturn(rowset);
242         Assert.assertTrue(transactionRecorderImpl.isTransactionDuplicate(input));
243     }
244
245     @Test
246     public void testGetInProgressRequestsCount() throws SQLException, APPCException {
247         TransactionRecord input = prepareTransactionsInput();
248         Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString())).thenAnswer(invocation ->
249                 inMemoryExecutionWithResultSet(invocation.getArguments()));
250         Assert.assertEquals(0, transactionRecorderImpl.getInProgressRequestsCount().intValue());
251     }
252
253     @Test
254     public void testGetInProgressRequestsCountSqlException() throws SQLException, APPCException {
255         TransactionRecord input = prepareTransactionsInput();
256         Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString())).thenThrow(new SQLException());
257         expectedEx.expect(APPCException.class);
258         expectedEx.expectMessage(TransactionConstants.ERROR_ACCESSING_DATABASE);
259         expectedEx.expectCause(isA(SQLException.class));
260         transactionRecorderImpl.getInProgressRequestsCount();
261     }
262
263     @Test
264     public void testGetInProgressRequestsCountNoRecords() throws SQLException, APPCException {
265         CachedRowSetImpl rowset = Mockito.mock(CachedRowSetImpl.class);
266         Mockito.when(rowset.first()).thenReturn(false);
267         Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString())).thenReturn(rowset);
268         expectedEx.expect(APPCException.class);
269         expectedEx.expectMessage(TransactionConstants.ERROR_ACCESSING_DATABASE);
270         transactionRecorderImpl.getInProgressRequestsCount();
271     }
272
273     @Test
274     public void testUpdate() throws APPCException, SQLException {
275         TransactionRecord input = prepareTransactionsInput();
276         insertRecord(input);
277         Map<TransactionConstants.TRANSACTION_ATTRIBUTES, String> updateColumns = new HashMap<>();
278         updateColumns.put(TransactionConstants.TRANSACTION_ATTRIBUTES.TARGET_TYPE, "Firewall");
279         Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString()))
280                 .thenAnswer(invocation -> returnResult(invocation.getArguments()));
281         Mockito.when(dbLibService.writeData(anyString(), anyObject(), anyString()))
282                 .thenAnswer(invocation -> testUpdateInMemory(invocation.getArguments()));
283         transactionRecorderImpl.update(input.getTransactionId(), input.getRequestId(), updateColumns);
284         Mockito.verify(dbLibService).getData(anyString(), anyObject(), anyString());
285         Mockito.verify(dbLibService).writeData(anyString(), anyObject(), anyString());
286     }
287
288     @Test
289     public void testUpdateExceptionFlow() throws APPCException, SQLException {
290         TransactionRecord input = prepareTransactionsInput();
291         insertRecord(input);
292         Map<TransactionConstants.TRANSACTION_ATTRIBUTES, String> updateColumns = new HashMap<>();
293         updateColumns.put(TransactionConstants.TRANSACTION_ATTRIBUTES.TARGET_TYPE, "Firewall");
294         Mockito.when(dbLibService.writeData(anyString(), anyObject(), anyString())).thenThrow(new SQLException());
295         expectedEx.expect(APPCException.class);
296         expectedEx.expectMessage(TransactionConstants.ERROR_ACCESSING_DATABASE);
297         expectedEx.expectCause(isA(SQLException.class));
298         transactionRecorderImpl.update(input.getTransactionId(), input.getRequestId(), updateColumns);
299     }
300
301     @Test
302     public void testUpdatewithNullInstance() throws APPCException, SQLException {
303         TransactionRecord input = prepareTransactionsInput();
304         Map<TransactionConstants.TRANSACTION_ATTRIBUTES, String> updateColumns = new HashMap<>();
305         updateColumns.put(TransactionConstants.TRANSACTION_ATTRIBUTES.TARGET_TYPE, "Firewall");
306         Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString()))
307                 .thenAnswer(invocation -> returnPositiveResult(invocation.getArguments()));
308         Mockito.when(dbLibService.writeData(anyString(), anyObject(), anyString()))
309                 .thenAnswer(invocation -> testUpdateInMemory(invocation.getArguments()));
310         transactionRecorderImpl.update(input.getTransactionId(), input.getRequestId(), updateColumns);
311         Mockito.verify(dbLibService).getData(anyString(), anyObject(), anyString());
312         Mockito.verify(dbLibService).writeData(anyString(), anyObject(), anyString());
313     }
314
315     private Object returnPositiveResult(Object[] obj) throws Exception {
316         String query = (String) obj[0];
317         ArrayList<String> args = (ArrayList<String>) obj[1];
318         System.out.println("returnPositiveResult: Query: " + query + "\nArgs: " + args);
319
320         insertNullInstanceData(args.get(0));
321
322         try (
323                 Connection con = dbConnectionPool.getConnection();
324                 PreparedStatement ps_second = con.prepareStatement(query)
325                 ) {
326             for (int i = 1; i <= args.size(); i++) {
327                 ps_second.setString(i, args.get(i - 1));
328             }
329             CachedRowSet rowSet = new CachedRowSetImpl();
330             rowSet.populate(ps_second.executeQuery());
331             return rowSet;
332         }
333     }
334
335     private void insertNullInstanceData(String transactionId) throws Exception {
336         final String nullInstanceQuery =
337                 TransactionConstants.INSERT_INTO + TransactionConstants.TRANSACTIONS
338                 + " values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
339         try (
340                 Connection con = dbConnectionPool.getConnection();
341                 PreparedStatement ps = con.prepareStatement(nullInstanceQuery)
342                 ) {
343             ArrayList<String> input = new ArrayList<String>();
344             input.add(transactionId);
345             input.add(dateToStringConverterMillis(Instant.parse("2017-09-12T00:00:01.00Z")));
346             input.add("REQUEST_ID");
347             input.add("SUB_REQUEST_ID");
348             input.add("ORIGINATOR_ID");
349             input.add(dateToStringConverterMillis(Instant.parse("2018-09-12T00:00:02.00Z")));
350             input.add(dateToStringConverterMillis(Instant.parse("2018-09-12T20:00:02.00Z")));
351             input.add("TARGET_ID");
352             input.add("TARGET_TYPE");
353             input.add("Audit");
354             input.add(String.valueOf(200));
355             input.add("SERVICE_INSTANCE_ID");
356             input.add("ACCEPTED");
357             input.add("DESCRIPTION");
358             input.add("test");
359             input.add("test");
360             input.add("test");
361             input.add("EXCLUSIVE");
362
363             for (int i = 1; i <= input.size(); i++) {
364                 ps.setString(i, input.get(i-1));
365             }
366             ps.execute();
367
368             if (checkIfRowIsPresent(input.get(0))) {
369                 System.out.println("RECORD INSERTED " + input.get(0));
370             }
371         }
372     }
373
374     private ResultSet returnResult(Object[] obj) throws Exception {
375         String query = (String) obj[0];
376         ArrayList<String> args = (ArrayList<String>) obj[1];
377         System.out.println("Query: " + query + "\nArgs: " + args);
378         try (
379                 Connection con = dbConnectionPool.getConnection();
380                 PreparedStatement ps = con.prepareStatement(query)
381                 ) {
382             for (int i = 1; i <= args.size(); i++) {
383                 ps.setString(i, args.get(i - 1));
384             }
385             CachedRowSet rowSet = new CachedRowSetImpl();
386             rowSet.populate(ps.executeQuery());
387             return rowSet;
388         }
389     }
390
391     @Test
392     public void testMarkTransactionsAborted() throws SQLException {
393         TransactionRecord input = prepareTransactionsInput();
394         insertRecord(input);
395         Mockito.when(dbLibService.writeData(anyString(), anyObject(), anyString())).thenAnswer(invocation ->
396                 testMarkAbortedInMemory(invocation.getArguments()));
397         transactionRecorderImpl.markTransactionsAborted("123~");
398     }
399
400     @Test
401     public void testMarkTransactionsAbortedExceptionFlow() throws SQLException {
402         TransactionRecord input = prepareTransactionsInput();
403         insertRecord(input);
404         Mockito.when(dbLibService.writeData(anyString(), anyObject(), anyString())).thenThrow(new SQLException());
405         expectedEx.expect(RuntimeException.class);
406         expectedEx.expectMessage("In progress transactions couldn't be marked aborted on server start up");
407         expectedEx.expectCause(isA(SQLException.class));
408         transactionRecorderImpl.markTransactionsAborted("123~");
409     }
410
411     @Test
412     public void testGetRecords() throws SQLException, APPCException {
413         CachedRowSetImpl rowset = Mockito.mock(CachedRowSetImpl.class);
414         Mockito.when(rowset.next()).thenReturn(true).thenReturn(false);
415         Mockito.when(rowset.getString(TRANSACTION_ATTRIBUTES.STATE.getColumnName())).thenReturn("NAME");
416         Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString())).thenReturn(rowset);
417         Assert.assertEquals(RequestStatus.UNKNOWN,
418                 transactionRecorderImpl.getRecords(null, "SUBREQUEST_ID", "ORIGINATOR_ID", null).get(0));
419     }
420
421     @Test
422     public void testGetRecordsSqlException() throws SQLException, APPCException {
423         Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString())).thenThrow(new SQLException());
424         expectedEx.expect(APPCException.class);
425         expectedEx.expectMessage("Error retrieving record for requestID null and vnfId null");
426         expectedEx.expectCause(isA(SQLException.class));
427         transactionRecorderImpl.getRecords(null, null, null, null);
428     }
429
430     private ResultSet inMemoryExecutionWithResultSet(Object[] obj) throws Exception {
431         String query = (String) obj[0];
432         ArrayList<String> args = (ArrayList<String>) obj[1];
433         // System.out.println("Query: " + query + "\nArgs: " + args);
434         try (
435                 Connection con = dbConnectionPool.getConnection();
436                 PreparedStatement ps = con.prepareStatement(query)
437                 ) {
438             for (int i = 1; i <= args.size(); i++) {
439                 ps.setString(i, args.get(i - 1));
440             }
441             CachedRowSet rowSet = new CachedRowSetImpl();
442             rowSet.populate(ps.executeQuery());
443             return rowSet;
444         }
445     }
446
447     private boolean testMarkAbortedInMemory(Object[] obj) throws Exception {
448         String query = (String) obj[0];
449         ArrayList<String> args = (ArrayList<String>) obj[1];
450         try (
451                 Connection con = dbConnectionPool.getConnection();
452                 PreparedStatement ps = con.prepareStatement(query)
453                 ) {
454             for (int i = 1; i <= args.size(); i++) {
455                 ps.setString(i, args.get(i - 1));
456             }
457             ps.execute();
458             return isTransactionAborted();
459         }
460     }
461
462     private boolean isTransactionAborted() throws Exception {
463         String query = "SELECT COUNT(*) FROM  TRANSACTIONS WHERE STATE = ?";
464         try (
465                 Connection con = dbConnectionPool.getConnection();
466                 PreparedStatement ps = con.prepareStatement(query)
467                 ) {
468             ps.setString(1, RequestStatus.ABORTED.toString());
469             try (
470                     ResultSet rs = ps.executeQuery()
471                     ) {
472                 while (rs.next()) {
473                     int value = rs.getInt(1);
474                     if (value == 1) {
475                         System.out.println("Non terminal Transactions are aborted");
476                         return true;
477                     }
478                 }
479                 throw new Exception("Transactions are not aborted");
480             }
481         }
482     }
483
484     private boolean testUpdateInMemory(Object[] obj) throws Exception {
485         String query = (String) obj[0];
486         ArrayList<String> args = (ArrayList<String>) obj[1];
487         try (
488                 Connection con = dbConnectionPool.getConnection();
489                 PreparedStatement ps = con.prepareStatement(query)
490                 ) {
491             for (int i = 1; i <= args.size(); i++) {
492                 System.out.println("Value at " + i + ": " + args.get(i - 1));
493                 ps.setString(i, args.get(i - 1));
494             }
495             ps.execute();
496             String updatedValue = checkIfValueIsUpdated(args.get(1));
497             System.out.println("updated Value is " + updatedValue);
498             if (updatedValue.equals("Firewall")) {
499                 return true;
500             }
501             throw new Exception("Not Updated");
502         }
503     }
504
505     private boolean testStoreInMemory(Object[] obj) throws Exception {
506         String query = (String) obj[0];
507         ArrayList<String> args = (ArrayList<String>) obj[1];
508         try (
509                 Connection con = dbConnectionPool.getConnection();
510                 PreparedStatement ps = con.prepareStatement(query)
511                 ) {
512             for (int i = 1; i <= args.size(); i++) {
513                 ps.setString(i, args.get(i - 1));
514             }
515             ps.execute();
516             if (checkIfRowIsPresent(args.get(0))) {
517                 return true;
518             }
519             throw new Exception("Failed to update");
520         }
521     }
522
523     private TransactionRecord prepareTransactionsInput() {
524         TransactionRecord input = new TransactionRecord();
525         input.setTransactionId(UUID.randomUUID().toString());
526         input.setOriginTimestamp(Instant.parse("2017-09-11T00:00:01.00Z"));
527         input.setRequestId("REQUEST_ID");
528         input.setSubRequestId("SUB_REQUEST_ID");
529         input.setOriginatorId("ORIGINATOR_ID");
530         input.setStartTime(Instant.parse("2017-09-11T00:00:02.00Z"));
531         input.setTargetId("TARGET_ID");
532         input.setTargetType("TARGET_TYPE");
533         input.setServiceInstanceId("SERVICE_INSTANCE_ID");
534         input.setOperation(VNFOperation.ActionStatus);
535         input.setResultCode(200);
536         input.setRequestState(RequestStatus.ACCEPTED);
537         input.setDescription("DESCRIPTION");
538         input.setMode(Flags.Mode.EXCLUSIVE);
539         return input;
540     }
541
542     private void insertRecord(TransactionRecord input) throws SQLException {
543         final String STORE_DATE_QUERY =
544                 TransactionConstants.INSERT_INTO + TransactionConstants.TRANSACTIONS
545                 + " values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
546         try (
547                 Connection con = dbConnectionPool.getConnection();
548                 PreparedStatement ps = con.prepareStatement(STORE_DATE_QUERY)
549                 ) {
550             ArrayList<String> args = prepareArguments(input);
551             args.remove(0);
552             args.add(0, "123~" + input.getTransactionId());
553             for (int i = 1; i <= 18; i++) {
554                 ps.setString(i, args.get(i - 1));
555             }
556             ps.execute();
557             if (checkIfRowIsPresent(args.get(0))) {
558                 System.out.println("RECORD INSERTED " + args.get(0));
559             }
560         }
561     }
562
563     private ArrayList<String> prepareArguments(TransactionRecord input) {
564         ArrayList<String> arguments = new ArrayList<>();
565         arguments.add(input.getTransactionId());
566         arguments.add(dateToStringConverterMillis(input.getOriginTimestamp()));
567         arguments.add(input.getRequestId());
568         arguments.add(input.getSubRequestId());
569         arguments.add(input.getOriginatorId());
570         arguments.add(dateToStringConverterMillis(input.getStartTime()));
571         arguments.add(dateToStringConverterMillis(input.getEndTime()));
572         arguments.add(input.getTargetId());
573         arguments.add(input.getTargetType());
574         arguments.add(input.getOperation().name());
575         arguments.add(String.valueOf(input.getResultCode()));
576         arguments.add(input.getDescription());
577         arguments.add(input.getRequestState());
578         arguments.add(input.getServiceInstanceId());
579         arguments.add(input.getVnfcName());
580         arguments.add(input.getVserverId());
581         arguments.add(input.getVfModuleId());
582         arguments.add(input.getMode());
583
584         return arguments;
585     }
586
587     private static String dateToStringConverterMillis(Instant date) {
588         if (date == null) {
589             return null;
590         }
591         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").withZone(ZoneOffset.UTC);
592         return formatter.format(date);
593     }
594
595     private boolean checkIfRowIsPresent(String key) {
596         Connection con = null;
597         ResultSet rs = null;
598         PreparedStatement ps = null;
599         try {
600             con = dbConnectionPool.getConnection();
601             ps = con.prepareStatement("SELECT COUNT(*) FROM  TRANSACTIONS WHERE TRANSACTION_ID = ?");
602             ps.setString(1, key);
603             rs = ps.executeQuery();
604             while (rs.next()) {
605                 int value = rs.getInt(1);
606                 System.out.println("KEY checked is " + key + " COUNT RETURNED IS " + value);
607                 if (value == 1) {
608                     return true;
609                 }
610             }
611         } catch (SQLException e) {
612             e.printStackTrace();
613         } finally {
614             DBHelper.close(rs, ps, con);
615         }
616         return false;
617     }
618
619     private String checkIfValueIsUpdated(String key) throws Exception {
620         try (
621                 Connection con = dbConnectionPool.getConnection();
622                 PreparedStatement ps = con.prepareStatement(
623                         "SELECT TARGET_TYPE, TRANSACTION_ID FROM TRANSACTIONS"
624                         + " WHERE TRANSACTION_ID = ?")
625                 ) {
626             ps.setString(1, key);
627             try (
628                     ResultSet rs = ps.executeQuery()
629                     ) {
630                 while (rs.next()) {
631                     String value = rs.getString("TARGET_TYPE");
632                     String transactionId = rs.getString("TRANSACTION_ID");
633                     System.out.println("Updated data: TRANSACTION_ID: " + transactionId + " TARGET_TYPE: " + value);
634                     return value;
635                 }
636                 throw new Exception("Value not found");
637             }
638         }
639     }
640
641
642     /**
643      * Verify the transactionRecorderImpl. getRecords () can be fetch with each of the parameter combinations
644      * @throws Exception
645      *//*
646     @Test
647     public void test_api_getRecords() throws Exception {
648
649
650         final int requestId = 0;
651         final int subrequestId = 1;
652         final int originatorId = 2;
653         final int vnfId = 3;
654         final int requestStatus = 4;
655
656
657         String[][] trCreateMatrix = {
658             {"request1", "subrequestId1", "originatorId1", "vnfId1", RequestStatus.UNKNOWN.name()},
659             {"request1", "subrequestId2", "originatorId1", "vnfId1", RequestStatus.RECEIVED.name()},
660             {"request2", "subrequestId1", "originatorId1", "vnfId1", RequestStatus.ACCEPTED.name()},
661             {"request2", "subrequestId2", "originatorId1", "vnfId1", RequestStatus.REJECTED.name()},
662             {"request1", "subrequestId1", "originatorId1", "vnfId2", RequestStatus.SUCCESSFUL.name()},
663             {"request1", "subrequestId2", "originatorId1", "vnfId2", RequestStatus.FAILED.name()},
664             {"request2", "subrequestId1", "originatorId1", "vnfId2", RequestStatus.TIMEOUT.name()},
665             {"request2", "subrequestId2", "originatorId1", "vnfId2", RequestStatus.ABORTED.name()},
666             {"request1", "subrequestId1", "originatorId2", "vnfId1", RequestStatus.UNKNOWN.name()},
667             {"request1", "subrequestId2", "originatorId2", "vnfId1", RequestStatus.RECEIVED.name()},
668             {"request2", "subrequestId1", "originatorId2", "vnfId1", RequestStatus.ACCEPTED.name()},
669             {"request2", "subrequestId2", "originatorId2", "vnfId1", RequestStatus.REJECTED.name()},
670             {"request1", "subrequestId1", "originatorId2", "vnfId2", RequestStatus.SUCCESSFUL.name()},
671             {"request1", "subrequestId2", "originatorId2", "vnfId2", RequestStatus.FAILED.name()},
672             {"request2", "subrequestId1", "originatorId2", "vnfId2", RequestStatus.TIMEOUT.name()},
673             {"request2", "subrequestId2", "originatorId2", "vnfId2", RequestStatus.ABORTED.name()},
674         };
675
676
677         TransactionRecord tr = new TransactionRecord();
678         tr.setTimeStamp(Instant.parse("2017-09-11T00:00:01.00Z"));
679         tr.setStartTime(Instant.parse("2017-09-11T00:00:02.00Z"));
680         tr.setEndTime(Instant.parse("2017-09-11T00:00:03.00Z"));
681         tr.setTargetType("TARGET_TYPE");
682         tr.setSubComponent("SUB_COMPONENT");
683         tr.setOperation(VNFOperation.ActionStatus);
684         tr.setResultCode("RESULT_CODE");
685         tr.setDescription("DESCRIPTION");
686
687         for (int row = 0; row < trCreateMatrix.length; row++) {
688             tr.setRequestID(trCreateMatrix[row][requestId]);
689             tr.setSubRequestID(trCreateMatrix[row][subrequestId]);
690             tr.setOriginatorId(trCreateMatrix[row][originatorId]);
691             tr.setTargetID(trCreateMatrix[row][vnfId]);
692             tr.setRequestStatus(RequestStatus.valueOf(trCreateMatrix[row][requestStatus]));
693             transactionRecorderImpl.store(tr);
694         }
695
696
697         String[][] trSearchMatrix = {
698             {"request1", null, null, "vnfId1"},
699             {"request2", "subrequestId1", null, "vnfId1"},
700             {"request1", null, "originatorId1", "vnfId1"},
701             {"request2", "subrequestId2", "originatorId1", "vnfId1"},
702         };
703
704
705         for (int i = 0; i < trSearchMatrix.length; i++) {
706             final int row = i;
707             List<RequestStatus> actualList = transactionRecorderImpl
708                 .getRecords(trSearchMatrix[row][requestId], trSearchMatrix[row][subrequestId],
709                     trSearchMatrix[row][originatorId], trSearchMatrix[row][vnfId])
710                 .stream()
711                 .sorted()
712                 .collect(Collectors.toList());
713
714             List<RequestStatus> expectedList = Arrays.stream(trCreateMatrix)
715                 .filter(entry -> entry[requestId].equals(trSearchMatrix[row][requestId]))
716                 .filter(entry -> trSearchMatrix[row][subrequestId] == null || entry[subrequestId].equals
717                     (trSearchMatrix[row][subrequestId]))
718                 .filter(entry -> trSearchMatrix[row][originatorId] == null || entry[originatorId].equals
719                     (trSearchMatrix[row][originatorId]))
720                 .filter(entry -> entry[vnfId].equals(trSearchMatrix[row][vnfId]))
721                 .map(entry -> RequestStatus.valueOf(entry[requestStatus]))
722                 .sorted()
723                 .collect(Collectors.toList());
724             System.out.println(expectedList);
725             System.out.println(actualList);
726             Assert.assertEquals("Unexpected results: ", expectedList, actualList);
727
728         }
729
730
731     }*/
732 }