From eaef24e96c1ce95195845258ce0a304ab9c0c21a Mon Sep 17 00:00:00 2001 From: "Boslet, Cory" Date: Wed, 17 Jul 2019 13:36:05 -0400 Subject: add query stack data and populate table step Need to check if audit is enabled first in the delete record task Updates to audit delete redeisgn and data to table Various updates to logging, audit object, added tag to query, updated tag value. Updated write method to make sure an entry for this heat stack doesnt already exist to avoid duplicate entrys Updated unit test to account for get query Added so that id is not hidden from query results Updated the was delete is done plus minor updates. Updated delete method to use resttemplate instead of bowman client Combined the write and get stack data task into the external tasks. Removed the task to delete the stack data from db Updates to junit request id so its not a random id for test Updated service tasks in att BB to call external task Update to be a real uuid format due to failing unit test Updated fields to protected and updated unit test Issue-ID: SO-2111 Signed-off-by: Benjamin, Max (mb388a) Change-Id: I8f479a046cf837403f60c330ed6ad8bc08a9c82f --- .../so/adapters/audit/AbstractAuditService.java | 10 +-- .../onap/so/adapters/audit/AuditDataService.java | 77 ++++++++++++++++++++++ .../so/adapters/audit/AuditDeleteStackService.java | 32 +++++---- .../so/adapters/audit/AuditQueryStackService.java | 68 +++++++++++++++++++ .../onap/so/adapters/audit/AuditStackService.java | 13 ++++ .../org/onap/so/adapters/audit/AuditVServer.java | 34 ++++++++++ .../org/onap/so/adapters/audit/HeatStackAudit.java | 52 +++++++++++++++ 7 files changed, 271 insertions(+), 15 deletions(-) create mode 100644 adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditDataService.java create mode 100644 adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditQueryStackService.java (limited to 'adapters/mso-openstack-adapters/src/main/java/org') diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AbstractAuditService.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AbstractAuditService.java index 5060e554eb..7500097b6a 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AbstractAuditService.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AbstractAuditService.java @@ -43,6 +43,8 @@ public abstract class AbstractAuditService { protected static final String UNABLE_TO_FIND_ALL_V_SERVERS_AND_L_INTERACES_IN_A_AI = "Unable to find all VServers and L-Interaces in A&AI"; + protected static final String UNABLE_TO_FIND_V_SERVERS_IN_OPENSTACK = "Unable to find VServers in Openstack"; + @Autowired public Environment env; @@ -68,12 +70,12 @@ public abstract class AbstractAuditService { * @param auditList * @return */ - protected boolean didDeleteAuditFail(Optional auditList) { - if (auditList.get().getAuditList() != null && !auditList.get().getAuditList().isEmpty()) { + protected boolean didDeleteAuditFail(AAIObjectAuditList auditList) { + if (auditList.getAuditList() != null && !auditList.getAuditList().isEmpty()) { if (logger.isInfoEnabled()) { - logger.info("Audit Results: {}", auditList.get().toString()); + logger.info("Audit Results: {}", auditList.toString()); } - return auditList.get().getAuditList().stream().filter(AAIObjectAudit::isDoesObjectExist).findFirst() + return auditList.getAuditList().stream().filter(AAIObjectAudit::isDoesObjectExist).findFirst() .map(v -> true).orElse(false); } else { return false; diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditDataService.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditDataService.java new file mode 100644 index 0000000000..1c707fe795 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditDataService.java @@ -0,0 +1,77 @@ +package org.onap.so.adapters.audit; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import org.onap.so.audit.beans.AuditInventory; +import org.onap.so.client.graphinventory.GraphInventoryCommonObjectMapperProvider; +import org.onap.so.db.request.beans.RequestProcessingData; +import org.onap.so.db.request.client.RequestsDbClient; +import org.onap.so.objects.audit.AAIObjectAuditList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; + +@Component +public class AuditDataService { + + @Autowired + private RequestsDbClient requestsDbClient; + + /** + * Checks to see if an entry already exist for the given heat stack and writes audit stack data to the request + * database if it doesn't. + * + * @throws JsonProcessingException + */ + public void writeStackDataToRequestDb(AuditInventory auditInventory, AAIObjectAuditList auditList) + throws JsonProcessingException { + List requestProcessingDataList = + requestsDbClient.getRequestProcessingDataByGroupingIdAndNameAndTag(auditInventory.getVfModuleId(), + auditInventory.getHeatStackName(), "AuditStackData"); + if (requestProcessingDataList.isEmpty()) { + GraphInventoryCommonObjectMapperProvider objectMapper = new GraphInventoryCommonObjectMapperProvider(); + String auditListString = objectMapper.getMapper().writeValueAsString(auditList);; + + RequestProcessingData requestProcessingData = new RequestProcessingData(); + requestProcessingData.setSoRequestId(auditInventory.getMsoRequestId()); + requestProcessingData.setGroupingId(auditInventory.getVfModuleId()); + requestProcessingData.setName(auditInventory.getHeatStackName()); + requestProcessingData.setTag("AuditStackData"); + requestProcessingData.setValue(auditListString); + + requestsDbClient.saveRequestProcessingData(requestProcessingData); + } + } + + /** + * Retrieves audit stack data from the request database. + * + * @throws IOException + * @throws JsonMappingException + * @throws JsonParseException + */ + public Optional getStackDataFromRequestDb(AuditInventory auditInventory) + throws JsonParseException, JsonMappingException, IOException { + + List requestProcessingDataList = + requestsDbClient.getRequestProcessingDataByGroupingIdAndNameAndTag(auditInventory.getVfModuleId(), + auditInventory.getHeatStackName(), "AuditStackData"); + if (!requestProcessingDataList.isEmpty()) { + RequestProcessingData requestProcessingData = requestProcessingDataList.get(0); + String auditListString = requestProcessingData.getValue(); + + GraphInventoryCommonObjectMapperProvider objectMapper = new GraphInventoryCommonObjectMapperProvider(); + AAIObjectAuditList auditList = + objectMapper.getMapper().readValue(auditListString, AAIObjectAuditList.class); + + return Optional.of(auditList); + } else { + return Optional.empty(); + } + } + + +} diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditDeleteStackService.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditDeleteStackService.java index 9b245ba695..b99eaa98d9 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditDeleteStackService.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditDeleteStackService.java @@ -40,10 +40,16 @@ public class AuditDeleteStackService extends AbstractAuditService { private static final Logger logger = LoggerFactory.getLogger(AuditDeleteStackService.class); @Autowired - public HeatStackAudit heatStackAudit; + protected HeatStackAudit heatStackAudit; @Autowired - public Environment environment; + protected AuditVServer auditVservers; + + @Autowired + protected AuditDataService auditDataService; + + @Autowired + protected Environment env; protected void executeExternalTask(ExternalTask externalTask, ExternalTaskService externalTaskService) { AuditInventory auditInventory = externalTask.getVariable("auditInventory"); @@ -51,17 +57,21 @@ public class AuditDeleteStackService extends AbstractAuditService { setupMDC(externalTask); boolean success = false; try { - logger.info("Executing External Task Audit Inventory, Retry Number: {} \n {}", auditInventory, - externalTask.getRetries()); - Optional auditListOpt = heatStackAudit.auditHeatStack(auditInventory.getCloudRegion(), - auditInventory.getCloudOwner(), auditInventory.getTenantId(), auditInventory.getHeatStackName()); + logger.info("Executing External Task Delete Audit Inventory. Retry Number: {}", externalTask.getRetries()); + Optional auditListOpt = auditDataService.getStackDataFromRequestDb(auditInventory); if (auditListOpt.isPresent()) { - auditListOpt.get().setAuditType("delete"); - auditListOpt.get().setHeatStackName(auditInventory.getHeatStackName()); - GraphInventoryCommonObjectMapperProvider objectMapper = new GraphInventoryCommonObjectMapperProvider(); - variables.put("auditInventoryResult", objectMapper.getMapper().writeValueAsString(auditListOpt.get())); - success = !didDeleteAuditFail(auditListOpt); + auditVservers.auditVservers(auditListOpt.get()); + } else { + logger.debug("Auditing Vservers based on vf module relationships"); + auditListOpt = auditVservers.auditVserversThroughRelationships(auditInventory.getGenericVnfId(), + auditInventory.getHeatStackName()); } + auditListOpt.get().setHeatStackName(auditInventory.getHeatStackName()); + auditListOpt.get().setAuditType("delete"); + GraphInventoryCommonObjectMapperProvider objectMapper = new GraphInventoryCommonObjectMapperProvider(); + variables.put("auditInventoryResult", objectMapper.getMapper().writeValueAsString(auditListOpt.get())); + success = !didDeleteAuditFail(auditListOpt.get()); + } catch (Exception e) { logger.error("Error during audit of stack", e); } diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditQueryStackService.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditQueryStackService.java new file mode 100644 index 0000000000..c8ac9d1a58 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditQueryStackService.java @@ -0,0 +1,68 @@ +package org.onap.so.adapters.audit; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import org.camunda.bpm.client.task.ExternalTask; +import org.camunda.bpm.client.task.ExternalTaskService; +import org.onap.so.audit.beans.AuditInventory; +import org.onap.so.objects.audit.AAIObjectAuditList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class AuditQueryStackService extends AbstractAuditService { + + private static final Logger logger = LoggerFactory.getLogger(AuditQueryStackService.class); + + @Autowired + protected HeatStackAudit heatStackAudit; + + @Autowired + protected AuditDataService auditDataService; + + protected void executeExternalTask(ExternalTask externalTask, ExternalTaskService externalTaskService) { + AuditInventory auditInventory = externalTask.getVariable("auditInventory"); + setupMDC(externalTask); + boolean success = false; + Map variables = new HashMap<>(); + try { + logger.info("Executing External Task Query Audit Inventory. Audit Inventory: {} \n Retry Number: {}", + auditInventory.toString(), externalTask.getRetries()); + + Optional auditList = heatStackAudit.queryHeatStack(auditInventory.getCloudOwner(), + auditInventory.getCloudRegion(), auditInventory.getTenantId(), auditInventory.getHeatStackName()); + + if (auditList.isPresent()) { + success = true; + auditDataService.writeStackDataToRequestDb(auditInventory, auditList.get()); + } + if (success) { + externalTaskService.complete(externalTask, variables); + logger.debug("The External Task {} was Successful", externalTask.getId()); + } else { + if (externalTask.getRetries() == null) { + logger.debug("The External Task {} Failed. Setting Retries to Default Start Value: {}", + externalTask.getId(), getRetrySequence().length); + externalTaskService.handleFailure(externalTask, UNABLE_TO_FIND_V_SERVERS_IN_OPENSTACK, + UNABLE_TO_FIND_V_SERVERS_IN_OPENSTACK, getRetrySequence().length, 10000); + } else if (externalTask.getRetries() != null && externalTask.getRetries() - 1 == 0) { + logger.debug("The External Task {} Failed. All Retries Exhausted", externalTask.getId()); + externalTaskService.complete(externalTask, variables); + } else { + logger.debug("The External Task {} Failed. Decrementing Retries to {} , Retry Delay: ", + externalTask.getId(), externalTask.getRetries() - 1, + calculateRetryDelay(externalTask.getRetries())); + externalTaskService.handleFailure(externalTask, UNABLE_TO_FIND_V_SERVERS_IN_OPENSTACK, + UNABLE_TO_FIND_V_SERVERS_IN_OPENSTACK, externalTask.getRetries() - 1, + calculateRetryDelay(externalTask.getRetries())); + } + logger.debug("The External Task {} Failed", externalTask.getId()); + } + } catch (Exception e) { + logger.error("Error during audit query of stack", e); + } + } +} diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java index 576acb1fd8..999d27335b 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java @@ -49,6 +49,9 @@ public class AuditStackService { @Autowired private AuditDeleteStackService auditDeleteStack; + @Autowired + private AuditQueryStackService auditQueryStack; + @PostConstruct public void auditAddAAIInventory() throws Exception { for (int i = 0; i < getMaxClients(); i++) { @@ -69,6 +72,16 @@ public class AuditStackService { } } + @PostConstruct + public void auditQueryInventory() throws Exception { + for (int i = 0; i < getMaxClients(); i++) { + ExternalTaskClient client = createExternalTaskClient(); + client.subscribe("InventoryQueryAudit") + .lockDuration(Long.parseLong(env.getProperty("mso.audit.lock-time", "60000"))) + .handler(auditQueryStack::executeExternalTask).open(); + } + } + protected ExternalTaskClient createExternalTaskClient() throws Exception { ClientRequestInterceptor interceptor = createClientRequestInterceptor(); ExternalTaskClient client = ExternalTaskClient.create() diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditVServer.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditVServer.java index e009c0e2fd..89e0320615 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditVServer.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditVServer.java @@ -20,10 +20,12 @@ package org.onap.so.adapters.audit; +import java.util.List; import java.util.Optional; import java.util.Set; import org.onap.aai.domain.yang.LInterface; import org.onap.aai.domain.yang.Vserver; +import org.onap.so.client.aai.AAIObjectPlurals; import org.onap.so.client.aai.AAIObjectType; import org.onap.so.client.aai.entities.uri.AAIResourceUri; import org.onap.so.client.aai.entities.uri.AAIUriFactory; @@ -40,6 +42,38 @@ import com.fasterxml.jackson.core.JsonProcessingException; public class AuditVServer extends AbstractAudit { private static final Logger logger = LoggerFactory.getLogger(AuditVServer.class); + public void auditVservers(AAIObjectAuditList aaiObjectAuditList) { + + aaiObjectAuditList.getAuditList().forEach(aaiObjectAudit -> { + boolean vserverExist = getAaiClient().exists(AAIUriFactory + .createResourceFromExistingURI(AAIObjectType.VSERVER, aaiObjectAudit.getResourceURI())); + aaiObjectAudit.setDoesObjectExist(vserverExist); + }); + } + + public Optional auditVserversThroughRelationships(String genericVnfId, String vfModuleName) { + AAIObjectAuditList auditList = new AAIObjectAuditList(); + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectPlurals.VF_MODULE, genericVnfId) + .queryParam("vf-module-name", vfModuleName); + if (getAaiClient().get(uri).getRelationships().isPresent()) { + List relatedVservers = + getAaiClient().get(uri).getRelationships().get().getRelatedUris(AAIObjectType.VSERVER); + if (!relatedVservers.isEmpty()) { + relatedVservers.forEach(vserverUri -> { + Optional vserver = getAaiClient().get(vserverUri).asBean(Vserver.class); + Vserver vServerShallow = new Vserver(); + BeanUtils.copyProperties(vserver, vServerShallow); + AAIObjectAudit vServerAudit = new AAIObjectAudit(); + vServerAudit.setAaiObject(vServerShallow); + vServerAudit.setAaiObjectType(AAIObjectType.VSERVER.typeName()); + vServerAudit.setDoesObjectExist(true); + auditList.getAuditList().add(vServerAudit); + }); + } + } + return Optional.of(auditList); + } + public Optional auditVservers(Set vServersToAudit, String tenantId, String cloudOwner, String cloudRegion) { if (vServersToAudit == null || vServersToAudit.isEmpty()) { diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/HeatStackAudit.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/HeatStackAudit.java index 2be87ff076..06fff19205 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/HeatStackAudit.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/HeatStackAudit.java @@ -35,11 +35,16 @@ import org.onap.aai.domain.yang.LInterfaces; import org.onap.aai.domain.yang.Vlan; import org.onap.aai.domain.yang.Vlans; import org.onap.aai.domain.yang.Vserver; +import org.onap.so.client.aai.AAIObjectType; +import org.onap.so.client.aai.entities.uri.AAIResourceUri; +import org.onap.so.client.aai.entities.uri.AAIUriFactory; +import org.onap.so.objects.audit.AAIObjectAudit; import org.onap.so.objects.audit.AAIObjectAuditList; import org.onap.so.openstack.utils.MsoHeatUtils; import org.onap.so.openstack.utils.MsoNeutronUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.woorea.openstack.heat.model.Link; @@ -66,6 +71,28 @@ public class HeatStackAudit { @Autowired protected AuditVServer auditVservers; + public Optional queryHeatStack(String cloudOwner, String cloudRegion, String tenantId, + String heatStackName) { + try { + logger.debug("Fetching Top Level Stack Information"); + Resources resources = heat.queryStackResources(cloudRegion, tenantId, heatStackName, 3); + List novaResources = resources.getList().stream() + .filter(p -> "OS::Nova::Server".equals(p.getType())).collect(Collectors.toList()); + if (novaResources.isEmpty()) + return Optional.of(new AAIObjectAuditList()); + else { + Set vserversToAudit = createVserverSet(novaResources); + AAIObjectAuditList aaiObjectAuditList = new AAIObjectAuditList(); + vserversToAudit.stream().forEach(vServer -> aaiObjectAuditList.getAuditList() + .add(createAAIObjectAudit(cloudOwner, cloudRegion, tenantId, vServer))); + return Optional.of(aaiObjectAuditList); + } + } catch (Exception e) { + logger.error("Error during query stack resources", e); + return Optional.of(new AAIObjectAuditList()); + } + } + public Optional auditHeatStack(String cloudRegion, String cloudOwner, String tenantId, String heatStackName) { try { @@ -215,6 +242,31 @@ public class HeatStackAudit { return vserversToAudit; } + protected Set createVserverSet(List novaResources) { + Set vserversToAudit = new HashSet<>(); + for (Resource novaResource : novaResources) { + Vserver auditVserver = new Vserver(); + auditVserver.setLInterfaces(new LInterfaces()); + auditVserver.setVserverId(novaResource.getPhysicalResourceId()); + vserversToAudit.add(auditVserver); + } + return vserversToAudit; + } + + protected AAIObjectAudit createAAIObjectAudit(String cloudOwner, String cloudRegion, String tenantId, + Vserver vServer) { + AAIObjectAudit aaiObjectAudit = new AAIObjectAudit(); + Vserver vServerShallow = new Vserver(); + BeanUtils.copyProperties(vServer, vServerShallow); + aaiObjectAudit.setAaiObject(vServerShallow); + aaiObjectAudit.setAaiObjectType(AAIObjectType.VSERVER.typeName()); + aaiObjectAudit.setResourceURI(AAIUriFactory + .createResourceUri(AAIObjectType.VSERVER, cloudOwner, cloudRegion, tenantId, vServer.getVserverId()) + .build()); + + return aaiObjectAudit; + } + /** * @param novaResource Single openstack resource that is of type Nova * @param neutronPorts List of Neutron ports created within the stack -- cgit 1.2.3-korg