aboutsummaryrefslogtreecommitdiffstats
path: root/appc-dispatcher
diff options
context:
space:
mode:
authorBalaji, Ramya (rb111y) <rb111y@att.com>2018-09-07 16:00:46 -0400
committerTakamune Cho <tc012c@att.com>2018-09-11 15:10:09 +0000
commitf1b353074c937b473e23e717966d97602bc981f8 (patch)
treef35ef0d0571f898ac7c9bf1d435da9d47effe944 /appc-dispatcher
parent99043712640be0ffc317f95d0630b2119998cb2b (diff)
In progress trxns criteria fix
Changed the criteria for inprogress transactions to the last X hours. This will eliminate stale transactions causing an incorrect scope overlap error. Issue-ID: APPC-1194 Change-Id: I2f3147503f4202e8e8931b2615e626e3b9af8261 Signed-off-by: Balaji, Ramya (rb111y) <rb111y@att.com>
Diffstat (limited to 'appc-dispatcher')
-rw-r--r--appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/onap/appc/transactionrecorder/TransactionRecorder.java9
-rw-r--r--appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/onap/appc/transactionrecorder/impl/TransactionRecorderImpl.java16
-rw-r--r--appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/test/java/org/onap/appc/transactionrecorder/impl/TransactionRecorderImplTest.java24
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/onap/appc/requesthandler/impl/RequestValidatorImpl.java73
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/onap/appc/requesthandler/impl/RequestValidatorImplTest.java43
5 files changed, 135 insertions, 30 deletions
diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/onap/appc/transactionrecorder/TransactionRecorder.java b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/onap/appc/transactionrecorder/TransactionRecorder.java
index 299115d99..17e0e2575 100644
--- a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/onap/appc/transactionrecorder/TransactionRecorder.java
+++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/onap/appc/transactionrecorder/TransactionRecorder.java
@@ -9,15 +9,15 @@
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
+ *
* ============LICENSE_END=========================================================
*/
@@ -62,10 +62,11 @@ public interface TransactionRecorder {
* Fetch list of Transactions which are in non-terminal state i.e. ACCEPTED or RECEIVED for particular TargetId.
* @param record Transactions object from which TargetId and StartTime is extracted to fetch list of in progress
* requests which APPC received before the current request.
+ * @param interval Number of hours - Time window to consider requests as being in progress
* @return List of Transactions in non terminal state.
* @throws APPCException
*/
- List<TransactionRecord> getInProgressRequests(TransactionRecord record) throws APPCException;
+ List<TransactionRecord> getInProgressRequests(TransactionRecord record, int interval) throws APPCException;
/**
* Checks whether the incoming request is duplicate.
diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/onap/appc/transactionrecorder/impl/TransactionRecorderImpl.java b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/onap/appc/transactionrecorder/impl/TransactionRecorderImpl.java
index 7c1581f57..98ea1b538 100644
--- a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/onap/appc/transactionrecorder/impl/TransactionRecorderImpl.java
+++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/onap/appc/transactionrecorder/impl/TransactionRecorderImpl.java
@@ -9,15 +9,15 @@
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
+ *
* ============LICENSE_END=========================================================
*/
@@ -45,6 +45,7 @@ import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.time.temporal.ChronoUnit;
import static org.onap.appc.transactionrecorder.objects.TransactionConstants.TRANSACTION_ATTRIBUTES.*;
import static org.onap.appc.transactionrecorder.objects.TransactionConstants.*;
@@ -165,19 +166,24 @@ public class TransactionRecorderImpl implements TransactionRecorder {
}
@Override
- public List<TransactionRecord> getInProgressRequests(TransactionRecord record) throws APPCException {
+ public List<TransactionRecord> getInProgressRequests(TransactionRecord record, int interval) throws APPCException {
- final String IN_PROGRESS_REQUESTS_QUERY = "SELECT * FROM " +
+ String IN_PROGRESS_REQUESTS_QUERY = "SELECT * FROM " +
TransactionConstants.TRANSACTIONS + WHERE +
TARGET_ID + " = ? AND " +
STATE.getColumnName() + " IN (?,?) AND " +
START_TIME.getColumnName() + " < ?";
ArrayList<String> inProgressQueryParams = new ArrayList<>();
+ Instant window = record.getStartTime().minus(interval, ChronoUnit.HOURS);
inProgressQueryParams.add(record.getTargetId());
inProgressQueryParams.add(RequestStatus.RECEIVED.name());
inProgressQueryParams.add(RequestStatus.ACCEPTED.name());
inProgressQueryParams.add(dateToStringConverterMillis(record.getStartTime()));
+ if (interval > 0) {
+ IN_PROGRESS_REQUESTS_QUERY += " AND " + START_TIME.getColumnName() + " > ? ";
+ inProgressQueryParams.add(dateToStringConverterMillis(window));
+ }
try (CachedRowSet rowSet = dbLibService.getData(IN_PROGRESS_REQUESTS_QUERY, inProgressQueryParams, SCHEMA)) {
List<TransactionRecord> inProgressRecords = new ArrayList<>();
diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/test/java/org/onap/appc/transactionrecorder/impl/TransactionRecorderImplTest.java b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/test/java/org/onap/appc/transactionrecorder/impl/TransactionRecorderImplTest.java
index fd1790d49..1418e89c6 100644
--- a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/test/java/org/onap/appc/transactionrecorder/impl/TransactionRecorderImplTest.java
+++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/test/java/org/onap/appc/transactionrecorder/impl/TransactionRecorderImplTest.java
@@ -9,15 +9,15 @@
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
+ *
* ============LICENSE_END=========================================================
*/
@@ -45,8 +45,10 @@ import java.sql.*;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -152,7 +154,21 @@ public class TransactionRecorderImplTest {
input.setStartTime(Instant.now());
Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString())).thenAnswer(invocation ->
inMemoryExecutionWithResultSet(invocation.getArguments()));
- Assert.assertEquals(1, transactionRecorderImpl.getInProgressRequests(input).size());
+ Assert.assertEquals(1, transactionRecorderImpl.getInProgressRequests(input,0).size());
+
+ }
+
+ @Test
+ public void testGetInProgressRequestsWithinTimeInterval() throws SQLException, APPCException {
+ TransactionRecord record1 = prepareTransactionsInput();
+ record1.setStartTime(Instant.now().minus(4,ChronoUnit.HOURS));
+ insertRecord(record1);
+ TransactionRecord input = prepareTransactionsInput();
+ input.setStartTime(Instant.now());
+ Mockito.when(dbLibService.getData(anyString(), anyObject(), anyString())).thenAnswer(invocation ->
+ inMemoryExecutionWithResultSet(invocation.getArguments()));
+ List<TransactionRecord> aList= transactionRecorderImpl.getInProgressRequests(input,12);
+ Assert.assertEquals(1, transactionRecorderImpl.getInProgressRequests(input,12).size());
}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/onap/appc/requesthandler/impl/RequestValidatorImpl.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/onap/appc/requesthandler/impl/RequestValidatorImpl.java
index 53f15a092..e97f7c05f 100644
--- a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/onap/appc/requesthandler/impl/RequestValidatorImpl.java
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/onap/appc/requesthandler/impl/RequestValidatorImpl.java
@@ -9,15 +9,15 @@
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
+ *
* ============LICENSE_END=========================================================
*/
@@ -93,21 +93,26 @@ public class RequestValidatorImpl extends AbstractRequestValidatorImpl {
private RequestValidationPolicy requestValidationPolicy;
private RestClientInvoker client;
private String path;
+ private int transactionWindowInterval=0;
static final String SCOPE_OVERLAP_ENDPOINT = "appc.LCM.scopeOverlap.endpoint";
static final String ODL_USER = "appc.LCM.provider.user";
static final String ODL_PASS = "appc.LCM.provider.pass";
-
+ static final String TRANSACTION_WINDOW_HOURS = "appc.inProgressTransactionWindow.hours";
+
public void initialize() throws APPCException {
logger.info("Initializing RequestValidatorImpl.");
String endpoint = null;
String user = null;
String pass =null;
+ String transactionWindow = null;
+
Properties properties = configuration.getProperties();
if (properties != null) {
endpoint = properties.getProperty(SCOPE_OVERLAP_ENDPOINT);
user = properties.getProperty(ODL_USER);
pass = properties.getProperty(ODL_PASS);
+ transactionWindow = properties.getProperty(TRANSACTION_WINDOW_HOURS);
}
if (endpoint == null) {
String message = "End point is not defined for scope over lap service in appc.properties.";
@@ -122,12 +127,24 @@ public class RequestValidatorImpl extends AbstractRequestValidatorImpl {
return;
}
+ if (StringUtils.isNotBlank(transactionWindow)) {
+ logger.info("RequestValidatorImpl::TransactionWindow defined !!!");
+ try {
+ transactionWindowInterval = Integer.parseInt(transactionWindow);
+ }
+ catch (NumberFormatException e) {
+ String message = "RequestValidatorImpl:::Error parsing transaction window interval!";
+ logger.error(message, e);
+ throw new APPCException(message);
+ }
+ }
+
try {
URL url = new URL(endpoint);
client = new RestClientInvoker(url);
client.setAuthentication(user, pass);
- path = url.getPath();
-
+ path = url.getPath();
+
} catch (MalformedURLException e) {
String message = "Invalid endpoint " + endpoint;
logger.error(message, e);
@@ -199,10 +216,22 @@ public class RequestValidatorImpl extends AbstractRequestValidatorImpl {
return;
}
+ List<TransactionRecord> inProgressTransactionsAll = transactionRecorder
+ .getInProgressRequests(runtimeContext.getTransactionRecord(),0);
List<TransactionRecord> inProgressTransactions = transactionRecorder
- .getInProgressRequests(runtimeContext.getTransactionRecord());
+ .getInProgressRequests(runtimeContext.getTransactionRecord(),transactionWindowInterval);
+
+ long inProgressTransactionsAllCount = inProgressTransactionsAll.size();
+ long inProgressTransactionsRelevant = inProgressTransactions.size();
logger.debug("In progress requests " + inProgressTransactions.toString());
+ if ( inProgressTransactions.isEmpty()){ //No need to check for scope overlap
+ return;
+ }
+
+ logInProgressTransactions(inProgressTransactions,inProgressTransactionsAllCount,
+ inProgressTransactionsRelevant );
+
Long exclusiveRequestCount = inProgressTransactions.stream()
.filter(record -> record.getMode().equals(Flags.Mode.EXCLUSIVE.name())).count();
if (exclusiveRequestCount > 0) {
@@ -319,7 +348,7 @@ public class RequestValidatorImpl extends AbstractRequestValidatorImpl {
ObjectMapper objectMapper = new ObjectMapper();
ScopeOverlapModel scopeOverlapModel = getScopeOverlapModel(requestContext, inProgressTransactions);
// Added for change in interface for action level
-
+
JsonNode jsonObject = objectMapper.valueToTree(scopeOverlapModel);
return jsonObject;
@@ -375,7 +404,7 @@ public class RequestValidatorImpl extends AbstractRequestValidatorImpl {
Request request = new Request();
Date date = new Date();
- request.setRequestID("RequestId-ScopeOverlap " + date.toString());
+ request.setRequestID("RequestId-ScopeOverlap " + date.toString());
request.setAction("isScopeOverlap");
ObjectMapper objectMapper = new ObjectMapper();
JsonNode json = objectMapper.valueToTree(requestData);
@@ -383,7 +412,7 @@ public class RequestValidatorImpl extends AbstractRequestValidatorImpl {
Input input = new Input();
input.setRequest(request);
scopeOverlapModel.setInput(input);
-
+
return scopeOverlapModel;
}
@@ -497,4 +526,28 @@ public class RequestValidatorImpl extends AbstractRequestValidatorImpl {
}
return workflowRequest;
}
+
+ public String logInProgressTransactions(List<TransactionRecord> inProgressTransactions,
+ long inProgressTransactionsAllCount, long inProgressTransactionsRelevant) {
+ if (inProgressTransactionsAllCount > inProgressTransactionsRelevant) {
+ logger.info("Found Stale Transactions! Ignoring Stale Transactions for target, only considering "
+ + "transactions within the last " + transactionWindowInterval + " hours as transactions in-progress");
+ }
+ String logMsg="";
+ for (TransactionRecord tr: inProgressTransactions) {
+ logMsg = ("In Progress transaction for Target ID - "+ tr.getTargetId()
+ + " in state " + tr.getRequestState()
+ + " with Start time " + tr.getStartTime().toString()
+ + " for more than configurable time period " + transactionWindowInterval
+ + " hours [transaction details - Request ID - " + tr.getTransactionId()
+ + ", Service Instance Id -" + tr.getServiceInstanceId()
+ + ", Vserver_id - " + tr.getVserverId()
+ + ", VNFC_name - "+ tr.getVnfcName()
+ + ", VF module Id - " + tr.getVfModuleId()
+ + " Start time " + tr.getStartTime().toString()
+ + "]" );
+ }
+ return logMsg;
+
+ }
}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/onap/appc/requesthandler/impl/RequestValidatorImplTest.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/onap/appc/requesthandler/impl/RequestValidatorImplTest.java
index e1c10dae1..8e3d77cd3 100644
--- a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/onap/appc/requesthandler/impl/RequestValidatorImplTest.java
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/onap/appc/requesthandler/impl/RequestValidatorImplTest.java
@@ -25,6 +25,7 @@
package org.onap.appc.requesthandler.impl;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
@@ -37,10 +38,13 @@ import com.att.eelf.configuration.EELFManager;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
+import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.entity.BasicHttpEntity;
@@ -60,6 +64,7 @@ import org.onap.appc.domainmodel.lcm.CommonHeader;
import org.onap.appc.domainmodel.lcm.Flags;
import org.onap.appc.domainmodel.lcm.Flags.Mode;
import org.onap.appc.domainmodel.lcm.RequestContext;
+import org.onap.appc.domainmodel.lcm.RequestStatus;
import org.onap.appc.domainmodel.lcm.ResponseContext;
import org.onap.appc.domainmodel.lcm.RuntimeContext;
import org.onap.appc.domainmodel.lcm.TransactionRecord;
@@ -184,7 +189,7 @@ public class RequestValidatorImplTest implements LocalRequestHanlderTestHelper {
}
- @Test(expected = RequestValidationException.class)
+ @Test (expected = RequestValidationException.class)
public void testValidateRequest() throws Exception {
RuntimeContext runtimeContext = createRequestValidatorInput();
logger = Mockito.spy(EELFManager.getInstance().getLogger(LCMStateManager.class));
@@ -193,9 +198,15 @@ public class RequestValidatorImplTest implements LocalRequestHanlderTestHelper {
lcmStateManager.enableLCMOperations();
transactionRecorder = Mockito.mock(TransactionRecorder.class);
Mockito.when(transactionRecorder.isTransactionDuplicate(anyObject())).thenReturn(false);
+ List<TransactionRecord> transactionRecordList = new ArrayList<TransactionRecord>(1);
TransactionRecord transactionRecord = new TransactionRecord();
transactionRecord.setMode(Mode.EXCLUSIVE);
+ transactionRecord.setStartTime(Instant.now().minus(5, ChronoUnit.HOURS));
+ transactionRecord.setRequestState(RequestStatus.ACCEPTED);
runtimeContext.setTransactionRecord(transactionRecord);
+ transactionRecordList.add(transactionRecord);
+ Mockito.when(transactionRecorder.getInProgressRequests(Mockito.any(TransactionRecord.class),Mockito.any(int.class)))
+ .thenReturn(transactionRecordList);
impl.setTransactionRecorder(transactionRecorder);
WorkflowExistsOutput workflowExistsOutput = new WorkflowExistsOutput(true, true);
WorkFlowManager workflowManager = Mockito.mock(WorkFlowManagerImpl.class);
@@ -244,8 +255,10 @@ public class RequestValidatorImplTest implements LocalRequestHanlderTestHelper {
List<TransactionRecord> transactionRecordList = new ArrayList<TransactionRecord>(1);
TransactionRecord inProgressTransaction = new TransactionRecord();
inProgressTransaction.setMode(Mode.EXCLUSIVE);
+ inProgressTransaction.setStartTime(Instant.now().minus(5, ChronoUnit.HOURS));
+ inProgressTransaction.setRequestState(RequestStatus.ACCEPTED);
transactionRecordList.add(inProgressTransaction);
- Mockito.when(transactionRecorder.getInProgressRequests(Mockito.any(TransactionRecord.class)))
+ Mockito.when(transactionRecorder.getInProgressRequests(Mockito.any(TransactionRecord.class),Mockito.any(int.class)))
.thenReturn(transactionRecordList);
runtimeContext.setTransactionRecord(inProgressTransaction);
impl.setTransactionRecorder(transactionRecorder);
@@ -277,18 +290,21 @@ public class RequestValidatorImplTest implements LocalRequestHanlderTestHelper {
RuntimeContext runtimeContext = createRequestValidatorInput();
lcmStateManager.enableLCMOperations();
transactionRecorder = Mockito.mock(TransactionRecorder.class);
- Mockito.when(transactionRecorder.isTransactionDuplicate(anyObject())).thenReturn(false);
+
List<TransactionRecord> transactionRecordList = new ArrayList<TransactionRecord>(1);
TransactionRecord inProgressTransaction = new TransactionRecord();
inProgressTransaction.setMode(Mode.NORMAL);
inProgressTransaction.setOperation(VNFOperation.ActionStatus);
+ inProgressTransaction.setRequestState(RequestStatus.ACCEPTED);
+ inProgressTransaction.setStartTime(Instant.now().minus(48, ChronoUnit.HOURS));
transactionRecordList.add(inProgressTransaction);
- runtimeContext.setTransactionRecord(inProgressTransaction);
- Mockito.when(transactionRecorder.getInProgressRequests(Mockito.any(TransactionRecord.class)))
- .thenReturn(transactionRecordList);
+ Mockito.when(transactionRecorder.getInProgressRequests(Mockito.any(TransactionRecord.class),Mockito.any(int.class)))
+ .thenReturn(transactionRecordList);
+ Mockito.when(transactionRecorder.isTransactionDuplicate(anyObject())).thenReturn(false);
impl.setTransactionRecorder(transactionRecorder);
- WorkflowExistsOutput workflowExistsOutput = new WorkflowExistsOutput(true, true);
+ runtimeContext.setTransactionRecord(inProgressTransaction);
WorkFlowManager workflowManager = Mockito.mock(WorkFlowManagerImpl.class);
+ WorkflowExistsOutput workflowExistsOutput = Mockito.spy(new WorkflowExistsOutput(true, true));
Mockito.when(workflowManager.workflowExists(Mockito.any(WorkflowRequest.class)))
.thenReturn(workflowExistsOutput);
impl.setWorkflowManager(workflowManager);
@@ -384,6 +400,19 @@ public class RequestValidatorImplTest implements LocalRequestHanlderTestHelper {
impl.validateRequest(runtimeContext);
}
+ @Test
+ public void testLogInProgressTransactions() {
+ ArrayList<TransactionRecord> trArray = new ArrayList();
+ TransactionRecord tr = new TransactionRecord();
+ tr.setRequestState(RequestStatus.ACCEPTED);
+ tr.setStartTime(Instant.now().minus(48, ChronoUnit.HOURS));
+ tr.setTargetId("Vnf001");
+ trArray.add(tr);
+ String loggedMessage = impl.logInProgressTransactions(trArray, 1, 1);
+ String partMessage = "In Progress transaction for Target ID - Vnf001 in state ACCEPTED";
+ assertTrue(StringUtils.contains(loggedMessage, partMessage));
+ }
+
private RuntimeContext createRequestValidatorInput() {
return createRequestHandlerRuntimeContext("VSCP", "{\"request-id\":\"request-id\"}");
}