diff options
107 files changed, 5532 insertions, 4852 deletions
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BaseController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BaseController.java index 8b590ca..818a30d 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BaseController.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BaseController.java @@ -42,12 +42,12 @@ public abstract class BaseController { return request.getAttribute("requestId").toString(); } - Asset checkout(String userId, String uuid, AssetType assetType, String requestId) throws Exception { - return baseBusinessLogic.getSdcRestClient().changeAssetLifecycleState(userId, uuid, LifecycleOperationType.CHECKOUT.name(), null, assetType, requestId); + ResourceDetailed checkoutVfcmt(String userId, String uuid, String requestId) { + return baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, uuid, LifecycleOperationType.CHECKOUT.name(), null, requestId); } - Asset checkin(String userId, String uuid, AssetType assetType, String requestId) throws Exception { - return baseBusinessLogic.getSdcRestClient().changeAssetLifecycleState(userId, uuid, LifecycleOperationType.CHECKIN.name(), "checking in " + assetType.name() + uuid, assetType, requestId); + ResourceDetailed checkinVfcmt(String userId, String uuid, String requestId) { + return baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, uuid, LifecycleOperationType.CHECKIN.name(), "checking in vfcmt" + uuid, requestId); } @@ -55,7 +55,7 @@ public abstract class BaseController { return DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT != DcaeBeConstants.LifecycleStateEnum.findState(lifecycleState); } - void checkUserIfResourceCheckedOut(String userId, Asset asset) throws DcaeException { + void checkUserIfResourceCheckedOut(String userId, Asset asset) { if (DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT == DcaeBeConstants.LifecycleStateEnum.findState(asset.getLifecycleState())) { String lastUpdaterUserId = asset.getLastUpdaterUserId(); if (lastUpdaterUserId != null && !lastUpdaterUserId.equals(userId)) { @@ -67,7 +67,7 @@ public abstract class BaseController { } void checkVfcmtType(ResourceDetailed vfcmt) { - if (!"VFCMT".equals(vfcmt.getResourceType()) || !"Template".equals(vfcmt.getCategory())) { + if (AssetType.VFCMT != getValidAssetTypeOrNull(vfcmt.getResourceType()) || !"Template".equals(vfcmt.getCategory())) { ResponseFormat responseFormat = ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.RESOURCE_NOT_VFCMT_ERROR, null, vfcmt.getUuid()); throw new DcaeException(HttpStatus.BAD_REQUEST, responseFormat.getRequestError()); } @@ -77,4 +77,13 @@ public abstract class BaseController { errLogger.log(LogLevel.ERROR, this.getClass().getName(), e.getMessage()); return ErrConfMgr.INSTANCE.handleException(e, apiType, variables); } + + AssetType getValidAssetTypeOrNull(String type) { + try { + return AssetType.getAssetTypeByName(type); + } catch (IllegalArgumentException e) { + debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "invalid asset type: {}. Error: {}", type, e); + return null; + } + } } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BlueprintController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BlueprintController.java index a12c6b8..5f4cee7 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BlueprintController.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BlueprintController.java @@ -1,239 +1,54 @@ package org.onap.sdc.dcae.composition.controller; -import org.apache.commons.lang.StringUtils; -import org.onap.sdc.common.onaplog.Enums.LogLevel; -import org.onap.sdc.dcae.composition.restmodels.MessageResponse; -import org.onap.sdc.dcae.catalog.asdc.ASDC; -import org.onap.sdc.dcae.catalog.asdc.ASDCUtils; -import org.onap.sdc.dcae.catalog.asdc.Blueprinter; -import org.onap.sdc.dcae.composition.restmodels.sdc.*; -import org.onap.sdc.dcae.utils.Normalizers; -import org.onap.sdc.dcae.composition.util.DcaeBeConstants; -import org.onap.sdc.dcae.enums.ArtifactType; +import org.onap.sdc.dcae.composition.impl.BlueprintBusinessLogic; import org.onap.sdc.dcae.enums.AssetType; -import org.onap.sdc.dcae.enums.LifecycleOperationType; -import org.onap.sdc.dcae.errormng.ActionStatus; -import org.onap.sdc.dcae.errormng.ErrConfMgr; -import org.onap.sdc.dcae.errormng.ErrConfMgr.ApiType; -import org.onap.sdc.dcae.utils.SdcRestClientUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.util.Base64Utils; -import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import javax.annotation.PostConstruct; -import java.io.StringReader; -import java.net.URI; @RestController @EnableAutoConfiguration @CrossOrigin -public class BlueprintController extends BaseController{ - - @Autowired - private Blueprinter blueprinter; - - @Autowired - private ASDC asdc; - - private static final String CREATE_DESC = "creating new artifact blueprint on the service vfi"; - private static final String UPDATE_DESC = "updating artifact blueprint on the service vfi"; - +public class BlueprintController extends BaseController { + @Autowired + private BlueprintBusinessLogic blueprintBusinessLogic; @PostConstruct public void init(){ - URI sdcUri = URI.create(systemProperties.getProperties().getProperty(DcaeBeConstants.Config.URI)); - asdc.setUri(sdcUri); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "SDC uri: {}", sdcUri); - } - - /*** - * VFCMT - Resource, blueprint - as an artifact as an service. - * @param userId - * @param vfcmtUuid - * @param serviceUuid - * @param serviceInstanceName - * @param monitoringFlowType - * @return ResponseEntity - */ - @RequestMapping(value = "/createBluePrint/{VFCMTUuid}/{serviceUuid}/{instanceName}/{monitoringFlowType}", method = RequestMethod.POST) - public ResponseEntity createBluePrint(@RequestHeader("USER_ID") String userId, - @PathVariable("VFCMTUuid") String vfcmtUuid, - @PathVariable("serviceUuid") String serviceUuid, - @PathVariable("instanceName") String serviceInstanceName, - @PathVariable("monitoringFlowType") String monitoringFlowType, - @ModelAttribute("requestId") String requestId) { - try { - - ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString()); - checkVfcmtType(vfcmt); - Artifact cdumpArtifactData = findCdumpArtifactData(vfcmt); - if (null != cdumpArtifactData) { - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Found the cdump (composition.yml) on top of VFCMT {}", vfcmtUuid); - String cdump = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, cdumpArtifactData.getArtifactUUID(), requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "---------------------------------------------------------------CDUMP: -----------------------------------------------------------------------------"); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), cdump); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "---------------------------------------------------------------------------------------------------------------------------------------------------"); - ASDCUtils utils = new ASDCUtils(asdc, blueprinter); - - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Going to use python procedure to create a blueprint...."); - String resultBlueprintCreation; - try{ - resultBlueprintCreation = utils.buildBlueprintViaToscaLab(new StringReader(cdump)).waitForResult().waitForResult(); - }catch (Exception e){ - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERATE_BLUEPRINT_ERROR, e.getMessage(), vfcmt.getName()); - } - if (StringUtils.isEmpty(resultBlueprintCreation)) { - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERATE_BLUEPRINT_ERROR, "", vfcmt.getName()); - } - - // 1806 US374595 flowType in cdump - String flowTypeFromCdump = StringUtils.substringBetween(cdump,"\"flowType\":\"","\""); - if(StringUtils.isNotBlank(flowTypeFromCdump)) { - monitoringFlowType = flowTypeFromCdump; - } - // saving to serviceVfInstance - Artifact savedBluePrint = saveBluePrint(userId, serviceUuid, serviceInstanceName, resultBlueprintCreation, monitoringFlowType, vfcmt.getName(), requestId); - if(savedBluePrint!=null){ - MessageResponse response = new MessageResponse(); - response.setSuccessResponse("Blueprint build complete \n. Blueprint="+savedBluePrint.getArtifactName()); - //1806 US374593 - certify VFCMT after BP generation - certifyVfcmt(vfcmt, requestId); - return new ResponseEntity<>(response, HttpStatus.OK); - } - else{ - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SUBMIT_BLUEPRINT_ERROR); - } - - }else{ - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", vfcmt.getName()); - } - } catch (Exception e) { - return handleException(e, ApiType.SUBMIT_BLUEPRINT); - } - } - - - /********************* private function ********************/ - - /** - * @param userId - * @param serviceUuid - * @param resourceInstanceName - * @param bluePrint - * @param monitoringFlowType - * @param vfcmtName - * @param requestId - * @return - * @throws Exception - */ - private Artifact saveBluePrint(String userId, String serviceUuid, String resourceInstanceName, String bluePrint, String monitoringFlowType, String vfcmtName, String requestId) throws Exception { - - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "BLUEPRINT:\n{}", bluePrint); - try { - ServiceDetailed service = baseBusinessLogic.getSdcRestClient().getService(serviceUuid, requestId); - //Validations - checkUserIfResourceCheckedOut(userId, service); - ResourceInstance vfi = findVfiOnService(service, resourceInstanceName); - if(null == vfi){ - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "VF instance {} not found on service {}", resourceInstanceName, serviceUuid); - return null; - } - - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), service.toString()); - - String normalizedArtifactLabel = Normalizers.normalizeArtifactLabel("blueprint-" + monitoringFlowType); - Artifact blueprintArtifact = CollectionUtils.isEmpty(vfi.getArtifacts()) ? null : vfi.getArtifacts().stream() - .filter(p -> normalizedArtifactLabel.equals(Normalizers.normalizeArtifactLabel(p.getArtifactLabel()))) - .findAny() - .orElse(null); - - boolean isNeed2Checkout = isNeedToCheckOut(service.getLifecycleState()); - if (isNeed2Checkout) { - Asset result = checkout(userId, serviceUuid, AssetType.SERVICE, requestId); - if (result != null) { - serviceUuid = result.getUuid(); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New service after checkout is: {}", serviceUuid); - } - } - //update mode - if (null != blueprintArtifact) { - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Found that service {} already consist of {} ----> updateMode", serviceUuid, normalizedArtifactLabel); - blueprintArtifact.setDescription(UPDATE_DESC); - blueprintArtifact.setPayloadData(Base64Utils.encodeToString(bluePrint.getBytes())); - blueprintArtifact = baseBusinessLogic.getSdcRestClient().updateVfInstanceArtifact(userId, serviceUuid, Normalizers.normalizeComponentInstanceName(resourceInstanceName), blueprintArtifact, requestId); - //create mode - } else { - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Service {} does not consist {} ----> createMode", serviceUuid, normalizedArtifactLabel); - blueprintArtifact = SdcRestClientUtils.generateDeploymentArtifact(CREATE_DESC, generateBlueprintFileName(monitoringFlowType, vfcmtName), ArtifactType.DCAE_INVENTORY_BLUEPRINT.name(), normalizedArtifactLabel, bluePrint.getBytes()); - blueprintArtifact = baseBusinessLogic.getSdcRestClient().createVfInstanceArtifact(userId, serviceUuid, Normalizers.normalizeComponentInstanceName(resourceInstanceName), blueprintArtifact, requestId); - } - - //No need to check the service in in 1806 -// Asset blueprintAsJson = checkin(user_id, serviceUuid, AssetType.SERVICE); -// debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "service result after check-in: {}", blueprintAsJson.toString()); - - return blueprintArtifact; - - } catch (Exception e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occurred while trying to save blueprint {}", e.toString()); - throw e; - } - } - - /** - * - * @param monitoringFlowType - * @param vfcmtName - * @return - */ - private String generateBlueprintFileName(String monitoringFlowType, String vfcmtName) { - StringBuffer sb = new StringBuffer(); - sb.append(monitoringFlowType); - sb.append("."); - sb.append(Normalizers.normalizeComponentName(vfcmtName)); - sb.append("."); - sb.append(DcaeBeConstants.Composition.fileNames.EVENT_PROC_BP_YAML); - return sb.toString(); - } - - private ResourceInstance findVfiOnService(ServiceDetailed service, String vfiName) { - return null == service ? null : CollectionUtils.isEmpty(service.getResources()) ? null : service.getResources().stream().filter(p -> vfiName.equals(p.getResourceInstanceName())).findAny().orElse(null); - } - - private Artifact findCdumpArtifactData(ResourceDetailed vfcmt) { - return null == vfcmt ? null : CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? null : vfcmt.getArtifacts().stream() - .filter(p -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(p.getArtifactName())).findAny().orElse(null); - } - - private void certifyVfcmt(ResourceDetailed vfcmt, String requestId){ - String state = vfcmt.getLifecycleState(); - if(null == state) { - debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "Couldn't read Vfcmt lifecycle state"); - return; - } - DcaeBeConstants.LifecycleStateEnum lifeCycleState = DcaeBeConstants.LifecycleStateEnum.findState(state); - if(null == lifeCycleState) { - debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "Undefined lifecycle state: {}", state); - return; - } - try{ - switch (lifeCycleState){ - case NOT_CERTIFIED_CHECKOUT: - baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(vfcmt.getLastUpdaterUserId(), vfcmt.getUuid(), LifecycleOperationType.CHECKIN.name(), "check in VFCMT after blueprint successful submission", requestId); - case NOT_CERTIFIED_CHECKIN: - baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(vfcmt.getLastUpdaterUserId(), vfcmt.getUuid(), LifecycleOperationType.CERTIFY.name(), "certify VFCMT after blueprint successful submission", requestId); - } - } - catch (Exception e){ - //informative only. no message to user (TBA) - debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occurred during vfcmt lifecycle operation: {}", e.toString()); - } } + /*** + * VFCMT - Resource, blueprint - as an artifact as an service. + * @param context + * @param userId + * @param vfcmtUuid + * @param serviceUuid + * @param instanceName + * @param requestId + * @return ResponseEntity + */ + @RequestMapping(value = "{context}/createBluePrint/{VFCMTUuid}/{serviceUuid}/{instanceName}", method = RequestMethod.POST) + public ResponseEntity createBlueprint(@RequestHeader("USER_ID") String userId, + @PathVariable String context, + @PathVariable("VFCMTUuid") String vfcmtUuid, + @PathVariable("serviceUuid") String serviceUuid, + @PathVariable("instanceName") String instanceName, + @ModelAttribute("requestId") String requestId) { + return blueprintBusinessLogic.generateAndSaveBlueprint(userId, context, vfcmtUuid, serviceUuid, instanceName, "", requestId); + } + + @Deprecated + @RequestMapping(value = "/createBluePrint/{VFCMTUuid}/{serviceUuid}/{instanceName}/{monitoringFlowType}", method = RequestMethod.POST) + public ResponseEntity createBluePrintWithFlowType(@RequestHeader("USER_ID") String userId, + @PathVariable("VFCMTUuid") String vfcmtUuid, + @PathVariable("serviceUuid") String serviceUuid, + @PathVariable("instanceName") String serviceInstanceName, + @PathVariable("monitoringFlowType") String monitoringFlowType, + @ModelAttribute("requestId") String requestId) { + return blueprintBusinessLogic.generateAndSaveBlueprint(userId, AssetType.SERVICE.name(), vfcmtUuid, serviceUuid, serviceInstanceName, monitoringFlowType, requestId); + } } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/CompositionController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/CompositionController.java index 5cba14f..3261ddc 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/CompositionController.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/CompositionController.java @@ -3,7 +3,9 @@ package org.onap.sdc.dcae.composition.controller; import org.json.JSONArray; import org.json.JSONException; import org.onap.sdc.common.onaplog.Enums.LogLevel; +import org.onap.sdc.dcae.composition.impl.CompositionBusinessLogic; import org.onap.sdc.dcae.composition.restmodels.MessageResponse; +import org.onap.sdc.dcae.composition.restmodels.ReferenceUUID; import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; import org.onap.sdc.dcae.composition.restmodels.sdc.Asset; import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed; @@ -11,17 +13,14 @@ import org.onap.sdc.dcae.catalog.Catalog; import org.onap.sdc.dcae.catalog.Catalog.*; import org.onap.sdc.dcae.catalog.engine.*; import org.onap.sdc.dcae.composition.util.DcaeBeConstants; -import org.onap.sdc.dcae.enums.ArtifactType; import org.onap.sdc.dcae.enums.LifecycleOperationType; import org.onap.sdc.dcae.errormng.ActionStatus; import org.onap.sdc.dcae.errormng.ErrConfMgr; import org.onap.sdc.dcae.errormng.ErrConfMgr.ApiType; -import org.onap.sdc.dcae.utils.SdcRestClientUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.util.Base64Utils; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.async.DeferredResult; @@ -37,302 +36,281 @@ import java.util.stream.Collectors; @RestController @EnableAutoConfiguration @CrossOrigin -public class CompositionController extends BaseController{ - - @Autowired - private CatalogController catalogController; - - @PostConstruct - public void init() { - catalogController.setDefaultCatalog(URI.create(systemProperties.getProperties().getProperty(DcaeBeConstants.Config.ASDC_CATALOG_URL))); - } - - @RequestMapping(value = { "/utils/clone/{assetType}/{sourceId}/{targetId}" }, method = {RequestMethod.GET }, produces = { "application/json" }) - public ResponseEntity clone(@RequestHeader("USER_ID") String userId, @PathVariable("assetType") String theAssetType, @PathVariable("sourceId") String theSourceId, @PathVariable("targetId") String theTargetId, - @ModelAttribute("requestId") String requestId) { - MessageResponse response = new MessageResponse(); - - try { - // fetch the source and assert it is a vfcmt containing clone worthy artifacts (composition + rules) - ResourceDetailed sourceVfcmt = baseBusinessLogic.getSdcRestClient().getResource(theSourceId, requestId); - checkVfcmtType(sourceVfcmt); - List<Artifact> artifactsToClone = CollectionUtils.isEmpty(sourceVfcmt.getArtifacts()) ? null : sourceVfcmt.getArtifacts().stream() - .filter(p -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(p.getArtifactName()) || p.getArtifactName().endsWith(DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX)) - .collect(Collectors.toList()); - if(CollectionUtils.isEmpty(artifactsToClone)) { - response.setSuccessResponse("Nothing to clone"); - return new ResponseEntity<>(response ,HttpStatus.NO_CONTENT); - } - - // fetch the target - ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(theTargetId, requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString()); - checkVfcmtType(vfcmt); - checkUserIfResourceCheckedOut(userId, vfcmt); - boolean isTargetNeed2Checkout = isNeedToCheckOut(vfcmt.getLifecycleState()); - if (isTargetNeed2Checkout) { - ResourceDetailed targetVfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, theTargetId, LifecycleOperationType.CHECKOUT.name(), "checking out VFCMT before clone", requestId); - if(null == targetVfcmt){ - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERAL_ERROR); - } - theTargetId = targetVfcmt.getUuid(); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New targetVfcmt (for artifact clone) after checkout is: {}", theTargetId); - } - - Map<String, Artifact> currentArtifacts = CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? new HashMap<>() : vfcmt.getArtifacts().stream() - .collect(Collectors.toMap(Artifact::getArtifactName, Function.identity())); - - //TODO target VFCMT rule artifacts should be removed - for(Artifact artifactToClone : artifactsToClone) { - String payload = baseBusinessLogic.getSdcRestClient().getResourceArtifact(theSourceId, artifactToClone.getArtifactUUID(), requestId); - baseBusinessLogic.cloneArtifactToTarget(userId, theTargetId, payload, artifactToClone, currentArtifacts.get(artifactToClone.getArtifactName()), requestId); - } - - baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, theTargetId, LifecycleOperationType.CHECKIN.name(), "check in VFCMT after clone", requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Cloning {} from {} has finished successfully", theSourceId, theTargetId); - response.setSuccessResponse("Clone VFCMT complete"); - return new ResponseEntity<>(response, HttpStatus.OK); - } catch (Exception e) { - return handleException(e, ApiType.CLONE_VFCMT); - } - } - - @RequestMapping(value = "/elements", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json") - public DeferredResult<CatalogResponse> items(@RequestBody(required = false) ItemsRequest theRequest) { - - final ItemsRequest request = (theRequest == null) ? ItemsRequest.EMPTY_REQUEST : theRequest; - - Catalog catalog = catalogController.getCatalog(request.getCatalog()); - DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout()); - - catalog.rootsByLabel(request.getStartingLabel()) - .setHandler(catalogController.new CatalogHandler<Folders>(request, result) { - public CatalogResponse handleData(Folders theFolders) { - JSONArray ja = new JSONArray(); - if (theFolders != null) { - for (Folder folder : theFolders) { - ja.put(catalogController.patchData(catalog, folder.data())); - } - } - CatalogResponse response = new CatalogResponse(this.request); - try { - response.data().put("elements", ja); - } catch (JSONException e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "JSONException putting json elements to response {}", e); - } - return response; - } - }); - return result; - } - - @RequestMapping(value = "/{theItemId}/elements", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json") - public DeferredResult<CatalogResponse> items(@RequestBody(required = false) ItemsRequest theRequest, @PathVariable String theItemId) { - - final ItemsRequest request = (theRequest == null) ? ItemsRequest.EMPTY_REQUEST : theRequest; - - Catalog catalog = catalogController.getCatalog(request.getCatalog()); - DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout()); - - catalog - // .fetchFolderByItemId(theItemId) - .folder(theItemId).withParts().withPartAnnotations().withItems().withItemAnnotations().withItemModels() - .execute().setHandler(catalogController.new CatalogHandler<Folder>(request, result) { - public CatalogResponse handleData(Folder theFolder) { - CatalogResponse response = new CatalogResponse(this.request); - if (theFolder == null) { - return response; - } - - try { - Elements folders = theFolder.elements("parts", Folders.class); - if (folders != null) { - for (Object folder : folders) { - catalogController.patchData(catalog, ((Element) folder).data()); - // lots of ephemere proxies created here .. - Elements annotations = ((Element) folder).elements("annotations", - Annotations.class); - if (annotations != null) { - for (Object a : annotations) { - catalogController.patchData(catalog, ((Annotation) a).data()); - } - } - } - } - Elements items = theFolder.elements("items", Items.class); - if (items != null) { - for (Object i : items) { - catalogController.patchData(catalog, ((Element) i).data()); - // lots of ephemere proxies created here .. - Elements annotations = ((Element) i).elements("annotations", Annotations.class); - if (annotations != null) { - for (Object a : annotations) { - catalogController.patchData(catalog, ((Annotation) a).data()); - } - } - } - } - } catch (Exception x) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Exception processing catalog {}", x); - return new CatalogError(this.request, "", x); - } - - try { - response.data().put("element", theFolder.data()); - } catch (JSONException e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "JSONException putting element to response {}", e); - } - return response; - } - }); - - return result; - } - - @RequestMapping(value = "/{theItemId}/model", method = { RequestMethod.POST,RequestMethod.GET }, produces = "application/json") - public DeferredResult model(@RequestBody(required = false) ElementRequest theRequest, - @PathVariable String theItemId) { - final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest; - - Catalog catalog = catalogController.getCatalog(request.getCatalog()); - DeferredResult<CatalogResponse> result = new DeferredResult<>(request.getTimeout()); - - catalog - .item(theItemId).withModels().execute() - .setHandler(catalogController.new CatalogHandler<Item>(request, result) { - public CatalogResponse handleData(Item theItem) { - if (theItem == null) { - return new CatalogError(this.request, "No such item"); - } - Templates models = null; - try { - models = (Templates) theItem.elements("models", Templates.class); - if (models == null || models.isEmpty()) { - return new CatalogError(this.request, "Item has no models"); - } - if (models.size() > 1) { - return new CatalogError(this.request, "Item has more than one model !?"); - } - catalog.template(models.get(0).id()).withInputs().withOutputs().withNodes() - .withNodeProperties().withNodePropertiesAssignments().withNodeRequirements() - .withNodeCapabilities().withNodeCapabilityProperties() - .withNodeCapabilityPropertyAssignments().withPolicies().withPolicyProperties() - .withPolicyPropertiesAssignments().execute().setHandler( - catalogController.new CatalogHandler<Template>(this.request, this.result) { - public CatalogResponse handleData(Template theTemplate) { - CatalogResponse response = new CatalogResponse(this.request); - if (theTemplate != null) { - try { - response.data().put("model", catalogController - .patchData(catalog, theTemplate.data())); - } catch (JSONException e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "JSONException putting model to response {}", e); - } - } - return response; - } - }); - } catch (Exception e) { - handleException(e, ApiType.GET_MODEL, models.get(0).name()); - } - return null; - } - }); - - return result; - } - - @RequestMapping(value = "/{theItemId}/type/{theTypeName}", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json") - public DeferredResult<CatalogResponse> model(@RequestBody(required = false) ElementRequest theRequest, @PathVariable String theItemId, @PathVariable String theTypeName) { - final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest; - - Catalog catalog = catalogController.getCatalog(request.getCatalog()); - DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout()); - - catalog.type(theItemId, theTypeName).withHierarchy().withCapabilities().withRequirements().execute() - .setHandler(catalogController.new CatalogHandler<Type>(request, result) { - public CatalogResponse handleData(Type theType) { - CatalogResponse response = new CatalogResponse(this.request); - if (theType != null) { - try { - response.data().put("type", catalogController.patchData(catalog, theType.data())); - } catch (JSONException e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Exception processing catalog {}", e); - } - } - return response; - } - }); - - return result; - } - - @RequestMapping(value = { "/getComposition/{vfcmtUuid}" }, method = { RequestMethod.GET }, produces = {"application/json" }) - public ResponseEntity getComposition(@PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId) { - MessageResponse response = new MessageResponse(); - try { - ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString()); - checkVfcmtType(vfcmt); - - Artifact compositionArtifact = CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? null : vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(a.getArtifactName())).findAny().orElse(null); - - if(null == compositionArtifact){ - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Couldn't find {} in VFCMT artifacts", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML); - response.setErrorResponse("No Artifacts"); - return new ResponseEntity<>(response, HttpStatus.NO_CONTENT); - } - - String artifact = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, compositionArtifact.getArtifactUUID(), requestId); - - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "ARTIFACT: {}", artifact); - response.setSuccessResponse(artifact); - return new ResponseEntity<>(response, HttpStatus.OK); - } catch (Exception e) { - return handleException(e, ApiType.GET_CDUMP); - } - } - - @RequestMapping(value = "/saveComposition/{vfcmtUuid}", method = RequestMethod.POST) - public ResponseEntity saveComposition(@RequestHeader("USER_ID") String userId, @RequestBody String theCdump, @PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId) { - - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "ARTIFACT CDUMP: {}", theCdump); - - try { - - ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "VFCMT: {}", vfcmt); - - checkVfcmtType(vfcmt); - checkUserIfResourceCheckedOut(userId, vfcmt); - boolean isNeed2Checkout = isNeedToCheckOut(vfcmt.getLifecycleState()); - Artifact compositionArtifact = CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? null : vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(a.getArtifactName())).findAny().orElse(null); - String resourceUuid = vfcmtUuid; // by default the resource is the original vfcmtId unless a checkout will be done - if (isNeed2Checkout) { - vfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, resourceUuid, LifecycleOperationType.CHECKOUT.name(), null, requestId); - if (vfcmt != null) { - resourceUuid = vfcmt.getUuid(); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New resource after checkout is: {}", resourceUuid); - } - } - boolean isUpdateMode = null != compositionArtifact; - if (isUpdateMode) { - compositionArtifact.setDescription("updating composition file"); - compositionArtifact.setPayloadData(Base64Utils.encodeToString(theCdump.getBytes())); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "VFCMT {} does consist {} ----> updateMode", resourceUuid, DcaeBeConstants.Composition.fileNames.COMPOSITION_YML); - baseBusinessLogic.getSdcRestClient().updateResourceArtifact(userId, resourceUuid, compositionArtifact, requestId); - - } else { - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "VFCMT {} does not consist {} ----> createMode", resourceUuid, DcaeBeConstants.Composition.fileNames.COMPOSITION_YML); - compositionArtifact = SdcRestClientUtils.generateDeploymentArtifact("creating composition file", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML, ArtifactType.DCAE_TOSCA.name(), "composition", theCdump.getBytes()); - baseBusinessLogic.getSdcRestClient().createResourceArtifact(userId, resourceUuid, compositionArtifact, requestId); - } - Asset result = checkin(userId, resourceUuid, org.onap.sdc.dcae.enums.AssetType.RESOURCE, requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "vfcmt check-in result: {}", result); - - return new ResponseEntity<>(result, HttpStatus.OK); - } catch (Exception e) { - return handleException(e, ApiType.SAVE_CDUMP); - } - } -} +public class CompositionController extends BaseController { + + @Autowired private CatalogController catalogController; + + @Autowired private CompositionBusinessLogic compositionBusinessLogic; + + @PostConstruct public void init() { + catalogController.setDefaultCatalog(URI.create(systemProperties.getProperties().getProperty(DcaeBeConstants.Config.ASDC_CATALOG_URL))); + } + + @RequestMapping(value = { "/utils/clone/{assetType}/{sourceId}/{targetId}" }, method = { RequestMethod.GET }, produces = { "application/json" }) public ResponseEntity clone(@RequestHeader("USER_ID") String userId, + @PathVariable("assetType") String theAssetType, @PathVariable("sourceId") String theSourceId, @PathVariable("targetId") String theTargetId, @ModelAttribute("requestId") String requestId) { + MessageResponse response = new MessageResponse(); + + try { + // fetch the source and assert it is a vfcmt containing clone worthy artifacts (composition + rules) + ResourceDetailed sourceVfcmt = baseBusinessLogic.getSdcRestClient().getResource(theSourceId, requestId); + checkVfcmtType(sourceVfcmt); + List<Artifact> artifactsToClone = CollectionUtils.isEmpty(sourceVfcmt.getArtifacts()) ? + null : + sourceVfcmt.getArtifacts().stream().filter(p -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(p.getArtifactName()) || p.getArtifactName().endsWith(DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX)) + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(artifactsToClone)) { + response.setSuccessResponse("Nothing to clone"); + return new ResponseEntity<>(response, HttpStatus.NO_CONTENT); + } + + // fetch the target + ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(theTargetId, requestId); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString()); + checkVfcmtType(vfcmt); + checkUserIfResourceCheckedOut(userId, vfcmt); + boolean isTargetNeed2Checkout = isNeedToCheckOut(vfcmt.getLifecycleState()); + if (isTargetNeed2Checkout) { + ResourceDetailed targetVfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, theTargetId, LifecycleOperationType.CHECKOUT.name(), "checking out VFCMT before clone", requestId); + if (null == targetVfcmt) { + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERAL_ERROR); + } + theTargetId = targetVfcmt.getUuid(); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New targetVfcmt (for artifact clone) after checkoutVfcmt is: {}", theTargetId); + } + + Map<String, Artifact> currentArtifacts = CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? new HashMap<>() : vfcmt.getArtifacts().stream().collect(Collectors.toMap(Artifact::getArtifactName, Function.identity())); + + //TODO target VFCMT rule artifacts should be removed + for (Artifact artifactToClone : artifactsToClone) { + String payload = baseBusinessLogic.getSdcRestClient().getResourceArtifact(theSourceId, artifactToClone.getArtifactUUID(), requestId); + baseBusinessLogic.cloneArtifactToTarget(userId, theTargetId, payload, artifactToClone, currentArtifacts.get(artifactToClone.getArtifactName()), requestId); + } + + baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, theTargetId, LifecycleOperationType.CHECKIN.name(), "check in VFCMT after clone", requestId); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Cloning {} from {} has finished successfully", theSourceId, theTargetId); + response.setSuccessResponse("Clone VFCMT complete"); + return new ResponseEntity<>(response, HttpStatus.OK); + } catch (Exception e) { + return handleException(e, ApiType.CLONE_VFCMT); + } + } + + @RequestMapping(value = "/elements", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json") public DeferredResult<CatalogResponse> items(@RequestBody(required = false) ItemsRequest theRequest) { + + final ItemsRequest request = (theRequest == null) ? ItemsRequest.EMPTY_REQUEST : theRequest; + + Catalog catalog = catalogController.getCatalog(request.getCatalog()); + DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout()); + + catalog.rootsByLabel(request.getStartingLabel()).setHandler(catalogController.new CatalogHandler<Folders>(request, result) { + public CatalogResponse handleData(Folders theFolders) { + JSONArray ja = new JSONArray(); + if (theFolders != null) { + for (Folder folder : theFolders) { + ja.put(catalogController.patchData(catalog, folder.data())); + } + } + CatalogResponse response = new CatalogResponse(this.request); + try { + response.data().put("elements", ja); + } catch (JSONException e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "JSONException putting json elements to response {}", e); + } + return response; + } + }); + return result; + } + + @RequestMapping(value = "/{theItemId}/elements", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json") public DeferredResult<CatalogResponse> items(@RequestBody(required = false) ItemsRequest theRequest, + @PathVariable String theItemId) { + + final ItemsRequest request = (theRequest == null) ? ItemsRequest.EMPTY_REQUEST : theRequest; + + Catalog catalog = catalogController.getCatalog(request.getCatalog()); + DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout()); + + catalog + // .fetchFolderByItemId(theItemId) + .folder(theItemId).withParts().withPartAnnotations().withItems().withItemAnnotations().withItemModels().execute().setHandler(catalogController.new CatalogHandler<Folder>(request, result) { + public CatalogResponse handleData(Folder theFolder) { + CatalogResponse response = new CatalogResponse(this.request); + if (theFolder == null) { + return response; + } + + try { + Elements folders = theFolder.elements("parts", Folders.class); + if (folders != null) { + for (Object folder : folders) { + catalogController.patchData(catalog, ((Element) folder).data()); + // lots of ephemere proxies created here .. + Elements annotations = ((Element) folder).elements("annotations", Annotations.class); + if (annotations != null) { + for (Object a : annotations) { + catalogController.patchData(catalog, ((Annotation) a).data()); + } + } + } + } + Elements items = theFolder.elements("items", Items.class); + if (items != null) { + for (Object i : items) { + catalogController.patchData(catalog, ((Element) i).data()); + // lots of ephemere proxies created here .. + Elements annotations = ((Element) i).elements("annotations", Annotations.class); + if (annotations != null) { + for (Object a : annotations) { + catalogController.patchData(catalog, ((Annotation) a).data()); + } + } + } + } + } catch (Exception x) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Exception processing catalog {}", x); + return new CatalogError(this.request, "", x); + } + + try { + response.data().put("element", theFolder.data()); + } catch (JSONException e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "JSONException putting element to response {}", e); + } + return response; + } + }); + + return result; + } + + @RequestMapping(value = "/{theItemId}/model", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json") public DeferredResult model(@RequestBody(required = false) ElementRequest theRequest, + @PathVariable String theItemId) { + final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest; + + Catalog catalog = catalogController.getCatalog(request.getCatalog()); + DeferredResult<CatalogResponse> result = new DeferredResult<>(request.getTimeout()); + + catalog.item(theItemId).withModels().execute().setHandler(catalogController.new CatalogHandler<Item>(request, result) { + public CatalogResponse handleData(Item theItem) { + if (theItem == null) { + return new CatalogError(this.request, "No such item"); + } + Templates models = null; + try { + models = (Templates) theItem.elements("models", Templates.class); + if (models == null || models.isEmpty()) { + return new CatalogError(this.request, "Item has no models"); + } + if (models.size() > 1) { + return new CatalogError(this.request, "Item has more than one model !?"); + } + catalog.template(models.get(0).id()).withInputs().withOutputs().withNodes().withNodeProperties().withNodePropertiesAssignments().withNodeRequirements().withNodeCapabilities().withNodeCapabilityProperties() + .withNodeCapabilityPropertyAssignments().withPolicies().withPolicyProperties().withPolicyPropertiesAssignments().execute().setHandler(catalogController.new CatalogHandler<Template>(this.request, this.result) { + public CatalogResponse handleData(Template theTemplate) { + CatalogResponse response = new CatalogResponse(this.request); + if (theTemplate != null) { + try { + response.data().put("model", catalogController.patchData(catalog, theTemplate.data())); + } catch (JSONException e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "JSONException putting model to response {}", e); + } + } + return response; + } + }); + } catch (Exception e) { + handleException(e, ApiType.GET_MODEL, models.get(0).name()); + } + return null; + } + }); + + return result; + } + + @RequestMapping(value = "/{theItemId}/type/{theTypeName}", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json") public DeferredResult<CatalogResponse> model(@RequestBody(required = false) ElementRequest theRequest, + @PathVariable String theItemId, @PathVariable String theTypeName) { + final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest; + + Catalog catalog = catalogController.getCatalog(request.getCatalog()); + DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout()); + + catalog.type(theItemId, theTypeName).withHierarchy().withCapabilities().withRequirements().execute().setHandler(catalogController.new CatalogHandler<Type>(request, result) { + public CatalogResponse handleData(Type theType) { + CatalogResponse response = new CatalogResponse(this.request); + if (theType != null) { + try { + response.data().put("type", catalogController.patchData(catalog, theType.data())); + } catch (JSONException e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Exception processing catalog {}", e); + } + } + return response; + } + }); + + return result; + } + + @RequestMapping(value = { "/getComposition/{vfcmtUuid}" }, method = { RequestMethod.GET }, produces = { "application/json" }) public ResponseEntity getComposition(@PathVariable("vfcmtUuid") String vfcmtUuid, + @ModelAttribute("requestId") String requestId) { + MessageResponse response = new MessageResponse(); + try { + ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString()); + checkVfcmtType(vfcmt); + + Artifact compositionArtifact = CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? null : vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(a.getArtifactName())).findAny().orElse(null); + + if (null == compositionArtifact) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Couldn't find {} in VFCMT artifacts", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML); + response.setErrorResponse("No Artifacts"); + return new ResponseEntity<>(response, HttpStatus.NO_CONTENT); + } + + String artifact = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, compositionArtifact.getArtifactUUID(), requestId); + + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "ARTIFACT: {}", artifact); + response.setSuccessResponse(artifact); + return new ResponseEntity<>(response, HttpStatus.OK); + } catch (Exception e) { + return handleException(e, ApiType.GET_CDUMP); + } + } + + + @RequestMapping(value = { "/getMC/{vfcmtUuid}" }, method = { RequestMethod.GET }, produces = {"application/json" }) + public ResponseEntity getMC(@PathVariable String vfcmtUuid, @ModelAttribute String requestId) { + try { + return new ResponseEntity<>(compositionBusinessLogic.getDataAndComposition(vfcmtUuid, requestId), HttpStatus.OK); + } catch (Exception e) { + return handleException(e, ApiType.GET_VFCMT); + } + } + + @RequestMapping(value = "/saveComposition/{vfcmtUuid}", method = RequestMethod.POST) + public ResponseEntity saveComposition(@RequestHeader("USER_ID") String userId, @RequestBody String theCdump, @PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId) { + + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "ARTIFACT CDUMP: {}", theCdump); + return compositionBusinessLogic.saveComposition(userId, vfcmtUuid, theCdump, requestId, true); + } + + @RequestMapping(value = "/{contextType}/{serviceUuid}/{vfiName}/saveComposition/{vfcmtUuid}", method = RequestMethod.POST) + public ResponseEntity updateComposition(@RequestHeader("USER_ID") String userId, @RequestBody String theCdump, + @PathVariable String contextType, @PathVariable String serviceUuid, @PathVariable String vfiName, @PathVariable String vfcmtUuid, @ModelAttribute String requestId) { + + ResponseEntity res = compositionBusinessLogic.saveComposition(userId, vfcmtUuid, theCdump, requestId, false); + if (HttpStatus.OK == res.getStatusCode()) { + ResourceDetailed vfcmt = (ResourceDetailed) res.getBody(); + if (!vfcmtUuid.equals(vfcmt.getUuid())) { + try { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New vfcmt major version created with id {} , adding new reference.", vfcmt.getUuid()); + baseBusinessLogic.getSdcRestClient().addExternalMonitoringReference(userId, contextType, serviceUuid, vfiName, new ReferenceUUID(vfcmt.getUuid()), requestId); + } catch (Exception e) { + return handleException(e, ApiType.SAVE_CDUMP); + } + } + } + return res; + } +}
\ No newline at end of file diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/LifecycleController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/LifecycleController.java index 3007335..4fa8c18 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/LifecycleController.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/LifecycleController.java @@ -1,6 +1,6 @@ package org.onap.sdc.dcae.composition.controller; -import org.onap.sdc.dcae.composition.restmodels.sdc.Asset; +import org.onap.sdc.common.onaplog.Enums.LogLevel; import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed; import org.onap.sdc.dcae.enums.AssetType; import org.onap.sdc.dcae.enums.LifecycleOperationType; @@ -17,24 +17,20 @@ import java.util.UUID; @CrossOrigin public class LifecycleController extends BaseController { - private static final String VFCMT = "vfcmt"; - @RequestMapping(value={"/checkin/{assetType}/{uuid}"}, method={RequestMethod.PUT}, produces={"application/json"}) public ResponseEntity putCheckin( @PathVariable("assetType") String assetType, @PathVariable("uuid") UUID uuid, - @RequestHeader("USER_ID") String user_id, + @RequestHeader("USER_ID") String userId, @ModelAttribute("requestId") String requestId) { try { - switch (assetType) { - case VFCMT: - Asset res_checkin = checkin(user_id, uuid.toString(), AssetType.RESOURCE, requestId); - return new ResponseEntity<>(res_checkin, HttpStatus.OK); - - default: - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - } + if (AssetType.VFCMT == getValidAssetTypeOrNull(assetType)) { + ResourceDetailed resCheckin = checkinVfcmt(userId, uuid.toString(), requestId); + return new ResponseEntity<>(resCheckin, HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } } catch (Exception e) { return handleException(e, ErrConfMgr.ApiType.CHECK_IN_RESOURCE); } @@ -44,17 +40,15 @@ public class LifecycleController extends BaseController { public ResponseEntity putCheckout( @PathVariable("assetType") String assetType, @PathVariable("uuid") UUID uuid, - @RequestHeader("USER_ID") String user_id, + @RequestHeader("USER_ID") String userId, @ModelAttribute("requestId") String requestId) { try { - switch (assetType) { - case VFCMT: - Asset asset = checkout(user_id, uuid.toString(), AssetType.RESOURCE, requestId); - return new ResponseEntity<>(asset, HttpStatus.OK); - - default: - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + if (AssetType.VFCMT == getValidAssetTypeOrNull(assetType)) { + ResourceDetailed asset = checkoutVfcmt(userId, uuid.toString(), requestId); + return new ResponseEntity<>(asset, HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } catch (Exception e) { return handleException(e, ErrConfMgr.ApiType.CHECK_OUT_RESOURCE); @@ -65,20 +59,20 @@ public class LifecycleController extends BaseController { public ResponseEntity putCertify( @PathVariable("assetType") String assetType, @PathVariable("uuid") String uuid, - @RequestHeader("USER_ID") String user_id, + @RequestHeader("USER_ID") String userId, @ModelAttribute("requestId") String requestId) { try { - switch (assetType) { - case VFCMT: - ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(user_id, uuid, LifecycleOperationType.CERTIFY.name(), "certifying VFCMT", requestId); - return new ResponseEntity<>(vfcmt, HttpStatus.OK); + if (AssetType.VFCMT == getValidAssetTypeOrNull(assetType)) { + ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, uuid, LifecycleOperationType.CERTIFY.name(), "certifying VFCMT", requestId); + return new ResponseEntity<>(vfcmt, HttpStatus.OK); - default: + } else { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } catch (Exception e) { return handleException(e, ErrConfMgr.ApiType.CHECK_OUT_RESOURCE); } } + } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/RuleEditorController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/RuleEditorController.java index 3f5ff1a..8de8520 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/RuleEditorController.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/RuleEditorController.java @@ -1,89 +1,37 @@ package org.onap.sdc.dcae.composition.controller; -import com.google.gson.JsonParseException; -import org.apache.commons.collections.ListUtils; -import org.apache.commons.collections.MapUtils; -import org.apache.commons.lang3.StringUtils; import org.onap.sdc.common.onaplog.Enums.LogLevel; -import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; -import org.onap.sdc.dcae.composition.restmodels.sdc.Asset; -import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed; -import org.onap.sdc.dcae.composition.CompositionConfig; -import org.onap.sdc.dcae.utils.Normalizers; -import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*; -import org.onap.sdc.dcae.composition.util.DcaeBeConstants; -import org.onap.sdc.dcae.enums.ArtifactType; -import org.onap.sdc.dcae.enums.AssetType; -import org.onap.sdc.dcae.errormng.ActionStatus; -import org.onap.sdc.dcae.errormng.ErrConfMgr; -import org.onap.sdc.dcae.errormng.ErrConfMgr.ApiType; -import org.onap.sdc.dcae.errormng.ServiceException; -import org.onap.sdc.dcae.rule.editor.impl.RulesBusinessLogic; -import org.onap.sdc.dcae.rule.editor.utils.RulesPayloadUtils; -import org.onap.sdc.dcae.utils.SdcRestClientUtils; -import org.onap.sdc.dcae.ves.VesDataItemsDefinition; -import org.onap.sdc.dcae.ves.VesDataTypeDefinition; -import org.onap.sdc.dcae.ves.VesSimpleTypesEnum; -import org.onap.sdc.dcae.ves.VesStructureLoader; +import org.onap.sdc.dcae.composition.impl.RuleEditorBusinessLogic; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.util.Base64Utils; -import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; -import java.util.stream.Stream; -@RestController -@EnableAutoConfiguration -@CrossOrigin -@RequestMapping("/rule-editor") +@RestController +@EnableAutoConfiguration +@CrossOrigin +@RequestMapping("/rule-editor") public class RuleEditorController extends BaseController { private static final String EXCEPTION = "Exception {}"; - @Autowired - private CompositionConfig compositionConfig; @Autowired - private RulesBusinessLogic rulesBusinessLogic; + private RuleEditorBusinessLogic ruleEditorBusinessLogic; @RequestMapping(value = "/list-events-by-versions", method = RequestMethod.GET) public ResponseEntity getEventsByVersion() { - try { - - Map<String, Set<String>> eventsByVersions = VesStructureLoader.getAvailableVersionsAndEventTypes(); - - List<EventTypesByVersionUI> resBody = eventsByVersions.entrySet().stream().map(entry -> { - Set<String> events = entry.getValue().stream().filter(event -> !EventTypesByVersionUI.DEFAULT_EVENTS.contains(event)).collect(Collectors.toSet()); - return new EventTypesByVersionUI(entry.getKey(), events); - }).collect(Collectors.toList()); - - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Got a request to return all ves event types by versions {}", eventsByVersions); - return new ResponseEntity<>(resBody, HttpStatus.OK); - } catch (Exception e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), EXCEPTION, e); - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.VES_SCHEMA_NOT_FOUND); - } + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Starting getEventsByVersion"); + return ruleEditorBusinessLogic.getEventsByVersion(); } - @RequestMapping(value = { "/definition/{version:.*}/{eventType}" }, method = { RequestMethod.GET }, produces = { "application/json" }) + @RequestMapping(value = {"/definition/{version:.*}/{eventType}"}, method = {RequestMethod.GET}, produces = {"application/json"}) public ResponseEntity getDefinition(@PathVariable("version") String version, - @PathVariable("eventType") String eventType) { + @PathVariable("eventType") String eventType) { - try { - List<EventTypeDefinitionUI> result = getEventTypeDefinitionUIs(version, eventType); - - return new ResponseEntity<>(result, HttpStatus.OK); - - } catch (Exception e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), EXCEPTION, e); - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.VES_SCHEMA_NOT_FOUND); - } + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Starting getDefinition", version); + return ruleEditorBusinessLogic.getDefinition(version, eventType); } /** @@ -100,59 +48,16 @@ public class RuleEditorController extends BaseController { * 2. That the cdump holds a dcae component with such nid (to avoid orphan rules) * 3. Check that the fetched VFCMT is actually a VFCMT and not a regular VF */ - @RequestMapping(value = "/rule/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}", method = { RequestMethod.POST }, produces = "application/json") + @RequestMapping(value = "/rule/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam:.*}", method = {RequestMethod.POST}, produces = "application/json") public ResponseEntity saveRule(@RequestBody String json, @ModelAttribute("requestId") String requestId, - @RequestHeader("USER_ID") String userId, - @PathVariable("vfcmtUuid") String vfcmtUuid, - @PathVariable("dcaeCompLabel") String dcaeCompLabel, - @PathVariable("nid") String nid, - @PathVariable("configParam") String configParam) { - try { - Rule rule = RulesPayloadUtils.parsePayloadToRule(json); - if (null == rule) { - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_RULE_FORMAT); - } - - List<ServiceException> errors = rulesBusinessLogic.validateRule(rule); - if(!errors.isEmpty()){ - return ErrConfMgr.INSTANCE.buildErrorArrayResponse(errors); - } - - ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId); - checkVfcmtType(vfcmt); - - if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) { - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SAVE_RULE_FAILED); - } - - String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam); - - // check for MappingRules artifact in existing artifacts - Artifact artifactFound = vfcmt.getArtifacts().stream() - .filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))) - .findAny().orElse(null); - - // exception thrown if vfcmt is checked out and current user is not its owner - // performs vfcmt checkout if required - String vfcmtId = assertOwnershipOfVfcmtId(userId, vfcmt, requestId); - // new mappingRules artifact, validate nid exists in composition before creating new artifact - if (null == artifactFound) { - if(cdumpContainsNid(vfcmt, nid, requestId)) { - return saveNewRulesArtifact(rule, vfcmtId, generateMappingRulesFileName(dcaeCompLabel, nid, configParam), artifactLabel , userId, requestId); - } - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.NODE_NOT_FOUND, "", dcaeCompLabel); - } - - //update artifact flow - append new rule or edit existing rule - return addOrEditRuleInArtifact(rule, vfcmtId, userId, artifactFound, requestId); - - } catch (JsonParseException je) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error: Rule format is invalid: {}", je); - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_RULE_FORMAT, "", je.getMessage()); - } catch (Exception e) { - return handleException(e, ErrConfMgr.ApiType.SAVE_RULE_ARTIFACT); - } + @RequestHeader("USER_ID") String userId, + @PathVariable("vfcmtUuid") String vfcmtUuid, + @PathVariable("dcaeCompLabel") String dcaeCompLabel, + @PathVariable("nid") String nid, + @PathVariable("configParam") String configParam) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Starting saveRule", json); + return ruleEditorBusinessLogic.saveRule(json, requestId, userId, vfcmtUuid, dcaeCompLabel, nid, configParam); } @@ -165,7 +70,7 @@ public class RuleEditorController extends BaseController { * @param configParam - the name of the DCAE Component configuration property the rule is linked to * @return json representing the rule editor UI */ - @RequestMapping(value = "/rule/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}", method = { RequestMethod.GET }, produces = "application/json") + @RequestMapping(value = "/rule/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}", method = {RequestMethod.GET}, produces = "application/json") public ResponseEntity getRules( @PathVariable("vfcmtUuid") String vfcmtUuid, @PathVariable("dcaeCompLabel") String dcaeCompLabel, @@ -173,28 +78,8 @@ public class RuleEditorController extends BaseController { @PathVariable("configParam") String configParam, @ModelAttribute("requestId") String requestId) { - try { - ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId); - if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) { - return new ResponseEntity<>("{}", HttpStatus.OK); - } - String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam); - - // check for MappingRules artifact in existing artifacts - Artifact artifactListed = vfcmt.getArtifacts().stream().filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))).findAny().orElse(null); - if (null == artifactListed) { - return new ResponseEntity<>("{}", HttpStatus.OK); - } - String ruleFile = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactListed.getArtifactUUID(), requestId); - - // To avoid opening the file for reading we search for the eventType and SchemaVer from the artifact metadata's description - SchemaInfo schemainfo = RulesPayloadUtils.extractInfoFromDescription(artifactListed); - List<EventTypeDefinitionUI> schema = null == schemainfo? new ArrayList<>() : getEventTypeDefinitionUIs(schemainfo.getVersion(), schemainfo.getEventType()); - return new ResponseEntity<>(RulesPayloadUtils.buildSchemaAndRulesResponse(ruleFile, schema), HttpStatus.OK); - } catch (Exception e) { - return handleException(e, ApiType.GET_RULE_ARTIFACT); - } - + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Starting getRules", vfcmtUuid); + return ruleEditorBusinessLogic.getRules(vfcmtUuid, dcaeCompLabel, nid, configParam, requestId); } /** @@ -204,10 +89,10 @@ public class RuleEditorController extends BaseController { * @param dcaeCompLabel - the name of the DCAE Component which the rule is applied to * @param nid - A unique id of the DCAE Component which the rule is applied to - exists also in the cdump * @param configParam - the name of the DCAE Component configuration property the rule is linked to - * @param ruleUid - the unique id of the rule to delete + * @param ruleUid - the unique id of the rule to delete * @return operation result */ - @RequestMapping(value = "/rule/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}/{ruleUid}", method = { RequestMethod.DELETE }, produces = "application/json") + @RequestMapping(value = "/rule/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}/{ruleUid}", method = {RequestMethod.DELETE}, produces = "application/json") public ResponseEntity deleteRule( @RequestHeader("USER_ID") String userId, @PathVariable("vfcmtUuid") String vfcmtUuid, @@ -215,44 +100,10 @@ public class RuleEditorController extends BaseController { @PathVariable("nid") String nid, @PathVariable("configParam") String configParam, @PathVariable("ruleUid") String ruleUid, - @ModelAttribute("requestId") String requestId){ - - try { - ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId); - if (null == vfcmt.getArtifacts()) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "VFCMT {} doesn't have artifacts", vfcmtUuid); - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED); - } - String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam); - - // check for MappingRules artifact in existing artifacts - Artifact mappingRuleFile = vfcmt.getArtifacts().stream() - .filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))) - .findAny().orElse(null); - - if (null == mappingRuleFile) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "{} doesn't exist for VFCMT {}", artifactLabel, vfcmtUuid); - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED); - } - - String vfcmtId = assertOwnershipOfVfcmtId(userId, vfcmt, requestId); - String payload = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtId, mappingRuleFile.getArtifactUUID(), requestId); - MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload); - Rule removedRule = rulesBusinessLogic.deleteRule(rules, ruleUid); - if(null == removedRule){ - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Rule {} not found.", ruleUid); - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED); - } - if(rules.isEmpty()){ // if file doesn't contain any rules after last deletion -> let's delete the file - baseBusinessLogic.getSdcRestClient().deleteResourceArtifact(userId, vfcmtId, mappingRuleFile.getArtifactUUID(), requestId); - } else { - updateRulesArtifact(vfcmtId, userId, mappingRuleFile, rules, requestId); - } - return checkInAndReturnSaveArtifactResult(removedRule, vfcmtId, userId, requestId); - } catch (Exception e) { - return handleException(e, ApiType.SAVE_RULE_ARTIFACT); - } + @ModelAttribute("requestId") String requestId) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Starting deleteRule", vfcmtUuid); + return ruleEditorBusinessLogic.deleteRule(userId, vfcmtUuid, dcaeCompLabel, nid, configParam, ruleUid, requestId); } /** @@ -262,7 +113,7 @@ public class RuleEditorController extends BaseController { * @param dcaeCompLabel - the name of the DCAE Component which the rule is applied to * @param nid - A unique id of the DCAE Component which the rule is applied to - exists also in the cdump * @param configParam - the name of the DCAE Component configuration property the rule is linked to - * @param flowType - the mapping rules flow type (SNMP,Syslog,FOI) + * @param flowType - the mapping rules flow type (SNMP,Syslog,FOI) * @return translateJson representing the translated Rules * Validations: * 1. That the user is able to edit the VFCMT @@ -270,184 +121,25 @@ public class RuleEditorController extends BaseController { * 3. Check that the fetched VFCMT is actually a VFCMT and not a regular VF * @throws Exception */ - @RequestMapping(value = "/rule/translate/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}", method = { RequestMethod.GET }, produces = "application/json") + @RequestMapping(value = "/rule/translate/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}", method = {RequestMethod.GET}, produces = "application/json") public ResponseEntity translateRules(@PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId, - @PathVariable("dcaeCompLabel") String dcaeCompLabel, - @PathVariable("nid") String nid, - @PathVariable("configParam") String configParam, - @RequestParam("flowType") String flowType) throws Exception { - - try { + @PathVariable("dcaeCompLabel") String dcaeCompLabel, + @PathVariable("nid") String nid, + @PathVariable("configParam") String configParam, + @RequestParam("flowType") String flowType) { - if (StringUtils.isBlank(flowType) || MapUtils.isEmpty(compositionConfig.getFlowTypesMap()) || null == compositionConfig.getFlowTypesMap().get(flowType)) { - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", "Flow type " + flowType + " not found"); - } - - // extract entry phase name and last phase name from configuration: - String entryPointPhaseName = compositionConfig.getFlowTypesMap().get(flowType).getEntryPointPhaseName(); - String lastPhaseName = compositionConfig.getFlowTypesMap().get(flowType).getLastPhaseName(); - - ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId); - checkVfcmtType(vfcmt); - - if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) { - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", "No rules found on VFCMT " + vfcmtUuid); - } - String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam); - - // check for MappingRules artifact in existing artifacts - Artifact rulesArtifact = vfcmt.getArtifacts().stream().filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))).findAny().orElse(null); - - if (rulesArtifact == null) { - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", artifactLabel + " doesn't exist on VFCMT " + vfcmtUuid); - } - - String payload = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, rulesArtifact.getArtifactUUID(), requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Retrieved mapping rules artifact {}, start parsing rules...", artifactLabel); - MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished parsing rules, calling validator..."); - List<ServiceException> errors = rulesBusinessLogic.validateRules(rules); - if (!errors.isEmpty()) { - return ErrConfMgr.INSTANCE.buildErrorArrayResponse(errors); - } - - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Validation completed successfully, calling translator..."); - String translateJson = rulesBusinessLogic.translateRules(rules, entryPointPhaseName, lastPhaseName, vfcmt.getName()); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translation completed successfully"); - return new ResponseEntity<>(translateJson, HttpStatus.OK); - } catch (Exception e) { - return handleException(e, ApiType.SAVE_RULE_ARTIFACT); - } + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Starting translateRules", vfcmtUuid); + return ruleEditorBusinessLogic.translateRules(vfcmtUuid, requestId, dcaeCompLabel, nid, configParam, flowType); } - ///////////////////PRIVATE METHODS//////////////////////////////////////////////////////////////////////// - - private String assertOwnershipOfVfcmtId(String userId, ResourceDetailed vfcmt, String requestId) throws Exception { - checkUserIfResourceCheckedOut(userId, vfcmt); - String newVfcmtId = vfcmt.getUuid(); // may change after checking out a certified vfcmt - if (isNeedToCheckOut(vfcmt.getLifecycleState())) { - Asset result = checkout(userId, newVfcmtId, AssetType.RESOURCE, requestId); - if (result != null) { - newVfcmtId = result.getUuid(); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New resource after checkout is: {}", newVfcmtId); - } - } - return newVfcmtId; - } - - - - // called after validating vfcmt.getArtifacts() is not null - private boolean cdumpContainsNid(ResourceDetailed vfcmt, String nid, String requestId) { - Artifact cdump = vfcmt.getArtifacts().stream() - .filter(a -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equalsIgnoreCase(a.getArtifactName())) - .findAny().orElse(null); - if (null == cdump || null == cdump.getArtifactUUID()) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "No {} found on vfcmt {}", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML, vfcmt.getUuid()); - return false; - } - try { - String artifact = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmt.getUuid(), cdump.getArtifactUUID(), requestId); - if (!artifact.contains("\"nid\":\""+nid)) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "{} doesn't contain nid {}. Cannot save mapping rule file", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML, nid); - return false; - } - } catch (Exception e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), EXCEPTION, e); - return false; - } - return true; - } - - private ResponseEntity<String> saveNewRulesArtifact(Rule rule, String vfcmtUuid, String artifactFileName, String artifactLabel, String userId, String requestId) throws Exception { - MappingRules body = new MappingRules(rule); - Artifact artifact = SdcRestClientUtils.generateDeploymentArtifact(body.describe(), artifactFileName, ArtifactType.OTHER.name(), artifactLabel, body.convertToPayload()); - baseBusinessLogic.getSdcRestClient().createResourceArtifact(userId, vfcmtUuid, artifact, requestId); - return checkInAndReturnSaveArtifactResult(rule, vfcmtUuid, userId, requestId); - } - - private ResponseEntity addOrEditRuleInArtifact(Rule rule, String vfcmtUuid, String userId, Artifact rulesArtifact, String requestId) throws Exception { - String payload = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, rulesArtifact.getArtifactUUID(), requestId); - MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload); - - // in case the rule id is passed but the rule doesn't exist on the mapping rule file: - if(!rulesBusinessLogic.addOrEditRule(rules, rule)) { - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SAVE_RULE_FAILED); - } - updateRulesArtifact(vfcmtUuid, userId, rulesArtifact, rules, requestId); - return checkInAndReturnSaveArtifactResult(rule, vfcmtUuid, userId, requestId); - } - - // regardless of check in result, return save artifact success - private ResponseEntity<String> checkInAndReturnSaveArtifactResult(Rule rule, String vfcmtUuid, String userId, String requestId) { - try { - checkin(userId, vfcmtUuid, AssetType.RESOURCE, requestId); - } catch (Exception e) { - // swallowing the exception intentionally since it is on the check in action - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occurred while performing check in on VFCMT {}:{}", vfcmtUuid, e); - } - return new ResponseEntity<>(rule.toJson(), HttpStatus.OK); - } - - private void updateRulesArtifact(String vfcmtUuid, String userId, Artifact artifactInfo, MappingRules rules, String requestId) throws Exception { - artifactInfo.setPayloadData(Base64Utils.encodeToString(rules.convertToPayload())); - // POST must contain 'description' while GET returns 'artifactDescription' - artifactInfo.setDescription(artifactInfo.getArtifactDescription()); - baseBusinessLogic.getSdcRestClient().updateResourceArtifact(userId, vfcmtUuid, artifactInfo, requestId); - } - - - /** - * @param eventMapStream - * @param parent - * @param path - * @return - */ - private List<EventTypeDefinitionUI> convertToEventTypeDefinition(Stream<Entry<String, VesDataTypeDefinition>> eventMapStream, VesDataTypeDefinition parent, String path) { - - return eventMapStream.map(entry -> { - Map<String, VesDataTypeDefinition> properties = entry.getValue().getProperties(); - VesDataItemsDefinition items = entry.getValue().getItems(); - String newPath = path + "." + entry.getKey(); - List<EventTypeDefinitionUI> children = (properties == null) ? null : convertToEventTypeDefinition(properties.entrySet().stream(), entry.getValue(), newPath); - if(VesSimpleTypesEnum.ARRAY.getType().equals(entry.getValue().getType())) { - newPath += "[]"; - if(innerTypeIsComplex(items)) { - children = convertComplexArrayType(items, newPath); - } else if(innerTypeIsArray(items)) { - newPath += "[]"; - } - } - - boolean isRequired = (parent != null) ? parent.getRequired().contains(entry.getKey()) : false; - return new EventTypeDefinitionUI(entry.getKey(), children, isRequired, newPath); - }).collect(Collectors.toList()); - } - - private boolean innerTypeIsComplex(VesDataItemsDefinition items){ - return items != null && items.stream().anyMatch(p -> p.getProperties() != null); - } - - private boolean innerTypeIsArray(VesDataItemsDefinition items){ - return items != null && items.stream().anyMatch(p -> p.getItems() != null); - } - - private List<EventTypeDefinitionUI> convertComplexArrayType(VesDataItemsDefinition items, String path){ - return items.stream().map(item -> item.getProperties() != null ? convertToEventTypeDefinition(item.getProperties().entrySet().stream(), item, path) : new ArrayList<EventTypeDefinitionUI>()) - .flatMap(List::stream).collect(Collectors.toList()); - } - - - private String generateMappingRulesFileName(String dcaeCompLabel, String nid, String configParam) { - return dcaeCompLabel + "_" + nid + "_" + configParam + DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX; + @RequestMapping(value = "/getExistingRuleTargets/{vfcmtUuid}/{dcaeCompLabel}/{nid:.*}", method = {RequestMethod.GET}, produces = "application/json") + public ResponseEntity getExistingRuleTargets(@PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId, + @PathVariable("dcaeCompLabel") String dcaeCompLabel, + @PathVariable("nid") String nid) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Starting getExistingRuleTargets ", vfcmtUuid); + return ruleEditorBusinessLogic.getExistingRuleTargets(vfcmtUuid, requestId, dcaeCompLabel, nid); } - private List<EventTypeDefinitionUI> getEventTypeDefinitionUIs(String version, String eventType) { - List<String> eventNamesToReturn = ListUtils.union(EventTypesByVersionUI.DEFAULT_EVENTS, Arrays.asList(eventType)); - Map<String, VesDataTypeDefinition> eventDefs = VesStructureLoader.getEventListenerDefinitionByVersion(version); - Stream<Entry<String, VesDataTypeDefinition>> filteredEvents = eventDefs.entrySet().stream().filter(entry -> eventNamesToReturn.contains(entry.getKey())); - return convertToEventTypeDefinition(filteredEvents, null, "event"); - } } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ServicesController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ServicesController.java index 257d1a9..b59f4a4 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ServicesController.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ServicesController.java @@ -1,37 +1,20 @@ package org.onap.sdc.dcae.composition.controller; import org.onap.sdc.common.onaplog.Enums.LogLevel; +import org.onap.sdc.dcae.composition.impl.ServiceBusinessLogic; import org.onap.sdc.dcae.composition.restmodels.AttachVFCMTServiceRequest; -import org.onap.sdc.dcae.composition.restmodels.DcaeMinimizedService; -import org.onap.sdc.dcae.composition.restmodels.MessageResponse; -import org.onap.sdc.dcae.composition.restmodels.sdc.*; -import org.onap.sdc.dcae.composition.util.DcaeBeConstants; -import org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateEnum; -import org.onap.sdc.dcae.enums.ArtifactType; -import org.onap.sdc.dcae.enums.LifecycleOperationType; -import org.onap.sdc.dcae.errormng.ActionStatus; -import org.onap.sdc.dcae.errormng.DcaeException; -import org.onap.sdc.dcae.errormng.ErrConfMgr; -import org.onap.sdc.dcae.errormng.ResponseFormat; -import org.onap.sdc.dcae.utils.SdcRestClientUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.util.Base64Utils; -import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.stream.Collectors; - @RestController @EnableAutoConfiguration @CrossOrigin public class ServicesController extends BaseController { + @Autowired + private ServiceBusinessLogic serviceBusinessLogic; /*** * GET services list by VFCMT * @param userId @@ -40,19 +23,9 @@ public class ServicesController extends BaseController { */ @RequestMapping(value = { "/services/{vfcmtUuid}" }, method = { RequestMethod.GET }, produces = {"application/json" }) public ResponseEntity services(@RequestHeader("USER_ID") String userId, @PathVariable String vfcmtUuid, @ModelAttribute("requestId") String requestId) { - try { - ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "GET ({}) Vfcmt form SDC: {}", vfcmtUuid, vfcmt); - checkVfcmtType(vfcmt); - checkUserIfResourceCheckedOut(userId, vfcmt); - List<Service> services = baseBusinessLogic.getSdcRestClient().getServices(requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "GET services data from SDC: {}", services); - List<Service> uuids = filterServicesByUser(services, userId); - return new ResponseEntity<>(uuids, HttpStatus.OK); - } catch (Exception e) { - return handleException(e, ErrConfMgr.ApiType.GET_SERVICE); - } + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Starting services"); + return serviceBusinessLogic.services(userId,vfcmtUuid,requestId); } /*** @@ -62,22 +35,9 @@ public class ServicesController extends BaseController { */ @RequestMapping(value = { "/service/{theServiceId}" }, method = { RequestMethod.GET }, produces = {"application/json" }) public ResponseEntity service(@PathVariable String theServiceId, @ModelAttribute("requestId") String requestId) { - try { - ServiceDetailed service = baseBusinessLogic.getSdcRestClient().getService(theServiceId, requestId); - if (service != null) { - if(service.getResources()!=null){ - List<ResourceInstance> vfResourcesOnly = service.getResources().stream().filter(vfi -> vfi.getResoucreType().equals("VF")).collect(Collectors.toList()); - service.setResources(vfResourcesOnly); - }else{ - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Service {} doesn't have any resources (e.g VFi's)", theServiceId); - } - } else { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Couldn't fetch service with uuid {} from SDC", theServiceId); - } - return new ResponseEntity<>(service, HttpStatus.OK); - } catch (Exception e) { - return handleException(e, ErrConfMgr.ApiType.GET_SERVICE); - } + + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Starting service"); + return serviceBusinessLogic.service(theServiceId,requestId); } @@ -87,6 +47,7 @@ public class ServicesController extends BaseController { * @param request * @return ResponseEntity */ + @Deprecated @RequestMapping(value = "/{vfcmtUuid}/attachment", method = RequestMethod.POST, produces = {"application/json" }) public ResponseEntity attachService( @PathVariable("vfcmtUuid") String vfcmtUuid, @@ -94,137 +55,15 @@ public class ServicesController extends BaseController { @RequestBody AttachVFCMTServiceRequest request, @ModelAttribute("requestId") String requestId) { - String serviceUuid = request.getServiceUuid(); - String vfiName = request.getInstanceName(); - String resourceUuid = vfcmtUuid; - MessageResponse response = new MessageResponse(); - - try { - ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString()); - - checkVfcmtType(vfcmt); - verifyVfiExists(serviceUuid, vfiName, requestId); - - boolean isUpdateMode = false; - Artifact artifactObj = null; - - String reference = serviceUuid + "/resources/" + vfiName; - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "*****************************************"); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Reference between service and vfi {}", reference); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "*****************************************"); - - if(!CollectionUtils.isEmpty(vfcmt.getArtifacts())){ - artifactObj = vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.SVC_REF.equals(a.getArtifactName())).findAny().orElse(null); - isUpdateMode = null != artifactObj; - } - - if (isNeedToCheckOut(vfcmt.getLifecycleState())) { - vfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, vfcmtUuid, LifecycleOperationType.CHECKOUT.name(), null, requestId); - if (vfcmt != null) { - resourceUuid = vfcmt.getUuid(); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New vfcmt uuid after checkout is: {}", resourceUuid); - } - } - - if(isUpdateMode){ - updateReferenceArtifact(userId, resourceUuid, artifactObj, reference, requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Artifact {} updated with content: {}", reference, DcaeBeConstants.Composition.fileNames.SVC_REF, reference); - }else{ - Artifact artifact = SdcRestClientUtils.generateDeploymentArtifact("createReferenceArtifact", DcaeBeConstants.Composition.fileNames.SVC_REF, ArtifactType.DCAE_TOSCA.name(), "servicereference", reference.getBytes()); - baseBusinessLogic.getSdcRestClient().createResourceArtifact(userId, resourceUuid, artifact, requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Artifact {} created with content: {}", DcaeBeConstants.Composition.fileNames.SVC_REF, reference); - } - checkin(userId, resourceUuid, org.onap.sdc.dcae.enums.AssetType.RESOURCE, requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Attachment of reference={} in VFCMT {} has finished successfully", reference, resourceUuid); - - response.setSuccessResponse("Artifact updated"); - return new ResponseEntity<>(response, HttpStatus.OK); - } catch (Exception e) { - return handleException(e, ErrConfMgr.ApiType.ATTACH_TO_SERVICE); - } + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Starting attachService"); + return serviceBusinessLogic.attachService(vfcmtUuid,userId,request,requestId); } @RequestMapping(value = { "/{vfcmtUuid}/attachment" }, method = { RequestMethod.GET }, produces = {"application/json" }) public ResponseEntity getAttachedService(@PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId) { - - MessageResponse response = new MessageResponse(); - - try { - ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString()); - checkVfcmtType(vfcmt); - String artifact = "No Artifacts"; - - if (!CollectionUtils.isEmpty(vfcmt.getArtifacts())) { - Artifact artifactObj = vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.SVC_REF.equals(a.getArtifactName())).findAny().orElse(null); - if (null != artifactObj) - artifact = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactObj.getArtifactUUID(), requestId); - } - response.setSuccessResponse(artifact); - return new ResponseEntity<>(response, HttpStatus.OK); - } catch (Exception e) { - return handleException(e, ErrConfMgr.ApiType.GET_VFCMT); - } - } - - /**** PRIVATE METHODS ****/ - - private void updateReferenceArtifact(String userId, String VFCMTUuid, Artifact artifactObj, String reference, String requestId) throws Exception { - artifactObj.setDescription("updateReferenceArtifact"); - artifactObj.setPayloadData(Base64Utils.encodeToString(reference.getBytes())); - baseBusinessLogic.getSdcRestClient().updateResourceArtifact(userId, VFCMTUuid, artifactObj, requestId); - } - - - /** - * - * @param lastUpdaterUserId - * @param services - * @param userId - * @return - */ - - //TODO move method to ci tests - public List<DcaeMinimizedService> parseAndFilterServicesByUser(String lastUpdaterUserId, List<LinkedHashMap<String, String>> services, String userId) { - List<DcaeMinimizedService> uuids = null; - if (services != null) { - //services.stream().filter(predicate) - uuids = services.stream() - .map(x -> new DcaeMinimizedService(x.get("uuid"), x.get("name"), x.get("lastUpdaterUserId"), x.get("lifecycleState"), x.get("version"), x.get("invariantUUID"))) - .collect(Collectors.groupingBy(DcaeMinimizedService::getInvariantUUID)).values().stream() - .map(p -> p.stream() - .sorted(Comparator.comparing(DcaeMinimizedService::getVersionAsFloat).reversed())).map(p -> p.collect(Collectors.toList())).map(p -> p.get(0)) - .filter(x -> (!(!x.getLastUpdaterUserId().equals(userId) && x.getLifeCycleState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())))) - .sorted(Comparator.comparing(DcaeMinimizedService::getName)).collect(Collectors.toList()); - } - return uuids; - } - private List<Service> filterServicesByUser(List<Service> services, String userId) { - return CollectionUtils.isEmpty(services) ? new ArrayList<>() : services.stream() - .collect(Collectors.groupingBy(Service::getInvariantUUID)).values().stream() - .map(p -> p.stream() - .sorted(Comparator.comparing(Service::versionAsFloat).reversed())).map(p -> p.collect(Collectors.toList())).map(p -> p.get(0)) - .filter(x -> (!(!x.getLastUpdaterUserId().equals(userId) && x.getLifecycleState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())))) - .sorted(Comparator.comparing(Service::getName)).collect(Collectors.toList()); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Starting getAttachedService"); + return serviceBusinessLogic.getAttachedService(vfcmtUuid,requestId); } - /** - * - * @param serviceUuid - * @param vfiName - * @param requestId - * @throws Exception - */ - private void verifyVfiExists(String serviceUuid, String vfiName, String requestId) throws Exception { - ServiceDetailed service = baseBusinessLogic.getSdcRestClient().getService(serviceUuid, requestId); - boolean isServiceContainsVfi = null != service && !CollectionUtils.isEmpty(service.getResources()) && service.getResources().stream() - .filter(vfi -> "VF".equals(vfi.getResoucreType())) - .anyMatch(vfi -> vfiName.equals(vfi.getResourceInstanceName())); - if (!isServiceContainsVfi) { - ResponseFormat responseFormat = ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.VFI_FETCH_ERROR, null, serviceUuid, vfiName); - throw new DcaeException(HttpStatus.NOT_FOUND, responseFormat.getRequestError()); - } - } } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/VfcmtController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/VfcmtController.java index 0e1b209..7d64dad 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/VfcmtController.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/VfcmtController.java @@ -8,6 +8,7 @@ import org.onap.sdc.dcae.composition.restmodels.ImportVFCMTRequest; import org.onap.sdc.dcae.composition.restmodels.sdc.ExternalReferencesMap; import org.onap.sdc.dcae.composition.restmodels.sdc.Resource; import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed; +import org.onap.sdc.dcae.enums.AssetType; import org.onap.sdc.dcae.errormng.ErrConfMgr.ApiType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -23,14 +24,14 @@ import java.util.List; public class VfcmtController extends BaseController{ - @Autowired - private VfcmtBusinessLogic vfcmtBusinessLogic; + @Autowired + private VfcmtBusinessLogic vfcmtBusinessLogic; @Autowired private ReferenceBusinessLogic referenceBusinessLogic; - private static final String VFCMT = "VFCMT"; - private static final String TEMPLATE = "Template"; + private static final String TEMPLATE = "Template"; private static final String BASE_MONITORING_TEMPLATE = "Base Monitoring Template"; + private static final String MONITORING_TEMPLATE = "Monitoring Template"; @@ -56,7 +57,7 @@ public class VfcmtController extends BaseController{ @RequestMapping(value = { "/getResourcesByCategory" }, method = { RequestMethod.GET }, produces = {"application/json" }) public ResponseEntity getResourcesByCategory(@ModelAttribute("requestId") String requestId) { try { - List<Resource> resources = baseBusinessLogic.getSdcRestClient().getResources(VFCMT, null, null, requestId); + List<Resource> resources = baseBusinessLogic.getSdcRestClient().getResources(AssetType.VFCMT.name(), TEMPLATE, MONITORING_TEMPLATE, requestId); return new ResponseEntity<>(resources, HttpStatus.OK); } catch (Exception e) { return handleException(e, ApiType.GET_ALL_VFCMTS); @@ -85,7 +86,7 @@ public class VfcmtController extends BaseController{ @RequestMapping(value = { "/getResourcesByMonitoringTemplateCategory" }, method = { RequestMethod.GET }, produces = {"application/json" }) public ResponseEntity getResourcesByMonitoringTemplateCategory(@ModelAttribute("requestId") String requestId) { try { - List<Resource> resources = baseBusinessLogic.getSdcRestClient().getResources(VFCMT, TEMPLATE, BASE_MONITORING_TEMPLATE, requestId); + List<Resource> resources = baseBusinessLogic.getSdcRestClient().getResources(AssetType.VFCMT.name(), TEMPLATE, BASE_MONITORING_TEMPLATE, requestId); return new ResponseEntity<>(resources, HttpStatus.OK); } catch (Exception e) { return handleException(e, ApiType.GET_ALL_VFCMTS); @@ -100,7 +101,7 @@ public class VfcmtController extends BaseController{ */ @RequestMapping(value = "/createVFCMT", method = RequestMethod.POST, produces = {"application/json" }) public ResponseEntity createVFCMT(@RequestHeader("USER_ID") String userId, @RequestBody CreateVFCMTRequest request, @ModelAttribute("requestId") String requestId) { - vfcmtBusinessLogic.addSdcMandatoryFields(request, userId); + vfcmtBusinessLogic.addSdcMandatoryFields(request, userId); try { ResourceDetailed response = baseBusinessLogic.getSdcRestClient().createResource(userId, request, requestId); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "createVFCMT after post: {}", response); @@ -122,28 +123,28 @@ public class VfcmtController extends BaseController{ } - /*** - * Clone or import existing VFCMT and attach to selected service/resource - * @param userId - * @param request - * @return ResponseEntity - */ - @RequestMapping(value = "/importMC", method = RequestMethod.POST, produces = {"application/json" }) - public ResponseEntity importMC(@RequestHeader("USER_ID") String userId, @RequestBody ImportVFCMTRequest request, @ModelAttribute("requestId") String requestId) { - return vfcmtBusinessLogic.importMC(userId, request, requestId); - } + /*** + * Clone or import existing VFCMT and attach to selected service/resource + * @param userId + * @param request + * @return ResponseEntity + */ + @RequestMapping(value = "/importMC", method = RequestMethod.POST, produces = {"application/json" }) + public ResponseEntity importMC(@RequestHeader("USER_ID") String userId, @RequestBody ImportVFCMTRequest request, @ModelAttribute("requestId") String requestId) { + return vfcmtBusinessLogic.importMC(userId, request, requestId); + } /*** * GET a list of Monitoring Components of a service by uuid and version - * @param context the context type of this request + * @param contextType the context type of this request * @param uuid the uuid of the type requested * @param version the version of the entity requested * @return ResponseEntity */ - @RequestMapping(value = { "/{context}/{uuid}/{version}/monitoringComponents" }, method = { RequestMethod.GET }, produces = {"application/json" }) - public ResponseEntity getMonitoringComponents(@PathVariable String context, @PathVariable String uuid, @PathVariable String version, @ModelAttribute("requestId") String requestId) { + @RequestMapping(value = { "/{contextType}/{uuid}/{version}/monitoringComponents" }, method = { RequestMethod.GET }, produces = {"application/json" }) + public ResponseEntity getMonitoringComponents(@PathVariable String contextType, @PathVariable String uuid, @PathVariable String version, @ModelAttribute("requestId") String requestId) { try { - ExternalReferencesMap mcRefs = baseBusinessLogic.getSdcRestClient().getMonitoringReferences(context, uuid, version, requestId); + ExternalReferencesMap mcRefs = baseBusinessLogic.getSdcRestClient().getMonitoringReferences(contextType, uuid, version, requestId); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Got monitoring references map from SDC: {}", mcRefs.values()); return new ResponseEntity<>(referenceBusinessLogic.fetchMonitoringComponents(mcRefs, requestId), HttpStatus.OK); } catch (Exception e) { @@ -151,33 +152,33 @@ public class VfcmtController extends BaseController{ } } - @RequestMapping(value = { "/{context}/{serviceUuid}/{vfiName}/{vfcmtUuid}/deleteVfcmtReference" }, method = { RequestMethod.DELETE }, produces = {"application/json" }) - public ResponseEntity deleteVfcmtReference(@RequestHeader("USER_ID") String userId, @PathVariable String context, @PathVariable String serviceUuid, @PathVariable String vfiName, @PathVariable String vfcmtUuid, @ModelAttribute String requestId) { + @RequestMapping(value = { "/{contextType}/{serviceUuid}/{vfiName}/{vfcmtUuid}/deleteVfcmtReference" }, method = { RequestMethod.DELETE }, produces = {"application/json" }) + public ResponseEntity deleteVfcmtReference(@RequestHeader("USER_ID") String userId, @PathVariable String contextType, @PathVariable String serviceUuid, @PathVariable String vfiName, @PathVariable String vfcmtUuid, @ModelAttribute String requestId) { try { - referenceBusinessLogic.deleteVfcmtReference(userId, context, serviceUuid, vfiName, vfcmtUuid, requestId); + referenceBusinessLogic.deleteVfcmtReference(userId, contextType, serviceUuid, vfiName, vfcmtUuid, requestId); return new ResponseEntity<>(HttpStatus.OK); } catch (Exception e) { return handleException(e, ApiType.DELETE_VFCMT_REFERENCE); } } - @RequestMapping(value = { "/{context}/{monitoringComponentName}/{serviceUuid}/{vfiName}/{vfcmtUuid}/deleteVfcmtReference" }, method = { RequestMethod.DELETE }, produces = {"application/json" }) - public ResponseEntity deleteVfcmtReferenceWithBlueprint(@RequestHeader("USER_ID") String userId, @PathVariable String context, @PathVariable String monitoringComponentName, @PathVariable String serviceUuid, @PathVariable String vfiName, @PathVariable String vfcmtUuid, @ModelAttribute String requestId) { + @RequestMapping(value = { "/{contextType}/{monitoringComponentName}/{serviceUuid}/{vfiName}/{vfcmtUuid}/deleteVfcmtReference" }, method = { RequestMethod.DELETE }, produces = {"application/json" }) + public ResponseEntity deleteVfcmtReferenceWithBlueprint(@RequestHeader("USER_ID") String userId, @PathVariable String contextType, @PathVariable String monitoringComponentName, @PathVariable String serviceUuid, @PathVariable String vfiName, @PathVariable String vfcmtUuid, @ModelAttribute String requestId) { try { - referenceBusinessLogic.deleteVfcmtReference(userId, context, serviceUuid, vfiName, vfcmtUuid, requestId); + referenceBusinessLogic.deleteVfcmtReference(userId, contextType, serviceUuid, vfiName, vfcmtUuid, requestId); } catch (Exception e) { return handleException(e, ApiType.DELETE_VFCMT_REFERENCE); } - return referenceBusinessLogic.deleteVfcmtReferenceBlueprint(userId, context, monitoringComponentName, serviceUuid, vfiName, vfcmtUuid, requestId); + return referenceBusinessLogic.deleteVfcmtReferenceBlueprint(userId, contextType, monitoringComponentName, serviceUuid, vfiName, vfcmtUuid, requestId); } - @RequestMapping(value = { "/getVfcmtReferenceData/{vfcmtUuid}" }, method = { RequestMethod.GET }, produces = {"application/json" }) - public ResponseEntity getVfcmtReferenceData(@PathVariable String vfcmtUuid, @ModelAttribute String requestId) { - try { - return vfcmtBusinessLogic.getVfcmtReferenceData(vfcmtUuid, requestId); - } catch (Exception e) { - return handleException(e, ApiType.GET_VFCMT); - } - } + @RequestMapping(value = { "/getVfcmtReferenceData/{vfcmtUuid}" }, method = { RequestMethod.GET }, produces = {"application/json" }) + public ResponseEntity getVfcmtReferenceData(@PathVariable String vfcmtUuid, @ModelAttribute String requestId) { + try { + return vfcmtBusinessLogic.getVfcmtReferenceData(vfcmtUuid, requestId); + } catch (Exception e) { + return handleException(e, ApiType.GET_VFCMT); + } + } } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java index f26c885..bfec7ed 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java @@ -1,15 +1,31 @@ package org.onap.sdc.dcae.composition.impl; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang.StringUtils; +import org.onap.sdc.common.onaplog.Enums.LogLevel; import org.onap.sdc.common.onaplog.OnapLoggerDebug; import org.onap.sdc.common.onaplog.OnapLoggerError; import org.onap.sdc.dcae.client.ISdcClient; -import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; -import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed; +import org.onap.sdc.dcae.composition.restmodels.CreateMcResponse; +import org.onap.sdc.dcae.composition.restmodels.VfcmtData; +import org.onap.sdc.dcae.composition.restmodels.sdc.*; +import org.onap.sdc.dcae.composition.util.DcaeBeConstants; +import org.onap.sdc.dcae.enums.AssetType; +import org.onap.sdc.dcae.enums.LifecycleOperationType; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.DcaeException; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ResponseFormat; +import org.onap.sdc.dcae.utils.Normalizers; import org.onap.sdc.dcae.utils.SdcRestClientUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.util.Base64Utils; -import org.springframework.util.CollectionUtils; + +import java.io.IOException; @Component public class BaseBusinessLogic { @@ -19,31 +35,130 @@ public class BaseBusinessLogic { protected static OnapLoggerError errLogger = OnapLoggerError.getInstance(); protected static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); - public ISdcClient getSdcRestClient() { - return sdcRestClient; - } - - void setSdcRestClient(ISdcClient sdcRestClient) { - this.sdcRestClient = sdcRestClient; - } - - Artifact cloneArtifactToTarget(String userId, String targetId, String payload, Artifact artifactToClone, String requestId) throws Exception { - Artifact cloned = SdcRestClientUtils.generateDeploymentArtifact(artifactToClone.getArtifactDescription(), artifactToClone.getArtifactName(), artifactToClone.getArtifactType(), artifactToClone.getArtifactLabel(), payload.getBytes()); - return sdcRestClient.createResourceArtifact(userId, targetId, cloned, requestId); - } - - public void cloneArtifactToTarget(String userId, String targetId, String payload, Artifact artifactToClone, Artifact artifactToOverride, String requestId) throws Exception{ - if (null != artifactToOverride) { - artifactToOverride.setDescription(artifactToOverride.getArtifactDescription()); - artifactToOverride.setPayloadData(Base64Utils.encodeToString(payload.getBytes())); - sdcRestClient.updateResourceArtifact(userId, targetId, artifactToOverride, requestId); - } else { - cloneArtifactToTarget(userId, targetId, payload, artifactToClone, requestId); - } - } - - Artifact findArtifactDataByArtifactName(ResourceDetailed vfcmt, String artifactName) { - return null == vfcmt ? null : CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? null : vfcmt.getArtifacts().stream() - .filter(p -> artifactName.equals(p.getArtifactName())).findAny().orElse(null); - } + public ISdcClient getSdcRestClient() { + return sdcRestClient; + } + + void setSdcRestClient(ISdcClient sdcRestClient) { + this.sdcRestClient = sdcRestClient; + } + + Artifact cloneArtifactToTarget(String userId, String targetId, String payload, Artifact artifactToClone, String requestId) throws JsonProcessingException { + Artifact cloned = SdcRestClientUtils.generateDeploymentArtifact(artifactToClone.getArtifactDescription(), artifactToClone.getArtifactName(), artifactToClone.getArtifactType(), artifactToClone.getArtifactLabel(), payload.getBytes()); + return sdcRestClient.createResourceArtifact(userId, targetId, cloned, requestId); + } + + public void cloneArtifactToTarget(String userId, String targetId, String payload, Artifact artifactToClone, Artifact artifactToOverride, String requestId) throws JsonProcessingException { + if (null != artifactToOverride) { + artifactToOverride.setDescription(artifactToOverride.getArtifactDescription()); + artifactToOverride.setPayloadData(Base64Utils.encodeToString(payload.getBytes())); + sdcRestClient.updateResourceArtifact(userId, targetId, artifactToOverride, requestId); + } else { + cloneArtifactToTarget(userId, targetId, payload, artifactToClone, requestId); + } + } + + Artifact findArtifactDataByArtifactName(ResourceDetailed vfcmt, String artifactName) { + if (null == vfcmt || null == vfcmt.getArtifacts()) { + return null; + } + return vfcmt.getArtifacts().stream() + .filter(p -> artifactName.equals(p.getArtifactName())).findAny().orElse(null); + } + + Artifact findCdumpArtifactData(ResourceDetailed vfcmt) { + return findArtifactDataByArtifactName(vfcmt, DcaeBeConstants.Composition.fileNames.COMPOSITION_YML); + } + + void rollBack(String userId, ResourceDetailed newVfcmt, String requestId) { + if (null != newVfcmt) { + try { + sdcRestClient.changeResourceLifecycleState(userId, newVfcmt.getUuid(), LifecycleOperationType.UNDO_CHECKOUT.getValue(), "DCAE rollback", requestId); + } catch (Exception e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(),"Failed rolling back Monitoring Component. ID:{}", newVfcmt.getUuid()); + debugLogger.log(LogLevel.ERROR, this.getClass().getName(),"Failed rolling back Monitoring Component:{}", e); + } + } + } + + CreateMcResponse buildVfcmtAndCdumpResponse(VfcmtData vfcmt, String cdumpPayload) throws IOException { + return new CreateMcResponse(vfcmt, new ObjectMapper().readValue(cdumpPayload, Object.class)); + } + + public Artifact fetchCdump(ResourceDetailed vfcmt, String requestId) { + Artifact cdumpArtifactData = findCdumpArtifactData(vfcmt); + if (null != cdumpArtifactData) { + String cdumpPayload = sdcRestClient.getResourceArtifact(vfcmt.getUuid(), cdumpArtifactData.getArtifactUUID(), requestId); + cdumpArtifactData.setPayloadData(cdumpPayload); + } + return cdumpArtifactData; + } + + String generateBlueprintFileName(String monitoringFlowType, String vfcmtName) { + return monitoringFlowType + .concat(".") + .concat(Normalizers.normalizeComponentName(vfcmtName)) + .concat(".") + .concat(DcaeBeConstants.Composition.fileNames.EVENT_PROC_BP_YAML); + } + + ResourceInstance findVfiOnService(ServiceDetailed service, String vfiName) { + if (null == service || null == service.getResources()) { + return null; + } + return service.getResources().stream() + .filter(p -> Normalizers.normalizeComponentInstanceName(vfiName).equals(Normalizers.normalizeComponentInstanceName(p.getResourceInstanceName()))).findAny().orElse(null); + } + + public String extractFlowTypeFromCdump(String cdump) { + return StringUtils.substringBetween(cdump,"\"flowType\":\"","\""); + } + + // TODO - reuse + + ResourceDetailed checkinVfcmt(String userId, String uuid, String requestId) { + return getSdcRestClient().changeResourceLifecycleState(userId, uuid, LifecycleOperationType.CHECKIN.name(), "checking in vfcmt" + uuid, requestId); + } + ResourceDetailed checkoutVfcmt(String userId, String uuid, String requestId) { + return getSdcRestClient().changeResourceLifecycleState(userId, uuid, LifecycleOperationType.CHECKOUT.name(), null, requestId); + } + + // TODO - remove from BaseController + + void checkUserIfResourceCheckedOut(String userId, Asset asset) { + if (DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT == DcaeBeConstants.LifecycleStateEnum.findState(asset.getLifecycleState())) { + String lastUpdaterUserId = asset.getLastUpdaterUserId(); + if (lastUpdaterUserId != null && !lastUpdaterUserId.equals(userId)) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "User conflicts. Operation not allowed for user {} on resource checked out by {}", userId, lastUpdaterUserId); + ResponseFormat responseFormat = ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.USER_CONFLICT, null, userId, asset.getName(), lastUpdaterUserId); + throw new DcaeException(HttpStatus.FORBIDDEN, responseFormat.getRequestError()); + } + } + } + + boolean isNeedToCheckOut(String lifecycleState) { + return DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT != DcaeBeConstants.LifecycleStateEnum.findState(lifecycleState); + } + + void checkVfcmtType(ResourceDetailed vfcmt) { + if (AssetType.VFCMT != getValidAssetTypeOrNull(vfcmt.getResourceType()) || !"Template".equals(vfcmt.getCategory())) { + ResponseFormat responseFormat = ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.RESOURCE_NOT_VFCMT_ERROR, null, vfcmt.getUuid()); + throw new DcaeException(HttpStatus.BAD_REQUEST, responseFormat.getRequestError()); + } + } + + AssetType getValidAssetTypeOrNull(String type) { + try { + return AssetType.getAssetTypeByName(type); + } catch (IllegalArgumentException e) { + debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "invalid asset type: {}. Error: {}", type, e); + return null; + } + } + + ResponseEntity handleException(Exception e, ErrConfMgr.ApiType apiType, String... variables){ + errLogger.log(LogLevel.ERROR, this.getClass().getName(), e.getMessage()); + return ErrConfMgr.INSTANCE.handleException(e, apiType, variables); + } + } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BlueprintBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BlueprintBusinessLogic.java new file mode 100644 index 0000000..0ccb6d8 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BlueprintBusinessLogic.java @@ -0,0 +1,98 @@ +package org.onap.sdc.dcae.composition.impl; + +import org.apache.commons.lang.StringUtils; +import org.onap.sdc.common.onaplog.Enums.LogLevel; +import org.onap.sdc.dcae.catalog.asdc.ASDC; +import org.onap.sdc.dcae.catalog.asdc.ASDCUtils; +import org.onap.sdc.dcae.catalog.asdc.Blueprinter; +import org.onap.sdc.dcae.composition.restmodels.MessageResponse; +import org.onap.sdc.dcae.composition.restmodels.VfcmtData; +import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; +import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed; +import org.onap.sdc.dcae.composition.util.DcaeBeConstants; +import org.onap.sdc.dcae.composition.util.SystemProperties; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.io.StringReader; +import java.net.URI; + +@Component +public class BlueprintBusinessLogic extends BaseBusinessLogic { + + @Autowired + private Blueprinter blueprinter; + @Autowired + private ASDC asdc; + @Autowired + private SystemProperties systemProperties; + @Autowired private CompositionBusinessLogic compositionBusinessLogic; + + + @PostConstruct + public void init() { + URI sdcUri = URI.create(systemProperties.getProperties().getProperty(DcaeBeConstants.Config.URI)); + asdc.setUri(sdcUri); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "SDC uri: {}", sdcUri); + } + + public ResponseEntity generateAndSaveBlueprint(String userId, String context, String vfcmtUuid, String serviceUuid, String vfiName, String flowType, String requestId) { + try { + // prepare - fetch vfcmt and cdump + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + Artifact cdumpArtifactData = fetchCdump(vfcmt, requestId); + if (null == cdumpArtifactData) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Composition not found on vfcmt {}", vfcmtUuid); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", vfcmt.getName()); + } + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Found the cdump (composition.yml) on top of VFCMT {}", vfcmtUuid); + String cdump = cdumpArtifactData.getPayloadData(); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Going to use python procedure to create a blueprint...."); + String resultBlueprintCreation = generateBlueprintViaToscaLab(cdump); + if (StringUtils.isEmpty(resultBlueprintCreation)) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occurred during blueprint generation"); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERATE_BLUEPRINT_ERROR, "", vfcmt.getName()); + } + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "BLUEPRINT:\n{}", resultBlueprintCreation); + + // 1806 US374595 flowType in cdump + String flowTypeFromCdump = extractFlowTypeFromCdump(cdump); + + // support backward compatibility + if(StringUtils.isBlank(flowTypeFromCdump)) { + flowTypeFromCdump = flowType; + } + + VfcmtData vfcmtData = new VfcmtData(vfcmt, vfiName, flowTypeFromCdump, serviceUuid); + Artifact blueprintArtifactResult = compositionBusinessLogic.submitComposition(userId, context, vfcmtData, resultBlueprintCreation, requestId); + if (null == blueprintArtifactResult) { + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SUBMIT_BLUEPRINT_ERROR); + } + + MessageResponse response = new MessageResponse(); + response.setSuccessResponse("Blueprint build complete \n. Blueprint=" + blueprintArtifactResult.getArtifactName()); + return new ResponseEntity<>(response, HttpStatus.OK); + } catch (Exception e) { + return handleException(e, ErrConfMgr.ApiType.SUBMIT_BLUEPRINT); + } + } + + private String generateBlueprintViaToscaLab(String cdump) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "---------------------------------------------------------------CDUMP: -----------------------------------------------------------------------------"); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), cdump); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "---------------------------------------------------------------------------------------------------------------------------------------------------"); + ASDCUtils utils = new ASDCUtils(asdc, blueprinter); + String resultBlueprintCreation = null; + try{ + resultBlueprintCreation = utils.buildBlueprintViaToscaLab(new StringReader(cdump)).waitForResult().waitForResult(); + }catch (Exception e){ + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Generate blueprint via tosca lab error: {}", e); + } + return resultBlueprintCreation; + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/CompositionBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/CompositionBusinessLogic.java new file mode 100644 index 0000000..e81ffe0 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/CompositionBusinessLogic.java @@ -0,0 +1,169 @@ +package org.onap.sdc.dcae.composition.impl; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.onap.sdc.common.onaplog.Enums.LogLevel; +import org.onap.sdc.dcae.composition.restmodels.CreateMcResponse; +import org.onap.sdc.dcae.composition.restmodels.VfcmtData; +import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; +import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed; +import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceInstance; +import org.onap.sdc.dcae.composition.restmodels.sdc.ServiceDetailed; +import org.onap.sdc.dcae.composition.util.DcaeBeConstants; +import org.onap.sdc.dcae.enums.ArtifactType; +import org.onap.sdc.dcae.enums.LifecycleOperationType; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.utils.Normalizers; +import org.onap.sdc.dcae.utils.SdcRestClientUtils; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.util.Base64Utils; +import org.springframework.util.CollectionUtils; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +@Component +public class CompositionBusinessLogic extends BaseBusinessLogic { + + private static final String CREATE_DESC = "creating new artifact blueprint on the service vfi"; + private static final String UPDATE_DESC = "updating artifact blueprint on the service vfi"; + + public CreateMcResponse getDataAndComposition(String vfcmtUuid, String requestId) throws IOException { + ResourceDetailed vfcmt = sdcRestClient.getResource(vfcmtUuid, requestId); + Artifact composition = fetchCdump(vfcmt, requestId); + return buildVfcmtAndCdumpResponse(new VfcmtData(vfcmt), composition.getPayloadData()); + } + + // 1806 US399018 update composition - assumes an artifact already exists (create mode flag for backward compatibility) + public ResponseEntity saveComposition(String userId, String vfcmtUuid, String updatedPayload, String requestId, boolean allowCreateNew) { + + boolean undoCheckoutOnFailure = false; + ResourceDetailed vfcmt = null; + try { + vfcmt = sdcRestClient.getResource(vfcmtUuid, requestId); + Artifact artifactData = findCdumpArtifactData(vfcmt); + if (null == artifactData && !allowCreateNew) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Composition not found on vfcmt {}", vfcmt.getUuid()); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", vfcmt.getName()); + } + if (DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT != DcaeBeConstants.LifecycleStateEnum.findState(vfcmt.getLifecycleState())) { + vfcmt = sdcRestClient.changeResourceLifecycleState(userId, vfcmt.getUuid(), LifecycleOperationType.CHECKOUT.name(), null, requestId); + undoCheckoutOnFailure = true; + } + if (null == artifactData) { + artifactData = SdcRestClientUtils.generateDeploymentArtifact("creating composition file", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML, ArtifactType.DCAE_TOSCA.name(), "composition", updatedPayload.getBytes()); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "creating new composition artifact for MC: {}", vfcmt.getUuid()); + sdcRestClient.createResourceArtifact(userId, vfcmt.getUuid(), artifactData, requestId); + } else { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "updating composition artifact for MC: {}", vfcmt.getUuid()); + artifactData.setDescription("updating composition"); + artifactData.setPayloadData(Base64Utils.encodeToString(updatedPayload.getBytes())); + sdcRestClient.updateResourceArtifact(userId, vfcmt.getUuid(), artifactData, requestId); + } + return new ResponseEntity<>(sdcRestClient.changeResourceLifecycleState(userId, vfcmt.getUuid(), LifecycleOperationType.CHECKIN.name(), "auto checkin after save composition", requestId), HttpStatus.OK); + } catch (Exception e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Save composition failed: {}", e); + if(undoCheckoutOnFailure) { + rollBack(userId, vfcmt, requestId); + } + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.SAVE_CDUMP); + } + } + + public Artifact submitComposition(String userId, String context, VfcmtData vfcmtData, String resultBlueprintCreation, String requestId) throws JsonProcessingException { + + // get service / find vfi + ServiceDetailed service = sdcRestClient.getAssetMetadata(context, vfcmtData.getServiceUuid(), requestId); + ResourceInstance vfi = findVfiOnService(service, vfcmtData.getVfiName()); + if(null == vfi){ + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "VF instance {} not found on service {}", vfcmtData.getVfiName(), vfcmtData.getServiceUuid()); + return null; + } + // look for existing blueprint details + //1802,1806 US412711 - Allow multiple BP from the same flow type on a single VFi - identify existing blueprint by name - for backward compatibility + String artifactName = generateBlueprintFileName(vfcmtData.getFlowType(), vfcmtData.getName()); + Artifact blueprintArtifact = findExistingBlueprint(vfi, artifactName); + + // save blueprint as instance artifact + // create mode + if(null == blueprintArtifact) { + String artifactLabel = "blueprint-".concat(vfcmtData.getFlowType()).concat("-").concat(Normalizers.normalizeComponentName(vfcmtData.getName())); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Service {} does not consist {} ----> createMode", vfcmtData.getServiceUuid(), artifactLabel); + blueprintArtifact = SdcRestClientUtils.generateDeploymentArtifact(CREATE_DESC, artifactName , ArtifactType.DCAE_INVENTORY_BLUEPRINT.name(), artifactLabel, resultBlueprintCreation.getBytes()); + blueprintArtifact = sdcRestClient.createInstanceArtifact(userId, context, vfcmtData.getServiceUuid(), Normalizers.normalizeComponentInstanceName(vfcmtData.getVfiName()), blueprintArtifact, requestId); + // update mode + } else { + blueprintArtifact = updateBlueprint(userId, context, vfcmtData.getServiceUuid(), vfcmtData.getVfiName(), blueprintArtifact, resultBlueprintCreation, requestId); + // TODO should this be safe? + //1806 US390018 - remove reference to previous version + deletePreviousReference(userId, context, service, vfcmtData, requestId); + } + //1806 US374593 - certify VFCMT after BP generation + certifyVfcmt(userId, vfcmtData, requestId); + return blueprintArtifact; + } + + + private Artifact updateBlueprint(String userId, String context, String serviceUuid, String vfiName, Artifact blueprintArtifact, String payload, String requestId) throws JsonProcessingException { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Found that service {} already consist of {} ----> updateMode", serviceUuid, blueprintArtifact.getArtifactLabel()); + blueprintArtifact.setDescription(UPDATE_DESC); + blueprintArtifact.setPayloadData(Base64Utils.encodeToString(payload.getBytes())); + return sdcRestClient.updateInstanceArtifact(userId, context, serviceUuid, Normalizers.normalizeComponentInstanceName(vfiName), blueprintArtifact, requestId); + } + + private Artifact findExistingBlueprint(ResourceInstance vfi, String artifactName) { + return CollectionUtils.isEmpty(vfi.getArtifacts()) ? null : vfi.getArtifacts().stream() + .filter(p -> Normalizers.normalizeArtifactLabel(artifactName).equals(Normalizers.normalizeArtifactLabel(p.getArtifactName()))) + .findAny() + .orElse(null); + } + + //TODO should this be safe or throw? + private void deletePreviousReference(String userId, String context, ServiceDetailed service, VfcmtData newReferencedMc, String requestId) { + String normalizedInstanceName = Normalizers.normalizeComponentInstanceName(newReferencedMc.getVfiName()); + List<String> vfiRefs = sdcRestClient.getMonitoringReferences(context, service.getUuid(), service.getVersion(), requestId).get(normalizedInstanceName); + if (null != vfiRefs && 1 < vfiRefs.size()) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Found {} external monitoring references for vfi {} on service {}:{}", vfiRefs.size(), newReferencedMc.getVfiName(), service.getUuid(), vfiRefs); + Collections.synchronizedList(vfiRefs).parallelStream() + .filter(p -> !newReferencedMc.getUuid().equals(p)) + .filter(p -> newReferencedMc.getInvariantUUID().equals(sdcRestClient.getResource(p, requestId).getInvariantUUID())) + .forEach(id -> sdcRestClient.deleteExternalMonitoringReference(userId, context, service.getUuid(), normalizedInstanceName, id, requestId)); + } else { + // this shouldn't happen - there should be at least two references registered to the vfi + debugLogger.log(LogLevel.WARN, this.getClass().getName(), "Sum Ting Wong. References found: {}", vfiRefs); + } + } + + private void certifyVfcmt(String userId, VfcmtData vfcmt, String requestId) { + String state = vfcmt.getLifecycleState(); + if(null == state) { + debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "Couldn't read Vfcmt lifecycle state"); + return; + } + DcaeBeConstants.LifecycleStateEnum lifeCycleState = DcaeBeConstants.LifecycleStateEnum.findState(state); + if(null == lifeCycleState) { + debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "Undefined lifecycle state: {}", state); + return; + } + try{ + switch (lifeCycleState){ + case NOT_CERTIFIED_CHECKOUT: + sdcRestClient.changeResourceLifecycleState(userId, vfcmt.getUuid(), LifecycleOperationType.CHECKIN.name(), "check in VFCMT after blueprint successful submission", requestId); + sdcRestClient.changeResourceLifecycleState(userId, vfcmt.getUuid(), LifecycleOperationType.CERTIFY.name(), "certify VFCMT after blueprint successful submission", requestId); + break; + case NOT_CERTIFIED_CHECKIN: + sdcRestClient.changeResourceLifecycleState(userId, vfcmt.getUuid(), LifecycleOperationType.CERTIFY.name(), "certify VFCMT after blueprint successful submission", requestId); + break; + default: + } + } + catch (Exception e){ + //informative only. no message to user (TBA) + debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occurred during vfcmt lifecycle operation: {}", e); + } + } + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java index d229b67..1396cc9 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java @@ -2,7 +2,6 @@ package org.onap.sdc.dcae.composition.impl; import org.onap.sdc.common.onaplog.Enums.LogLevel; import org.onap.sdc.dcae.composition.restmodels.MonitoringComponent; -import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; import org.onap.sdc.dcae.composition.restmodels.sdc.ExternalReferencesMap; import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceInstance; import org.onap.sdc.dcae.composition.restmodels.sdc.ServiceDetailed; @@ -12,6 +11,7 @@ import org.onap.sdc.dcae.utils.Normalizers; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import java.util.*; @@ -25,23 +25,27 @@ public class ReferenceBusinessLogic extends BaseBusinessLogic { try { String normalizedVfiName = Normalizers.normalizeComponentInstanceName(vfiName); ServiceDetailed serviceDetailed = sdcRestClient.getService(serviceUuid, requestId); - Optional<ResourceInstance> resourceInstance = serviceDetailed.getResources().stream().filter(item -> item.getResourceInstanceName().equalsIgnoreCase(vfiName)).findAny(); - if (resourceInstance.isPresent() && resourceInstance.get().getArtifacts() != null) { - Optional<Artifact> artifact = resourceInstance.get().getArtifacts().stream().filter(item -> item.getArtifactName().contains(monitoringComponentName)).findAny(); - artifact.ifPresent(artifact1 -> sdcRestClient.deleteInstanceResourceArtifact(userId, context, serviceUuid, normalizedVfiName, artifact1.getArtifactUUID(), requestId)); + ResourceInstance resourceInstance = findVfiOnService(serviceDetailed, vfiName); + if (resourceInstance != null && resourceInstance.getArtifacts() != null) { + String artifactNameEndsWith = generateBlueprintFileName("", monitoringComponentName); + resourceInstance.getArtifacts().stream() + .filter(item -> StringUtils.endsWithIgnoreCase(item.getArtifactName(), artifactNameEndsWith)) + .findAny() + .ifPresent(artifact -> sdcRestClient.deleteInstanceArtifact(userId, context, serviceUuid, normalizedVfiName, artifact.getArtifactUUID(), requestId)); } } catch (Exception e) { debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Failed to delete blueprint with serviceUuid {}, vfcmtUuid . message: {} ", serviceUuid, vfcmtUuid, e); - return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_BLUEPRINT_FAILED); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_BLUEPRINT_FAILED, e.getMessage()); } return new ResponseEntity<>(HttpStatus.OK); } + public void deleteVfcmtReference(String userId, String context, String serviceUuid, String vfiName, String vfcmtUuid, String requestId) { debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Going to delete vfcmt reference, vfiName = {}", vfiName); String normalizedVfiName = Normalizers.normalizeComponentInstanceName(vfiName); - sdcRestClient.deleteExternalMonitoringReference(userId, context, serviceUuid, normalizedVfiName, vfcmtUuid, requestId); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished to delete vfcmt reference. serviceUuid {}, vfcmtUuid {}", serviceUuid, vfcmtUuid); + sdcRestClient.deleteExternalMonitoringReference(userId, context, serviceUuid, normalizedVfiName, vfcmtUuid, requestId); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished to delete vfcmt reference. serviceUuid {}, vfcmtUuid {}", serviceUuid, vfcmtUuid); } // 1806 US381853 Return a list of monitoring components by external reference id. Support partial success @@ -70,5 +74,4 @@ public class ReferenceBusinessLogic extends BaseBusinessLogic { return result; } - } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/RuleEditorBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/RuleEditorBusinessLogic.java new file mode 100644 index 0000000..d17a6bf --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/RuleEditorBusinessLogic.java @@ -0,0 +1,389 @@ +package org.onap.sdc.dcae.composition.impl; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.gson.JsonParseException; +import org.apache.commons.collections.ListUtils; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.onap.sdc.common.onaplog.Enums.LogLevel; +import org.onap.sdc.dcae.composition.CompositionConfig; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*; +import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; +import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed; +import org.onap.sdc.dcae.composition.util.DcaeBeConstants; +import org.onap.sdc.dcae.enums.ArtifactType; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ServiceException; +import org.onap.sdc.dcae.rule.editor.impl.RulesBusinessLogic; +import org.onap.sdc.dcae.rule.editor.utils.RulesPayloadUtils; +import org.onap.sdc.dcae.utils.Normalizers; +import org.onap.sdc.dcae.utils.SdcRestClientUtils; +import org.onap.sdc.dcae.ves.VesDataItemsDefinition; +import org.onap.sdc.dcae.ves.VesDataTypeDefinition; +import org.onap.sdc.dcae.ves.VesSimpleTypesEnum; +import org.onap.sdc.dcae.ves.VesStructureLoader; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.util.Base64Utils; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.*; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Component +public class RuleEditorBusinessLogic extends BaseBusinessLogic { + + @Autowired + private RulesBusinessLogic rulesBusinessLogic; + @Autowired + private CompositionConfig compositionConfig; + + private static final String EXCEPTION = "Exception {}"; + + public ResponseEntity saveRule(String json, String requestId, String userId, String vfcmtUuid, String dcaeCompLabel, String nid, String configParam) { + + try { + Rule rule = RulesPayloadUtils.parsePayloadToRule(json); + if (null == rule) { + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_RULE_FORMAT); + } + + List<ServiceException> errors = rulesBusinessLogic.validateRule(rule); + if (!errors.isEmpty()) { + return ErrConfMgr.INSTANCE.buildErrorArrayResponse(errors); + } + + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + checkVfcmtType(vfcmt); + + if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) { + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SAVE_RULE_FAILED); + } + + String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam); + + // check for MappingRules artifact in existing artifacts + Artifact artifactFound = vfcmt.getArtifacts().stream() + .filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))) + .findAny().orElse(null); + + // exception thrown if vfcmt is checked out and current user is not its owner + // performs checkoutVfcmt if required + String vfcmtId = assertOwnershipOfVfcmtId(userId, vfcmt, requestId); + // new mappingRules artifact, validate nid exists in composition before creating new artifact + if (null == artifactFound) { + if (cdumpContainsNid(vfcmt, nid, requestId)) { + return saveNewRulesArtifact(rule, vfcmtId, generateMappingRulesFileName(dcaeCompLabel, nid, configParam), artifactLabel, userId, requestId); + } + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.NODE_NOT_FOUND, "", dcaeCompLabel); + } + + //update artifact flow - append new rule or edit existing rule + return addOrEditRuleInArtifact(rule, vfcmtId, userId, artifactFound, requestId); + + } catch (JsonParseException je) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error: Rule format is invalid: {}", je); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_RULE_FORMAT, "", je.getMessage()); + } catch (Exception e) { + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.SAVE_RULE_ARTIFACT); + } + + } + + public ResponseEntity getRules(String vfcmtUuid, String dcaeCompLabel, String nid, String configParam, String requestId) { + + try { + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) { + return new ResponseEntity<>("{}", HttpStatus.OK); + } + String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam); + + // check for MappingRules artifact in existing artifacts + Artifact artifactListed = vfcmt.getArtifacts().stream().filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))).findAny().orElse(null); + if (null == artifactListed) { + return new ResponseEntity<>("{}", HttpStatus.OK); + } + String ruleFile = getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactListed.getArtifactUUID(), requestId); + + // To avoid opening the file for reading we search for the eventType and SchemaVer from the artifact metadata's description + SchemaInfo schemainfo = RulesPayloadUtils.extractInfoFromDescription(artifactListed); + List<EventTypeDefinitionUI> schema = null == schemainfo ? new ArrayList<>() : getEventTypeDefinitionUIs(schemainfo.getVersion(), schemainfo.getEventType()); + return new ResponseEntity<>(RulesPayloadUtils.buildSchemaAndRulesResponse(ruleFile, schema), HttpStatus.OK); + } catch (Exception e) { + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.GET_RULE_ARTIFACT); + } + + } + + public ResponseEntity deleteRule(String userId, String vfcmtUuid, String dcaeCompLabel, String nid, String configParam, String ruleUid, String requestId) { + + try { + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + if (null == vfcmt.getArtifacts()) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "VFCMT {} doesn't have artifacts", vfcmtUuid); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED); + } + String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam); + + // check for MappingRules artifact in existing artifacts + Artifact mappingRuleFile = vfcmt.getArtifacts().stream() + .filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))) + .findAny().orElse(null); + + if (null == mappingRuleFile) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "{} doesn't exist for VFCMT {}", artifactLabel, vfcmtUuid); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED); + } + + String vfcmtId = assertOwnershipOfVfcmtId(userId, vfcmt, requestId); + String payload = getSdcRestClient().getResourceArtifact(vfcmtId, mappingRuleFile.getArtifactUUID(), requestId); + MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload); + Rule removedRule = rulesBusinessLogic.deleteRule(rules, ruleUid); + if (null == removedRule) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Rule {} not found.", ruleUid); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED); + } + if (rules.isEmpty()) { // if file doesn't contain any rules after last deletion -> let's delete the file + getSdcRestClient().deleteResourceArtifact(userId, vfcmtId, mappingRuleFile.getArtifactUUID(), requestId); + } else { + updateRulesArtifact(vfcmtId, userId, mappingRuleFile, rules, requestId); + } + return checkInAndReturnSaveArtifactResult(removedRule, vfcmtId, userId, requestId); + } catch (Exception e) { + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.SAVE_RULE_ARTIFACT); + } + + } + + public ResponseEntity translateRules(String vfcmtUuid, String requestId, String dcaeCompLabel, String nid, String configParam, String flowType) { + + try { + + if (StringUtils.isBlank(flowType) || MapUtils.isEmpty(compositionConfig.getFlowTypesMap()) || null == compositionConfig.getFlowTypesMap().get(flowType)) { + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", "Flow type " + flowType + " not found"); + } + + // extract entry phase name and last phase name from configuration: + String entryPointPhaseName = compositionConfig.getFlowTypesMap().get(flowType).getEntryPointPhaseName(); + String lastPhaseName = compositionConfig.getFlowTypesMap().get(flowType).getLastPhaseName(); + + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + checkVfcmtType(vfcmt); + + if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) { + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", "No rules found on VFCMT " + vfcmtUuid); + } + String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam); + + // check for MappingRules artifact in existing artifacts + Artifact rulesArtifact = vfcmt.getArtifacts().stream().filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))).findAny().orElse(null); + + if (rulesArtifact == null) { + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", artifactLabel + " doesn't exist on VFCMT " + vfcmtUuid); + } + + String payload = getSdcRestClient().getResourceArtifact(vfcmtUuid, rulesArtifact.getArtifactUUID(), requestId); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Retrieved mapping rules artifact {}, start parsing rules...", artifactLabel); + MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished parsing rules, calling validator..."); + List<ServiceException> errors = rulesBusinessLogic.validateRules(rules); + if (!errors.isEmpty()) { + return ErrConfMgr.INSTANCE.buildErrorArrayResponse(errors); + } + + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Validation completed successfully, calling translator..."); + String translateJson = rulesBusinessLogic.translateRules(rules, entryPointPhaseName, lastPhaseName, vfcmt.getName()); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translation completed successfully"); + return new ResponseEntity<>(translateJson, HttpStatus.OK); + } catch (Exception e) { + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.SAVE_RULE_ARTIFACT); + } + } + + public ResponseEntity getExistingRuleTargets(String vfcmtUuid, String requestId, String dcaeCompLabel, String nid) { + + try { + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "getExistingRuleTargets - no rules found! returning zero response."); + return new ResponseEntity<>("{}", HttpStatus.OK); + } + String artifactNameStartWith = dcaeCompLabel + "_" + nid + "_"; + + List<String> artifactWithRules = vfcmt.getArtifacts().stream().filter(artifact -> + artifact.getArtifactName().startsWith(artifactNameStartWith)) + .map(artifact -> StringUtils.substringBetween(artifact.getArtifactName(), artifactNameStartWith, DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX)).collect(Collectors.toList()); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "getExistingRuleTargets completed successfully"); + return new ResponseEntity<>(artifactWithRules, HttpStatus.OK); + } catch (Exception e) { + debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "getExistingRuleTargets had exception", e); + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.GET_RULE_ARTIFACT); + } + } + + public ResponseEntity getDefinition(String version, String eventType) { + + try { + List<EventTypeDefinitionUI> result = getEventTypeDefinitionUIs(version, eventType); + + return new ResponseEntity<>(result, HttpStatus.OK); + + } catch (Exception e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), EXCEPTION, e); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.VES_SCHEMA_NOT_FOUND); + } + } + + public ResponseEntity getEventsByVersion() { + try { + + Map<String, Set<String>> eventsByVersions = VesStructureLoader.getAvailableVersionsAndEventTypes(); + + List<EventTypesByVersionUI> resBody = eventsByVersions.entrySet().stream().map(entry -> { + Set<String> events = entry.getValue().stream().filter(event -> !EventTypesByVersionUI.DEFAULT_EVENTS.contains(event)).collect(Collectors.toSet()); + return new EventTypesByVersionUI(entry.getKey(), events); + }).collect(Collectors.toList()); + + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Got a request to return all ves event types by versions {}", eventsByVersions); + return new ResponseEntity<>(resBody, HttpStatus.OK); + + } catch (Exception e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), EXCEPTION, e); + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.VES_SCHEMA_NOT_FOUND); + } + } + + ///////////////////PRIVATE METHODS//////////////////////////////////////////////////////////////////////// + + private String assertOwnershipOfVfcmtId(String userId, ResourceDetailed vfcmt, String requestId) { + checkUserIfResourceCheckedOut(userId, vfcmt); + String newVfcmtId = vfcmt.getUuid(); // may change after checking out a certified vfcmt + if (isNeedToCheckOut(vfcmt.getLifecycleState())) { + ResourceDetailed result = checkoutVfcmt(userId, newVfcmtId, requestId); + if (result != null) { + newVfcmtId = result.getUuid(); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New resource after checkoutVfcmt is: {}", newVfcmtId); + } + } + return newVfcmtId; + } + + // called after validating vfcmt.getArtifacts() is not null + private boolean cdumpContainsNid(ResourceDetailed vfcmt, String nid, String requestId) { + Artifact cdump = vfcmt.getArtifacts().stream() + .filter(a -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equalsIgnoreCase(a.getArtifactName())) + .findAny().orElse(null); + if (null == cdump || null == cdump.getArtifactUUID()) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "No {} found on vfcmt {}", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML, vfcmt.getUuid()); + return false; + } + try { + String artifact = getSdcRestClient().getResourceArtifact(vfcmt.getUuid(), cdump.getArtifactUUID(), requestId); + if (!artifact.contains("\"nid\":\"" + nid)) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "{} doesn't contain nid {}. Cannot save mapping rule file", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML, nid); + return false; + } + } catch (Exception e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), EXCEPTION, e); + return false; + } + return true; + } + + private ResponseEntity<String> saveNewRulesArtifact(Rule rule, String vfcmtUuid, String artifactFileName, String artifactLabel, String userId, String requestId) throws JsonProcessingException { + MappingRules body = new MappingRules(rule); + Artifact artifact = SdcRestClientUtils.generateDeploymentArtifact(body.describe(), artifactFileName, ArtifactType.OTHER.name(), artifactLabel, body.convertToPayload()); + getSdcRestClient().createResourceArtifact(userId, vfcmtUuid, artifact, requestId); + return checkInAndReturnSaveArtifactResult(rule, vfcmtUuid, userId, requestId); + } + + private ResponseEntity addOrEditRuleInArtifact(Rule rule, String vfcmtUuid, String userId, Artifact rulesArtifact, String requestId) throws JsonProcessingException { + String payload = getSdcRestClient().getResourceArtifact(vfcmtUuid, rulesArtifact.getArtifactUUID(), requestId); + MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload); + + // in case the rule id is passed but the rule doesn't exist on the mapping rule file: + if (!rulesBusinessLogic.addOrEditRule(rules, rule)) { + return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SAVE_RULE_FAILED); + } + updateRulesArtifact(vfcmtUuid, userId, rulesArtifact, rules, requestId); + return checkInAndReturnSaveArtifactResult(rule, vfcmtUuid, userId, requestId); + } + + // regardless of check in result, return save artifact success + private ResponseEntity<String> checkInAndReturnSaveArtifactResult(Rule rule, String vfcmtUuid, String userId, String requestId) { + try { + checkinVfcmt(userId, vfcmtUuid, requestId); + } catch (Exception e) { + // swallowing the exception intentionally since it is on the check in action + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occurred while performing check in on VFCMT {}:{}", vfcmtUuid, e); + } + return new ResponseEntity<>(rule.toJson(), HttpStatus.OK); + } + + private void updateRulesArtifact(String vfcmtUuid, String userId, Artifact artifactInfo, MappingRules rules, String requestId) throws JsonProcessingException { + artifactInfo.setPayloadData(Base64Utils.encodeToString(rules.convertToPayload())); + // POST must contain 'description' while GET returns 'artifactDescription' + artifactInfo.setDescription(artifactInfo.getArtifactDescription()); + getSdcRestClient().updateResourceArtifact(userId, vfcmtUuid, artifactInfo, requestId); + } + + + /** + * @param eventMapStream + * @param parent + * @param path + * @return + */ + private List<EventTypeDefinitionUI> convertToEventTypeDefinition(Stream<Map.Entry<String, VesDataTypeDefinition>> eventMapStream, VesDataTypeDefinition parent, String path) { + + return eventMapStream.map(entry -> { + Map<String, VesDataTypeDefinition> properties = entry.getValue().getProperties(); + VesDataItemsDefinition items = entry.getValue().getItems(); + String newPath = path + "." + entry.getKey(); + List<EventTypeDefinitionUI> children = (properties == null) ? null : convertToEventTypeDefinition(properties.entrySet().stream(), entry.getValue(), newPath); + if (VesSimpleTypesEnum.ARRAY.getType().equals(entry.getValue().getType())) { + newPath += "[]"; + if (innerTypeIsComplex(items)) { + children = convertComplexArrayType(items, newPath); + } else if (innerTypeIsArray(items)) { + newPath += "[]"; + } + } + + boolean isRequired = (parent != null) ? parent.getRequired().contains(entry.getKey()) : false; + return new EventTypeDefinitionUI(entry.getKey(), children, isRequired, newPath); + }).collect(Collectors.toList()); + } + + private boolean innerTypeIsComplex(VesDataItemsDefinition items) { + return items != null && items.stream().anyMatch(p -> p.getProperties() != null); + } + + private boolean innerTypeIsArray(VesDataItemsDefinition items) { + return items != null && items.stream().anyMatch(p -> p.getItems() != null); + } + + private List<EventTypeDefinitionUI> convertComplexArrayType(VesDataItemsDefinition items, String path) { + return items.stream().map(item -> item.getProperties() != null ? convertToEventTypeDefinition(item.getProperties().entrySet().stream(), item, path) : new ArrayList<EventTypeDefinitionUI>()) + .flatMap(List::stream).collect(Collectors.toList()); + } + + + private String generateMappingRulesFileName(String dcaeCompLabel, String nid, String configParam) { + return dcaeCompLabel + "_" + nid + "_" + configParam + DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX; + } + + private List<EventTypeDefinitionUI> getEventTypeDefinitionUIs(String version, String eventType) { + List<String> eventNamesToReturn = ListUtils.union(EventTypesByVersionUI.DEFAULT_EVENTS, Arrays.asList(eventType)); + Map<String, VesDataTypeDefinition> eventDefs = VesStructureLoader.getEventListenerDefinitionByVersion(version); + Stream<Map.Entry<String, VesDataTypeDefinition>> filteredEvents = eventDefs.entrySet().stream().filter(entry -> eventNamesToReturn.contains(entry.getKey())); + + return convertToEventTypeDefinition(filteredEvents, null, "event"); + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ServiceBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ServiceBusinessLogic.java new file mode 100644 index 0000000..d04c67a --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ServiceBusinessLogic.java @@ -0,0 +1,194 @@ +package org.onap.sdc.dcae.composition.impl; + + import org.onap.sdc.common.onaplog.Enums.LogLevel; + import org.onap.sdc.dcae.composition.restmodels.AttachVFCMTServiceRequest; + import org.onap.sdc.dcae.composition.restmodels.DcaeMinimizedService; + import org.onap.sdc.dcae.composition.restmodels.MessageResponse; + import org.onap.sdc.dcae.composition.restmodels.sdc.*; + import org.onap.sdc.dcae.composition.util.DcaeBeConstants; + import org.onap.sdc.dcae.enums.ArtifactType; + import org.onap.sdc.dcae.enums.LifecycleOperationType; + import org.onap.sdc.dcae.errormng.ActionStatus; + import org.onap.sdc.dcae.errormng.DcaeException; + import org.onap.sdc.dcae.errormng.ErrConfMgr; + import org.onap.sdc.dcae.errormng.ResponseFormat; + import org.onap.sdc.dcae.utils.SdcRestClientUtils; + import org.springframework.http.HttpStatus; + import org.springframework.http.ResponseEntity; + import org.springframework.stereotype.Component; + import org.springframework.util.Base64Utils; + import org.springframework.util.CollectionUtils; + + import java.util.ArrayList; + import java.util.Comparator; + import java.util.LinkedHashMap; + import java.util.List; + import java.util.stream.Collectors; + +@Component +public class ServiceBusinessLogic extends BaseBusinessLogic { + + + public ResponseEntity services(String userId, String vfcmtUuid, String requestId) { + try { + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "GET ({}) Vfcmt form SDC: {}", vfcmtUuid, vfcmt); + checkVfcmtType(vfcmt); + checkUserIfResourceCheckedOut(userId, vfcmt); + + List<Service> services = getSdcRestClient().getServices(requestId); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "GET services data from SDC: {}", services); + List<Service> uuids = filterServicesByUser(services, userId); + return new ResponseEntity<>(uuids, HttpStatus.OK); + } catch (Exception e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), e.getMessage()); + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.GET_SERVICE); + } + } + + public ResponseEntity service(String theServiceId, String requestId) { + try { + ServiceDetailed service = getSdcRestClient().getService(theServiceId, requestId); + if (service != null) { + if(service.getResources()!=null){ + List<ResourceInstance> vfResourcesOnly = service.getResources().stream().filter(vfi -> vfi.getResoucreType().equals("VF")).collect(Collectors.toList()); + service.setResources(vfResourcesOnly); + }else{ + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Service {} doesn't have any resources (e.g VFi's)", theServiceId); + } + } else { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Couldn't fetch service with uuid {} from SDC", theServiceId); + } + return new ResponseEntity<>(service, HttpStatus.OK); + } catch (Exception e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), e.getMessage()); + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.GET_SERVICE); + } + } + + + public ResponseEntity attachService( String vfcmtUuid, String userId, AttachVFCMTServiceRequest request, String requestId) { + + String serviceUuid = request.getServiceUuid(); + String vfiName = request.getInstanceName(); + String resourceUuid = vfcmtUuid; + MessageResponse response = new MessageResponse(); + + try { + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString()); + + checkVfcmtType(vfcmt); + verifyVfiExists(serviceUuid, vfiName, requestId); + + boolean isUpdateMode = false; + Artifact artifactObj = null; + + String reference = serviceUuid + "/resources/" + vfiName; + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "*****************************************"); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Reference between service and vfi {}", reference); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "*****************************************"); + + if(!CollectionUtils.isEmpty(vfcmt.getArtifacts())){ + artifactObj = vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.SVC_REF.equals(a.getArtifactName())).findAny().orElse(null); + isUpdateMode = null != artifactObj; + } + + if (isNeedToCheckOut(vfcmt.getLifecycleState())) { + vfcmt = getSdcRestClient().changeResourceLifecycleState(userId, vfcmtUuid, LifecycleOperationType.CHECKOUT.name(), null, requestId); + if (vfcmt != null) { + resourceUuid = vfcmt.getUuid(); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New vfcmt uuid after checkoutVfcmt is: {}", resourceUuid); + } + } + + if(isUpdateMode){ + updateReferenceArtifact(userId, resourceUuid, artifactObj, reference, requestId); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Artifact {} updated with content: {}", reference, DcaeBeConstants.Composition.fileNames.SVC_REF, reference); + }else{ + Artifact artifact = SdcRestClientUtils.generateDeploymentArtifact("createReferenceArtifact", DcaeBeConstants.Composition.fileNames.SVC_REF, ArtifactType.DCAE_TOSCA.name(), "servicereference", reference.getBytes()); + getSdcRestClient().createResourceArtifact(userId, resourceUuid, artifact, requestId); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Artifact {} created with content: {}", DcaeBeConstants.Composition.fileNames.SVC_REF, reference); + } + checkinVfcmt(userId, resourceUuid, requestId); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Attachment of reference={} in VFCMT {} has finished successfully", reference, resourceUuid); + + response.setSuccessResponse("Artifact updated"); + return new ResponseEntity<>(response, HttpStatus.OK); + } catch (Exception e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), e.getMessage()); + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.ATTACH_TO_SERVICE); + } + } + + public ResponseEntity getAttachedService(String vfcmtUuid, String requestId) { + + MessageResponse response = new MessageResponse(); + + try { + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString()); + checkVfcmtType(vfcmt); + String artifact = "No Artifacts"; + + if (!CollectionUtils.isEmpty(vfcmt.getArtifacts())) { + Artifact artifactObj = vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.SVC_REF.equals(a.getArtifactName())).findAny().orElse(null); + if (null != artifactObj) { + artifact = getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactObj.getArtifactUUID(), requestId); + } + } + response.setSuccessResponse(artifact); + return new ResponseEntity<>(response, HttpStatus.OK); + } catch (Exception e) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), e.getMessage()); + return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.GET_VFCMT); + } + } + + /**** PRIVATE METHODS ****/ + + private void updateReferenceArtifact(String userId, String VFCMTUuid, Artifact artifactObj, String reference, String requestId) throws Exception { + artifactObj.setDescription("updateReferenceArtifact"); + artifactObj.setPayloadData(Base64Utils.encodeToString(reference.getBytes())); + getSdcRestClient().updateResourceArtifact(userId, VFCMTUuid, artifactObj, requestId); + } + + + + //TODO move method to ci tests + public List<DcaeMinimizedService> parseAndFilterServicesByUser(String lastUpdaterUserId, List<LinkedHashMap<String, String>> services, String userId) { + List<DcaeMinimizedService> uuids = null; + if (services != null) { + //services.stream().filter(predicate) + uuids = services.stream() + .map(x -> new DcaeMinimizedService(x.get("uuid"), x.get("name"), x.get("lastUpdaterUserId"), x.get("lifecycleState"), x.get("version"), x.get("invariantUUID"))) + .collect(Collectors.groupingBy(DcaeMinimizedService::getInvariantUUID)).values().stream() + .map(p -> p.stream() + .sorted(Comparator.comparing(DcaeMinimizedService::getVersionAsFloat).reversed())).map(p -> p.collect(Collectors.toList())).map(p -> p.get(0)) + .filter(x -> (!(!x.getLastUpdaterUserId().equals(userId) && x.getLifeCycleState().equals(DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())))) + .sorted(Comparator.comparing(DcaeMinimizedService::getName)).collect(Collectors.toList()); + } + return uuids; + } + + private List<Service> filterServicesByUser(List<Service> services, String userId) { + return CollectionUtils.isEmpty(services) ? new ArrayList<>() : services.stream() + .collect(Collectors.groupingBy(Service::getInvariantUUID)).values().stream() + .map(p -> p.stream() + .sorted(Comparator.comparing(Service::versionAsFloat).reversed())).map(p -> p.collect(Collectors.toList())).map(p -> p.get(0)) + .filter(x -> (!(!x.getLastUpdaterUserId().equals(userId) && x.getLifecycleState().equals(DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())))) + .sorted(Comparator.comparing(Service::getName)).collect(Collectors.toList()); + } + + + private void verifyVfiExists(String serviceUuid, String vfiName, String requestId) throws Exception { + ServiceDetailed service = getSdcRestClient().getService(serviceUuid, requestId); + boolean isServiceContainsVfi = null != service && !CollectionUtils.isEmpty(service.getResources()) && service.getResources().stream() + .filter(vfi -> "VF".equals(vfi.getResoucreType())) + .anyMatch(vfi -> vfiName.equals(vfi.getResourceInstanceName())); + if (!isServiceContainsVfi) { + ResponseFormat responseFormat = ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.VFI_FETCH_ERROR, null, serviceUuid, vfiName); + throw new DcaeException(HttpStatus.NOT_FOUND, responseFormat.getRequestError()); + } + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogic.java index e68a8ee..4093555 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogic.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogic.java @@ -1,15 +1,19 @@ package org.onap.sdc.dcae.composition.impl; -import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.JsonProcessingException; import org.apache.commons.lang.StringUtils; import org.onap.sdc.common.onaplog.Enums.LogLevel; -import org.onap.sdc.dcae.composition.restmodels.*; +import org.onap.sdc.dcae.composition.restmodels.CreateVFCMTRequest; +import org.onap.sdc.dcae.composition.restmodels.ImportVFCMTRequest; +import org.onap.sdc.dcae.composition.restmodels.ReferenceUUID; +import org.onap.sdc.dcae.composition.restmodels.VfcmtData; import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; import org.onap.sdc.dcae.composition.restmodels.sdc.ExternalReferencesMap; import org.onap.sdc.dcae.composition.restmodels.sdc.Resource; import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed; import org.onap.sdc.dcae.composition.util.DcaeBeConstants; import org.onap.sdc.dcae.enums.ArtifactType; +import org.onap.sdc.dcae.enums.AssetType; import org.onap.sdc.dcae.enums.LifecycleOperationType; import org.onap.sdc.dcae.errormng.ActionStatus; import org.onap.sdc.dcae.errormng.ErrConfMgr; @@ -20,7 +24,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.Base64Utils; import java.io.IOException; -import java.util.*; +import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -30,7 +34,6 @@ import static org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateE @Component public class VfcmtBusinessLogic extends BaseBusinessLogic { - private static final String VFCMT = "VFCMT"; private static final String TEMPLATE = "Template"; private static final String MONITORING_TEMPLATE = "Monitoring Template"; private static final String DEFAULTICON = "defaulticon"; @@ -42,21 +45,20 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Missing information"); return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_CONTENT); } - return cloneMcAndAddServiceReference(userId, request, requestId); + return cloneMcAndAddServiceReference(userId, request, requestId, false); } //1806 US388513 collect existing VFCMT data - flowType from cdump artifact and external reference from svc_reference artifact. If cdump not found - return error - - public ResponseEntity getVfcmtReferenceData(String vfcmtUuid, String requestId) throws Exception { - ResourceDetailed vfcmt = sdcRestClient.getResource(vfcmtUuid, requestId); - Artifact artifactData = findCdumpArtifactData(vfcmt); + public ResponseEntity getVfcmtReferenceData(String vfcmtUuid, String requestId) { + ResourceDetailed vfcmt = getSdcRestClient().getResource(vfcmtUuid, requestId); + Artifact artifactData = fetchCdump(vfcmt, requestId); if(null == artifactData) { debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"No composition found on vfcmt {}", vfcmtUuid); return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", vfcmt.getName()); } VfcmtData vfcmtData = new VfcmtData(vfcmt); //fetch cdump payload - String payload = getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactData.getArtifactUUID(), requestId); + String payload = artifactData.getPayloadData(); //extract and set flowType from cdump payload debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Looking for flowType definition in cdump"); vfcmtData.setFlowType(StringUtils.substringBetween(payload,"\"flowType\":\"","\"")); @@ -74,7 +76,6 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { return new ResponseEntity<>(vfcmtData, HttpStatus.OK); } - //1806 US388525 import or clone VFCMT - always pass the flowType - update will only take place if missing from cdump public ResponseEntity importMC(String userId, ImportVFCMTRequest request, String requestId) { if(!validateMCRequestFields(request)) { @@ -83,7 +84,7 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { } // option 1 - clone if(request.isCloneVFCMT()) { - return cloneMcAndAddServiceReference(userId, request, requestId); + return cloneMcAndAddServiceReference(userId, request, requestId, request.isUpdateFlowType()); } ResourceDetailed vfcmt = null; @@ -91,11 +92,12 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { // fetch vfcmt and cdump try { vfcmt = sdcRestClient.getResource(request.getTemplateUuid(), requestId); - Artifact cdumpArtifactData = fetchCdumpAndSetFlowType(vfcmt, request.getFlowType(), requestId); + Artifact cdumpArtifactData = fetchCdump(vfcmt, requestId); if (null == cdumpArtifactData) { errLogger.log(LogLevel.ERROR, this.getClass().getName(), "No cdump found for monitoring component {}", vfcmt.getUuid()); return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", vfcmt.getName()); } + String cdumpPayload = cdumpArtifactData.getPayloadData(); // option 2 - edit original cdump - requires check out @@ -104,7 +106,9 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { vfcmt = sdcRestClient.changeResourceLifecycleState(userId, vfcmt.getUuid(), LifecycleOperationType.CHECKOUT.name(), "checking out VFCMT", requestId); undoCheckoutOnFailure = true; } + cdumpArtifactData.setDescription("updating flowType on cdump"); + cdumpPayload = cdumpArtifactData.getPayloadData().replaceFirst("\\{", "{\"flowType\":\"" + request.getFlowType() + "\","); cdumpArtifactData.setPayloadData(Base64Utils.encodeToString(cdumpPayload.getBytes())); sdcRestClient.updateResourceArtifact(userId, vfcmt.getUuid(), cdumpArtifactData, requestId); } @@ -114,7 +118,7 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { // this will not throw an exception checkinVfcmtAfterClone(userId, vfcmt, requestId); } - return new ResponseEntity<>(buildVfcmtAndCdumpResponse(vfcmt, request.getVfiName(), request.getFlowType(), cdumpPayload), HttpStatus.OK); + return new ResponseEntity<>(buildVfcmtAndCdumpResponse(new VfcmtData(vfcmt, request.getVfiName(), extractFlowTypeFromCdump(cdumpPayload)), cdumpPayload), HttpStatus.OK); } catch (Exception e) { errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed updating Monitoring Component:{}", e.getMessage()); if(undoCheckoutOnFailure) { @@ -122,7 +126,6 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { } return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.CREATE_NEW_VFCMT); } - } private boolean validateMCRequestFields(CreateVFCMTRequest request) { @@ -140,25 +143,15 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { } - private void rollBack(String userId, ResourceDetailed newVfcmt, String requestId) { - if (null != newVfcmt) { - try { - getSdcRestClient().changeResourceLifecycleState(userId, newVfcmt.getUuid(), LifecycleOperationType.UNDO_CHECKOUT.getValue(), "DCAE rollback", requestId); - } catch (Exception e) { - errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed rolling back Monitoring Component. ID:{}", newVfcmt.getUuid()); - debugLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed rolling back Monitoring Component:{}", e); - } - } - } - private ResponseEntity cloneMcAndAddServiceReference(String userId, CreateVFCMTRequest request, String requestId) { + private ResponseEntity cloneMcAndAddServiceReference(String userId, CreateVFCMTRequest request, String requestId, boolean updateFlowType) { addSdcMandatoryFields(request, userId); ResourceDetailed newVfcmt = null; try { // Retrieve the Template VFCMT from SDC - use the template UUID provided from UI ResourceDetailed templateMC = sdcRestClient.getResource(request.getTemplateUuid(), requestId); // Download the CDUMP file from the template VFCMT - Artifact cdumpArtifactData = fetchCdumpAndSetFlowType(templateMC, request.getFlowType(), requestId); + Artifact cdumpArtifactData = updateFlowType ? fetchCdumpAndSetFlowType(templateMC, request.getFlowType(), requestId) : fetchCdump(templateMC, requestId); if (null == cdumpArtifactData) { errLogger.log(LogLevel.ERROR,this.getClass().getName(),"No cdump found for template {} while creating monitoring component", templateMC.getUuid()); return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", templateMC.getName()); @@ -176,7 +169,7 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { // this will not throw an exception checkinVfcmtAfterClone(userId, newVfcmt, requestId); - return new ResponseEntity<>(buildVfcmtAndCdumpResponse(newVfcmt, request.getVfiName(), request.getFlowType(), cdumpPayload), HttpStatus.OK); + return new ResponseEntity<>(buildVfcmtAndCdumpResponse(new VfcmtData(newVfcmt, request.getVfiName(), extractFlowTypeFromCdump(cdumpPayload)), cdumpPayload), HttpStatus.OK); } catch (Exception e) { errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed creating Monitoring Component:{}", e.getMessage()); rollBack(userId, newVfcmt, requestId); @@ -184,9 +177,6 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { } } - private CreateMcResponse buildVfcmtAndCdumpResponse(ResourceDetailed vfcmt, String vfiName, String flowType, String cdumpPayload) throws IOException { - return new CreateMcResponse(new VfcmtData(vfcmt, vfiName, flowType), new ObjectMapper().readValue(cdumpPayload, Object.class)); - } private void checkinVfcmtAfterClone(String userId, ResourceDetailed vfcmt, String requestId) { try { @@ -196,12 +186,7 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { } } - - private Artifact findCdumpArtifactData(ResourceDetailed vfcmt) { - return findArtifactDataByArtifactName(vfcmt, DcaeBeConstants.Composition.fileNames.COMPOSITION_YML); - } - - private void cloneRuleArtifacts(String userId, ResourceDetailed templateMC, String newVfcmtUuid, String requestId) throws Exception { + private void cloneRuleArtifacts(String userId, ResourceDetailed templateMC, String newVfcmtUuid, String requestId) throws JsonProcessingException { // handle rule artifacts using java 7 for-loop - exception propagation to calling method for(Artifact artifact : templateMC.getArtifacts()) { if(artifact.getArtifactName().endsWith(DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX)) { @@ -211,21 +196,17 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { } // fetch the vfcmt cdump artifact payload and insert the flowType. Return the artifact with updated payload or null (artifact doesn't exist) - private Artifact fetchCdumpAndSetFlowType(ResourceDetailed vfcmt, String flowType, String requestId) throws Exception { - Artifact cdumpArtifactData = findCdumpArtifactData(vfcmt); - if (null != cdumpArtifactData) { - String cdumpPayload = sdcRestClient.getResourceArtifact(vfcmt.getUuid(), cdumpArtifactData.getArtifactUUID(), requestId); - // Add flowType data to cdump if provided - if(!cdumpPayload.contains("\"flowType\":\"") && StringUtils.isNotBlank(flowType)) { - cdumpPayload = cdumpPayload.replaceFirst("\\{", "{\"flowType\":\"" + flowType + "\","); - } + private Artifact fetchCdumpAndSetFlowType(ResourceDetailed vfcmt, String flowType, String requestId) throws IOException { + Artifact cdumpArtifactData = fetchCdump(vfcmt, requestId); + if (null != cdumpArtifactData && null != cdumpArtifactData.getPayloadData() && !cdumpArtifactData.getPayloadData().contains("\"flowType\":\"")) { + String cdumpPayload = cdumpArtifactData.getPayloadData().replaceFirst("\\{", "{\"flowType\":\"" + flowType + "\","); cdumpArtifactData.setPayloadData(cdumpPayload); } return cdumpArtifactData; } // backward compatibility (very backward) - private void createReferenceArtifact(String userId, CreateVFCMTRequest request, String newVfcmtUuid, String requestId) throws Exception { + private void createReferenceArtifact(String userId, CreateVFCMTRequest request, String newVfcmtUuid, String requestId) throws JsonProcessingException { String referencePayload = request.getServiceUuid() + "/resources/" + request.getVfiName(); Artifact refArtifact = SdcRestClientUtils.generateDeploymentArtifact("createReferenceArtifact", DcaeBeConstants.Composition.fileNames.SVC_REF, ArtifactType.DCAE_TOSCA.name(), "servicereference", referencePayload.getBytes()); sdcRestClient.createResourceArtifact(userId, newVfcmtUuid, refArtifact, requestId); @@ -238,7 +219,7 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { ExternalReferencesMap connectedVfcmts; try { connectedVfcmts = getSdcRestClient().getMonitoringReferences(contextType, uuid, version, requestId); - resources = getSdcRestClient().getResources(VFCMT, TEMPLATE, MONITORING_TEMPLATE, requestId); + resources = getSdcRestClient().getResources(AssetType.VFCMT.name(), TEMPLATE, MONITORING_TEMPLATE, requestId); } catch (Exception e) { errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Exception getVfcmtsForMigration {}", e); debugLogger.log(LogLevel.DEBUG,this.getClass().getName(),"Exception getVfcmtsForMigration {}", e); @@ -268,7 +249,7 @@ public class VfcmtBusinessLogic extends BaseBusinessLogic { public void addSdcMandatoryFields(CreateVFCMTRequest createRequest, String user) { createRequest.setContactId(user); createRequest.setIcon(DEFAULTICON); - createRequest.setResourceType(VFCMT); + createRequest.setResourceType(AssetType.VFCMT.name()); createRequest.setVendorName(VENDOR_NAME); createRequest.setVendorRelease(VENDOR_RELEASE); if (StringUtils.isBlank(createRequest.getCategory())) { diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/filter/LoggingFilter.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/filter/LoggingFilter.java index 919d244..84ce0b7 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/filter/LoggingFilter.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/filter/LoggingFilter.java @@ -1,21 +1,6 @@ package org.onap.sdc.dcae.filter; -import static java.net.HttpURLConnection.HTTP_BAD_METHOD; -import static java.net.HttpURLConnection.HTTP_BAD_REQUEST; -import static java.net.HttpURLConnection.HTTP_CLIENT_TIMEOUT; -import static java.net.HttpURLConnection.HTTP_CONFLICT; -import static java.net.HttpURLConnection.HTTP_ENTITY_TOO_LARGE; -import static java.net.HttpURLConnection.HTTP_FORBIDDEN; -import static java.net.HttpURLConnection.HTTP_GONE; -import static java.net.HttpURLConnection.HTTP_LENGTH_REQUIRED; -import static java.net.HttpURLConnection.HTTP_NOT_ACCEPTABLE; -import static java.net.HttpURLConnection.HTTP_NOT_FOUND; -import static java.net.HttpURLConnection.HTTP_PAYMENT_REQUIRED; -import static java.net.HttpURLConnection.HTTP_PRECON_FAILED; -import static java.net.HttpURLConnection.HTTP_PROXY_AUTH; -import static java.net.HttpURLConnection.HTTP_REQ_TOO_LONG; -import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED; -import static java.net.HttpURLConnection.HTTP_UNSUPPORTED_TYPE; +import static java.net.HttpURLConnection.*; import java.io.IOException; import java.util.Locale; @@ -32,126 +17,129 @@ import javax.servlet.http.HttpServletResponse; import org.apache.http.impl.EnglishReasonPhraseCatalog; import org.onap.sdc.common.onaplog.OnapLoggerAudit; +import org.onap.sdc.common.onaplog.OnapLoggerDebug; import org.onap.sdc.common.onaplog.OnapMDCWrapper; import org.onap.sdc.common.onaplog.Enums.OnapLoggerErrorCode; import org.onap.sdc.common.onaplog.Enums.LogLevel; public class LoggingFilter implements Filter { - - private static final String serviceName = "DCAE-D-BE"; - - private OnapMDCWrapper commonLoggerArgs = OnapMDCWrapper.getInstance(); - private OnapLoggerAudit auditLogger = OnapLoggerAudit.getInstance(); - - public LoggingFilter() { - super(); - } - - - @Override - public void destroy() {} - - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) - throws IOException, ServletException { - - boolean shouldLogRequest = true; - - try { - if (request instanceof HttpServletRequest) { - HttpServletRequest httpRequest = (HttpServletRequest) request; - if (httpRequest.getServletPath().equals("/healthCheck")) { - shouldLogRequest = false; - } - - if (shouldLogRequest) { - beforeHandle(httpRequest); - } - } - } catch (Exception e) { - // TODO: log problem with extracting parameters or writing to log - } - - filterChain.doFilter(request, response); // handle request - - try { - if (response instanceof HttpServletResponse && shouldLogRequest) { - afterHandle((HttpServletResponse) response); - } - } catch (Exception e) { - // TODO: log problem with extracting parameters or writing to log - } - } - - - private void beforeHandle(HttpServletRequest request) { - - String requestId = getRequestId(request); - request.setAttribute("requestId", requestId); // making requestId available for the API controllers - commonLoggerArgs - .clear() - .startTimer() - .setRemoteHost(request.getRemoteAddr()) - .setServiceName(serviceName) - .setPartnerName(getPartnerName(request.getHeader("USER_ID"), request.getHeader("user-agent"))) - .setKeyRequestId(requestId) - .setAutoServerIPAddress(request.getLocalAddr()) - .setOptCustomField1(request.getProtocol()) - .setOptCustomField2(request.getMethod()) - .setOptCustomField3(request.getServletPath()); - - } - - - private static String getRequestId(HttpServletRequest request) { - String requestId = request.getHeader("X-ECOMP-RequestID"); - return isNullOrEmpty(requestId) - ? UUID.randomUUID().toString() - : requestId; - } - - - private void afterHandle(HttpServletResponse response) { - String responseDesc = EnglishReasonPhraseCatalog.INSTANCE.getReason(response.getStatus(), Locale.ENGLISH); - commonLoggerArgs - .stopTimer() - .setResponseCode(getLoggingErrorCode(response.getStatus()).getErrorCode()) - .setResponseDesc(responseDesc) - .setOptCustomField4(Integer.toString(response.getStatus())); - - auditLogger - .setStatusCode(Integer.toString(response.getStatus())) - .log(LogLevel.INFO, this.getClass().getName(), responseDesc); - } - - - private OnapLoggerErrorCode getLoggingErrorCode(int httpResponseCode) { - if (isSuccessError(httpResponseCode)) { - return OnapLoggerErrorCode.SUCCESS; - } - else if (isSchemaError(httpResponseCode)) { - return OnapLoggerErrorCode.SCHEMA_ERROR; - } - else if (isDataError(httpResponseCode)) { - return OnapLoggerErrorCode.DATA_ERROR; - } - else if (isPermissionsError(httpResponseCode)) { - return OnapLoggerErrorCode.PERMISSION_ERROR; - } - else if (isTimeoutOrAvailabilityError(httpResponseCode)) { - return OnapLoggerErrorCode.AVAILABILITY_TIMEOUTS_ERROR; - } - else if (isBusinessProcessError(httpResponseCode)) { - return OnapLoggerErrorCode.BUSINESS_PROCESS_ERROR; - } - else { - return OnapLoggerErrorCode.UNKNOWN_ERROR; - } - } - - - private boolean isTimeoutOrAvailabilityError(int httpResponseCode) { + + private static final String SERVICE_NAME = "DCAE-D-BE"; + + private OnapMDCWrapper commonLoggerArgs = OnapMDCWrapper.getInstance(); + private OnapLoggerAudit auditLogger = OnapLoggerAudit.getInstance(); + private OnapLoggerDebug onapLoggerDebug = OnapLoggerDebug.getInstance(); + + public LoggingFilter() { + super(); + } + + + @Override + public void destroy() { + // We have nothing to destroy + } + + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) + throws IOException, ServletException { + + boolean shouldLogRequest = true; + + try { + if (request instanceof HttpServletRequest) { + HttpServletRequest httpRequest = (HttpServletRequest) request; + if ("/healthCheck".equals(httpRequest.getServletPath())) { + shouldLogRequest = false; + } + + if (shouldLogRequest) { + beforeHandle(httpRequest); + } + } + } catch (Exception e) { + onapLoggerDebug.log(LogLevel.DEBUG,this.getClass().getName(),"Exception:{}",e); + } + + filterChain.doFilter(request, response); // handle request + + try { + if (response instanceof HttpServletResponse && shouldLogRequest) { + afterHandle((HttpServletResponse) response); + } + } catch (Exception e) { + onapLoggerDebug.log(LogLevel.DEBUG,this.getClass().getName(),"Exception:{}",e); + } + } + + + private void beforeHandle(HttpServletRequest request) { + String requestId = getRequestId(request); + request.setAttribute("requestId", requestId); // making requestId available for the API controllers + commonLoggerArgs + .clear() + .startTimer() + .setRemoteHost(request.getRemoteAddr()) + .setServiceName(SERVICE_NAME) + .setPartnerName(getPartnerName(request.getHeader("USER_ID"), request.getHeader("user-agent"))) + .setKeyRequestId(requestId) + .setAutoServerIPAddress(request.getLocalAddr()) + .setOptCustomField1(request.getProtocol()) + .setOptCustomField2(request.getMethod()) + .setOptCustomField3(request.getServletPath()); + + } + + + private static String getRequestId(HttpServletRequest request) { + String requestId = request.getHeader("X-ECOMP-RequestID"); + return isNullOrEmpty(requestId) + ? UUID.randomUUID().toString() + : requestId; + } + + + private void afterHandle(HttpServletResponse response) { + String responseDesc = EnglishReasonPhraseCatalog.INSTANCE.getReason(response.getStatus(), Locale.ENGLISH); + commonLoggerArgs + .stopTimer() + .setResponseCode(getLoggingErrorCode(response.getStatus()).getErrorCode()) + .setResponseDesc(responseDesc) + .setOptCustomField4(Integer.toString(response.getStatus())); + + auditLogger + .setStatusCode(Integer.toString(response.getStatus())) + .log(LogLevel.INFO, this.getClass().getName(), responseDesc); + } + + + private OnapLoggerErrorCode getLoggingErrorCode(int httpResponseCode) { + if (isSuccessError(httpResponseCode)) { + return OnapLoggerErrorCode.SUCCESS; + } + else if (isSchemaError(httpResponseCode)) { + return OnapLoggerErrorCode.SCHEMA_ERROR; + } + else if (isDataError(httpResponseCode)) { + return OnapLoggerErrorCode.DATA_ERROR; + } + else if (isPermissionsError(httpResponseCode)) { + return OnapLoggerErrorCode.PERMISSION_ERROR; + } + else if (isTimeoutOrAvailabilityError(httpResponseCode)) { + return OnapLoggerErrorCode.AVAILABILITY_TIMEOUTS_ERROR; + } + else if (isBusinessProcessError(httpResponseCode)) { + return OnapLoggerErrorCode.BUSINESS_PROCESS_ERROR; + } + else { + return OnapLoggerErrorCode.UNKNOWN_ERROR; + } + } + + + private boolean isTimeoutOrAvailabilityError(int httpResponseCode) { switch (httpResponseCode) { case HTTP_BAD_REQUEST: @@ -160,9 +148,9 @@ public class LoggingFilter implements Filter { case HTTP_CLIENT_TIMEOUT: case HTTP_GONE: return true; + default: + return false; } - - return false; } private boolean isPermissionsError(int httpResponseCode) { @@ -173,9 +161,9 @@ public class LoggingFilter implements Filter { case HTTP_BAD_METHOD: case HTTP_PROXY_AUTH: return true; + default: + return false; } - - return false; } private boolean isDataError(int httpResponseCode) { @@ -188,19 +176,13 @@ public class LoggingFilter implements Filter { case HTTP_ENTITY_TOO_LARGE: case HTTP_UNSUPPORTED_TYPE: return true; + default: + return false; } - - return false; } private boolean isSchemaError(int httpResponseCode) { - - switch (httpResponseCode) { - case HTTP_CONFLICT: - return true; - } - - return false; + return httpResponseCode == HTTP_CONFLICT; } private boolean isSuccessError(int httpResponseCode) { @@ -212,13 +194,13 @@ public class LoggingFilter implements Filter { } private String getPartnerName(String userId, String userAgent) { - return (isNullOrEmpty(userId)) - ? getClientApplication(userAgent) - : userId; + return isNullOrEmpty(userId) + ? getClientApplication(userAgent) + : userId; } private String getClientApplication(String userAgent) { - if (userAgent != null && userAgent.length() > 0) { + if (userAgent != null && userAgent.length() > 0) { if (userAgent.toLowerCase().contains("firefox")) { return "fireFox_FE"; } @@ -234,14 +216,15 @@ public class LoggingFilter implements Filter { return userAgent; } return ""; - } - + } - private static boolean isNullOrEmpty(String str) { - return (str == null || str.isEmpty()); + private static boolean isNullOrEmpty(String str) { + return str == null || str.isEmpty(); } - @Override - public void init(FilterConfig config) throws ServletException {} + @Override + public void init(FilterConfig config) { + // We have nothing to do when initializing + } } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/RuleEditorElementType.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/RuleEditorElementType.java index 0bec7d8..a5e4a39 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/RuleEditorElementType.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/RuleEditorElementType.java @@ -2,34 +2,26 @@ package org.onap.sdc.dcae.rule.editor.enums; import java.util.Arrays; -import org.onap.sdc.dcae.rule.editor.translators.ConditionGroupTranslator; -import org.onap.sdc.dcae.rule.editor.translators.ConditionTranslator; -import org.onap.sdc.dcae.rule.editor.translators.CopyActionTranslator; -import org.onap.sdc.dcae.rule.editor.translators.DateFormatterTranslator; -import org.onap.sdc.dcae.rule.editor.translators.FieldConditionTranslator; -import org.onap.sdc.dcae.rule.editor.translators.IRuleElementTranslator; -import org.onap.sdc.dcae.rule.editor.translators.MapActionTranslator; -import org.onap.sdc.dcae.rule.editor.translators.MappingRulesTranslator; -import org.onap.sdc.dcae.rule.editor.translators.RegexActionTranslator; -import org.onap.sdc.dcae.rule.editor.translators.RuleTranslator; -import org.onap.sdc.dcae.rule.editor.validators.ActionValidator; -import org.onap.sdc.dcae.rule.editor.validators.ConcatActionValidator; -import org.onap.sdc.dcae.rule.editor.validators.ConditionGroupValidator; -import org.onap.sdc.dcae.rule.editor.validators.ConditionValidator; -import org.onap.sdc.dcae.rule.editor.validators.DateFormatterValidator; -import org.onap.sdc.dcae.rule.editor.validators.IRuleElementValidator; -import org.onap.sdc.dcae.rule.editor.validators.MapActionValidator; -import org.onap.sdc.dcae.rule.editor.validators.RuleValidator; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.LogEventAction; +import org.onap.sdc.dcae.rule.editor.translators.*; +import org.onap.sdc.dcae.rule.editor.validators.*; public enum RuleEditorElementType { - COPY("Copy", ActionValidator.getInstance(), CopyActionTranslator.getInstance()), + COPY("Copy", CopyActionValidator.getInstance(), CopyActionTranslator.getInstance()), CONCAT("Concat", ConcatActionValidator.getInstance(), CopyActionTranslator.getInstance()), MAP("Map", MapActionValidator.getInstance(), MapActionTranslator.getInstance()), - REGEX("Regex", ActionValidator.getInstance(), RegexActionTranslator.getInstance()), + REGEX("Regex", CopyActionValidator.getInstance(), RegexActionTranslator.getInstance()), DATE_FORMATTER("DateFormatter", DateFormatterValidator.getInstance(), DateFormatterTranslator.getInstance()), + //1806 US390049 additional hp processors support + CLEAR("Clear", ClearActionValidator.getInstance(), ClearActionTranslator.getInstance()), + REPLACE_TEXT("ReplaceText", ReplaceActionValidator.getInstance(), ReplaceActionTranslator.getInstance()), + LOG_EVENT("LogEvent", LogEventValidator.getInstance(), LogEventTranslator.getInstance()), + LOG_TEXT("LogText", LogTextValidator.getInstance(), LogTextTranslator.getInstance()), + CONDITION("Condition", ConditionValidator.getInstance(), ConditionTranslator.getInstance()), FIELD_CONDITION("FieldCondition", ConditionValidator.getInstance(), FieldConditionTranslator.getInstance()), CONDITION_GROUP("ConditionGroup", ConditionGroupValidator.getInstance(), ConditionGroupTranslator.getInstance()), + RULE("Rule", RuleValidator.getInstance(), RuleTranslator.getInstance()), MAPPING_RULES("MappingRules", null, MappingRulesTranslator.getInstance()); diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogic.java index 849ad42..5270a18 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogic.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogic.java @@ -31,8 +31,9 @@ public class RulesBusinessLogic { public List<ServiceException> validateRule(Rule rule) { List<ResponseFormat> errors = new ArrayList<>(); - if(ruleValidator.validate(rule, errors)) + if(ruleValidator.validate(rule, errors)) { detectAndResolveActionDependencies(rule, errors); + } return errors.stream().map(r -> r.getRequestError().getServiceException()).collect(Collectors.toList()); } @@ -49,8 +50,9 @@ public class RulesBusinessLogic { public boolean addOrEditRule(MappingRules rules, Rule rule) { // in case the rule id is passed but the rule doesn't exist on the mapping rule file: - if(StringUtils.isNotBlank(rule.getUid()) && !rules.ruleExists(rule)) + if(StringUtils.isNotBlank(rule.getUid()) && !rules.ruleExists(rule)) { return false; + } rules.addOrReplaceRule(rule); return true; } @@ -72,8 +74,9 @@ public class RulesBusinessLogic { List<T> resolvable = dependentItems.stream() .filter(i -> !dependencyDetector.apply(i, dependentItems)) .collect(Collectors.toList()); - if(CollectionUtils.isEmpty(resolvable)) + if(CollectionUtils.isEmpty(resolvable)) { break; + } dependentItems.removeAll(resolvable); } return dependentItems; @@ -98,7 +101,7 @@ public class RulesBusinessLogic { if(!CollectionUtils.isEmpty(dependentActions)) { List<BaseAction> nonResolvable = detectCircularDependenciesByDependencyDefinition(dependentActions, BaseAction::hasDependencies); if (!CollectionUtils.isEmpty(nonResolvable)) { - errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.ACTION_DEPENDENCY, null, nonResolvable.stream().map(BaseAction::getTarget).collect(Collectors.joining(", ")))); + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.ACTION_DEPENDENCY, null, nonResolvable.stream().map(BaseAction::strippedTarget).collect(Collectors.joining(", ")))); return; } List<BaseAction> actions = reorderItemsByDependencyDefinition(rule.getActions(), BaseAction::referencesTarget); @@ -128,14 +131,15 @@ public class RulesBusinessLogic { List<BaseAction> allActions = dependentRules.stream().map(Rule::getActions).flatMap(List::stream).collect(Collectors.toList()); // option 1: circular dependency between actions List<BaseAction> nonResolvable = detectCircularDependenciesByDependencyDefinition(allActions, BaseAction::hasDependencies); - if(CollectionUtils.isEmpty(nonResolvable)) + if(CollectionUtils.isEmpty(nonResolvable)) { // option 2: circular dependency between rules - collect dependent actions and condition dependencies nonResolvable = dependentRules.stream() .map(r -> r.findDependencies(dependentRules)) .flatMap(List::stream) .collect(Collectors.toList()); + } return nonResolvable.stream() - .map(BaseAction::getTarget) + .map(BaseAction::strippedTarget) .collect(Collectors.joining(", ")); } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ActionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ActionTranslator.java new file mode 100644 index 0000000..0ad33ce --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ActionTranslator.java @@ -0,0 +1,15 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import org.onap.sdc.common.onaplog.Enums.LogLevel; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; + +import java.util.List; + +abstract class ActionTranslator<A extends BaseAction> implements IRuleElementTranslator<A> { + + boolean addToHpJsonProcessors(A action, List<Object> processors, boolean asNewProcessor){ + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating {} action", action.getActionType()); + processors.add(translateToHpJson(action)); + return true; + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ClearActionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ClearActionTranslator.java new file mode 100644 index 0000000..31a3fdc --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ClearActionTranslator.java @@ -0,0 +1,30 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.UnaryFieldAction; + +import java.util.List; + +public class ClearActionTranslator extends ActionTranslator<UnaryFieldAction> { + + private static ClearActionTranslator clearActionTranslator = new ClearActionTranslator(); + + public static ClearActionTranslator getInstance() { + return clearActionTranslator; + } + + private ClearActionTranslator(){} + + public Object translateToHpJson(UnaryFieldAction action) { + return new ClearActionTranslation(action); + } + + + private class ClearActionTranslation extends ProcessorTranslation { + private List<String> fields; + + ClearActionTranslation(UnaryFieldAction action) { + clazz = "Clear"; + fields = action.getFromValues(); + } + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionGroupTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionGroupTranslator.java index 093c239..86f55c9 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionGroupTranslator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionGroupTranslator.java @@ -19,7 +19,7 @@ public class ConditionGroupTranslator implements IRuleElementTranslator<Conditio private ConditionGroupTranslator(){} - public Translation translateToHpJson(ConditionGroup conditionGroup) { + public Object translateToHpJson(ConditionGroup conditionGroup) { String clazz = ConditionTypeEnum.getTypeByName(conditionGroup.getType()).getFilterClass(); FiltersTranslation translation = new FiltersTranslation(clazz, conditionGroup.getChildren().stream() .map(this::getTranslation) @@ -34,12 +34,12 @@ public class ConditionGroupTranslator implements IRuleElementTranslator<Conditio ValidationUtils.validateNotEmpty(OperatorTypeEnum.getTypeByName(((Condition)condition).getOperator()).getModifiedType()) ? FieldConditionTranslator.getInstance() : ConditionTranslator.getInstance(); } - private Translation getTranslation(BaseCondition condition) { + private Object getTranslation(BaseCondition condition) { return getConditionTranslator(condition).translateToHpJson(condition); } private void flattenNestedFilters(FiltersTranslation filtersTranslation, String clazz) { - Map<Boolean, List<Translation>> partitioned = filtersTranslation.filters.stream().collect(Collectors.partitioningBy(f -> clazz.equals(((ProcessorTranslation) f).clazz))); + Map<Boolean, List<Object>> partitioned = filtersTranslation.filters.stream().collect(Collectors.partitioningBy(f -> clazz.equals(((ProcessorTranslation) f).clazz))); filtersTranslation.filters.removeAll(partitioned.get(Boolean.TRUE)); filtersTranslation.filters.addAll(partitioned.get(Boolean.TRUE).stream().map(f -> ((FiltersTranslation) f).filters).flatMap(List::stream).collect(Collectors.toList())); } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionTranslator.java index f93101b..aa30fc3 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionTranslator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionTranslator.java @@ -31,7 +31,7 @@ public class ConditionTranslator implements IRuleElementTranslator<Condition> { } } - public Translation translateToHpJson(Condition condition) { + public Object translateToHpJson(Condition condition) { return 1 == condition.getRight().size() ? new StringFilterTranslation(condition) : new FiltersTranslation(ConditionTypeEnum.ANY.getFilterClass(), condition.getRight().stream() .map(r -> new StringFilterTranslation(condition, r)).collect(Collectors.toList())); } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/CopyActionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/CopyActionTranslator.java index 9d02c8e..4226eba 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/CopyActionTranslator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/CopyActionTranslator.java @@ -1,15 +1,13 @@ package org.onap.sdc.dcae.rule.editor.translators; import org.onap.sdc.common.onaplog.Enums.LogLevel; -import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseCopyAction; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; - -public class CopyActionTranslator<A extends BaseAction> implements IRuleElementTranslator<A>{ +public class CopyActionTranslator extends ActionTranslator<BaseCopyAction> { private static CopyActionTranslator copyActionTranslator = new CopyActionTranslator(); @@ -19,20 +17,19 @@ public class CopyActionTranslator<A extends BaseAction> implements IRuleElementT CopyActionTranslator(){} - public Translation translateToHpJson(A action) { + public Object translateToHpJson(BaseCopyAction action) { return new CopyActionSetTranslation(action.getTarget(), action.getFromValue()); } - void addToHpJsonProcessors(A action, List<Translation> processors) { - processors.add(translateToHpJson(action)); - } - - public boolean addToHpJsonProcessors(A action, List<Translation> processors, boolean asNewProcessor) { + @Override + public boolean addToHpJsonProcessors(BaseCopyAction action, List<Object> processors, boolean asNewProcessor) { debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating {} action. New Processor: {}", action.getActionType(), asNewProcessor); - if(asNewProcessor) - addToHpJsonProcessors(action, processors); - else - ((CopyActionSetTranslation) processors.get(processors.size()-1)).updates.put(action.getTarget(), action.getFromValue()); + if(asNewProcessor) { + processors.add(translateToHpJson(action)); + } + else { + ((CopyActionSetTranslation) processors.get(processors.size() - 1)).updates.put(action.getTarget(), action.getFromValue()); + } return false; } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/DateFormatterTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/DateFormatterTranslator.java index 89f0def..449dbf0 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/DateFormatterTranslator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/DateFormatterTranslator.java @@ -1,11 +1,8 @@ package org.onap.sdc.dcae.rule.editor.translators; -import org.onap.sdc.common.onaplog.Enums.LogLevel; -import java.util.List; - import org.onap.sdc.dcae.composition.restmodels.ruleeditor.DateFormatterAction; -public class DateFormatterTranslator extends CopyActionTranslator<DateFormatterAction> { +public class DateFormatterTranslator extends ActionTranslator<DateFormatterAction> { private static DateFormatterTranslator dateFormatterTranslator = new DateFormatterTranslator(); @@ -34,15 +31,7 @@ public class DateFormatterTranslator extends CopyActionTranslator<DateFormatterA } } - @Override - public boolean addToHpJsonProcessors(DateFormatterAction action, List<Translation> processors, boolean asNewProcessor) { - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating date formatter action"); - addToHpJsonProcessors(action, processors); - return true; - } - - @Override - public Translation translateToHpJson(DateFormatterAction action){ + public Object translateToHpJson(DateFormatterAction action){ return new DateFormatterTranslation(action); } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/FieldConditionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/FieldConditionTranslator.java index ef2949e..dddbc89 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/FieldConditionTranslator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/FieldConditionTranslator.java @@ -37,7 +37,7 @@ public class FieldConditionTranslator implements IRuleElementTranslator<Conditio } } - public Translation translateToHpJson(Condition condition) { + public Object translateToHpJson(Condition condition) { return 1 == condition.getRight().size() ? new FieldFilterTranslation(condition) : new MultiFieldFilterTranslation(condition); } } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/IRuleElementTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/IRuleElementTranslator.java index dac818d..97269ef 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/IRuleElementTranslator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/IRuleElementTranslator.java @@ -12,30 +12,28 @@ public interface IRuleElementTranslator<T> { OnapLoggerError errLogger = OnapLoggerError.getInstance(); OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); - Translation translateToHpJson(T element); + Object translateToHpJson(T element); - abstract class Translation { - } - class ProcessorTranslation extends Translation { + class ProcessorTranslation { @SerializedName("class") protected String clazz; } class FiltersTranslation extends ProcessorTranslation { - protected List<Translation> filters; + protected List<Object> filters; - protected FiltersTranslation(String clazz, List<Translation> filters) { + protected FiltersTranslation(String clazz, List<Object> filters) { this.clazz = clazz; this.filters = filters; } } - class RuleTranslation extends Translation { + class RuleTranslation { protected String phase; - protected Translation filter; - protected List<Translation> processors = new ArrayList<>(); + protected Object filter; + protected List<Object> processors = new ArrayList<>(); } class RunPhaseProcessorsTranslation extends ProcessorTranslation { diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/LogEventTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/LogEventTranslator.java new file mode 100644 index 0000000..8c29070 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/LogEventTranslator.java @@ -0,0 +1,28 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.LogEventAction; + +public class LogEventTranslator extends ActionTranslator<LogEventAction> { + + private static LogEventTranslator logEventTranslator = new LogEventTranslator(); + + public static LogEventTranslator getInstance() { + return logEventTranslator; + } + + private LogEventTranslator(){} + + public Object translateToHpJson(LogEventAction action) { + return new LogEventTranslation(action); + } + + + private class LogEventTranslation extends ProcessorTranslation { + String title; + + LogEventTranslation(LogEventAction action) { + clazz = "LogEvent"; + title = action.getTitle(); + } + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/LogTextTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/LogTextTranslator.java new file mode 100644 index 0000000..a9ed5bb --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/LogTextTranslator.java @@ -0,0 +1,33 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.LogTextAction; + +public class LogTextTranslator extends ActionTranslator<LogTextAction> { + + private static LogTextTranslator logTextTranslator = new LogTextTranslator(); + + public static LogTextTranslator getInstance() { + return logTextTranslator; + } + + private LogTextTranslator(){} + + public Object translateToHpJson(LogTextAction action) { + return new LogTextTranslation(action); + } + + + class LogTextTranslation extends ProcessorTranslation { + private String logLevel; + private String logName; + private String logText; + + private LogTextTranslation(LogTextAction action) { + clazz = "LogText"; + logLevel = action.getLevel(); + logName = action.getName(); + logText = action.getText(); + } + } + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MapActionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MapActionTranslator.java index 922312e..d493abb 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MapActionTranslator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MapActionTranslator.java @@ -2,14 +2,11 @@ package org.onap.sdc.dcae.rule.editor.translators; import com.google.gson.annotations.SerializedName; -import org.onap.sdc.common.onaplog.Enums.LogLevel; - -import java.util.List; import java.util.Map; import org.onap.sdc.dcae.composition.restmodels.ruleeditor.MapAction; -public class MapActionTranslator extends CopyActionTranslator<MapAction> { +public class MapActionTranslator extends ActionTranslator<MapAction> { private static MapActionTranslator mapActionTranslator = new MapActionTranslator(); @@ -36,15 +33,8 @@ public class MapActionTranslator extends CopyActionTranslator<MapAction> { } } - @Override - public Translation translateToHpJson(MapAction action) { + public Object translateToHpJson(MapAction action) { return new MapActionTranslation(action); } - @Override - public boolean addToHpJsonProcessors(MapAction action, List<Translation> processors, boolean asNewProcessor) { - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating map action"); - addToHpJsonProcessors(action, processors); - return true; - } } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MappingRulesTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MappingRulesTranslator.java index 0164446..91a1ab0 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MappingRulesTranslator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MappingRulesTranslator.java @@ -18,19 +18,19 @@ public class MappingRulesTranslator implements IRuleElementTranslator<MappingRul private RuleTranslator ruleTranslator = RuleTranslator.getInstance(); - public Translation translateToHpJson(MappingRules mappingRules) { + public Object translateToHpJson(MappingRules mappingRules) { return new MappingRulesTranslation(mappingRules); } - public Translation translateToHpJson(MappingRules mappingRules, String entryPointPhaseName, String lastPhaseName, String runPhase) { + public Object translateToHpJson(MappingRules mappingRules, String entryPointPhaseName, String lastPhaseName, String runPhase) { // 1806 US349308 assign Vfcmt name as rule phaseName mappingRules.getRules().forEach((k,v) -> v.setPhase(runPhase)); return new MappingRulesTranslation(mappingRules, entryPointPhaseName, lastPhaseName, runPhase); } - private class MappingRulesTranslation extends Translation { + private class MappingRulesTranslation { - private List<Translation> processing; + private List<Object> processing; private MappingRulesTranslation(MappingRules mappingRules) { processing = mappingRules.getRules().values().stream().map(ruleTranslator::translateToHpJson).collect(Collectors.toList()); @@ -49,8 +49,9 @@ public class MappingRulesTranslator implements IRuleElementTranslator<MappingRul private RunPhaseRuleTranslation(String phaseName, String runPhase) { phase = phaseName; - if ("snmp_map".equals(phaseName)) + if("snmp_map".equals(phaseName)) { processors.add(new SnmpConvertor()); + } processors.add(new RunPhaseProcessorsTranslation(runPhase)); } } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RegexActionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RegexActionTranslator.java index c49a04e..85fdf1d 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RegexActionTranslator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RegexActionTranslator.java @@ -1,11 +1,10 @@ package org.onap.sdc.dcae.rule.editor.translators; import org.onap.sdc.common.onaplog.Enums.LogLevel; -import java.util.List; -import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseCopyAction; -public class RegexActionTranslator extends CopyActionTranslator<BaseAction> { +public class RegexActionTranslator extends ActionTranslator<BaseCopyAction> { private static RegexActionTranslator regexActionTranslator = new RegexActionTranslator(); @@ -21,7 +20,7 @@ public class RegexActionTranslator extends CopyActionTranslator<BaseAction> { private String field; private String value; - private RegexCopyActionTranslation(BaseAction action) { + private RegexCopyActionTranslation(BaseCopyAction action) { clazz = "ExtractText"; regex = action.getRegexValue(); field = action.getTarget(); @@ -29,15 +28,9 @@ public class RegexActionTranslator extends CopyActionTranslator<BaseAction> { } } - @Override - public boolean addToHpJsonProcessors(BaseAction action, List<Translation> processors, boolean asNewProcessor) { - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating copy action as regex action"); - addToHpJsonProcessors(action, processors); - return true; - } - @Override - public Translation translateToHpJson(BaseAction action) { + public Object translateToHpJson(BaseCopyAction action) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating copy action as regex action"); return new RegexCopyActionTranslation(action); } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ReplaceActionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ReplaceActionTranslator.java new file mode 100644 index 0000000..3069df3 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ReplaceActionTranslator.java @@ -0,0 +1,33 @@ +package org.onap.sdc.dcae.rule.editor.translators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.ReplaceTextAction; + +public class ReplaceActionTranslator extends ActionTranslator<ReplaceTextAction> { + + private static ReplaceActionTranslator replaceActionTranslator = new ReplaceActionTranslator(); + + public static ReplaceActionTranslator getInstance() { + return replaceActionTranslator; + } + + private ReplaceActionTranslator(){} + + public Object translateToHpJson(ReplaceTextAction action) { + return new ReplaceActionTranslation(action); + } + + + private class ReplaceActionTranslation extends ProcessorTranslation { + private String field; + private String find; + private String replace; + + ReplaceActionTranslation(ReplaceTextAction action) { + clazz = "ReplaceText"; + field = action.getFromValue(); + find = action.getFind(); + replace = action.getReplace(); + } + } + +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RuleTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RuleTranslator.java index f7dea47..b98050d 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RuleTranslator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RuleTranslator.java @@ -30,9 +30,9 @@ public class RuleTranslator implements IRuleElementTranslator<Rule> { } } - public Translation translateToHpJson(Rule rule) { + public Object translateToHpJson(Rule rule) { debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Start translating rule {}", rule.getUid()); - Translation translation = new ActionRuleTranslation(rule); + Object translation = new ActionRuleTranslation(rule); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished translation for rule {}. Result: {}", rule.getUid(), new Gson().toJson(translation)); return translation; } @@ -42,10 +42,11 @@ public class RuleTranslator implements IRuleElementTranslator<Rule> { ValidationUtils.validateNotEmpty(OperatorTypeEnum.getTypeByName(((Condition)condition).getOperator()).getModifiedType()) ? FieldConditionTranslator.getInstance() : ConditionTranslator.getInstance(); } - private CopyActionTranslator getActionTranslator(BaseAction action) { + private ActionTranslator getActionTranslator(BaseAction action) { ActionTypeEnum type = ActionTypeEnum.getTypeByName(action.getActionType()); - if(ActionTypeEnum.COPY == type && ValidationUtils.validateNotEmpty(action.getRegexValue())) + if(ActionTypeEnum.COPY == type && ValidationUtils.validateNotEmpty(((BaseCopyAction)action).getRegexValue())) { return RegexActionTranslator.getInstance(); - return (CopyActionTranslator)RuleEditorElementType.getElementTypeByName(type.getType()).getTranslator(); + } + return (ActionTranslator) RuleEditorElementType.getElementTypeByName(type.getType()).getTranslator(); } }
\ No newline at end of file diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ClearActionValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ClearActionValidator.java new file mode 100644 index 0000000..8be49b5 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ClearActionValidator.java @@ -0,0 +1,27 @@ +package org.onap.sdc.dcae.rule.editor.validators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.UnaryFieldAction; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ResponseFormat; + +import java.util.List; + +public class ClearActionValidator implements IRuleElementValidator<UnaryFieldAction> { + + private static ClearActionValidator clearActionValidator = new ClearActionValidator(); + + public static ClearActionValidator getInstance() { + return clearActionValidator; + } + + private ClearActionValidator(){} + + public boolean validate(UnaryFieldAction action, List<ResponseFormat> errors) { + if(action.getFromValues().isEmpty()) { + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "from", action.getActionType(), action.strippedTarget())); + return false; + } + return true; + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConcatActionValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConcatActionValidator.java index 965c898..956ac51 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConcatActionValidator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConcatActionValidator.java @@ -1,6 +1,6 @@ package org.onap.sdc.dcae.rule.editor.validators; -import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseCopyAction; import org.onap.sdc.dcae.errormng.ActionStatus; import org.onap.sdc.dcae.errormng.ErrConfMgr; import org.onap.sdc.dcae.errormng.ResponseFormat; @@ -8,7 +8,7 @@ import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; import java.util.List; -public class ConcatActionValidator extends ActionValidator<BaseAction> { +public class ConcatActionValidator extends CopyActionValidator<BaseCopyAction> { private static ConcatActionValidator concatActionValidator = new ConcatActionValidator(); @@ -19,7 +19,7 @@ public class ConcatActionValidator extends ActionValidator<BaseAction> { private ConcatActionValidator(){} @Override - protected boolean validateFromValue(BaseAction action, List<ResponseFormat> errors) { + protected boolean validateFromValue(BaseCopyAction action, List<ResponseFormat> errors) { if(!ValidationUtils.validateNotEmpty(action.getFromValue()) || 2 > action.getFromValues().size()) { errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_CONCAT_VALUE, null, action.getTarget())); return false; diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ActionValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/CopyActionValidator.java index 3eb0eb5..74102a6 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ActionValidator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/CopyActionValidator.java @@ -1,6 +1,6 @@ package org.onap.sdc.dcae.rule.editor.validators; -import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseCopyAction; import org.onap.sdc.dcae.errormng.ActionStatus; import org.onap.sdc.dcae.errormng.ErrConfMgr; import org.onap.sdc.dcae.errormng.ResponseFormat; @@ -8,15 +8,15 @@ import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; import java.util.List; -public class ActionValidator<A extends BaseAction> implements IRuleElementValidator<A> { +public class CopyActionValidator<A extends BaseCopyAction> implements IRuleElementValidator<A> { - private static ActionValidator actionValidator = new ActionValidator(); + private static CopyActionValidator copyActionValidator = new CopyActionValidator(); - public static ActionValidator getInstance() { - return actionValidator; + public static CopyActionValidator getInstance() { + return copyActionValidator; } - ActionValidator(){} + CopyActionValidator(){} public boolean validate(A action, List<ResponseFormat> errors) { diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/DateFormatterValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/DateFormatterValidator.java index d5ec0fc..19af40c 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/DateFormatterValidator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/DateFormatterValidator.java @@ -8,7 +8,7 @@ import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; import java.util.List; -public class DateFormatterValidator extends ActionValidator<DateFormatterAction> { +public class DateFormatterValidator extends CopyActionValidator<DateFormatterAction> { private static DateFormatterValidator dateFormatterValidator = new DateFormatterValidator(); public static DateFormatterValidator getInstance() { diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/IRuleElementValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/IRuleElementValidator.java index dd1eaf4..cdcf5b2 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/IRuleElementValidator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/IRuleElementValidator.java @@ -1,9 +1,13 @@ package org.onap.sdc.dcae.rule.editor.validators; +import org.onap.sdc.common.onaplog.OnapLoggerError; import org.onap.sdc.dcae.errormng.ResponseFormat; import java.util.List; public interface IRuleElementValidator <T> { + + OnapLoggerError errLogger = OnapLoggerError.getInstance(); + boolean validate(T element, List<ResponseFormat> errors); } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/LogEventValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/LogEventValidator.java new file mode 100644 index 0000000..1bbf07a --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/LogEventValidator.java @@ -0,0 +1,28 @@ +package org.onap.sdc.dcae.rule.editor.validators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.LogEventAction; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ResponseFormat; +import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; + +import java.util.List; + +public class LogEventValidator implements IRuleElementValidator<LogEventAction> { + + private static LogEventValidator logEventValidator = new LogEventValidator(); + + public static LogEventValidator getInstance() { + return logEventValidator; + } + + LogEventValidator(){} + + public boolean validate(LogEventAction action, List<ResponseFormat> errors) { + if(!ValidationUtils.validateNotEmpty(action.getTitle())){ + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "title", action.getActionType(), action.strippedTarget())); + return false; + } + return true; + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/LogTextValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/LogTextValidator.java new file mode 100644 index 0000000..711692f --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/LogTextValidator.java @@ -0,0 +1,28 @@ +package org.onap.sdc.dcae.rule.editor.validators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.LogTextAction; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ResponseFormat; +import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; + +import java.util.List; + +public class LogTextValidator implements IRuleElementValidator<LogTextAction> { + + private static LogTextValidator logTextValidator = new LogTextValidator(); + + public static LogTextValidator getInstance() { + return logTextValidator; + } + + LogTextValidator(){} + + public boolean validate(LogTextAction action, List<ResponseFormat> errors) { + if(!ValidationUtils.validateNotEmpty(action.getText())){ + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "text", action.getActionType(), action.strippedTarget())); + return false; + } + return true; + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/MapActionValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/MapActionValidator.java index 8cbcaa8..130e428 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/MapActionValidator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/MapActionValidator.java @@ -1,5 +1,6 @@ package org.onap.sdc.dcae.rule.editor.validators; +import org.onap.sdc.common.onaplog.Enums.LogLevel; import org.onap.sdc.dcae.composition.restmodels.ruleeditor.MapAction; import org.onap.sdc.dcae.errormng.ActionStatus; import org.onap.sdc.dcae.errormng.ErrConfMgr; @@ -9,7 +10,7 @@ import org.springframework.util.CollectionUtils; import java.util.List; -public class MapActionValidator extends ActionValidator<MapAction> { +public class MapActionValidator extends CopyActionValidator<MapAction> { private static MapActionValidator mapActionValidator = new MapActionValidator(); @@ -37,6 +38,7 @@ public class MapActionValidator extends ActionValidator<MapAction> { } } catch (IllegalStateException err) { valid = false; + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Map validation error: {}", err); errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.DUPLICATE_KEY, null)); } } diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ReplaceActionValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ReplaceActionValidator.java new file mode 100644 index 0000000..d9aea82 --- /dev/null +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ReplaceActionValidator.java @@ -0,0 +1,37 @@ +package org.onap.sdc.dcae.rule.editor.validators; + +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.ReplaceTextAction; +import org.onap.sdc.dcae.errormng.ActionStatus; +import org.onap.sdc.dcae.errormng.ErrConfMgr; +import org.onap.sdc.dcae.errormng.ResponseFormat; +import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; + +import java.util.List; + +public class ReplaceActionValidator implements IRuleElementValidator<ReplaceTextAction> { + + private static ReplaceActionValidator replaceActionValidator = new ReplaceActionValidator(); + + public static ReplaceActionValidator getInstance() { + return replaceActionValidator; + } + + private ReplaceActionValidator(){} + + public boolean validate(ReplaceTextAction action, List<ResponseFormat> errors) { + boolean valid = true; + if(!ValidationUtils.validateNotEmpty(action.getFromValue())) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "from", action.getActionType(), action.strippedTarget())); + } + if(!ValidationUtils.validateNotEmpty(action.getFind())) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "find", action.getActionType(), action.strippedTarget())); + } + if(!ValidationUtils.validateNotEmpty(action.getReplace())) { + valid = false; + errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "replace", action.getActionType(), action.strippedTarget())); + } + return valid; + } +} diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/RuleValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/RuleValidator.java index 371d1e9..e03ca8a 100644 --- a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/RuleValidator.java +++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/RuleValidator.java @@ -1,13 +1,9 @@ package org.onap.sdc.dcae.rule.editor.validators; -import org.onap.sdc.dcae.composition.restmodels.ruleeditor.ActionTypeEnum; -import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; -import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseCondition; -import org.onap.sdc.dcae.composition.restmodels.ruleeditor.Rule; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*; import org.onap.sdc.dcae.errormng.ActionStatus; import org.onap.sdc.dcae.errormng.ErrConfMgr; import org.onap.sdc.dcae.errormng.ResponseFormat; -import org.onap.sdc.dcae.errormng.ServiceException; import org.onap.sdc.dcae.rule.editor.enums.RuleEditorElementType; import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils; import org.springframework.util.CollectionUtils; diff --git a/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/application.properties b/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/application.properties index d5333c4..b833be9 100644 --- a/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/application.properties +++ b/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/application.properties @@ -6,6 +6,7 @@ scheduled.timer.value=5000 asdc_catalog_url=asdc #uri=https://dcaeDesigner:Aa123456@zldcrdm2sdc2abe01.3f1a87.rdm2.tci.att.com:8443#demo uri=https://dcaeDesigner:Aa123456@zldcrdm2sdc4cbe01.3f1a87.rdm2.tci.att.com:8443#demo +#uri=https://dcaeDesigner:Aa123456@zldcrdm2sdc2dbe01.3f1a87.rdm2.tci.att.com:8443#demo toscalab_url=http://localhost:8080/ blueprinter.uri=${toscalab_url}translate blueprinter.hcuri=${toscalab_url}healthcheck @@ -19,4 +20,21 @@ compositionConfig.flowTypes={"Syslog":{"entryPointPhaseName":"syslog_map","lastP "Guest OS":{"entryPointPhaseName":"guest_os_map","lastPhaseName":"map_publish"},\ "Status Poller":{"entryPointPhaseName":"status_poller_map","lastPhaseName":"map_publish"},\ "SNMP Polling":{"entryPointPhaseName":"snmp_polling_map","lastPhaseName":"map_publish"},\ - "TCA Hi Lo":{"entryPointPhaseName":"tca_hi_lo_map","lastPhaseName":"map_publish"}} + "TCA Hi Lo":{"entryPointPhaseName":"tca_hi_lo_map","lastPhaseName":"map_publish"},\ + "Syslog Collector":{"entryPointPhaseName":"syslog_map","lastPhaseName":"syslog_publish"},\ + "Syslog MSEA":{"entryPointPhaseName":"syslog_map","lastPhaseName":"syslog_publish"},\ + "Status Poller Collector":{"entryPointPhaseName":"status_poller_map","lastPhaseName":"status_poller_publish"},\ + "Status Poller MSE":{"entryPointPhaseName":"snmp_map","lastPhaseName":"snmp_publish"},\ + "FOI Collector":{"entryPointPhaseName":"pmossFoiPhase","lastPhaseName":"foiEventToDmaapPhase"},\ + "Docker Map":{"entryPointPhaseName":"docker_map","lastPhaseName":"docker_publish"},\ + "SNMP MSE":{"entryPointPhaseName":"snmp_map","lastPhaseName":"snmp_publish"},\ + "SAM Collector":{"entryPointPhaseName":"sam_collector_map","lastPhaseName":"sam_collector_publish"},\ + "Docker MSE":{"entryPointPhaseName":"docker_map","lastPhaseName":"docker_publish"},\ + "SNMP PM Poller":{"entryPointPhaseName":"docker_map","lastPhaseName":"docker_publilsh"},\ + "Discovery and MIB Poller":{"entryPointPhaseName":"snmp_pm_map","lastPhaseName":"snmp_pm_publish"},\ + "Nagios docker MSE":{"entryPointPhaseName":"docker_map","lastPhaseName":"docker_publish"},\ + "VES Fault":{"entryPointPhaseName":"ves_fault_map","lastPhaseName":"ves_fault_publish"},\ + "VES Heartbeat":{"entryPointPhaseName":"ves_heartbeat_map","lastPhaseName":"ves_heartbeat_publish"},\ + "VES Measurement":{"entryPointPhaseName":"ves_measurement_map","lastPhaseName":"ves_measurement_publish"},\ + "VES Syslog":{"entryPointPhaseName":"ves_syslog_map","lastPhaseName":"ves_syslog_publish"}} + diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/BlueprintBusinessLogicTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/BlueprintBusinessLogicTest.java new file mode 100644 index 0000000..a00130f --- /dev/null +++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/BlueprintBusinessLogicTest.java @@ -0,0 +1,69 @@ +package org.onap.sdc.dcae.composition.impl; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.onap.sdc.dcae.client.ISdcClient; +import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; +import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed; +import org.onap.sdc.dcae.errormng.ErrorConfigurationLoader; +import org.springframework.http.ResponseEntity; + +import java.util.ArrayList; + +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; +import static org.onap.sdc.dcae.composition.util.DcaeBeConstants.Composition.fileNames.COMPOSITION_YML; + +@RunWith(MockitoJUnitRunner.class) +public class BlueprintBusinessLogicTest { + + private static final String USER_ID = "UserId"; + private static final String CONTEXT = "Context"; + private static final String VFCMT_UUID = "VfcmtUuid"; + private static final String SERVICE_UUID = "ServiceUuid"; + private static final String VFI_NAME = "VfiName"; + private static final String FLOW_TYPE = "FlowType"; + private static final String REQUEST_ID = "RequestId"; + + @InjectMocks + BlueprintBusinessLogic classUnderTest; + @Mock + private ISdcClient sdcClientMock; + private ResourceDetailed resourceDetailed; + + @Before + public void setup() { + new ErrorConfigurationLoader(System.getProperty("user.dir")+"/src/main/webapp/WEB-INF"); + + resourceDetailed = new ResourceDetailed(); + resourceDetailed.setUuid(VFCMT_UUID); + classUnderTest.setSdcRestClient(sdcClientMock); + when(sdcClientMock.getResource(eq(VFCMT_UUID), eq(REQUEST_ID))).thenReturn(resourceDetailed); + when(sdcClientMock.getResourceArtifact(eq(VFCMT_UUID), anyString(), anyString())).thenReturn("\"{\\\\\\\"version\\\\\\\":0,\\\\\\\"flowType\\\\\\\":\\\\\\\"templateInfoFlowType\\\\\\\",\\\\\\\"nodes\\\\\\\":[],\\\\\\\"inputs\\\\\\\":[],\\\\\\\"outputs\\\\\\\":[],\\\\\\\"relations\\\\\\\":[]}\\\"\""); + } + + @Test + public void generateAndSaveBlueprint_compositionNotFound() { + ResponseEntity responseEntity = classUnderTest.generateAndSaveBlueprint(USER_ID, CONTEXT, VFCMT_UUID, SERVICE_UUID, VFI_NAME, FLOW_TYPE, REQUEST_ID); + Assert.assertEquals( 404, responseEntity.getStatusCodeValue()); + } + + @Test + public void generateAndSaveBlueprint_toscaFailed() { + Artifact artifact = new Artifact(); + artifact.setArtifactName(COMPOSITION_YML); + artifact.setPayloadData("{\\\"version\\\":0,\\\"flowType\\\":\\\"templateInfoFlowType\\\",\\\"nodes\\\":[],\\\"inputs\\\":[],\\\"outputs\\\":[],\\\"relations\\\":[]}\""); + ArrayList<Artifact> artifacts = new ArrayList<>(); + artifacts.add(artifact); + resourceDetailed.setArtifacts(artifacts); + ResponseEntity responseEntity = classUnderTest.generateAndSaveBlueprint(USER_ID, CONTEXT, VFCMT_UUID, SERVICE_UUID, VFI_NAME, FLOW_TYPE, REQUEST_ID); + Assert.assertEquals( 500, responseEntity.getStatusCodeValue()); + } + +} diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/CompositionBusinessLogicTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/CompositionBusinessLogicTest.java new file mode 100644 index 0000000..d9b65b2 --- /dev/null +++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/CompositionBusinessLogicTest.java @@ -0,0 +1,218 @@ +package org.onap.sdc.dcae.composition.impl; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.sdc.dcae.catalog.asdc.ASDCException; +import org.onap.sdc.dcae.client.ISdcClient; +import org.onap.sdc.dcae.composition.restmodels.VfcmtData; +import org.onap.sdc.dcae.composition.restmodels.sdc.*; +import org.onap.sdc.dcae.composition.util.DcaeBeConstants; +import org.onap.sdc.dcae.errormng.ErrorConfigurationLoader; +import org.onap.sdc.dcae.errormng.RequestError; +import org.onap.sdc.dcae.errormng.ServiceException; +import org.onap.sdc.dcae.utils.Normalizers; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.*; + +public class CompositionBusinessLogicTest { + + private ISdcClient sdcClientMock = Mockito.mock(ISdcClient.class); + private ResourceDetailed vfcmt = Mockito.mock(ResourceDetailed.class); + private ServiceDetailed service = Mockito.mock(ServiceDetailed.class); + private CompositionBusinessLogic compositionBusinessLogic = new CompositionBusinessLogic(); + private String justAString = "aStringForAllSeasons"; + + @Before + public void setup(){ + MockitoAnnotations.initMocks(this); + compositionBusinessLogic.setSdcRestClient(sdcClientMock); + new ErrorConfigurationLoader(System.getProperty("user.dir")+"/src/main/webapp/WEB-INF"); + when(vfcmt.getUuid()).thenReturn(justAString); + when(vfcmt.getName()).thenReturn(justAString); + when(vfcmt.getDescription()).thenReturn(justAString); + when(vfcmt.getInvariantUUID()).thenReturn(justAString); + } + + @Test + public void successfulSaveCompositionAndCheckInInitialStateCheckedOut() throws Exception { + emulateListOfArtifactsWithCompositionYml(); + when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(vfcmt); + when(vfcmt.getLifecycleState()).thenReturn("NOT_CERTIFIED_CHECKOUT"); + + compositionBusinessLogic.saveComposition(justAString, justAString, justAString, justAString, false); + + verify(sdcClientMock).getResource(anyString(),anyString()); + verify(sdcClientMock, times(0)).createResourceArtifact(anyString(),anyString(),any(),anyString()); + verify(sdcClientMock).updateResourceArtifact(anyString(), anyString(), any(), anyString()); + verify(sdcClientMock).changeResourceLifecycleState(anyString(),anyString(),anyString(),anyString(),anyString()); + } + + @Test + public void successfulSaveCompositionAndCheckInInitialStateCheckedIn() throws Exception { + emulateListOfArtifactsWithCompositionYml(); + when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(vfcmt); + when(vfcmt.getLifecycleState()).thenReturn("NOT_CERTIFIED_CHECKIN"); + when(sdcClientMock.changeResourceLifecycleState(anyString(), anyString(), anyString(), anyString(), anyString())).thenReturn(vfcmt); + + compositionBusinessLogic.saveComposition(justAString, justAString, justAString, justAString, false); + + verify(sdcClientMock).getResource(anyString(),anyString()); + verify(sdcClientMock, times(0)).createResourceArtifact(anyString(),anyString(),any(),anyString()); + verify(sdcClientMock).updateResourceArtifact(anyString(), anyString(), any(), anyString()); + verify(sdcClientMock, times(2)).changeResourceLifecycleState(anyString(),anyString(),anyString(),anyString(),anyString()); + } + + @Test + public void saveCompositionCheckInFailureDoRollback() throws Exception { + + emulateListOfArtifactsWithCompositionYml(); + when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(vfcmt); + when(vfcmt.getLifecycleState()).thenReturn("NOT_CERTIFIED_CHECKIN"); + RequestError requestError = new RequestError(); + requestError.setServiceException(new ServiceException("SVC4086", "", null)); + when(sdcClientMock.changeResourceLifecycleState(anyString(), anyString(), anyString(), anyString(), anyString())).thenReturn(vfcmt).thenThrow(new ASDCException(HttpStatus.FORBIDDEN, requestError)); + + ResponseEntity result = compositionBusinessLogic.saveComposition(justAString, justAString, justAString, justAString, false); + + verify(sdcClientMock).getResource(anyString(),anyString()); + verify(sdcClientMock, times(0)).createResourceArtifact(anyString(),anyString(),any(),anyString()); + verify(sdcClientMock).updateResourceArtifact(anyString(), anyString(), any(), anyString()); + verify(sdcClientMock, times(3)).changeResourceLifecycleState(anyString(),anyString(),anyString(),anyString(),anyString()); + assertEquals(403, result.getStatusCodeValue()); + } + + @Test + public void saveCompositionUpdateArtifactFailureNoRollback() throws Exception { + + emulateListOfArtifactsWithCompositionYml(); + when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(vfcmt); + when(vfcmt.getLifecycleState()).thenReturn("NOT_CERTIFIED_CHECKOUT"); + RequestError requestError = new RequestError(); + requestError.setServiceException(new ServiceException("SVC4127", "", null)); + when(sdcClientMock.updateResourceArtifact(anyString(), anyString(), any(), anyString())).thenThrow(new ASDCException(HttpStatus.BAD_REQUEST, requestError)); + ResponseEntity result = compositionBusinessLogic.saveComposition(justAString, justAString, justAString, justAString, false); + + verify(sdcClientMock).getResource(anyString(),anyString()); + verify(sdcClientMock, times(0)).createResourceArtifact(anyString(),anyString(),any(),anyString()); + verify(sdcClientMock).updateResourceArtifact(anyString(), anyString(), any(), anyString()); + verify(sdcClientMock, times(0)).changeResourceLifecycleState(anyString(),anyString(),anyString(),anyString(),anyString()); + assertEquals(409, result.getStatusCodeValue()); + } + + @Test + public void saveCompositionNoExistingCompositionFailure() throws Exception { + + when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(vfcmt); + + ResponseEntity result = compositionBusinessLogic.saveComposition(justAString, justAString, justAString, justAString, false); + + verify(sdcClientMock).getResource(anyString(),anyString()); + verify(sdcClientMock, times(0)).createResourceArtifact(anyString(),anyString(),any(),anyString()); + verify(sdcClientMock, times(0)).updateResourceArtifact(anyString(), anyString(), any(), anyString()); + verify(sdcClientMock, times(0)).changeResourceLifecycleState(anyString(),anyString(),anyString(),anyString(),anyString()); + assertEquals(404, result.getStatusCodeValue()); + } + + + //backward compatibility - create new composition + @Test + public void successfulSaveNewCompositionAndCheckIn() throws Exception { + + when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(vfcmt); + when(vfcmt.getLifecycleState()).thenReturn("NOT_CERTIFIED_CHECKOUT"); + + compositionBusinessLogic.saveComposition(justAString, justAString, justAString, justAString, true); + + verify(sdcClientMock).getResource(anyString(),anyString()); + verify(sdcClientMock).createResourceArtifact(anyString(),anyString(),any(),anyString()); + verify(sdcClientMock, times(0)).updateResourceArtifact(anyString(), anyString(), any(), anyString()); + verify(sdcClientMock).changeResourceLifecycleState(anyString(),anyString(),anyString(),anyString(),anyString()); + } + + + @Test + public void submitCompositionSuccessNoPreviousBlueprint() throws Exception { + + String vfiName = "vfiName"; + mockVfiList(vfiName); + when(vfcmt.getLifecycleState()).thenReturn("NOT_CERTIFIED_CHECKOUT"); + when(sdcClientMock.getAssetMetadata(anyString(),anyString(), anyString())).thenReturn(service); + VfcmtData vfcmtData = new VfcmtData(vfcmt, vfiName, justAString, justAString); + + compositionBusinessLogic.submitComposition(justAString, justAString, vfcmtData, justAString, justAString); + + verify(sdcClientMock).getAssetMetadata(anyString(), anyString(), anyString()); + verify(sdcClientMock).createInstanceArtifact(anyString(), anyString(), anyString(), anyString(), any(),anyString()); + verify(sdcClientMock, times(0)).updateInstanceArtifact(anyString(), anyString(), anyString(), anyString(), any(), anyString()); + verify(sdcClientMock, times(0)).getMonitoringReferences(anyString(), anyString(), anyString(), anyString()); + verify(sdcClientMock, times(2)).changeResourceLifecycleState(anyString(),anyString(),anyString(),anyString(),anyString()); + } + + @Test + public void submitCompositionSuccessDeletePreviousReference() throws Exception { + + String vfiName = "vfiName"; + String flowType = "flowType"; + mockVfiWithBlueprint(vfiName, flowType); + when(vfcmt.getLifecycleState()).thenReturn("NOT_CERTIFIED_CHECKIN"); + when(sdcClientMock.getAssetMetadata(anyString(),anyString(), anyString())).thenReturn(service); + when(service.getVersion()).thenReturn("0.3"); + when(service.getUuid()).thenReturn(justAString); + ExternalReferencesMap referencesMap = new ExternalReferencesMap(); + ResourceDetailed previousMcVersion = new ResourceDetailed(); + previousMcVersion.setInvariantUUID(vfcmt.getInvariantUUID()); + previousMcVersion.setUuid("previousId"); + referencesMap.put(Normalizers.normalizeComponentInstanceName(vfiName), Arrays.asList(vfcmt.getUuid(), previousMcVersion.getUuid())); + when(sdcClientMock.getMonitoringReferences(anyString(), anyString(), anyString(), anyString())).thenReturn(referencesMap); + when(sdcClientMock.getResource(previousMcVersion.getUuid(), justAString)).thenReturn(previousMcVersion); + VfcmtData vfcmtData = new VfcmtData(vfcmt, vfiName, flowType, justAString); + + compositionBusinessLogic.submitComposition(justAString, justAString, vfcmtData, justAString, justAString); + + verify(sdcClientMock).getAssetMetadata(anyString(), anyString(), anyString()); + verify(sdcClientMock).updateInstanceArtifact(anyString(), anyString(), anyString(), anyString(), any(),anyString()); + verify(sdcClientMock, times(0)).createInstanceArtifact(anyString(), anyString(), anyString(), anyString(), any(), anyString()); + verify(sdcClientMock).getMonitoringReferences(anyString(), anyString(), anyString(), anyString()); + verify(sdcClientMock).getResource(anyString(), anyString()); + verify(sdcClientMock).deleteExternalMonitoringReference(anyString(), anyString(), anyString(), anyString(), anyString(), anyString()); + verify(sdcClientMock).changeResourceLifecycleState(anyString(),anyString(),anyString(),anyString(),anyString()); + } + + private void emulateListOfArtifactsWithCompositionYml() { + List<Artifact> listOfArtifactCompositionYml = new ArrayList<>(); + Artifact compositionArtifact = Mockito.mock(Artifact.class); + when(compositionArtifact.getArtifactName()).thenReturn(DcaeBeConstants.Composition.fileNames.COMPOSITION_YML); + listOfArtifactCompositionYml.add(compositionArtifact); + when(vfcmt.getArtifacts()).thenReturn(listOfArtifactCompositionYml); + } + + private void mockVfiList(String vfiName) { + List<ResourceInstance> vfiList = new ArrayList<>(); + ResourceInstance vfi = Mockito.mock(ResourceInstance.class); + when(vfi.getResourceInstanceName()).thenReturn(vfiName); + vfiList.add(vfi); + when(service.getResources()).thenReturn(vfiList); + } + + private void mockVfiWithBlueprint(String vfiName, String flowType) { + mockVfiList(vfiName); + List<Artifact> instanceArtifacts = new ArrayList<>(); + Artifact blueprint = Mockito.mock(Artifact.class); + String artifactName = compositionBusinessLogic.generateBlueprintFileName(flowType, vfcmt.getName()); + when(blueprint.getArtifactName()).thenReturn(artifactName); + instanceArtifacts.add(blueprint); + when(service.getResources().get(0).getArtifacts()).thenReturn(instanceArtifacts); + } + +}
\ No newline at end of file diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogicTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogicTest.java index c353701..70c0577 100644 --- a/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogicTest.java +++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogicTest.java @@ -10,6 +10,7 @@ import org.mockito.runners.MockitoJUnitRunner; import org.onap.sdc.dcae.client.ISdcClient; import org.onap.sdc.dcae.composition.restmodels.MonitoringComponent; import org.onap.sdc.dcae.composition.restmodels.sdc.*; +import org.onap.sdc.dcae.composition.util.DcaeBeConstants; import org.onap.sdc.dcae.errormng.ErrorConfigurationLoader; import org.onap.sdc.dcae.errormng.ResponseFormat; import org.springframework.http.HttpStatus; @@ -36,7 +37,7 @@ public class ReferenceBusinessLogicTest { private ResourceDetailed templateMC; @InjectMocks - ReferenceBusinessLogic classUnderTest; + private ReferenceBusinessLogic classUnderTest; @Before public void setup(){ @@ -86,7 +87,7 @@ public class ReferenceBusinessLogicTest { ServiceDetailed serviceDetailed = new ServiceDetailed(); ResourceInstance resourceInstance = new ResourceInstance(); Artifact artifact = new Artifact(); - artifact.setArtifactName(monitoringComponentName); + artifact.setArtifactName("." + monitoringComponentName + "." + DcaeBeConstants.Composition.fileNames.EVENT_PROC_BP_YAML); resourceInstance.setArtifacts(Collections.singletonList(artifact)); resourceInstance.setResourceInstanceName(vfiName); serviceDetailed.setResources(Collections.singletonList(resourceInstance)); @@ -98,7 +99,7 @@ public class ReferenceBusinessLogicTest { mockGetService(); ResponseEntity responseEntity = classUnderTest.deleteVfcmtReferenceBlueprint(userId, "", monitoringComponentName, serviceUuid, vfiName, "", requestId); verify(sdcClientMock).getService(serviceUuid, requestId); - verify(sdcClientMock).deleteInstanceResourceArtifact(anyString(), anyString(), anyString(), anyString(), anyString(), anyString()); + verify(sdcClientMock).deleteInstanceArtifact(anyString(), anyString(), anyString(), anyString(), anyString(), anyString()); Assert.assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); } @@ -114,7 +115,7 @@ public class ReferenceBusinessLogicTest { @Test public void deleteVfcmtReferenceBlueprint_exceptionSdcdeleteInstanceResourceArtifact() throws Exception { mockGetService(); - doThrow(new RuntimeException("")).when(sdcClientMock).deleteInstanceResourceArtifact(anyString(), anyString(), anyString(), anyString(), anyString(), anyString()); + doThrow(new RuntimeException("")).when(sdcClientMock).deleteInstanceArtifact(anyString(), anyString(), anyString(), anyString(), anyString(), anyString()); ResponseEntity<ResponseFormat> responseEntity = classUnderTest.deleteVfcmtReferenceBlueprint(userId, "", monitoringComponentName, serviceUuid, vfiName, "", requestId); diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/RuleEditorBusinessLogicTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/RuleEditorBusinessLogicTest.java new file mode 100644 index 0000000..d421113 --- /dev/null +++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/RuleEditorBusinessLogicTest.java @@ -0,0 +1,217 @@ +package org.onap.sdc.dcae.composition.impl; + +import org.onap.sdc.dcae.client.ISdcClient; +import org.onap.sdc.dcae.composition.CompositionConfig; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*; +import org.onap.sdc.dcae.composition.restmodels.sdc.*; +import org.onap.sdc.dcae.composition.util.DcaeBeConstants; +import org.onap.sdc.dcae.errormng.ErrorConfigurationLoader; +import org.onap.sdc.dcae.errormng.ResponseFormat; +import org.onap.sdc.dcae.rule.editor.impl.RulesBusinessLogic; +import org.springframework.http.ResponseEntity; +import org.testng.Assert; + +import java.util.*; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.mockito.Mockito.*; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +public class RuleEditorBusinessLogicTest { + + // DEFAULT PROPERTIES + private String justAString = "aStringForAllSeasons"; + private String userId = "gc786h"; + private String vfcmtUuid = "26e8d4b5-f087-4821-a75a-0b9514b5a7ab"; + private String dcaeCompLabel = "dMp.DockerMap"; + private String nId = "n.1525864440166.30"; + private String resourceUuid = "26e8d4b5-f087-4821-a75a-0b9514b5a7ab"; + private String artifactUuid = "9b00ba74-da02-4706-8db0-ac3c11d1d47b"; + private String configParam = "aaf_username"; + private String requestId = "9a89b5c7-33b2-4f7e-a404-66bf4115f510"; + private String flowTypeName = "SNMP MSE"; + private String ruleUuid = "sadsads"; + private String categoryName = "Template"; + private String resourceType = "VFCMT"; + private String saveRulesJsonRequest = "{\n\"version\":\"4.1\",\n\"eventType\":\"syslogFields\",\n\"uid\":\"\",\n\"description\":\"sfasfsaf\",\n\"actions\":[\n{\n\"id\":\"6e0175a0-581f-11e8-82eb-53bb060b790a\",\n\"actionType\":\"copy\",\n\"from\":{\n\"value\":\"asfsf\",\n\"regex\":\"\",\n\"state\":\"closed\",\n\"values\":[\n{\n" + "\"value\":\"\"\n" + "},\n" + "{\n\"value\":\"\"\n}\n]\n},\n\"target\":\"event.commonEventHeader.eventType\",\n\"map\":{\n\"values\":[\n{\n\"key\":\"\",\n\"value\":\"\"\n}\n],\n\"haveDefault\":false,\n\"default\":\"\"\n},\n\"dateFormatter\":{\n\"fromFormat\":\"\",\n\"toFormat\":\"\",\n\"fromTimezone\":\"\",\n\"toTimezone\":\"\"\n},\n\"replaceText\":{\n\"find\":\"\",\n\"replace\":\"\"\n},\n\"logText\":{\n\"name\":\"\",\n\"level\":\"\",\n\"text\":\"\"\n},\n\"logEvent\":{\n\"title\":\"\"\n}\n}\n],\n\"condition\":null\n}"; + private String artifactJson = "{\n \"artifactName\":\"composition.yml\",\n \"artifactType\":\"DCAE_TOSCA\",\n \"artifactURL\":\"/sdc/v1/catalog/resources/c2877686-616a-48ca-a37b-7e311bf83adc/artifacts/9b00ba74-da02-4706-8db0-ac3c11d1d47b\",\n \"artifactDescription\":\"createReferenceArtifact\",\n \"artifactTimeout\":null,\n \"artifactChecksum\":\"MjhhYTAwOTIxZGZkMGMyMmFjYmEzYjI1NTIwYjA3YzM=\",\n \"artifactUUID\":\"9b00ba74-da02-4706-8db0-ac3c11d1d47b\",\n \"artifactVersion\":\"1\",\n \"generatedFromUUID\":null,\n \"artifactLabel\":\"servicereference\",\n \"artifactGroupType\":\"DEPLOYMENT\",\n \"payloadData\":null,\n \"description\":null\n" + "}"; + private String defaultPayload = "{eventType:syslogFields,version:4.1,rules:{'test':{'version':'4.1'}}}"; + + + // MOCKS + private ISdcClient sdcClientMock = Mockito.mock(ISdcClient.class); + private ResourceDetailed vfcmt = Mockito.mock(ResourceDetailed.class); + private SchemaInfo schemaInfo = Mockito.mock(SchemaInfo.class); + private CompositionConfig compositionConfig = Mockito.mock(CompositionConfig.class); + private RulesBusinessLogic rulesBusinessLogic = Mockito.mock(RulesBusinessLogic.class); + private CompositionConfig.FlowType flowType = Mockito.mock(CompositionConfig.FlowType.class); + + @InjectMocks + private RuleEditorBusinessLogic ruleEditorBusinessLogic = new RuleEditorBusinessLogic(); + + @Before + public void setup() { + + MockitoAnnotations.initMocks(this); + ruleEditorBusinessLogic.setSdcRestClient(sdcClientMock); + + new ErrorConfigurationLoader(System.getProperty("user.dir") + "/src/main/webapp/WEB-INF"); + when(vfcmt.getUuid()).thenReturn(vfcmtUuid); + when(vfcmt.getName()).thenReturn(justAString); + when(vfcmt.getDescription()).thenReturn(justAString); + when(vfcmt.getResourceType()).thenReturn(resourceType); + when(vfcmt.getCategory()).thenReturn(categoryName); + + when(ruleEditorBusinessLogic.getSdcRestClient().getResource(anyString(), anyString())).thenReturn(vfcmt); + when(schemaInfo.getVersion()).thenReturn("0.2"); + + /* PowerMockito.doReturn(vs).when(VesStructureLoader.class); + when(vs.getEventListenerDefinitionByVersion(anyString())).thenReturn(null);*/ + } + + @Test + public void test_saveRules() throws Exception { + + emulateMockListOfArtifacts(dcaeCompLabel, nId, configParam, true); + + when(ruleEditorBusinessLogic.getSdcRestClient().getResourceArtifact(resourceUuid, artifactUuid, requestId)).thenReturn(defaultPayload); + when(rulesBusinessLogic.addOrEditRule(any(MappingRules.class), any(Rule.class))).thenReturn(true); + + ResponseEntity result = ruleEditorBusinessLogic.saveRule(saveRulesJsonRequest, requestId, userId, vfcmtUuid, dcaeCompLabel, nId, configParam); + assertEquals(200,result.getStatusCodeValue()); + Assert.assertTrue(result.getBody().toString().contains("6e0175a0-581f-11e8-82eb-53bb060b790a")); + verify(rulesBusinessLogic,times(1)).addOrEditRule(any(MappingRules.class), any(Rule.class)); + + } + + @Test + public void test_saveRules_artifactNotFound() throws Exception { + + emulateMockListOfArtifacts(dcaeCompLabel, nId, configParam, false); + + when(rulesBusinessLogic.addOrEditRule(any(MappingRules.class), any(Rule.class))).thenReturn(true); + String payload = "{eventType:syslogFields,version:4.1,rules:{'test':{'version':'4.1'}},\"nid\":\"n.1525864440166.30}"; + when(ruleEditorBusinessLogic.getSdcRestClient().getResourceArtifact(anyString(),anyString(), anyString())).thenReturn(payload); + + ResponseEntity result = ruleEditorBusinessLogic.saveRule(saveRulesJsonRequest, requestId, userId, vfcmtUuid, dcaeCompLabel, nId, configParam); + assertEquals(200,result.getStatusCodeValue()); + Assert.assertTrue(result.getBody().toString().contains("6e0175a0-581f-11e8-82eb-53bb060b790a")); + verify(rulesBusinessLogic,times(0)).addOrEditRule(any(MappingRules.class), any(Rule.class)); + + } + + @Test + public void test_saveRules_artifactNotFound_Error() throws Exception { + + emulateMockListOfArtifacts(dcaeCompLabel, nId, configParam, false); + + when(ruleEditorBusinessLogic.getSdcRestClient().getResourceArtifact(anyString(),anyString(), anyString())).thenReturn(defaultPayload); + + ResponseEntity<ResponseFormat> result = ruleEditorBusinessLogic.saveRule(saveRulesJsonRequest, requestId, userId, vfcmtUuid, dcaeCompLabel, nId, configParam); + assertEquals(400,result.getStatusCodeValue()); + assertEquals("SVC6114",result.getBody().getRequestError().getServiceException().getMessageId()); + assertEquals("DCAE component %1 not found in composition",result.getBody().getRequestError().getServiceException().getText()); + verify(rulesBusinessLogic,times(0)).addOrEditRule(any(MappingRules.class), any(Rule.class)); + + } + + @Test + public void test_getRules() throws Exception { + + emulateMockListOfArtifacts(dcaeCompLabel, nId, configParam, true); + + when(ruleEditorBusinessLogic.getSdcRestClient().getResourceArtifact(resourceUuid, artifactUuid, requestId)) + .thenReturn(defaultPayload); + + ResponseEntity result = ruleEditorBusinessLogic.getRules(vfcmtUuid, dcaeCompLabel, nId, configParam, requestId); + assertEquals(200,result.getStatusCodeValue()); + Assert.assertTrue(result.getBody().toString().contains("eventType:syslogFields,version:4.1,rules:{'test':{'version':'4.1'")); + + } + + @Test + public void test_getExistingRuleTargets() throws Exception { + + emulateMockListOfArtifacts(dcaeCompLabel, nId, configParam, true); + + when(ruleEditorBusinessLogic.getSdcRestClient().getResourceArtifact(resourceUuid, artifactUuid, requestId)).thenReturn(defaultPayload); + + ResponseEntity result = ruleEditorBusinessLogic.getExistingRuleTargets(vfcmtUuid, requestId, dcaeCompLabel, nId); + assertEquals(200,result.getStatusCodeValue()); + assertNotEquals(null,result.getBody()); + + } + + @Test + public void test_translate() throws Exception { + + emulateMockListOfArtifacts(dcaeCompLabel, nId, configParam, true); + + when(ruleEditorBusinessLogic.getSdcRestClient().getResourceArtifact(resourceUuid, artifactUuid, requestId)).thenReturn(defaultPayload); + Map<String, CompositionConfig.FlowType> flowTypeMap = new HashMap<>(); + flowTypeMap.put("SNMP MSE", flowType); + when(compositionConfig.getFlowTypesMap()).thenReturn(flowTypeMap); + when(compositionConfig.getFlowTypesMap().get("SNMP MSE").getEntryPointPhaseName()).thenReturn("testName"); + when(compositionConfig.getFlowTypesMap().get("SNMP MSE").getLastPhaseName()).thenReturn("testLastName"); + + when(rulesBusinessLogic.translateRules(any(MappingRules.class), anyString(), anyString(), anyString())).thenReturn("testLastName"); + ResponseEntity result = ruleEditorBusinessLogic.translateRules(vfcmtUuid, requestId, dcaeCompLabel, nId, configParam, flowTypeName); + verify(compositionConfig,times(6)).getFlowTypesMap(); + verify(rulesBusinessLogic,times(1)).translateRules(any(MappingRules.class), anyString(), anyString(), anyString()); + + assertEquals(200,result.getStatusCodeValue()); + + } + + @Test + public void test_deleteRule() throws Exception { + + emulateMockListOfArtifacts(dcaeCompLabel, nId, configParam, true); + + when(ruleEditorBusinessLogic.getSdcRestClient().getResourceArtifact(resourceUuid, artifactUuid, requestId)).thenReturn(defaultPayload); + + when(rulesBusinessLogic.deleteRule(any(MappingRules.class), anyString())).thenReturn(new Rule()); + ResponseEntity result = ruleEditorBusinessLogic.deleteRule(userId, vfcmtUuid, dcaeCompLabel, nId, configParam, ruleUuid, requestId); + assertEquals(200,result.getStatusCodeValue()); + + } + + @Test + public void test_getDefinition(){ + + +/* + PowerMockito.mockStatic(VesStructureLoader.class); + when(VesStructureLoader.getEventListenerDefinitionByVersion(anyString())).thenReturn(null); +*/ + + ResponseEntity res = ruleEditorBusinessLogic.getDefinition("4.1","syslogFields"); + + } + + private void emulateMockListOfArtifacts(String dcaeCompLabel, String nid, String configParam, boolean isApprovedArtifact) { + List<Artifact> listOfArtifactCompositionYml = new ArrayList<>(); + Artifact artifact = Mockito.mock(Artifact.class);//gson.fromJson(artifactJson, Artifact.class); + + if (isApprovedArtifact) { + when(artifact.getArtifactLabel()).thenReturn(dcaeCompLabel + nid + configParam); + when(artifact.getArtifactName()).thenReturn(dcaeCompLabel + "_" + nid + "_" + DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX); + }else { + when(artifact.getArtifactLabel()).thenReturn("servicereference"); + when(artifact.getArtifactName()).thenReturn("composition.yml"); + } + when(artifact.getArtifactType()).thenReturn("DCAE_TOSCA"); + when(artifact.getArtifactUUID()).thenReturn(artifactUuid); + when(artifact.getArtifactDescription()).thenReturn("createmapArtifact"); + + listOfArtifactCompositionYml.add(artifact); + when(vfcmt.getArtifacts()).thenReturn(listOfArtifactCompositionYml); + } + + +} diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/services/GetServicesTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/ServiceBusinessLogicTest.java index 68f055f..3cac355 100644 --- a/dcaedt_be/src/test/java/org/onap/sdc/dcae/services/GetServicesTest.java +++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/ServiceBusinessLogicTest.java @@ -1,22 +1,47 @@ -package org.onap.sdc.dcae.services; +package org.onap.sdc.dcae.composition.impl; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.when; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.junit.Before; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.sdc.dcae.client.ISdcClient; import org.onap.sdc.dcae.composition.restmodels.DcaeMinimizedService; -import org.onap.sdc.dcae.composition.controller.ServicesController; +import org.onap.sdc.dcae.composition.impl.ServiceBusinessLogic; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.ActionDeserializer; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseCondition; +import org.onap.sdc.dcae.composition.restmodels.ruleeditor.ConditionDeserializer; +import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; +import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceInstance; +import org.onap.sdc.dcae.composition.restmodels.sdc.ServiceDetailed; import org.onap.sdc.dcae.composition.util.DcaeBeConstants; import org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateEnum; +import org.onap.sdc.dcae.errormng.ErrorConfigurationLoader; import org.testng.annotations.Test; -public class GetServicesTest { - +public class ServiceBusinessLogicTest { + + private String userId = "me"; + private String requestId = "1"; + private String monitoringComponentName = "monitoringComponentName"; + private String serviceUuid = "serviceUuid"; + private String vfiName = "vfiName"; + + private static Gson gson = new GsonBuilder() + .registerTypeAdapter(BaseAction.class, new ActionDeserializer()) + .registerTypeAdapter(BaseCondition.class, new ConditionDeserializer()).create(); + + ServiceBusinessLogic target = new ServiceBusinessLogic(); + @Test public void parseAndFliterServicesByUser_nullServices_TBD() { @@ -27,7 +52,6 @@ public class GetServicesTest { @Test public void parseAndFliterServicesByUser_emptyList_emptyList() { // arrange - ServicesController target = new ServicesController(); String user_id = "test"; String lastUpdaterUserId = "test"; List<LinkedHashMap<String, String>> services = new ArrayList<LinkedHashMap<String, String>>(); @@ -49,7 +73,6 @@ public class GetServicesTest { String version = "0.1"; String serviceName = "TestService"; - ServicesController target = new ServicesController(); LinkedHashMap<String, String> service = createServiceAsMap(lastUpdaterUserId, uuid, invariantUUID, lifecycleState, version, serviceName); List<LinkedHashMap<String, String>> services = new ArrayList<LinkedHashMap<String, String>>( @@ -77,7 +100,6 @@ public class GetServicesTest { .map(x -> createServiceAsMap(lastUpdaterUserId, uuid, UUID.randomUUID().toString(), lifecycleState, version, x)) .collect(Collectors.toList()); - ServicesController target = new ServicesController(); // act List<DcaeMinimizedService> result = target.parseAndFilterServicesByUser(lastUpdaterUserId, unsortedServices, @@ -112,8 +134,6 @@ public class GetServicesTest { List<LinkedHashMap<String, String>> singleServiceWithMultiVersions = Arrays.asList("1.0", "0.3", "11.0", "2.0", "1.8").stream() .map(x -> createServiceAsMap(lastUpdaterUserId, uuid, invariantUUID, lifecycleState, x, serviceName)) .collect(Collectors.toList()); - - ServicesController target = new ServicesController(); // act List<DcaeMinimizedService> result = target.parseAndFilterServicesByUser(lastUpdaterUserId, singleServiceWithMultiVersions, user_id); @@ -139,5 +159,15 @@ public class GetServicesTest { return service; } - + private void mockGetService() + { + ServiceDetailed serviceDetailed = new ServiceDetailed(); + ResourceInstance resourceInstance = new ResourceInstance(); + Artifact artifact = new Artifact(); + artifact.setArtifactName("." + monitoringComponentName + "." + DcaeBeConstants.Composition.fileNames.EVENT_PROC_BP_YAML); + resourceInstance.setArtifacts(Collections.singletonList(artifact)); + resourceInstance.setResourceInstanceName(vfiName); + serviceDetailed.setResources(Collections.singletonList(resourceInstance)); + when(target.getSdcRestClient().getService(serviceUuid, requestId)).thenReturn(serviceDetailed); + } } diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogicTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogicTest.java index 12ed040..5f1ba41 100644 --- a/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogicTest.java +++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogicTest.java @@ -7,10 +7,8 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.onap.sdc.dcae.catalog.asdc.ASDCException; import org.onap.sdc.dcae.client.ISdcClient; -import org.onap.sdc.dcae.client.SdcRestClient; import org.onap.sdc.dcae.composition.restmodels.CreateVFCMTRequest; import org.onap.sdc.dcae.composition.restmodels.ImportVFCMTRequest; -import org.onap.sdc.dcae.composition.restmodels.MonitoringComponent; import org.onap.sdc.dcae.composition.restmodels.VfcmtData; import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact; import org.onap.sdc.dcae.composition.restmodels.sdc.ExternalReferencesMap; @@ -23,20 +21,20 @@ import org.onap.sdc.dcae.errormng.RequestError; import org.onap.sdc.dcae.errormng.ResponseFormat; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.client.HttpClientErrorException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; import static org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateEnum.CERTIFIED; import static org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT; public class VfcmtBusinessLogicTest { - private ISdcClient sdcClientMock = Mockito.mock(SdcRestClient.class); + private ISdcClient sdcClientMock = Mockito.mock(ISdcClient.class); private ResourceDetailed templateMC = Mockito.mock(ResourceDetailed.class); private VfcmtBusinessLogic vfcmtBusinessLogic = new VfcmtBusinessLogic(); @@ -60,7 +58,7 @@ public class VfcmtBusinessLogicTest { } @Test - public void sdcIsDown_creatingVfcmt_gotResponseWithError500() throws Exception{ + public void sdcIsDown_creatingVfcmt_gotResponseWithError500() { RequestError requestError = new RequestError(); requestError.setPolicyException(new PolicyException("POL5000", "Error: Internal Server Error. Please try again later.", null)); when(sdcClientMock.createResource(userId,request,requestId)).thenThrow(new ASDCException(HttpStatus.INTERNAL_SERVER_ERROR, requestError)); @@ -77,7 +75,6 @@ public class VfcmtBusinessLogicTest { requestError.setPolicyException(new PolicyException("POL5000", "Error: Internal Server Error. Please try again later.", null)); when(sdcClientMock.createResourceArtifact(anyString(),anyString(),any(),anyString())).thenThrow(new ASDCException(HttpStatus.INTERNAL_SERVER_ERROR, requestError)); when(sdcClientMock.createResource(userId,request,requestId)).thenReturn(templateMC); - when(sdcClientMock.getResourceArtifact(anyString(), anyString(), anyString())).thenReturn("{\"flowType\":\"don't override\""); when(templateMC.getUuid()).thenReturn("3"); when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC); emulateListOfArtifactsWithCompositionYml(); @@ -113,7 +110,6 @@ public class VfcmtBusinessLogicTest { @Test public void successfulImportAndAttachmentOfVfcmtAlreadyConnectedWithoutEditDoCheckin() throws Exception { when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC); - when(sdcClientMock.getResourceArtifact(anyString(),anyString(),anyString())).thenReturn("{\"flowType\":\"don't override\"}"); when(templateMC.getLifecycleState()).thenReturn("NOT_CERTIFIED_CHECKOUT"); emulateListOfArtifactsWithCompositionYmlAndSvcRef(); request.setCloneVFCMT(false); @@ -136,7 +132,6 @@ public class VfcmtBusinessLogicTest { when(templateMC.getUuid()).thenReturn("3"); when(sdcClientMock.changeResourceLifecycleState(anyString(), anyString(), anyString(), anyString(), anyString())).thenReturn(templateMC); when(sdcClientMock.updateResourceArtifact(anyString(), anyString(), any(), anyString())).thenReturn(new Artifact()); - when(sdcClientMock.getResourceArtifact(anyString(),anyString(),anyString())).thenReturn("{\"cid\":\"xsssdaerrwr\"}"); when(templateMC.getLifecycleState()).thenReturn("NOT_CERTIFIED_CHECKIN").thenReturn("NOT_CERTIFIED_CHECKOUT"); emulateListOfArtifactsWithCompositionYmlAndSvcRef(); request.setCloneVFCMT(false); @@ -154,46 +149,69 @@ public class VfcmtBusinessLogicTest { @Test - public void successfulFetchVfcmtDataFull() throws Exception { + public void invalidateMCRequestFields_returnError() { + ResponseEntity response = vfcmtBusinessLogic.importMC(userId, new ImportVFCMTRequest(), requestId); + Assert.assertEquals(response.getStatusCodeValue(), 400); + } + + @Test + public void cloneVfcmt_missingToscaFile_returnError() { + when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC); + request.setCloneVFCMT(true); + ResponseEntity response = vfcmtBusinessLogic.importMC(userId, request, requestId); + Assert.assertEquals(response.getStatusCodeValue(), 404); + } + + @Test + public void checkCatchingSdcExceptions_returnError() { + RequestError requestError = new RequestError(); + requestError.setPolicyException(new PolicyException("POL5000", "Error: Internal Server Error. Please try again later.", null)); + when(sdcClientMock.getResource(request.getTemplateUuid(), requestId)).thenThrow(new ASDCException(HttpStatus.INTERNAL_SERVER_ERROR, requestError)); + request.setCloneVFCMT(false); + request.setUpdateFlowType(true); + ResponseEntity response = vfcmtBusinessLogic.importMC(userId, request, requestId); + Assert.assertEquals(response.getStatusCodeValue(), 500); + } + + + @Test + public void successfulFetchVfcmtDataFull() { String templateUuid = "3"; when(templateMC.getUuid()).thenReturn(templateUuid); when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC); emulateListOfArtifactsWithCompositionYmlAndSvcRef(); when(sdcClientMock.getResourceArtifact(templateUuid, "svcRefArtifactUuid", requestId)).thenReturn("thisIsTheServiceId/resources/thisIsTheVfiName"); - when(sdcClientMock.getResourceArtifact(templateUuid, "compositionArtifactUuid", requestId)).thenReturn("\"flowType\":\"Syslog\""); ResponseEntity<VfcmtData> result = vfcmtBusinessLogic.getVfcmtReferenceData(templateUuid, requestId); verify(sdcClientMock).getResource(anyString(),anyString()); verify(sdcClientMock,times(2)).getResourceArtifact(anyString(),anyString(),anyString()); Assert.assertEquals(200, result.getStatusCodeValue()); - Assert.assertEquals("Syslog", result.getBody().getFlowType()); + Assert.assertEquals("don't override", result.getBody().getFlowType()); Assert.assertEquals("thisIsTheServiceId", result.getBody().getServiceUuid()); Assert.assertEquals("thisIsTheVfiName", result.getBody().getVfiName()); } @Test - public void successfulFetchVfcmtDataPartial() throws Exception { + public void successfulFetchVfcmtDataPartial() { String templateUuid = "3"; when(templateMC.getUuid()).thenReturn(templateUuid); when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC); emulateListOfArtifactsWithCompositionYml(); - when(sdcClientMock.getResourceArtifact(templateUuid, "compositionArtifactUuid", requestId)).thenReturn("\"flowType\":\"Syslog\""); ResponseEntity<VfcmtData> result = vfcmtBusinessLogic.getVfcmtReferenceData(templateUuid, requestId); verify(sdcClientMock).getResource(anyString(),anyString()); verify(sdcClientMock,times(1)).getResourceArtifact(anyString(),anyString(),anyString()); Assert.assertEquals(200, result.getStatusCodeValue()); - Assert.assertEquals("Syslog", result.getBody().getFlowType()); + Assert.assertEquals("don't override", result.getBody().getFlowType()); Assert.assertEquals(null, result.getBody().getServiceUuid()); Assert.assertEquals(null, result.getBody().getVfiName()); } @Test - public void successfulFetchVfcmtDataEmpty() throws Exception { + public void successfulFetchVfcmtDataEmpty() { String templateUuid = "3"; when(templateMC.getUuid()).thenReturn(templateUuid); when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC); - emulateListOfArtifactsWithCompositionYml(); - when(sdcClientMock.getResourceArtifact(templateUuid, "compositionArtifactUuid", requestId)).thenReturn(""); + emulateCdumpArtifactWithoutFlowtype(); ResponseEntity<VfcmtData> result = vfcmtBusinessLogic.getVfcmtReferenceData(templateUuid, requestId); verify(sdcClientMock).getResource(anyString(),anyString()); verify(sdcClientMock,times(1)).getResourceArtifact(anyString(),anyString(),anyString()); @@ -204,7 +222,7 @@ public class VfcmtBusinessLogicTest { } @Test - public void fetchVfcmtDataNoCompositionFound() throws Exception { + public void fetchVfcmtDataNoCompositionFound() { String templateUuid = "3"; when(templateMC.getUuid()).thenReturn(templateUuid); @@ -219,7 +237,7 @@ public class VfcmtBusinessLogicTest { } @Test - public void getVfcmtsForMigration() throws Exception { + public void getVfcmtsForMigration() { ExternalReferencesMap connectedVfcmts = new ExternalReferencesMap(); connectedVfcmts.put("11",Arrays.asList("Red", "Blue", "Yellow")); connectedVfcmts.put("22",Arrays.asList("Ibiza", "Bora Bora", "Mykonos")); @@ -281,6 +299,17 @@ public class VfcmtBusinessLogicTest { when(templateMC.getArtifacts()).thenReturn(listOfArtifactCompositionYml); } + + private void emulateCdumpArtifactWithoutFlowtype() { + List<Artifact> listOfArtifactCompositionYml = new ArrayList<>(); + Artifact compositionArtifact = Mockito.mock(Artifact.class); + when(compositionArtifact.getArtifactName()).thenReturn(DcaeBeConstants.Composition.fileNames.COMPOSITION_YML); + when(compositionArtifact.getArtifactUUID()).thenReturn("compositionArtifactUuid"); + when(compositionArtifact.getPayloadData()).thenReturn("{\"cid\":\"xsssdaerrwr\"}\""); + listOfArtifactCompositionYml.add(compositionArtifact); + when(templateMC.getArtifacts()).thenReturn(listOfArtifactCompositionYml); + } + private void emulateListOfArtifactsWithCompositionYmlAndSvcRef() { List<Artifact> listOfArtifactCompositionYml = new ArrayList<>(); Artifact compositionArtifact = Mockito.mock(Artifact.class); @@ -296,7 +325,7 @@ public class VfcmtBusinessLogicTest { } @Test - public void uiHasABug_creatingVfcmtWithBadRequestNoServiceUuid_gotResponseWithError400() throws Exception{ + public void uiHasABug_creatingVfcmtWithBadRequestNoServiceUuid_gotResponseWithError400() { RequestError requestError = new RequestError(); requestError.setPolicyException(new PolicyException("POL5000", "Error: Internal Server Error. Please try again later.", null)); when(sdcClientMock.createResource(userId,request,requestId)).thenThrow(new ASDCException(HttpStatus.INTERNAL_SERVER_ERROR, requestError)); diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/filter/LoggingFilterTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/filter/LoggingFilterTest.java new file mode 100644 index 0000000..cfe9f56 --- /dev/null +++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/filter/LoggingFilterTest.java @@ -0,0 +1,119 @@ +package org.onap.sdc.dcae.filter; + +import org.apache.http.impl.EnglishReasonPhraseCatalog; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.sdc.common.onaplog.Enums.LogLevel; +import org.onap.sdc.common.onaplog.Enums.OnapLoggerErrorCode; +import org.onap.sdc.common.onaplog.OnapMDCWrapper; + + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.HttpServletResponse; +import java.util.Enumeration; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class LoggingFilterTest { + @Mock private HttpServletRequest request; + @Mock private HttpServletResponse httpResponse; + @Mock private ServletResponse response; + @Mock private FilterChain filterChain; + + private FilterConfig filterConfig = new FilterConfig() { + @Override + public String getFilterName() { + return null; + } + + @Override + public ServletContext getServletContext() { + return null; + } + + @Override + public String getInitParameter(String name) { + return null; + } + + @Override + public Enumeration<String> getInitParameterNames() { + return null; + } + }; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void loggingFilterInstanciationLifeCycle() { + LoggingFilter loggingFilter = new LoggingFilter(); + + loggingFilter.init(filterConfig); + + loggingFilter.destroy(); + } + + @Test + public void doFilter_healthCheck_noReadingHeader(){ + LoggingFilter loggingFilter = new LoggingFilter(); + boolean exceptionThrown = false; + + when(request.getServletPath()).thenReturn("/healthCheck"); + try { + loggingFilter.doFilter(request, response, filterChain); + } + catch (Exception e){ + exceptionThrown = true; + } + verify(request,never()).getHeader("X-ECOMP-RequestID"); + assertEquals(exceptionThrown, false); + } + + @Test + public void doFilter_notHealthCheck_noReadingHeader(){ + LoggingFilter loggingFilter = new LoggingFilter(); + boolean exceptionThrown = false; + + when(request.getServletPath()).thenReturn("/notHealthCheck"); + try { + loggingFilter.doFilter(request, response, filterChain); + } + catch (Exception e){ + exceptionThrown = true; + } + verify(request).getHeader("X-ECOMP-RequestID"); + assertEquals(exceptionThrown, false); + } + @Test + public void doFilter_InternalServerError(){ + LoggingFilter loggingFilter = new LoggingFilter(); + boolean exceptionThrown = false; + + when(request.getServletPath()).thenReturn("/notHealthCheck"); + try { + + when(httpResponse.getStatus()).thenReturn(500); + when(request.getHeader("user-agent")).thenReturn("test"); + + loggingFilter.doFilter(request, httpResponse, filterChain); + } + catch (Exception e){ + exceptionThrown = true; + } + verify(request).getHeader("X-ECOMP-RequestID"); + assertEquals(exceptionThrown, false); + } + + +} diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogicTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogicTest.java index d3ae600..bc03632 100644 --- a/dcaedt_be/src/test/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogicTest.java +++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogicTest.java @@ -201,6 +201,17 @@ public class RulesBusinessLogicTest { } @Test + public void missingLogTextFailureTest() { + Rule rule = new Rule(); + rule.setDescription("description"); + rule.setActions(new ArrayList<>()); + rule.getActions().add(buildLogTextMissingTextAction()); + List<ServiceException> errors = rulesBusinessLogic.validateRule(rule); + String expectedError = "Please fill the text field of Log Text action to "; + assertEquals(expectedError, errors.get(0).getFormattedErrorMessage()); + } + + @Test public void reorderMappingRulesCircularDependencyFailureTest() { MappingRules mr = new MappingRules(buildRuleWithMultipleCopyActions()); @@ -266,24 +277,31 @@ public class RulesBusinessLogicTest { return rule; } - private BaseAction buildCopyAction(String from, String to) { - BaseAction action = new BaseAction(); + private BaseCopyAction buildCopyAction(String from, String to) { + BaseCopyAction action = new BaseCopyAction(); action.setActionType("copy"); action.setFrom(from); action.setTarget(to); return action; } - private BaseAction buildConcatAction(List<String> from, String to) { - BaseAction action = new BaseAction(); + private LogTextAction buildLogTextMissingTextAction(){ + LogTextAction logTextAction = new LogTextAction(); + logTextAction.setActionType("Log Text"); + logTextAction.setLogText("a name", "a level", ""); + return logTextAction; + } + + private BaseCopyAction buildConcatAction(List<String> from, String to) { + BaseCopyAction action = new BaseCopyAction(); action.setActionType("concat"); action.setFrom(from); action.setTarget(to); return action; } - private BaseAction buildRegexAction(String from, String to, String regex) { - BaseAction action = new BaseAction(); + private BaseCopyAction buildRegexAction(String from, String to, String regex) { + BaseCopyAction action = new BaseCopyAction(); action.setActionType("copy"); action.setFrom(from, regex); action.setTarget(to); diff --git a/dcaedt_catalog/api/src/main/java/org/onap/sdc/dcae/catalog/Catalog.java b/dcaedt_catalog/api/src/main/java/org/onap/sdc/dcae/catalog/Catalog.java index b73bb09..c9813e4 100644 --- a/dcaedt_catalog/api/src/main/java/org/onap/sdc/dcae/catalog/Catalog.java +++ b/dcaedt_catalog/api/src/main/java/org/onap/sdc/dcae/catalog/Catalog.java @@ -2,14 +2,8 @@ package org.onap.sdc.dcae.catalog; import java.net.URI; -import java.util.Arrays; -import java.util.Collection; import java.util.Iterator; -import java.util.List; -import java.util.Map; import java.util.LinkedList; -import java.util.HashMap; -import java.util.EnumSet; import org.json.JSONObject; import org.onap.sdc.dcae.catalog.commons.Action; @@ -20,421 +14,258 @@ import org.onap.sdc.dcae.catalog.commons.Proxies; import org.json.JSONArray; -/* - * - */ public interface Catalog { - public abstract URI getUri(); - - public abstract String namespace(); - - public abstract boolean same(Catalog theCatalog); - - public abstract <T> T proxy(JSONObject theData, Class<T> theType); - - - /* Base class for all Catalog objects. - */ - public static interface Element<T extends Element<T>> { - - /** - * provide a typed 'self' reference - */ - public default T self() { return (T)this; } - - /** - */ - public default Class<T> selfClass() { - return (Class<T>)getClass().getInterfaces()[0]; - } - - /* */ - public Catalog catalog(); - - /** - */ - public String id(); - - /** - * Direct access to the underlying JSON object. - * Warning: Modifications to the JSON object are reflected in the Element. - */ - public JSONObject data(); - - /** - * Provides the labels of the artifacts (we use labels to type/classify the - * neo4j artifacts, nodes and edges. - * Currently not all queries retrieve the labels. - */ - public String[] labels(); - - /* Allows for typed deep exploration of the backing JSON data structure - * <pre> - * {@code - * element("type", Type.class); - * } - * </pre> - * - * @arg theName name of a JSON entry ; It must map another JSONObject. - * @arg theType the expected wrapping catalog artifact type - * @return the JSON entry wrapped in the specified type - */ - public default <E extends Element<E>> E element(String theName, Class<E> theType) { - JSONObject elemData = data().optJSONObject(theName); - if (elemData == null) - return null; - else - return catalog().proxy(elemData, theType); - } - - /* Similar to {@link #element(String,Class)} but for collection wrapping. - * Example: - * <pre> - * {@code - * element("nodes", Nodes.class); - * } - * </pre> - */ - public default <E extends Elements> E elements(String theName, Class<E> theType) { - //throws ReflectiveOperationException { - JSONArray elemsData = data().optJSONArray(theName); - if (elemsData == null) { - return null; - } - else { - Class etype = Proxies.typeArgument(theType); - Elements elems = null; - try { - elems = theType.newInstance(); - } - catch (ReflectiveOperationException rox) { - throw new RuntimeException("Failed to instantiate " + theType, rox); - } - - try{ - for (Iterator i = elemsData.iterator(); i.hasNext();) { - JSONObject elemData = (JSONObject)i.next(); - elems.add(catalog().proxy(elemData, etype)); - } - } - catch(Exception e){ - throw new RuntimeException("Failed to fetch json data ", e); - } - return (E)elems; - } - } - - /* - */ - public default boolean same(Element theElem) { - return this.catalog().same(theElem.catalog()) && - this.id().equals(theElem.id()); - } - } - - /* - * Base class for all collections of elements. - */ - public static class Elements<T extends Element> - extends LinkedList<T> { - - public String toString() { - StringBuilder sb = new StringBuilder("["); - for (Element el: this) { - sb.append(el.selfClass().getSimpleName()) - .append("(") - .append(el.data()) - .append("),"); - } - sb.append("]"); - return sb.toString(); - } - } - - /* - * We need this contraption in order to store a mix of Folders and CatalogItem - * instances (Elements in self is not good because it is defined around a - * type variable so we cannot use reflection to determine the type at runtime - * - generics are resolved compile time) - */ - public static class Mixels extends Elements<Element> { - } - - /* - */ - public static interface Item<T extends Item<T>> extends Element<T> { - - public String name(); - - public String description(); - - /* catalog item native identifier */ - public String itemId(); - - /* similar to @ItemAction#withModels - */ - default public Future<Templates> models() { - Templates t = elements("models", Templates.class); - if (t != null) - return Futures.succeededFuture(t); - else - return Futures.advance(catalog().item(itemId()) - .withModels() - .execute(), - item -> (Templates)item.elements("models", Templates.class)); - } - - /* similar to @ItemAction#withAnnotations - */ - default public Future<Annotations> annotations() { - Annotations a = elements("annotations", Annotations.class); - if (a != null) - return Futures.succeededFuture(a); - else - return Futures.advance(catalog().item(itemId()) - .withAnnotations() - .execute(), - item -> (Annotations)item.elements("annotations", Annotations.class)); - } - } - - /* - * Collection of catalog items. - */ - public static class Items extends Elements<Item> { - } - - /* - */ - public static interface Folder extends Element<Folder> { - - public String name(); - - public String description(); - - public String itemId(); - - /* the namespace is immutable */ - public default String namespace() { - return catalog().namespace(); - } - - /* - */ - default public Future<Items> items() { - Items i = elements("items", Items.class); - if (i != null) - return Futures.succeededFuture(i); - else - return Futures.advance(catalog().folder(itemId()) - .withItems() - .execute(), - folder -> (Items)folder.elements("items", Items.class)); - } - - /* - */ - default public Future<Folders> parts() { - Folders f = elements("parts", Folders.class); - if (f != null) - return Futures.succeededFuture(f); - else - return Futures.advance(catalog().folder(itemId()) - .withParts() - .execute(), - folder -> (Folders)folder.elements("parts", Folders.class)); - } - - /* - */ - public Future<Folders> partof(); - - } - - - public static class Folders extends Elements<Folder> { - } - - //no predefined properties here - public static interface Annotation extends Element<Annotation> { - - public default String namespace() { - return catalog().namespace(); + URI getUri(); + + <T> T proxy(JSONObject theData, Class<T> theType); + + + /* Base class for all Catalog objects. */ + interface Element<T extends Element<T>> { + + default Class<T> selfClass() { + return (Class<T>)getClass().getInterfaces()[0]; + } + + Catalog catalog(); + + String id(); + + /** + * Direct access to the underlying JSON object. + * Warning: Modifications to the JSON object are reflected in the Element. + */ + JSONObject data(); + + /* Allows for typed deep exploration of the backing JSON data structure + * @arg theName name of a JSON entry ; It must map another JSONObject. + * @arg theType the expected wrapping catalog artifact type + * @return the JSON entry wrapped in the specified type + */ + default <E extends Element<E>> E element(String theName, Class<E> theType) { + JSONObject elemData = data().optJSONObject(theName); + if (elemData == null) { + return null; + } + else { + return catalog().proxy(elemData, theType); + } + } + + /* Similar to {@link #element(String,Class)} but for collection wrapping. */ + default <E extends Elements> E elements(String theName, Class<E> theType) { + JSONArray elemsData = data().optJSONArray(theName); + if (elemsData == null) { + return null; + } + else { + Class etype = Proxies.typeArgument(theType); + Elements elems; + try { + elems = theType.newInstance(); + } + catch (ReflectiveOperationException rox) { + throw new RuntimeException("Failed to instantiate " + theType, rox); + } + + try{ + for (Iterator i = elemsData.iterator(); i.hasNext();) { + JSONObject elemData = (JSONObject)i.next(); + elems.add(catalog().proxy(elemData, etype)); + } + } + catch(Exception e){ + throw new RuntimeException("Failed to fetch json data ", e); + } + return (E)elems; + } + } + } + + /* Base class for all collections of elements. */ + class Elements<T extends Element> + extends LinkedList<T> { + @Override + public String toString() { + StringBuilder sb = new StringBuilder("["); + for (Element el: this) { + sb.append(el.selfClass().getSimpleName()) + .append("(") + .append(el.data()) + .append("),"); + } + sb.append("]"); + return sb.toString(); + } + } + + /* + * We need this contraption in order to store a mix of Folders and CatalogItem + * instances (Elements in self is not good because it is defined around a + * type variable so we cannot use reflection to determine the type at runtime + * - generics are resolved compile time) + */ + class Mixels extends Elements<Element> {} + + interface Item<T extends Item<T>> extends Element<T> { + String name(); + String description(); + } + + /* + * Collection of catalog items. + */ + class Items extends Elements<Item> {} + + interface Folder extends Element<Folder> { + + String name(); + + String description(); + + String itemId(); + + default Future<Items> items() { + Items i = elements("items", Items.class); + if (i != null) { + return Futures.succeededFuture(i); + } + else { + return Futures.advance(catalog().folder(itemId()) + .withItems() + .execute(), + folder -> folder.elements("items", Items.class)); + } + } } - } - public static class Annotations extends Elements<Annotation> { + class Folders extends Elements<Folder> {} + + //no predefined properties here + interface Annotation extends Element<Annotation> {} + + class Annotations extends Elements<Annotation> { } - /** - * A TOSCA teamplate. - * When a deep loading method is used to obtain a Template its collection - * of inputs and nodes will be immediately available (and 'cached' within - * the backing JSON object). It can be retrieved through a call to - * {@link Element#elements(String,Class)} as in: - * elements("inputs", Inputs.class) - * or - * elements("nodes", Nodes.class) - * - * The same result will be obtained through one of the methods of the - * navigation interface, {@link #inputs()} or {@link #nodes()}; in this case - * the result does not become part of the backing JSONObject. - */ - public static interface Template extends Element<Template> { - - public String name(); - - public String version(); - - public String description(); - - } - - /** - * Collection of {@link Catalog.Template template} instances. - */ - public static class Templates extends Elements<Template> { - } - - - /** - * A TOSCA type declaration. - */ - public interface Type extends Element<Type> { - - public String name(); - - /** - * Allows navigation to the parent {@link Catalog.Type type}, if any. - */ - public Future<Type> derivedfrom(); - - } - - /** - * Collection of {@link Catalog.Type type} instances. - */ - public static class Types extends Elements<Type> { - } - - - public static interface TemplateAction extends Action<Template> { - - public TemplateAction withInputs(); - - public TemplateAction withOutputs(); - - public TemplateAction withNodes(); - - public TemplateAction withNodeProperties(); - - public TemplateAction withNodeRequirements(); - - public TemplateAction withNodePropertiesAssignments(); - - public TemplateAction withNodeCapabilities(); - - public TemplateAction withNodeCapabilityProperties(); - - public TemplateAction withNodeCapabilityPropertyAssignments(); - - public TemplateAction withPolicies(); - - public TemplateAction withPolicyProperties(); - - public TemplateAction withPolicyPropertiesAssignments(); - - @Override - public Future<Template> execute(); - - } - - /* - */ - public static interface TypeAction extends Action<Type> { - - public TypeAction withHierarchy(); - - public TypeAction withRequirements(); - - public TypeAction withCapabilities(); - - @Override - public Future<Type> execute(); - - } - - /* - */ - public static interface FolderAction extends Action<Folder> { - - public FolderAction withAnnotations(); - - public FolderAction withAnnotations(String theSelector); - - public FolderAction withItems(); - - public FolderAction withItemAnnotations(); - - public FolderAction withItemAnnotations(String theSelector); + /** + * A TOSCA teamplate. + * When a deep loading method is used to obtain a Template its collection + * of inputs and nodes will be immediately available (and 'cached' within + * the backing JSON object). It can be retrieved through a call to + * {@link Element#elements(String,Class)} as in: + * elements("inputs", Inputs.class) + * or + * elements("nodes", Nodes.class) + * + * The same result will be obtained through one of the methods of the + * navigation interface. in this case + * the result does not become part of the backing JSONObject. + */ + interface Template extends Element<Template> { + String name(); + + String version(); + + String description(); + } + + /** + * Collection of {@link Catalog.Template template} instances. + */ + class Templates extends Elements<Template> { + } + + + /** + * A TOSCA type declaration. + */ + interface Type extends Element<Type> { + String name(); + } + + /** + * Collection of {@link Catalog.Type type} instances. + */ + class Types extends Elements<Type> { + } + - public FolderAction withItemModels(); + interface TemplateAction extends Action<Template> { - public FolderAction withParts(); - - public FolderAction withPartAnnotations(); + TemplateAction withInputs(); - public FolderAction withPartAnnotations(String theSelector); + TemplateAction withOutputs(); - @Override - public Future<Folder> execute(); - } - - /* - */ - public static interface ItemAction<T extends Item> extends Action<T> { + TemplateAction withNodes(); - public ItemAction<T> withModels(); + TemplateAction withNodeProperties(); - public ItemAction<T> withAnnotations(); - - @Override - public Future<T> execute(); + TemplateAction withNodeRequirements(); - } + TemplateAction withNodePropertiesAssignments(); - /** - */ - public abstract Future<Folders> roots(); + TemplateAction withNodeCapabilities(); - /** - */ - public abstract Future<Folders> rootsByLabel(String theLabel); + TemplateAction withNodeCapabilityProperties(); - /** - */ - public abstract Future<Mixels> lookup(JSONObject theSelector); - - public abstract Future<Mixels> lookup(String theAnnotation, JSONObject theSelector); - - /** - */ - public abstract FolderAction folder(String theFolderId); + TemplateAction withNodeCapabilityPropertyAssignments(); - /** - */ - public abstract <T extends Item> ItemAction<T> item(String theItemId); + TemplateAction withPolicies(); + + TemplateAction withPolicyProperties(); + + TemplateAction withPolicyPropertiesAssignments(); + + @Override + Future<Template> execute(); + } + + interface TypeAction extends Action<Type> { + + TypeAction withHierarchy(); + + TypeAction withRequirements(); + + TypeAction withCapabilities(); + + @Override + Future<Type> execute(); + } + + interface FolderAction extends Action<Folder> { + + FolderAction withItems(); + + FolderAction withItemAnnotations(); + + FolderAction withItemModels(); + + FolderAction withParts(); + + FolderAction withPartAnnotations(); + + @Override + Future<Folder> execute(); + } + + interface ItemAction<T extends Item> extends Action<T> { + + ItemAction<T> withModels(); + + @Override + Future<T> execute(); + + } - /** - */ - public abstract TemplateAction template(String theTemplateId); + Future<Folders> rootsByLabel(String theLabel); - /** - */ - public abstract TypeAction type(String theNamespace, String theTypeName); + FolderAction folder(String theFolderId); + <T extends Item> ItemAction<T> item(String theItemId); + TemplateAction template(String theTemplateId); + TypeAction type(String theNamespace, String theTypeName); } diff --git a/dcaedt_catalog/api/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCCatalog.java b/dcaedt_catalog/api/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCCatalog.java index e08f3a6..dfbaeaa 100644 --- a/dcaedt_catalog/api/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCCatalog.java +++ b/dcaedt_catalog/api/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCCatalog.java @@ -22,6 +22,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; +@SuppressWarnings("ALL") public class ASDCCatalog implements Catalog { private @@ -87,10 +88,10 @@ public class ASDCCatalog implements Catalog { private String[] folderFields = new String[] {ID, ITEM_ID, NAME}; private ProxyBuilder proxies; - private Map<Target, JXPathContext> contexts = new HashMap<Target, JXPathContext>(); + private Map<Target, JXPathContext> contexts = new HashMap<>(); // resource and its catalog - private Map<UUID, org.onap.sdc.dcae.checker.Catalog> catalogs = new HashMap<UUID, org.onap.sdc.dcae.checker.Catalog>(); + private Map<UUID, org.onap.sdc.dcae.checker.Catalog> catalogs = new HashMap<>(); public ASDCCatalog(URI theURI) { @@ -171,7 +172,6 @@ public class ASDCCatalog implements Catalog { return Futures.succeededFuture(roots); } - /** */ public Future<Mixels> lookup(JSONObject theSelector) { return Futures.succeededFuture(new Mixels()); } @@ -180,66 +180,48 @@ public class ASDCCatalog implements Catalog { return Futures.succeededFuture(new Mixels()); } - /** */ public ItemAction item(String theItemId) { return new ResourceAction(UUID.fromString(theItemId)); } - /** */ - public FolderAction folder(String theFolderId) { - return new FolderAction(theFolderId); - } - - public TemplateAction template(String theId) { - return new TemplateAction(theId); + public CatalogFolderAction folder(String theFolderId) { + return new CatalogFolderAction(theFolderId); } - public TypeAction type(String theItemId, String theName) { - return new TypeAction(UUID.fromString(theItemId), theName); + public CatalogTemplateAction template(String theId) { + return new CatalogTemplateAction(theId); } - protected static String resolveTargetName(Target theTarget) { - return (String) ((Map) ((Map) theTarget.getTarget()).get("metadata")).get("template_name"); + public CatalogTypeAction type(String theItemId, String theName) { + return new CatalogTypeAction(UUID.fromString(theItemId), theName); } - protected Object resolve(Target theTarget, String thePath) { + private Object resolve(Target theTarget, String thePath) { try { return contexts.get(theTarget).getValue(thePath); } catch (JXPathNotFoundException pnfx) { - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "JXPathNotFoundException {}", pnfx); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), JXPATH_NOT_FOUND_EXCEPTION, pnfx); return null; } } // covers common TOSCA pattern of single entry maps - public Map.Entry<String, Map> toEntry(Object theValue) { + private Map.Entry<String, Map> toEntry(Object theValue) { return (Map.Entry<String, Map>) ((Map) theValue).entrySet().iterator().next(); } - protected Map selectEntries(Map theOriginal, String... theKeys) { + private Map selectEntries(Map theOriginal, String... theKeys) { Arrays.sort(theKeys); - Map selection = ((Set<Map.Entry>) theOriginal.entrySet()).stream() + return ((Set<Map.Entry>) theOriginal.entrySet()).stream() .filter(e -> Arrays.binarySearch(theKeys, e.getKey().toString()) >= 0) .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); - return selection; } - protected Map evictEntries(Map theOriginal, String... theKeys) { + private Map evictEntries(Map theOriginal, String... theKeys) { Arrays.sort(theKeys); - Map selection = ((Set<Map.Entry>) theOriginal.entrySet()).stream() + return ((Set<Map.Entry>) theOriginal.entrySet()).stream() .filter(e -> Arrays.binarySearch(theKeys, e.getKey().toString()) < 0) .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); - return selection; - } - - protected MapBuilder renderEntry(Map.Entry theEntry, String... theKeys) { - MapBuilder out = new MapBuilder(); - out.put(NAME, theEntry.getKey()); - - for (String key : theKeys) { - out.put(key, ((Map) theEntry.getValue()).get(key)); - } - return out; } protected <T> Stream<T> stream(Iterator<T> theSource) { @@ -277,18 +259,17 @@ public class ASDCCatalog implements Catalog { } private static void dumpTargets(String theDirName, Collection<Target> theTargets) { - try { - File targetDir = new File(theDirName); - if (!targetDir.exists() && !targetDir.mkdirs()) { - throw new IllegalStateException("Couldn't create dir: " + theDirName); - } - for (Target t : theTargets) { - FileWriter dump = new FileWriter(new File(theDirName, t.getName())); + File targetDir = new File(theDirName); + if (!targetDir.exists() && !targetDir.mkdirs()) { + throw new IllegalStateException("Couldn't create dir: " + theDirName); + } + for (Target t : theTargets) { + try (FileWriter dump = new FileWriter(new File(theDirName, t.getName()))) { IOUtils.copy(t.open(), dump); dump.close(); + } catch (IOException e) { + debugLogger.log(LogLevel.DEBUG, "ASDCCatalog", "IOException {}", e); } - } catch (IOException iox) { - debugLogger.log(LogLevel.DEBUG,"ASDCCatalog", "IOException {}", iox); } } @@ -365,50 +346,50 @@ public class ASDCCatalog implements Catalog { } } - public class FolderAction implements Catalog.FolderAction { + public class CatalogFolderAction implements Catalog.FolderAction { private boolean doItemModels; private String folderName; // use the id/UUID of the folder ?? - private FolderAction(String theFolderName) { + private CatalogFolderAction(String theFolderName) { this.folderName = theFolderName; } - public FolderAction withAnnotations() { + public CatalogFolderAction withAnnotations() { return this; } - public FolderAction withAnnotations(String theSelector) { + public CatalogFolderAction withAnnotations(String theSelector) { return this; } - public FolderAction withItems() { + public CatalogFolderAction withItems() { return this; } - public FolderAction withItemAnnotations() { + public CatalogFolderAction withItemAnnotations() { return this; } - public FolderAction withItemAnnotations(String theSelector) { + public CatalogFolderAction withItemAnnotations(String theSelector) { return this; } - public FolderAction withItemModels() { + public CatalogFolderAction withItemModels() { doItemModels = true; return this; } - public FolderAction withParts() { + public CatalogFolderAction withParts() { return this; } - public FolderAction withPartAnnotations() { + public CatalogFolderAction withPartAnnotations() { return this; } - public FolderAction withPartAnnotations(String theSelector) { + public CatalogFolderAction withPartAnnotations(String theSelector) { return this; } @@ -425,7 +406,7 @@ public class ASDCCatalog implements Catalog { return Futures.advance(asdc.getResources(JSONArray.class, "DCAE Component", this.folderName), resourcesData -> { - Actions.CompoundAction<Resource> itemsAction = new Actions.BasicCompoundAction<Resource>(); + Actions.CompoundAction<Resource> itemsAction = new Actions.BasicCompoundAction<>(); for (int i = 0; i < resourcesData.length(); i++) { JSONObject resource = resourcesData.getJSONObject(i); @@ -453,7 +434,7 @@ public class ASDCCatalog implements Catalog { }, resourcesError -> new RuntimeException("Failed to retrieve resources", resourcesError)); } - public Collection<Resource> filterLatestVersion(Collection<Resource> items) throws IllegalArgumentException { + public Collection<Resource> filterLatestVersion(Collection<Resource> items) { if (items == null) { throw new IllegalArgumentException("null is not acceptable as a list of items"); } @@ -475,7 +456,7 @@ public class ASDCCatalog implements Catalog { } /** */ - public class TemplateAction implements Catalog.TemplateAction { + public class CatalogTemplateAction implements Catalog.TemplateAction { private String artifactId; private Target target; @@ -485,32 +466,28 @@ public class ASDCCatalog implements Catalog { private boolean doNodes, doNodeProperties, doNodePropertiesAssignments, doNodeRequirements, doNodeCapabilities, doNodeCapabilityProperties, doNodeCapabilityPropertyAssignments; - protected TemplateAction(Target theTarget) { - this.target = theTarget; - } - /* * expected to be the relative url provided by asdc for the template * artifact */ - protected TemplateAction(String theArtifactId) { + CatalogTemplateAction(String theArtifactId) { this.artifactId = theArtifactId; } - public TemplateAction withInputs() { + public CatalogTemplateAction withInputs() { return this; } - public TemplateAction withOutputs() { + public CatalogTemplateAction withOutputs() { return this; } - public TemplateAction withNodes() { + public CatalogTemplateAction withNodes() { this.doNodes = true; return this; } - protected TemplateAction doNodes() { + CatalogTemplateAction doNodes() { if (!this.doNodes) { return this; } @@ -531,12 +508,12 @@ public class ASDCCatalog implements Catalog { } // pre-requisite: a call to 'withNodes' - public TemplateAction withNodeProperties() { + public CatalogTemplateAction withNodeProperties() { this.doNodeProperties = true; return this; } - protected TemplateAction doNodeProperties() { + protected CatalogTemplateAction doNodeProperties() { if (!this.doNodeProperties) { return this; } @@ -558,12 +535,12 @@ public class ASDCCatalog implements Catalog { } // pre-requisite: a call to 'withNodesProperties' - public TemplateAction withNodePropertiesAssignments() { + public CatalogTemplateAction withNodePropertiesAssignments() { this.doNodePropertiesAssignments = true; return this; } - protected TemplateAction doNodePropertiesAssignments() { + CatalogTemplateAction doNodePropertiesAssignments() { if (!this.doNodePropertiesAssignments) { return this; } @@ -573,8 +550,8 @@ public class ASDCCatalog implements Catalog { return this; } - nodes.entrySet().stream().forEach(node -> { - List nodeProps = null; + nodes.entrySet().forEach(node -> { + List nodeProps; try { nodeProps = (List) ctx.getValue(NODES_NAME + ((Map.Entry) node).getKey() + PROPERTIES); } catch (JXPathNotFoundException pnfx) { @@ -582,7 +559,7 @@ public class ASDCCatalog implements Catalog { return; } - nodeProps.stream().forEach(prop -> { + nodeProps.forEach(prop -> { // pick from String propPath = TOPOLOGY_TEMPLATE_NODE_TEMPLATES1 + ((Map.Entry) node).getKey() + "/properties/" + ((Map) prop).get(NAME); @@ -602,7 +579,7 @@ public class ASDCCatalog implements Catalog { return this; } - protected Map renderRequirementDefinition(Map.Entry theReq) { + Map renderRequirementDefinition(Map.Entry theReq) { Map def = (Map) theReq.getValue(); return new MapBuilder().put(NAME, theReq.getKey()) // capability must be present @@ -613,7 +590,7 @@ public class ASDCCatalog implements Catalog { } // TODO: see how this comes out of neo and match it - protected Map renderRequirementAssignment(Map.Entry theReq) { + Map renderRequirementAssignment(Map.Entry theReq) { Map def = (Map) theReq.getValue(); return new MapBuilder().put(NAME, theReq.getKey()) // capability must be present @@ -628,12 +605,12 @@ public class ASDCCatalog implements Catalog { .putAll(evictEntries(def, CAPABILITY)).build(); } - public TemplateAction withNodeRequirements() { + public CatalogTemplateAction withNodeRequirements() { this.doNodeRequirements = true; return this; } - TemplateAction doNodeRequirements() { + CatalogTemplateAction doNodeRequirements() { if (!this.doNodeRequirements) { return this; } @@ -647,7 +624,7 @@ public class ASDCCatalog implements Catalog { } // type - nodes.entrySet().stream() + nodes.entrySet() .forEach( node -> ctx .setValue( @@ -666,13 +643,13 @@ public class ASDCCatalog implements Catalog { .collect(Collectors.toList()))); // merge assignments on top of definitions - nodes.entrySet().stream().forEach(node -> { + nodes.entrySet().forEach(node -> { List nodeReqsAssigns = (List) resolve(this.target, TOPOLOGY_TEMPLATE_NODE_TEMPLATES1 + ((Map.Entry) node).getKey() + "/requirements"); if (nodeReqsAssigns == null) { return; } - nodeReqsAssigns.stream().forEach(req -> { + nodeReqsAssigns.forEach(req -> { Map.Entry reqAssign = toEntry(req); catalog.mergeDefinitions((Map) ctx.getValue(NODES_NAME + ((Map.Entry) node).getKey() + "']/requirements[name='" + reqAssign.getKey() + "']"), @@ -683,12 +660,12 @@ public class ASDCCatalog implements Catalog { return this; } - public TemplateAction withNodeCapabilities() { + public CatalogTemplateAction withNodeCapabilities() { this.doNodeCapabilities = true; return this; } - protected Map renderCapabilityDefinition(Map.Entry theCap) { + Map renderCapabilityDefinition(Map.Entry theCap) { Map def = (Map) theCap.getValue(); return new MapBuilder().put(NAME, theCap.getKey()) .put("type", @@ -697,7 +674,7 @@ public class ASDCCatalog implements Catalog { .putAll(evictEntries(def, "properties", "type")).build(); } - TemplateAction doNodeCapabilities() { + CatalogTemplateAction doNodeCapabilities() { if (!this.doNodeCapabilities) { return this; } @@ -718,18 +695,18 @@ public class ASDCCatalog implements Catalog { stream(catalog.facets(Construct.Node, Facet.capabilities, ((Map) ((Map.Entry) node).getValue()).get("type").toString())) - .map((Map.Entry capEntry) -> renderCapabilityDefinition(capEntry)) + .map(this::renderCapabilityDefinition) .collect(Collectors.toList()))); return this; } - public TemplateAction withNodeCapabilityProperties() { + public CatalogTemplateAction withNodeCapabilityProperties() { this.doNodeCapabilityProperties = true; return this; } - TemplateAction doNodeCapabilityProperties() { + CatalogTemplateAction doNodeCapabilityProperties() { if (!this.doNodeCapabilityProperties) { return this; @@ -742,7 +719,7 @@ public class ASDCCatalog implements Catalog { // pick up all the properties from the capability type hierarchy // definition - nodes.entrySet().stream().forEach(node -> { + nodes.entrySet().forEach(node -> { List nodeCapabilities = (List) ctx .getValue(NODES_NAME + ((Map.Entry) node).getKey() + CAPABILITIES); if (nodeCapabilities == null) { @@ -750,7 +727,7 @@ public class ASDCCatalog implements Catalog { } // collect properties from the capability type hierarchy - nodeCapabilities.stream().forEach(capability -> { + nodeCapabilities.forEach(capability -> { List capabilityProperties = StreamSupport .stream(Spliterators.spliteratorUnknownSize( catalog.facets(Construct.Capability, Facet.properties, @@ -781,7 +758,7 @@ public class ASDCCatalog implements Catalog { return; } - properties.entrySet().stream().forEach(property -> { + properties.entrySet().forEach(property -> { String propertyLoc = NODES_NAME + ((Map.Entry) node).getKey() + CAPABILITIES_NAME + ((Map) capability).get(NAME) + PROPERTIES_NAME + ((Map.Entry) property).getKey() + "']"; @@ -794,12 +771,12 @@ public class ASDCCatalog implements Catalog { return this; } - public TemplateAction withNodeCapabilityPropertyAssignments() { + public CatalogTemplateAction withNodeCapabilityPropertyAssignments() { this.doNodeCapabilityPropertyAssignments = true; return this; } - TemplateAction doNodeCapabilityPropertyAssignments() { + CatalogTemplateAction doNodeCapabilityPropertyAssignments() { if (!this.doNodeCapabilityPropertyAssignments) { return this; } @@ -818,14 +795,14 @@ public class ASDCCatalog implements Catalog { return this; } - nodes.stream().forEach(node -> { + nodes.forEach(node -> { List capabilities = (List) ctx.getValue(NODES_NAME + ((Map) node).get(NAME) + CAPABILITIES); if (capabilities == null) { return; } - capabilities.stream().forEach(capability -> { - List properties = null; + capabilities.forEach(capability -> { + List properties; try { properties = (List) ctx.getValue(NODES_NAME + ((Map) node).get(NAME) + CAPABILITIES_NAME + ((Map) capability).get(NAME) + PROPERTIES); @@ -834,7 +811,7 @@ public class ASDCCatalog implements Catalog { return; } - properties.stream().forEach(property -> { + properties.forEach(property -> { String location = NODES_NAME + ((Map) node).get(NAME) + CAPABILITIES_NAME + ((Map) capability).get(NAME) + PROPERTIES_NAME + ((Map) property).get(NAME) + "']/assignment"; @@ -859,15 +836,15 @@ public class ASDCCatalog implements Catalog { return this; } - public TemplateAction withPolicies() { + public CatalogTemplateAction withPolicies() { return this; } - public TemplateAction withPolicyProperties() { + public CatalogTemplateAction withPolicyProperties() { return this; } - public TemplateAction withPolicyPropertiesAssignments() { + public CatalogTemplateAction withPolicyPropertiesAssignments() { return this; } @@ -913,7 +890,7 @@ public class ASDCCatalog implements Catalog { this.catalog = checker.catalog(); ASDCCatalog.this.catalogs.put(resourceId, this.catalog); // we should only be doing this if we discovered an update - // (by checking timestampts). Actually, we should + // (by checking timestamps). Actually, we should // only do the artifact fetching if we detect an update ASDCCatalog.this.contexts.put(template, JXPathContext.newContext(template.getTarget())); } catch (Exception x) { @@ -924,7 +901,7 @@ public class ASDCCatalog implements Catalog { this.doNodes().doNodeProperties().doNodePropertiesAssignments().doNodeRequirements().doNodeCapabilities() .doNodeCapabilityProperties().doNodeCapabilityPropertyAssignments(); - JSONObject pack = new JSONObject((Map) ctx.getContextBean()).put(NAME, this.target.getName().toString()) + JSONObject pack = new JSONObject((Map) ctx.getContextBean()).put(NAME, this.target.getName()) .put(ID, this.target.getLocation().toString()) .put(ITEM_ID, this.target.getLocation().toString()); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), pack.toString(2)); @@ -933,7 +910,7 @@ public class ASDCCatalog implements Catalog { } } - public class TypeAction implements Catalog.TypeAction { + public class CatalogTypeAction implements Catalog.TypeAction { private String name; private UUID resourceId; @@ -941,17 +918,17 @@ public class ASDCCatalog implements Catalog { private boolean doHierarchy = false, doRequirements = false, doCapabilities = false; - private TypeAction(UUID theResourceId, /* Construct theConstruct, */ String theName) { + private CatalogTypeAction(UUID theResourceId, /* Construct theConstruct, */ String theName) { this.resourceId = theResourceId; this.name = theName; } - public TypeAction withHierarchy() { + public CatalogTypeAction withHierarchy() { this.doHierarchy = true; return this; } - TypeAction doHierarchy(org.onap.sdc.dcae.checker.Catalog theCatalog) { + CatalogTypeAction doHierarchy(org.onap.sdc.dcae.checker.Catalog theCatalog) { if (!this.doHierarchy) { return this; } @@ -968,12 +945,12 @@ public class ASDCCatalog implements Catalog { return this; } - public TypeAction withRequirements() { + public CatalogTypeAction withRequirements() { this.doRequirements = true; return this; } - TypeAction doRequirements(org.onap.sdc.dcae.checker.Catalog theCatalog) { + CatalogTypeAction doRequirements(org.onap.sdc.dcae.checker.Catalog theCatalog) { if (!this.doRequirements) { return this; } @@ -991,7 +968,7 @@ public class ASDCCatalog implements Catalog { // (within a node type) .put(ID, getCatalog(resourceId).hasType(Construct.Capability, capability) - ? (resourceId + "/" + capability) : capability.toString()) + ? (resourceId + "/" + capability) : capability) .build()) .put("node", new MapBuilder().putOpt(NAME, node).putOpt(ID, node == null ? null : (resourceId + "/" + node)).buildOpt()) @@ -1004,12 +981,12 @@ public class ASDCCatalog implements Catalog { return this; } - public TypeAction withCapabilities() { + public CatalogTypeAction withCapabilities() { this.doCapabilities = true; return this; } - TypeAction doCapabilities(org.onap.sdc.dcae.checker.Catalog theCatalog) { + CatalogTypeAction doCapabilities(org.onap.sdc.dcae.checker.Catalog theCatalog) { if (!this.doCapabilities) { return this; } @@ -1065,7 +1042,7 @@ public class ASDCCatalog implements Catalog { } } - public static interface Resource extends Catalog.Item<Resource> { + public interface Resource extends Catalog.Item<Resource> { @Override @Proxy.DataMap(map = "uuid") @@ -1091,22 +1068,22 @@ public class ASDCCatalog implements Catalog { public static class Resources extends Elements<Resource> { } - public static interface Artifact extends Catalog.Element<Artifact> { + public interface Artifact extends Catalog.Element<Artifact> { @Proxy.DataMap(map = ARTIFACT_NAME) - public String name(); + String name(); @Proxy.DataMap(map = "artifactType") - public String type(); + String type(); @Proxy.DataMap(map = "artifactDescription") - public String description(); + String description(); @Proxy.DataMap(map = "artifactUUID") - public UUID uuid(); + UUID uuid(); @Proxy.DataMap(map = "artifactVersion") - public int version(); + int version(); } @@ -1150,7 +1127,7 @@ public class ASDCCatalog implements Catalog { return null; } - ASDCTarget target = null; + ASDCTarget target; if (this.catalog != null) { // this is the caching!! target = (ASDCTarget) this.catalog.getTarget(ASDCCatalog.this.getArtifactURI(targetArtifact)); @@ -1210,16 +1187,20 @@ public class ASDCCatalog implements Catalog { Resources items = f.elements(ITEMS, Resources.class); if (items != null) { for (Resource item : items) { - debugLogger.log(LogLevel.DEBUG, ASDCCatalog.class.getName(), "\titem: {} : {}",item.name(), item.data()); - Templates templates = item.elements(MODELS, Templates.class); - if (templates != null) { - for (Template t : templates) { - Template ft = catalog.template(t.id()).withNodes().withNodeProperties() - .withNodePropertiesAssignments().execute().waitForResult(); - - debugLogger.log(LogLevel.DEBUG, ASDCCatalog.class.getName(), "template data: {}", ft.data()); - } - } + executeItemsNodePropertiesAssignments(catalog, item); + } + } + } + + private static void executeItemsNodePropertiesAssignments(ASDCCatalog catalog, Resource item) throws Exception { + debugLogger.log(LogLevel.DEBUG, ASDCCatalog.class.getName(), "\titem: {} : {}",item.name(), item.data()); + Templates templates = item.elements(MODELS, Templates.class); + if (templates != null) { + for (Template t : templates) { + Template ft = catalog.template(t.id()).withNodes().withNodeProperties() + .withNodePropertiesAssignments().execute().waitForResult(); + + debugLogger.log(LogLevel.DEBUG, ASDCCatalog.class.getName(), "template data: {}", ft.data()); } } } diff --git a/dcaedt_catalog/api/src/test/java/org/onap/sdc/dcae/catalog/ASDCCatalogTest.java b/dcaedt_catalog/api/src/test/java/org/onap/sdc/dcae/catalog/ASDCCatalogTest.java index fcd92f0..360b76d 100644 --- a/dcaedt_catalog/api/src/test/java/org/onap/sdc/dcae/catalog/ASDCCatalogTest.java +++ b/dcaedt_catalog/api/src/test/java/org/onap/sdc/dcae/catalog/ASDCCatalogTest.java @@ -12,7 +12,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.onap.sdc.dcae.catalog.asdc.ASDCCatalog; -import org.onap.sdc.dcae.catalog.asdc.ASDCCatalog.FolderAction; +import org.onap.sdc.dcae.catalog.asdc.ASDCCatalog.CatalogFolderAction; import org.onap.sdc.dcae.catalog.asdc.ASDCCatalog.Resource; import static org.mockito.Mockito.*; @@ -23,17 +23,17 @@ public class ASDCCatalogTest { @Rule public ExpectedException thrown = ExpectedException.none(); - private static FolderAction getTarget() { + private static CatalogFolderAction getTarget() { ASDCCatalog catalog = mock(ASDCCatalog.class); when(catalog.folder("test")).thenCallRealMethod(); - FolderAction target = catalog.folder("test"); + CatalogFolderAction target = catalog.folder("test"); return target; } @Test public void filterLatestVersion_null_throwIllegalArgumentException() { // arrange - FolderAction target = getTarget(); + CatalogFolderAction target = getTarget(); // assert thrown.expect(IllegalArgumentException.class); // act @@ -43,7 +43,7 @@ public class ASDCCatalogTest { @Test public void filterLatestVersion_emptyItemsList_emptyItemsList() throws URISyntaxException { // arrange - FolderAction target = getTarget(); + CatalogFolderAction target = getTarget(); // act Collection<Resource> result = target.filterLatestVersion(new ArrayList<>()); // assert @@ -53,7 +53,7 @@ public class ASDCCatalogTest { @Test public void filterLatestVersion_itemWithTwoVersions_itemWithLatestVersion() { // arrange - FolderAction target = getTarget(); + CatalogFolderAction target = getTarget(); UUID invariantUUID = UUID.randomUUID(); Resource r1v1 = mock(Resource.class); @@ -72,7 +72,7 @@ public class ASDCCatalogTest { @Test public void filterLatestVersion_2distinctItems_2distinctItems() { // arrange - FolderAction target = getTarget(); + CatalogFolderAction target = getTarget(); Resource r1 = mock(Resource.class); Resource r2 = mock(Resource.class); diff --git a/dcaedt_catalog/asdc/pom.xml b/dcaedt_catalog/asdc/pom.xml index abaff6a..635868e 100644 --- a/dcaedt_catalog/asdc/pom.xml +++ b/dcaedt_catalog/asdc/pom.xml @@ -125,5 +125,10 @@ <artifactId>assertj-core</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> </dependencies> </project> diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDC.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDC.java index 66afab1..08383ea 100644 --- a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDC.java +++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDC.java @@ -38,13 +38,11 @@ import org.springframework.web.client.HttpClientErrorException; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.util.Base64Utils; -//import org.springframework.util.DigestUtils; import org.apache.commons.codec.digest.DigestUtils; import org.springframework.stereotype.Component; import org.springframework.context.annotation.Scope; import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFutureCallback; @@ -57,8 +55,6 @@ import org.onap.sdc.dcae.catalog.commons.Action; import org.onap.sdc.dcae.catalog.commons.Future; import org.onap.sdc.dcae.catalog.commons.Futures; import org.onap.sdc.dcae.catalog.commons.JSONHttpMessageConverter; -import org.onap.sdc.dcae.composition.util.DcaeBeConstants; -import org.onap.sdc.dcae.composition.util.SystemProperties; import org.json.JSONArray; import org.apache.commons.cli.BasicParser; @@ -69,82 +65,68 @@ import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; - @Component("asdc") @Scope("singleton") -//@ConfigurationProperties(prefix="asdc") public class ASDC { - public static enum AssetType { + private static final String TARGET = "target"; + private static final String ACTION = "action"; + private static final String ASSET_TYPE = "assetType"; + private static final String USER_ID = "USER_ID"; + public static final String ASSET_ID = "assetId"; + public static final String ARTIFACT_ID = "artifactId"; + public static final String LIST_FILTER = "listFilter"; + + public enum AssetType { resource, service, product } -// public static enum ArtifactType { -// DCAE_TOSCA, -// DCAE_JSON, -// DCAE_POLICY, -// DCAE_DOC, -// DCAE_EVENT, -// DCAE_INVENTORY_TOSCA, -// DCAE_INVENTORY_JSON, -// DCAE_INVENTORY_POLICY, -// DCAE_INVENTORY_DOC, -// DCAE_INVENTORY_BLUEPRINT, -// DCAE_INVENTORY_EVENT, -// HEAT, -// HEAT_VOL, -// HEAT_NET, -// HEAT_NESTED, -// HEAT_ARTIFACT, -// HEAT_ENV, -// OTHER -// } - -// public static enum ArtifactGroupType { -// DEPLOYMENT, -// INFORMATIONAL -// } - - public static enum LifecycleState { + public enum LifecycleState { Checkin, Checkout, Certify, undocheckout } - -// @Retention(RetentionPolicy.RUNTIME) -// @Target(ElementType.METHOD) -// public @interface Mandatory { -// } protected static OnapLoggerError errLogger = OnapLoggerError.getInstance(); protected static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); - - @Autowired - private SystemProperties systemProperties; - private URI rootUri; - private String rootPath = "/sdc/v1/catalog/"; - private String user, - passwd; - private String instanceId; + private static final String ARTIFACT_TYPE = "artifactType"; + private static final String ARTIFACT_GROUP_TYPE = "artifactGroupType"; + private static final String ARTIFACT_LABEL = "artifactLabel"; + private static final String ARTIFACT_NAME = "artifactName"; + private static final String DESCRIPTION = "description"; + private static final String PAYLOAD_DATA = "payloadData"; + + private static final String[] artifactMandatoryEntries = new String[] {}; + + private static final String[] updateMandatoryEntries = new String[] {ARTIFACT_NAME, + ARTIFACT_TYPE, ARTIFACT_GROUP_TYPE, ARTIFACT_LABEL, DESCRIPTION, PAYLOAD_DATA}; + + private static final String[] uploadMandatoryEntries = new String[] {ARTIFACT_NAME, + ARTIFACT_TYPE, ARTIFACT_GROUP_TYPE, ARTIFACT_LABEL, DESCRIPTION, PAYLOAD_DATA}; + private URI rootUri; + private String rootPath = "/sdc/v1/catalog/"; + private String user, passwd; + private String instanceId; public void setUri(URI theUri) { - //theUri = URI.create(systemProperties.getProperties().getProperty(SystemProperties.ASDC_CATALOG_URL)); String userInfo = theUri.getUserInfo(); if (userInfo != null) { String[] userInfoParts = userInfo.split(":"); setUser(userInfoParts[0]); - if (userInfoParts.length > 1) + if (userInfoParts.length > 1) { setPassword(userInfoParts[1]); + } } String fragment = theUri.getFragment(); - if (fragment == null) + if (fragment == null) { throw new IllegalArgumentException("The URI must contain a fragment specification, to be used as ASDC instance id"); + } setInstanceId(fragment); try { @@ -179,24 +161,14 @@ public class ASDC { this.instanceId = theId; } - public String getInstanceId() { - return this.instanceId; - } - - public void setRootPath(String thePath) { - this.rootPath = systemProperties.getProperties().getProperty(DcaeBeConstants.Config.ASDC_ROOTPATH); - } - - public String getRootPath() { - return systemProperties.getProperties().getProperty(DcaeBeConstants.Config.ASDC_ROOTPATH); - } - @Scheduled(fixedRateString = "${beans.context.scripts.updateCheckFrequency?:60000}") - public void checkForUpdates() { + public void checkForUpdates() { + // ffu } @PostConstruct public void initASDC() { + // ffu } public <T> Future<T> getResources(Class<T> theType) { @@ -236,7 +208,7 @@ public class ASDC { } public <T> Action<T> getAssetsAction(AssetType theAssetType, Class<T> theType) { - return (() -> fetch(refAssets(theAssetType), theType)); + return () -> fetch(refAssets(theAssetType), theType); } public <T> Future<T> getAssets(AssetType theAssetType, Class<T> theType, @@ -251,7 +223,7 @@ public class ASDC { public <T> Action<T> getAssetsAction(AssetType theAssetType, Class<T> theType, String theCategory, String theSubCategory, String theResourceType) { - return (() -> fetch(refAssets(theAssetType) + filter(theCategory, theSubCategory, theResourceType), theType)); + return () -> fetch(refAssets(theAssetType) + filter(theCategory, theSubCategory, theResourceType), theType); } protected String refAssets(AssetType theAssetType) { @@ -306,7 +278,7 @@ public class ASDC { } public <T> Action<T> getAssetAction(AssetType theAssetType, UUID theId, Class<T> theType) { - return (() -> fetch(refAsset(theAssetType, theId) + "/metadata", theType)); + return () -> fetch(refAsset(theAssetType, theId) + "/metadata", theType); } public Future<byte[]> getResourceArchive(UUID theId) { @@ -322,7 +294,7 @@ public class ASDC { } public Action<byte[]> getAssetArchiveAction(AssetType theAssetType, UUID theId) { - return (() -> fetch(refAsset(theAssetType, theId) + "/toscaModel", byte[].class)); + return () -> fetch(refAsset(theAssetType, theId) + "/toscaModel", byte[].class); } public Future<JSONObject> checkinResource(UUID theId, String theUser, String theMessage) { @@ -354,9 +326,7 @@ public class ASDC { public Future<JSONObject> cycleAsset(AssetType theAssetType, UUID theId, LifecycleState theState, String theUser, String theMessage) { return post(refAsset(theAssetType, theId) + "/lifecycleState/" + theState, - (headers) -> prepareHeaders(headers) - .header("USER_ID", theUser), - new JSONObject().putOpt("userRemarks", theMessage)); + headers -> prepareHeaders(headers).header(USER_ID, theUser), new JSONObject().putOpt("userRemarks", theMessage)); } protected String refAssetInstanceArtifact(AssetType theAssetType, UUID theAssetId, String theAssetInstance, UUID theArtifactId) { @@ -388,7 +358,7 @@ public class ASDC { } public <T> Action<T> getAssetArtifactAction(AssetType theAssetType, UUID theAssetId, UUID theArtifactId, Class<T> theType) { - return (() -> fetch(refAssetArtifact(theAssetType, theAssetId, theArtifactId), theType)); + return () -> fetch(refAssetArtifact(theAssetType, theAssetId, theArtifactId), theType); } public <T> Future<T> getAssetInstanceArtifact(AssetType theAssetType, UUID theAssetId, String theInstance, UUID theArtifactId, Class<T> theType) { @@ -396,7 +366,7 @@ public class ASDC { } public <T> Action<T> getAssetInstanceArtifactAction(AssetType theAssetType, UUID theAssetId, String theInstance, UUID theArtifactId, Class<T> theType) { - return (() -> fetch(refAssetInstanceArtifact(theAssetType, theAssetId, theInstance, theArtifactId), theType)); + return () -> fetch(refAssetInstanceArtifact(theAssetType, theAssetId, theInstance, theArtifactId), theType); } public ArtifactUploadAction createResourceArtifact(UUID theAssetId) { @@ -518,8 +488,9 @@ public class ASDC { protected void checkMandatoryInfo() { for (String field: mandatoryInfoEntries()) { - if (!info.has(field)) + if (!info.has(field)) { throw new IllegalStateException("No '" + field + "' was provided"); + } } } @@ -529,10 +500,9 @@ public class ASDC { } } - protected static final String[] artifactMandatoryEntries = new String[] {}; /** - * We use teh same API to operate on artifacts attached to assets or to their instances + * We use teh same API to operate on artifacts attached to assets or to their instances */ public abstract class ASDCArtifactAction<A extends ASDCArtifactAction<A>> extends ASDCAction<A, JSONObject> { @@ -570,17 +540,12 @@ public class ASDC { refAssetArtifact(this.assetType, this.assetId, theArtifactId) : refAssetInstanceArtifact(this.assetType, this.assetId, normalizeInstanceName(this.assetInstance), theArtifactId); } - } - - protected static final String[] uploadMandatoryEntries = new String[] { "artifactName", - "artifactType", - "artifactGroupType", - "artifactLabel", - "description", - "payloadData" }; + } public class ArtifactUploadAction extends ASDCArtifactAction<ArtifactUploadAction> { - + + public static final String PAYLOAD_DATA = ASDC.PAYLOAD_DATA; + protected ArtifactUploadAction() { super(new JSONObject()); } @@ -590,7 +555,7 @@ public class ASDC { } public ArtifactUploadAction withContent(byte[] theContent) { - return with("payloadData", Base64Utils.encodeToString(theContent)); + return with(PAYLOAD_DATA, Base64Utils.encodeToString(theContent)); } public ArtifactUploadAction withContent(File theFile) throws IOException { @@ -598,11 +563,11 @@ public class ASDC { } public ArtifactUploadAction withLabel(String theLabel) { - return with("artifactLabel", theLabel); + return with(ARTIFACT_LABEL, theLabel); } public ArtifactUploadAction withName(String theName) { - return with("artifactName", theName); + return with(ARTIFACT_NAME, theName); } public ArtifactUploadAction withDisplayName(String theName) { @@ -610,17 +575,18 @@ public class ASDC { } public ArtifactUploadAction withType(ArtifactType theType) { - return with("artifactType", theType.toString()); + return with(ARTIFACT_TYPE, theType.toString()); } public ArtifactUploadAction withGroupType(ArtifactGroupType theGroupType) { - return with("artifactGroupType", theGroupType.toString()); + return with(ARTIFACT_GROUP_TYPE, theGroupType.toString()); } public ArtifactUploadAction withDescription(String theDescription) { - return with("description", theDescription); + return with(DESCRIPTION, theDescription); } - + + @Override protected String[] mandatoryInfoEntries() { return ASDC.this.uploadMandatoryEntries; } @@ -628,18 +594,11 @@ public class ASDC { public Future<JSONObject> execute() { checkMandatory(); return ASDC.this.post(ref(null), - (headers) -> prepareHeaders(headers) - .header("USER_ID", this.operatorId), - this.info); + headers -> prepareHeaders(headers).header(USER_ID, this.operatorId), this.info); } } - protected static final String[] updateMandatoryEntries = new String[] { "artifactName", - "artifactType", - "artifactGroupType", - "artifactLabel", - "description", - "payloadData" }; + /** * In its current form the update relies on a previous artifact retrieval. One cannot build an update from scratch. @@ -657,7 +616,7 @@ public class ASDC { } public ArtifactUpdateAction withContent(byte[] theContent) { - return with("payloadData", Base64Utils.encodeToString(theContent)); + return with(PAYLOAD_DATA, Base64Utils.encodeToString(theContent)); } public ArtifactUpdateAction withContent(File theFile) throws IOException { @@ -665,13 +624,14 @@ public class ASDC { } public ArtifactUpdateAction withDescription(String theDescription) { - return with("description", theDescription); + return with(DESCRIPTION, theDescription); } public ArtifactUpdateAction withName(String theName) { - return with("artifactName", theName); + return with(ARTIFACT_NAME, theName); } - + + @Override protected String[] mandatoryInfoEntries() { return ASDC.this.updateMandatoryEntries; } @@ -690,9 +650,7 @@ public class ASDC { checkMandatory(); cleanupInfoEntries(); return ASDC.this.post(ref(artifactUUID), - (headers) -> prepareHeaders(headers) - .header("USER_ID", this.operatorId), - this.info); + headers -> prepareHeaders(headers).header(USER_ID, this.operatorId),this.info); } } @@ -712,26 +670,25 @@ public class ASDC { public Future<JSONObject> execute() { checkMandatory(); return ASDC.this.delete(ref(this.artifactId), - (headers) -> prepareHeaders(headers) - .header("USER_ID", this.operatorId)); + headers -> prepareHeaders(headers).header(USER_ID, this.operatorId)); } } - public VFCMTCreateAction createVFCMT() { + private VFCMTCreateAction createVFCMT() { return new VFCMTCreateAction(); } - - protected static final String[] vfcmtMandatoryEntries = new String[] { "name", - "vendorName", - "vendorRelease", - "contactId" }; + + public class VFCMTCreateAction extends ASDCAction<VFCMTCreateAction, JSONObject> { + private static final String CONTACT_ID = "contactId"; + private final String[] vfcmtMandatoryEntries = new String[] { "name", "vendorName", "vendorRelease", CONTACT_ID}; + protected VFCMTCreateAction() { super(new JSONObject()); @@ -751,7 +708,7 @@ public class ASDC { } public VFCMTCreateAction withDescription(String theDescription) { - return with("description", theDescription); + return with(DESCRIPTION, theDescription); } public VFCMTCreateAction withVendorName(String theVendorName) { @@ -763,8 +720,9 @@ public class ASDC { } public VFCMTCreateAction withTags(String... theTags) { - for (String tag: theTags) + for (String tag: theTags) { this.info.append("tags", tag); + } return this; } @@ -773,30 +731,29 @@ public class ASDC { } protected String[] mandatoryInfoEntries() { - return ASDC.this.vfcmtMandatoryEntries; + return vfcmtMandatoryEntries; } public VFCMTCreateAction withContact(String theContact) { - return with("contactId", theContact); + return with(CONTACT_ID, theContact); } public Future<JSONObject> execute() { - this.info.putOnce("contactId", this.operatorId); + this.info.putOnce(CONTACT_ID, this.operatorId); this.info.append("tags", info.optString("name")); checkMandatory(); return ASDC.this.post(refAssets(AssetType.resource), - (headers) -> prepareHeaders(headers) - .header("USER_ID", this.operatorId), - this.info); + headers -> prepareHeaders(headers).header(USER_ID, this.operatorId), this.info); } } public static JSONObject merge(JSONObject theOriginal, JSONObject thePatch) { for (String key: (Set<String>)thePatch.keySet()) { - if (!theOriginal.has(key)) + if (!theOriginal.has(key)) { theOriginal.put(key, thePatch.get(key)); + } } return theOriginal; } @@ -883,18 +840,7 @@ public class ASDC { - public class ASDCFuture<T> - extends Futures.BasicFuture<T> { - - private boolean http404toEmpty = false; - - ASDCFuture() { - } - - public ASDCFuture setHttp404ToEmpty(boolean doEmpty) { - this.http404toEmpty = doEmpty; - return this; - } + public class ASDCFuture<T> extends Futures.BasicFuture<T> { ListenableFutureCallback<ResponseEntity<T>> callback = new ListenableFutureCallback<ResponseEntity<T>>() { @@ -904,9 +850,6 @@ public class ASDC { public void onFailure(Throwable theError) { if (theError instanceof HttpClientErrorException) { - // if (theError.getRawStatusCode() == 404 && this.http404toEmpty) - // ASDCFuture.this.result(); //th eresult is of type T ... - // else ASDCFuture.this.cause(new ASDCException((HttpClientErrorException)theError)); } else { @@ -918,70 +861,66 @@ public class ASDC { } public class ContentMD5Interceptor implements AsyncClientHttpRequestInterceptor { - - @Override - public ListenableFuture<ClientHttpResponse> intercept( - HttpRequest theRequest, byte[] theBody, AsyncClientHttpRequestExecution theExecution) - throws IOException { - if (HttpMethod.POST == theRequest.getMethod()) { - HttpHeaders headers = theRequest.getHeaders(); - headers.add("Content-MD5", Base64Utils.encodeToString( - //DigestUtils.md5Digest(theBody))); - DigestUtils.md5Hex(theBody).getBytes())); - - } - return theExecution.executeAsync(theRequest, theBody); - } + @Override + public ListenableFuture<ClientHttpResponse> intercept( + HttpRequest theRequest, byte[] theBody, AsyncClientHttpRequestExecution theExecution) + throws IOException { + if (HttpMethod.POST == theRequest.getMethod()) { + HttpHeaders headers = theRequest.getHeaders(); + headers.add("Content-MD5", Base64Utils.encodeToString(DigestUtils.md5Hex(theBody).getBytes())); + } + return theExecution.executeAsync(theRequest, theBody); + } } public static void main(String[] theArgs) throws Exception { CommandLineParser parser = new BasicParser(); - String user_id = "jh0003"; + String userId = "jh0003"; Options options = new Options(); options.addOption(OptionBuilder - .withArgName("target") - .withLongOpt("target") + .withArgName(TARGET) + .withLongOpt(TARGET) .withDescription("target asdc system") .hasArg() .isRequired() .create('t') ); options.addOption(OptionBuilder - .withArgName("action") - .withLongOpt("action") + .withArgName(ACTION) + .withLongOpt(ACTION) .withDescription("one of: list, get, getartifact, checkin, checkout") .hasArg() .isRequired() .create('a') ); options.addOption(OptionBuilder - .withArgName("assetType") - .withLongOpt("assetType") + .withArgName(ASSET_TYPE) + .withLongOpt(ASSET_TYPE) .withDescription("one of resource, service, product") .hasArg() .isRequired() .create('k') ); //k for 'kind' .. options.addOption(OptionBuilder - .withArgName("assetId") - .withLongOpt("assetId") + .withArgName(ASSET_ID) + .withLongOpt(ASSET_ID) .withDescription("asset uuid") .hasArg() .create('u') ); //u for 'uuid' options.addOption(OptionBuilder - .withArgName("artifactId") - .withLongOpt("artifactId") + .withArgName(ARTIFACT_ID) + .withLongOpt(ARTIFACT_ID) .withDescription("artifact uuid") .hasArg() .create('s') ); //s for 'stuff' options.addOption(OptionBuilder - .withArgName("listFilter") - .withLongOpt("listFilter") + .withArgName(LIST_FILTER) + .withLongOpt(LIST_FILTER) .withDescription("filter for list operations") .hasArg() .create('f') ); //u for 'uuid' @@ -997,86 +936,67 @@ public class ASDC { } ASDC asdc = new ASDC(); - asdc.setUri(new URI(line.getOptionValue("target"))); + asdc.setUri(new URI(line.getOptionValue(TARGET))); - String action = line.getOptionValue("action"); - if (action.equals("list")) { + String action = line.getOptionValue(ACTION); + if ("list".equals(action)) { JSONObject filterInfo = new JSONObject( - line.hasOption("listFilter") ? - line.getOptionValue("listFilter") : "{}"); + line.hasOption(LIST_FILTER) ? + line.getOptionValue(LIST_FILTER) : "{}"); JSONArray assets = - asdc.getAssets(ASDC.AssetType.valueOf(line.getOptionValue("assetType")), JSONArray.class, + asdc.getAssets(ASDC.AssetType.valueOf(line.getOptionValue(ASSET_TYPE)), JSONArray.class, filterInfo.optString("category", null), filterInfo.optString("subCategory", null)) .waitForResult(); for (int i = 0; i < assets.length(); i++) { debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),"> {}", assets.getJSONObject(i).toString(2)); } } - else if (action.equals("get")) { + else if ("get".equals(action)) { debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(), - asdc.getAsset(ASDC.AssetType.valueOf(line.getOptionValue("assetType")), - UUID.fromString(line.getOptionValue("assetId")), + asdc.getAsset(ASDC.AssetType.valueOf(line.getOptionValue(ASSET_TYPE)), + UUID.fromString(line.getOptionValue(ASSET_ID)), JSONObject.class) .waitForResult() .toString(2) ); } - else if (action.equals("getartifact")) { + else if ("getartifact".equals(action)) { debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(), - asdc.getAssetArtifact(ASDC.AssetType.valueOf(line.getOptionValue("assetType")), - UUID.fromString(line.getOptionValue("assetId")), - UUID.fromString(line.getOptionValue("artifactId")), + asdc.getAssetArtifact(ASDC.AssetType.valueOf(line.getOptionValue(ASSET_TYPE)), + UUID.fromString(line.getOptionValue(ASSET_ID)), + UUID.fromString(line.getOptionValue(ARTIFACT_ID)), String.class) .waitForResult() ); } - else if (action.equals("checkin")) { + else if ("checkin".equals(action)) { debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(), - asdc.cycleAsset(ASDC.AssetType.valueOf(line.getOptionValue("assetType")), - UUID.fromString(line.getOptionValue("assetId")), + asdc.cycleAsset(ASDC.AssetType.valueOf(line.getOptionValue(ASSET_TYPE)), + UUID.fromString(line.getOptionValue(ASSET_ID)), ASDC.LifecycleState.Checkin, - user_id, + userId, "cli op") .waitForResult() .toString() ); } - else if (action.equals("checkout")) { + else if ("checkout".equals(action)) { debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(), - asdc.cycleAsset(ASDC.AssetType.valueOf(line.getOptionValue("assetType")), - UUID.fromString(line.getOptionValue("assetId")), + asdc.cycleAsset(ASDC.AssetType.valueOf(line.getOptionValue(ASSET_TYPE)), + UUID.fromString(line.getOptionValue(ASSET_ID)), ASDC.LifecycleState.Checkout, - user_id, + userId, "cli op") .waitForResult() .toString() ); } - else if (action.equals("cleanup")) { + else if ("cleanup".equals(action)) { JSONArray resources = asdc.getResources() .waitForResult(); debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),"Got {} resources", resources.length()); - // vfcmt cleanup - for (int i = 0; i < resources.length(); i++) { - - JSONObject resource = resources.getJSONObject(i); - - if (resource.getString("resourceType").equals("VFCMT") && - resource.getString("name").contains("test")) { - - debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),"undocheckout for {}", resource.getString("uuid")); - - try { - asdc.cycleAsset(AssetType.resource, UUID.fromString(resource.getString("uuid")), LifecycleState.undocheckout, user_id, null) - .waitForResult(); - } - catch (Exception x) { - debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),"** {}", x); - } - } - } - + vfcmtCleanup(userId, asdc, resources); } else { try { @@ -1087,7 +1007,7 @@ public class ASDC { .withVendorName("CloneInc") .withVendorRelease("1.0") .withTags("clone") - .withOperator(user_id) + .withOperator(userId) .execute() .waitForResult() .toString() @@ -1098,4 +1018,25 @@ public class ASDC { } } } + + private static void vfcmtCleanup(String userId, ASDC asdc, JSONArray resources) { + for (int i = 0; i < resources.length(); i++) { + + JSONObject resource = resources.getJSONObject(i); + + if ("VFCMT".equals(resource.getString("resourceType")) && + resource.getString("name").contains("test")) { + + debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),"undocheckout for {}", resource.getString("uuid")); + + try { + asdc.cycleAsset(AssetType.resource, UUID.fromString(resource.getString("uuid")), LifecycleState.undocheckout, userId, null) + .waitForResult(); + } + catch (Exception x) { + debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),"** {}", x); + } + } + } + } } diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtils.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtils.java index 1d70627..d6a175f 100644 --- a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtils.java +++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtils.java @@ -35,414 +35,422 @@ import java.util.zip.ZipInputStream; @ConfigurationProperties(prefix="asdcutils") public class ASDCUtils { - private static OnapLoggerError errLogger = OnapLoggerError.getInstance(); - private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); - - @Autowired - private ASDC asdc; - - @Autowired - private Blueprinter blueprint; - - public ASDCUtils() { - // Making sonar happy - } - - public ASDCUtils(URI theASDCURI) { - this(theASDCURI, null); - } - - public ASDCUtils(URI theASDCURI, URI theBlueprinterURI) { - this.asdc = new ASDC(); - this.asdc.setUri(theASDCURI); - if (theBlueprinterURI != null) { - this.blueprint = new Blueprinter(); - this.blueprint.setUri(theBlueprinterURI); - } - } - - public ASDCUtils(ASDC theASDC) { - this(theASDC, null); - } - - public ASDCUtils(ASDC theASDC, Blueprinter theBlueprinter) { - this.asdc = theASDC; - this.blueprint = theBlueprinter; - } - - public CloneAssetArtifactsAction cloneAssetArtifacts(ASDC.AssetType theAssetType, UUID theSourceId, UUID theTargetId) { - return new CloneAssetArtifactsAction(this.asdc, theAssetType, theSourceId, theTargetId); - } - - public static class CloneAssetArtifactsAction extends ASDC.ASDCAction<CloneAssetArtifactsAction, List<JSONObject>> { - - private ASDC.AssetType assetType; - private UUID sourceId, targetId; - - protected CloneAssetArtifactsAction(ASDC theASDC, ASDC.AssetType theAssetType, UUID theSourceId, UUID theTargetId) { - theASDC.super(new JSONObject()); - this.assetType = theAssetType; - this.sourceId = theSourceId; - this.targetId = theTargetId; - } - - protected CloneAssetArtifactsAction self() { - return this; - } - - public CloneAssetArtifactsAction withLabel(String theLabel) { - return with("artifactLabel", theLabel); - } - - protected String[] mandatoryInfoEntries() { - return new String[] {}; - } - - public Future<List<JSONObject>> execute() { - checkMandatory(); - - final Actions.Sequence<JSONObject> sequencer = new Actions.Sequence<JSONObject>(); - - new Actions.Sequence().add(super.asdc().getAssetArchiveAction(this.assetType, this.sourceId)).add(super.asdc().getAssetAction(this.assetType, this.sourceId, JSONObject.class)).execute().setHandler(assetFuture -> { - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "*** {}", assetFuture.result()); - processArtifacts((List) assetFuture.result(), (JSONObject theInfo, byte[] theData) -> { - theInfo.remove("artifactChecksum"); - theInfo.remove("artifactUUID"); - theInfo.remove("artifactVersion"); - theInfo.remove("artifactURL"); - theInfo.put("description", theInfo.remove("artifactDescription")); - theInfo.put("payloadData", Base64Utils.encodeToString(theData)); - return theInfo; - }, null).forEach(artifactInfo -> sequencer.add(super.asdc().createAssetArtifact(this.assetType, this.targetId).withInfo(ASDC.merge(artifactInfo, this.info)).withOperator(this.operatorId))); - sequencer.execute(); - }); - - return sequencer.future(); - } - } //the Action class - - /* */ - private static JSONObject lookupArtifactInfo(JSONArray theArtifacts, String theName) { - - for (int i = 0; theArtifacts != null && i < theArtifacts.length(); i++) { - JSONObject artifactInfo = theArtifacts.getJSONObject(i); - if (theName.equals(artifactInfo.getString("artifactName"))) { - debugLogger.log(LogLevel.DEBUG, ASDCUtils.class.getName(), "Found artifact info {}", artifactInfo); - return artifactInfo; - } - } - - return null; - } - - private static byte[] extractArtifactData(InputStream theEntryStream) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - byte[] buff = new byte[4096]; - int cnt = 0; - while ((cnt = theEntryStream.read(buff)) != -1) { - baos.write(buff, 0, cnt); - } - } finally { - baos.close(); - } - return baos.toByteArray(); - } - - /** - * Recycle a cdump, fetch all relevant ASDC artifacts, interact with Shu's toscalib service in order to generate - * a blueprint. No 'Action' object here as there is nothig to set up. - */ - public Future<Future<String>> buildBlueprint(Reader theCdump) { - - final Recycler recycler = new Recycler(); - Object template = null; - - try { - template = recycler.recycle(theCdump); - - } catch (Exception x) { - return Futures.failedFuture(x); - } - - JXPathContext jxroot = JXPathContext.newContext(template); - jxroot.setLenient(true); - - //based on the output of ASDCCatalog the node description will contain the UUID of the resource declaring it - List uuids = (List) StreamSupport.stream(Spliterators.spliteratorUnknownSize(jxroot.iterate("topology_template/node_templates/*/description"), 16), false).distinct().filter(desc -> desc != null) - //the desc contains the full URI and the resource uuid is the 5th path element - .map(desc -> desc.toString().split("/")[5]).collect(Collectors.toList()); - - //prepare fetching all archives/resource details - final Futures.Accumulator accumulator = new Futures.Accumulator(); - uuids.stream().forEach(uuid -> { - UUID rid = UUID.fromString((String) uuid); - accumulator.add(this.asdc.getAssetArchive(ASDC.AssetType.resource, rid)); - accumulator.add(this.asdc.getAsset(ASDC.AssetType.resource, rid, JSONObject.class)); - }); - - final byte[] templateData = recycler.toString(template).getBytes(/*"UTF-8"*/); - //retrieve all resource archive+details, prepare blueprint service request and send its request - return Futures.advance(accumulator.accumulate(), (List theArchives) -> { - Blueprinter.BlueprintAction action = blueprint.generateBlueprint(); - processArtifacts(theArchives, (JSONObject theInfo, byte[] theData) -> new JSONObject().put(theInfo.getString("artifactName").split("\\.")[0], Base64Utils.encodeToString(theData)), - (Stream<JSONObject> theAssetArtifacts) -> theAssetArtifacts.reduce(new JSONObject(), ASDC::merge)).forEach(artifactInfo -> action.withModelInfo(artifactInfo)); - - return action.withTemplateData(templateData).execute(); - }); - } - - public Future<Future<String>> buildBlueprintViaToscaLab(Reader theCdump) { - return processCdump(theCdump, (theTemplate, theArchives) -> { - Blueprinter.BlueprintAction action = blueprint.generateBlueprint(); - processArtifacts(theArchives, (JSONObject theInfo, byte[] theData) -> new JSONObject().put(theInfo.getString("artifactName").split("\\.")[0], Base64Utils.encodeToString(theData)), - (Stream<JSONObject> theAssetArtifacts) -> theAssetArtifacts.reduce(new JSONObject(), ASDC::merge)).forEach(artifactInfo -> action.withModelInfo(artifactInfo)); - - return action.withTemplateData(Recycler.toString(theTemplate).getBytes()).execute(); - - }); - } - - private static class Tracker implements TargetLocator { - - private static enum Position { - SCHEMA, TEMPLATE, TRANSLATE; - } - - private static final int Positions = Position.values().length; - - private List<Target> tgts = new ArrayList<Target>(3); - - public Tracker() { - clear(); - } - - public boolean addSearchPath(URI theURI) { - return false; - } - - public boolean addSearchPath(String thePath) { - return false; - } - - public Iterable<URI> searchPaths() { - return Collections.emptyList(); - } - - protected int position(String... theKeys) { - for (String key : theKeys) { - if ("schema".equals(key)) { - return Position.SCHEMA.ordinal(); - } - if ("template".equals(key)) { - return Position.TEMPLATE.ordinal(); - } - if ("translate".equals(key)) { - return Position.TRANSLATE.ordinal(); - } - } - return -1; - } - - public Target resolve(String theName) { - for (Target tgt : tgts) { - if (tgt != null && tgt.getName().equals(theName)) { - return tgt; - } - } - return null; - } - - public void track(JSONObject theInfo, final byte[] theData) { - String uri = theInfo.getString("artifactURL").split("/")[5]; - String name = theInfo.getString("artifactName"), desc = theInfo.getString("artifactDescription"), label = theInfo.getString("artifactLabel"); - int pos = position(desc, label); - - debugLogger.log(LogLevel.DEBUG, ASDCUtils.class.getName(), "Tracking {} at {}, {}", name, pos, theInfo.optString("artifactURL")); - - if (pos > -1) { - tgts.set(pos, new Target(name, URI.create("asdc:" + uri + "/" + name)) { - @Override - public Reader open(){ - return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(theData))); - } - }); - } - } - - public boolean hasSchema() { - return tgts.get(Position.SCHEMA.ordinal()) != null; - } - - public Target schema() { - return tgts.get(Position.SCHEMA.ordinal()); - } - - public boolean hasTemplate() { - return tgts.get(Position.TEMPLATE.ordinal()) != null; - } - - public Target template() { - return tgts.get(Position.TEMPLATE.ordinal()); - } - - public boolean hasTranslation() { - return tgts.get(Position.TRANSLATE.ordinal()) != null; - } - - public Target translation() { - return tgts.get(Position.TRANSLATE.ordinal()); - } - - public void clear() { - if (tgts.isEmpty()) { - for (int i = 0; i < Positions; i++) { - tgts.add(null); - } - } else { - Collections.fill(tgts, null); - } - } - } - - private Checker buildChecker() { - try { - return new Checker(); - } catch (CheckerException cx) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "CheckerException while creating Checker {}", cx); - return null; - } - } - - public Future<Catalog> buildCatalog(Reader theCdump) { - - // - //the purpose of the tracking is to be able to resolve import references within the 'space' of an - //asset's artifacts - //processing order is important too so we 'order the targets: schema, template, translation - // - final Tracker tracker = new Tracker(); - final Catalog catalog = Checker.buildCatalog(); - - return processCdump(theCdump, (theTemplate, theArchives) -> { - - final Checker checker = buildChecker(); - if (checker == null) { - return null; - } - checker.setTargetLocator(tracker); - - processArtifacts(theArchives, (JSONObject theInfo, byte[] theData) -> { - tracker.track(theInfo, theData); - return (Catalog) null; - }, - // aggregation: this is where the actual processing takes place now that - // we have all the targets - (Stream<Catalog> theAssetArtifacts) -> { - //the stream is full of nulls, ignore it, work with the tracker - - try { - if (tracker.hasSchema()) { - checker.check(tracker.schema(), catalog); - } - if (tracker.hasTemplate()) { - checker.check(tracker.template(), catalog); - } - if (tracker.hasTranslation()) { - checker.check(tracker.translation(), catalog); - } - } catch (CheckerException cx) { - //got to do better than this - errLogger.log(LogLevel.ERROR, ASDC.class.getName(),"CheckerException while checking catalog:{}", cx); - } finally { - tracker.clear(); - } - return checker.catalog(); - }); - - Target cdump = new Target("cdump", URI.create("asdc:cdump")); - cdump.setTarget(theTemplate); - - validateCatalog(catalog, checker, cdump); - - return catalog; - }); - } - - private void validateCatalog(Catalog catalog, Checker checker, Target cdump) { - try { + private static final String ARTIFACT_URL = "artifactURL"; + private static final String ARTIFACT_NAME = "artifactName"; + private static OnapLoggerError errLogger = OnapLoggerError.getInstance(); + private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); + + @Autowired + private ASDC asdc; + + @Autowired + private Blueprinter blueprint; + + public ASDCUtils() { + // Making sonar happy + } + + public ASDCUtils(URI theASDCURI) { + this(theASDCURI, null); + } + + public ASDCUtils(URI theASDCURI, URI theBlueprinterURI) { + this.asdc = new ASDC(); + this.asdc.setUri(theASDCURI); + if (theBlueprinterURI != null) { + this.blueprint = new Blueprinter(); + this.blueprint.setUri(theBlueprinterURI); + } + } + + public ASDCUtils(ASDC theASDC) { + this(theASDC, null); + } + + public ASDCUtils(ASDC theASDC, Blueprinter theBlueprinter) { + this.asdc = theASDC; + this.blueprint = theBlueprinter; + } + + public CloneAssetArtifactsAction cloneAssetArtifacts(ASDC.AssetType theAssetType, UUID theSourceId, UUID theTargetId) { + return new CloneAssetArtifactsAction(this.asdc, theAssetType, theSourceId, theTargetId); + } + + public static class CloneAssetArtifactsAction extends ASDC.ASDCAction<CloneAssetArtifactsAction, List<JSONObject>> { + + private ASDC.AssetType assetType; + private UUID sourceId, targetId; + + CloneAssetArtifactsAction(ASDC theASDC, ASDC.AssetType theAssetType, UUID theSourceId, UUID theTargetId) { + theASDC.super(new JSONObject()); + this.assetType = theAssetType; + this.sourceId = theSourceId; + this.targetId = theTargetId; + } + + protected CloneAssetArtifactsAction self() { + return this; + } + + public CloneAssetArtifactsAction withLabel(String theLabel) { + return with("artifactLabel", theLabel); + } + + protected String[] mandatoryInfoEntries() { + return new String[] {}; + } + + public Future<List<JSONObject>> execute() { + checkMandatory(); + + final Actions.Sequence<JSONObject> sequencer = new Actions.Sequence<JSONObject>(); + + new Actions.Sequence().add(super.asdc().getAssetArchiveAction(this.assetType, this.sourceId)).add(super.asdc().getAssetAction(this.assetType, this.sourceId, JSONObject.class)).execute().setHandler(assetFuture -> { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "*** {}", assetFuture.result()); + processArtifacts((List) assetFuture.result(), (JSONObject theInfo, byte[] theData) -> { + theInfo.remove("artifactChecksum"); + theInfo.remove("artifactUUID"); + theInfo.remove("artifactVersion"); + theInfo.remove(ARTIFACT_URL); + theInfo.put("description", theInfo.remove("artifactDescription")); + theInfo.put("payloadData", Base64Utils.encodeToString(theData)); + return theInfo; + }, null).forEach(artifactInfo -> sequencer.add(super.asdc().createAssetArtifact(this.assetType, this.targetId).withInfo(ASDC.merge(artifactInfo, this.info)).withOperator(this.operatorId))); + sequencer.execute(); + }); + + return sequencer.future(); + } + } //the Action class + + /* */ + private static JSONObject lookupArtifactInfo(JSONArray theArtifacts, String theName) { + + for (int i = 0; theArtifacts != null && i < theArtifacts.length(); i++) { + JSONObject artifactInfo = theArtifacts.getJSONObject(i); + if (theName.equals(artifactInfo.getString(ARTIFACT_NAME))) { + debugLogger.log(LogLevel.DEBUG, ASDCUtils.class.getName(), "Found artifact info {}", artifactInfo); + return artifactInfo; + } + } + + return null; + } + + private static byte[] extractArtifactData(InputStream theEntryStream) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + byte[] buff = new byte[4096]; + int cnt = 0; + while ((cnt = theEntryStream.read(buff)) != -1) { + baos.write(buff, 0, cnt); + } + } finally { + baos.close(); + } + return baos.toByteArray(); + } + + /** + * Recycle a cdump, fetch all relevant ASDC artifacts, interact with Shu's toscalib service in order to generate + * a blueprint. No 'Action' object here as there is nothig to set up. + */ + public Future<Future<String>> buildBlueprint(Reader theCdump) { + + final Recycler recycler = new Recycler(); + Object template = null; + + try { + template = recycler.recycle(theCdump); + + } catch (Exception x) { + return Futures.failedFuture(x); + } + + JXPathContext jxroot = JXPathContext.newContext(template); + jxroot.setLenient(true); + + //based on the output of ASDCCatalog the node description will contain the UUID of the resource declaring it + List uuids = (List) StreamSupport.stream(Spliterators.spliteratorUnknownSize(jxroot.iterate("topology_template/node_templates/*/description"), 16), false).distinct().filter(desc -> desc != null) + //the desc contains the full URI and the resource uuid is the 5th path element + .map(desc -> desc.toString().split("/")[5]).collect(Collectors.toList()); + + //prepare fetching all archives/resource details + final Futures.Accumulator accumulator = new Futures.Accumulator(); + uuids.forEach(uuid -> { + UUID rid = UUID.fromString((String) uuid); + accumulator.add(this.asdc.getAssetArchive(ASDC.AssetType.resource, rid)); + accumulator.add(this.asdc.getAsset(ASDC.AssetType.resource, rid, JSONObject.class)); + }); + + final byte[] templateData = recycler.toString(template).getBytes(/*"UTF-8"*/); + //retrieve all resource archive+details, prepare blueprint service request and send its request + return Futures.advance(accumulator.accumulate(), (List theArchives) -> { + Blueprinter.BlueprintAction action = blueprint.generateBlueprint(); + processArtifacts(theArchives, (JSONObject theInfo, byte[] theData) -> new JSONObject().put(theInfo.getString(ARTIFACT_NAME).split("\\.")[0], Base64Utils.encodeToString(theData)), + (Stream<JSONObject> theAssetArtifacts) -> theAssetArtifacts.reduce(new JSONObject(), ASDC::merge)).forEach(artifactInfo -> action.withModelInfo(artifactInfo)); + + return action.withTemplateData(templateData).execute(); + }); + } + + public Future<Future<String>> buildBlueprintViaToscaLab(Reader theCdump) { + return processCdump(theCdump, (theTemplate, theArchives) -> { + Blueprinter.BlueprintAction action = blueprint.generateBlueprint(); + processArtifacts(theArchives, (JSONObject theInfo, byte[] theData) -> new JSONObject().put(theInfo.getString(ARTIFACT_NAME).split("\\.")[0], Base64Utils.encodeToString(theData)), + (Stream<JSONObject> theAssetArtifacts) -> theAssetArtifacts.reduce(new JSONObject(), ASDC::merge)).forEach(artifactInfo -> action.withModelInfo(artifactInfo)); + + return action.withTemplateData(Recycler.toString(theTemplate).getBytes()).execute(); + + }); + } + + private static class Tracker implements TargetLocator { + + private enum Position { + SCHEMA, TEMPLATE, TRANSLATE; + } + + private static final int POSITIONS = Position.values().length; + + private List<Target> tgts = new ArrayList<Target>(3); + + Tracker() { + clear(); + } + + public boolean addSearchPath(URI theURI) { + return false; + } + + public boolean addSearchPath(String thePath) { + return false; + } + + public Iterable<URI> searchPaths() { + return Collections.emptyList(); + } + + int position(String... theKeys) { + for (String key : theKeys) { + if ("schema".equals(key)) { + return Position.SCHEMA.ordinal(); + } + if ("template".equals(key)) { + return Position.TEMPLATE.ordinal(); + } + if ("translate".equals(key)) { + return Position.TRANSLATE.ordinal(); + } + } + return -1; + } + + public Target resolve(String theName) { + for (Target tgt : tgts) { + if (tgt != null && tgt.getName().equals(theName)) { + return tgt; + } + } + return null; + } + + void track(JSONObject theInfo, final byte[] theData) { + String uri = theInfo.getString(ARTIFACT_URL).split("/")[5]; + String name = theInfo.getString(ARTIFACT_NAME), desc = theInfo.getString("artifactDescription"), label = theInfo.getString("artifactLabel"); + int pos = position(desc, label); + + debugLogger.log(LogLevel.DEBUG, ASDCUtils.class.getName(), "Tracking {} at {}, {}", name, pos, theInfo.optString(ARTIFACT_URL)); + + if (pos > -1) { + tgts.set(pos, new Target(name, URI.create("asdc:" + uri + "/" + name)) { + @Override + public Reader open(){ + return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(theData))); + } + }); + } + } + + boolean hasSchema() { + return tgts.get(Position.SCHEMA.ordinal()) != null; + } + + public Target schema() { + return tgts.get(Position.SCHEMA.ordinal()); + } + + boolean hasTemplate() { + return tgts.get(Position.TEMPLATE.ordinal()) != null; + } + + public Target template() { + return tgts.get(Position.TEMPLATE.ordinal()); + } + + boolean hasTranslation() { + return tgts.get(Position.TRANSLATE.ordinal()) != null; + } + + public Target translation() { + return tgts.get(Position.TRANSLATE.ordinal()); + } + + public void clear() { + if (tgts.isEmpty()) { + for (int i = 0; i < POSITIONS; i++) { + tgts.add(null); + } + } else { + Collections.fill(tgts, null); + } + } + } + + private Checker buildChecker() { + try { + return new Checker(); + } catch (CheckerException cx) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "CheckerException while creating Checker {}", cx); + return null; + } + } + + public Future<Catalog> buildCatalog(Reader theCdump) { + + // + //the purpose of the tracking is to be able to resolve import references within the 'space' of an + //asset's artifacts + //processing order is important too so we 'order the targets: schema, template, translation + // + final Tracker tracker = new Tracker(); + final Catalog catalog = Checker.buildCatalog(); + + return processCdump(theCdump, (theTemplate, theArchives) -> { + + final Checker checker = buildChecker(); + if (checker == null) { + return null; + } + checker.setTargetLocator(tracker); + + processArtifacts(theArchives, (JSONObject theInfo, byte[] theData) -> { + tracker.track(theInfo, theData); + return (Catalog) null; + }, + // aggregation: this is where the actual processing takes place now that + // we have all the targets + (Stream<Catalog> theAssetArtifacts) -> checkAndGetCatalog(tracker, catalog, checker)); + + Target cdump = new Target("cdump", URI.create("asdc:cdump")); + cdump.setTarget(theTemplate); + + validateCatalog(catalog, checker, cdump); + + return catalog; + }); + } + + private Catalog checkAndGetCatalog(Tracker tracker, Catalog catalog, Checker checker) { + //the stream is full of nulls, ignore it, work with the tracker + + try { + if (tracker.hasSchema()) { + checker.check(tracker.schema(), catalog); + } + if (tracker.hasTemplate()) { + checker.check(tracker.template(), catalog); + } + if (tracker.hasTranslation()) { + checker.check(tracker.translation(), catalog); + } + } catch (CheckerException cx) { + //got to do better than this + errLogger.log(LogLevel.ERROR, ASDC.class.getName(),"CheckerException while checking catalog:{}", cx); + } finally { + tracker.clear(); + } + return checker.catalog(); + } + + private void validateCatalog(Catalog catalog, Checker checker, Target cdump) { + try { checker.validate(cdump, catalog); } catch (CheckerException cx) { errLogger.log(LogLevel.ERROR, ASDC.class.getName(),"CheckerException while building catalog:{}", cx); } - } - - /* The common process of recycling, retrieving all related artifacts and then doing 'something' */ - private <T> Future<T> processCdump(Reader theCdump, BiFunction<Object, List, T> theProcessor) { - - final Recycler recycler = new Recycler(); - Object template = null; - try { - template = recycler.recycle(theCdump); - - } catch (Exception x) { - return Futures.failedFuture(x); - } - - JXPathContext jxroot = JXPathContext.newContext(template); - jxroot.setLenient(true); - - //based on the output of ASDCCatalog the node description will contain the UUID of the resource declaring it - //the desc contains the full URI and the resource uuid is the 5th path element - List uuids = (List) StreamSupport.stream(Spliterators.spliteratorUnknownSize(jxroot.iterate("topology_template/node_templates/*/description"), 16), false).distinct().filter(desc -> desc != null) - .map(desc -> desc.toString().split("/")[5]).collect(Collectors.toList()); - - //serialized fetch version - final Actions.Sequence sequencer = new Actions.Sequence(); - uuids.stream().forEach(uuid -> { - UUID rid = UUID.fromString((String) uuid); - sequencer.add(this.asdc.getAssetArchiveAction(ASDC.AssetType.resource, rid)); - sequencer.add(this.asdc.getAssetAction(ASDC.AssetType.resource, rid, JSONObject.class)); - }); - - final Object tmpl = template; - return Futures.advance(sequencer.execute(), (List theArchives) -> theProcessor.apply(tmpl, theArchives)); - } - - private static <T> Stream<T> processArtifacts(List theArtifactData, BiFunction<JSONObject, byte[], T> theProcessor, Function<Stream<T>, T> theAggregator) { - - Stream.Builder<T> assetBuilder = Stream.builder(); - - for (int i = 0; i < theArtifactData.size(); i = i + 2) { //cute old style loop - - JSONObject assetInfo = (JSONObject) theArtifactData.get(i + 1); - byte[] assetData = (byte[]) theArtifactData.get(i + 0); - - JSONArray artifacts = assetInfo.optJSONArray("artifacts"); - - Stream.Builder<T> artifactBuilder = Stream.builder(); - - try (ZipInputStream zipper = new ZipInputStream(new ByteArrayInputStream(assetData))){ - //we process the artifacts in the order they are stored in the archive .. fugly - for (ZipEntry zipped = zipper.getNextEntry(); zipped != null; zipped = zipper.getNextEntry()) { - JSONObject artifactInfo = lookupArtifactInfo(artifacts, StringUtils.substringAfterLast(zipped.getName(), "/")); - if (artifactInfo != null) { - artifactBuilder.add(theProcessor.apply(artifactInfo, extractArtifactData(zipper))); - } - zipper.closeEntry(); - } - } catch (IOException iox) { - errLogger.log(LogLevel.ERROR, ASDC.class.getName(), "IOException: {}", iox); - return null; - } - - if (theAggregator != null) { - assetBuilder.add(theAggregator.apply(artifactBuilder.build())); - } else { - artifactBuilder.build().forEach(entry -> assetBuilder.add(entry)); - } - } - - return assetBuilder.build(); - } + } + + /* The common process of recycling, retrieving all related artifacts and then doing 'something' */ + private <T> Future<T> processCdump(Reader theCdump, BiFunction<Object, List, T> theProcessor) { + + final Recycler recycler = new Recycler(); + Object template = null; + try { + template = recycler.recycle(theCdump); + + } catch (Exception x) { + return Futures.failedFuture(x); + } + + JXPathContext jxroot = JXPathContext.newContext(template); + jxroot.setLenient(true); + + //based on the output of ASDCCatalog the node description will contain the UUID of the resource declaring it + //the desc contains the full URI and the resource uuid is the 5th path element + List uuids = (List) StreamSupport.stream(Spliterators.spliteratorUnknownSize(jxroot.iterate("topology_template/node_templates/*/description"), 16), false).distinct().filter(desc -> desc != null) + .map(desc -> desc.toString().split("/")[5]).collect(Collectors.toList()); + + //serialized fetch version + final Actions.Sequence sequencer = new Actions.Sequence(); + uuids.stream().forEach(uuid -> { + UUID rid = UUID.fromString((String) uuid); + sequencer.add(this.asdc.getAssetArchiveAction(ASDC.AssetType.resource, rid)); + sequencer.add(this.asdc.getAssetAction(ASDC.AssetType.resource, rid, JSONObject.class)); + }); + + final Object tmpl = template; + return Futures.advance(sequencer.execute(), (List theArchives) -> theProcessor.apply(tmpl, theArchives)); + } + + private static <T> Stream<T> processArtifacts(List theArtifactData, BiFunction<JSONObject, byte[], T> theProcessor, Function<Stream<T>, T> theAggregator) { + + Stream.Builder<T> assetBuilder = Stream.builder(); + + for (int i = 0; i < theArtifactData.size(); i = i + 2) { //cute old style loop + + JSONObject assetInfo = (JSONObject) theArtifactData.get(i + 1); + byte[] assetData = (byte[]) theArtifactData.get(i + 0); + + JSONArray artifacts = assetInfo.optJSONArray("artifacts"); + + Stream.Builder<T> artifactBuilder = Stream.builder(); + + try (ZipInputStream zipper = new ZipInputStream(new ByteArrayInputStream(assetData))){ + //we process the artifacts in the order they are stored in the archive .. fugly + processZipArtifacts(theProcessor, artifacts, artifactBuilder, zipper); + } catch (IOException iox) { + errLogger.log(LogLevel.ERROR, ASDC.class.getName(), "IOException: {}", iox); + return null; + } + + if (theAggregator != null) { + assetBuilder.add(theAggregator.apply(artifactBuilder.build())); + } else { + artifactBuilder.build().forEach(entry -> assetBuilder.add(entry)); + } + } + + return assetBuilder.build(); + } + + private static <T> void processZipArtifacts(BiFunction<JSONObject, byte[], T> theProcessor, JSONArray artifacts, Stream.Builder<T> artifactBuilder, ZipInputStream zipper) throws IOException { + for (ZipEntry zipped = zipper.getNextEntry(); zipped != null; zipped = zipper.getNextEntry()) { + JSONObject artifactInfo = lookupArtifactInfo(artifacts, StringUtils.substringAfterLast(zipped.getName(), "/")); + if (artifactInfo != null) { + artifactBuilder.add(theProcessor.apply(artifactInfo, extractArtifactData(zipper))); + } + zipper.closeEntry(); + } + } } diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtilsController.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtilsController.java index 4432712..377e71b 100644 --- a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtilsController.java +++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtilsController.java @@ -1,70 +1,30 @@ package org.onap.sdc.dcae.catalog.asdc; -import java.io.StringReader; - -import java.util.UUID; -import java.util.Map; -import java.util.List; -import java.util.concurrent.Callable; - -import java.net.URI; -import java.net.URISyntaxException; - -import javax.servlet.http.HttpServletRequest; - -import org.onap.sdc.common.onaplog.OnapLoggerDebug; import org.onap.sdc.common.onaplog.Enums.LogLevel; +import org.onap.sdc.common.onaplog.OnapLoggerDebug; import org.springframework.beans.BeansException; - -import org.springframework.web.bind.annotation.RestController; - -import org.onap.sdc.dcae.catalog.asdc.ASDC; -import org.onap.sdc.dcae.catalog.asdc.ASDCUtils; -import org.onap.sdc.dcae.catalog.asdc.ASDCUtilsController; - -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.http.HttpStatus; -import org.springframework.http.HttpHeaders; -import org.springframework.http.ResponseEntity; - +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; - -import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.web.bind.annotation.RestController; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; -import org.json.JSONObject; - @RestController @ConfigurationProperties(prefix="asdcUtilsController") public class ASDCUtilsController implements ApplicationContextAware { - private ApplicationContext appCtx; private OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); - - //Constants// - private static String NOT_CERTIFIED_CHECKOUT = "NOT_CERTIFIED_CHECKOUT"; - private static String NOT_CERTIFIED_CHECKIN = "NOT_CERTIFIED_CHECKIN"; - private static String CERTIFICATION_IN_PROGRESS = "CERTIFICATION_IN_PROGRESS"; - private static String CERTIFIED = "CERTIFIED"; - public void setApplicationContext(ApplicationContext theCtx) throws BeansException { - this.appCtx = theCtx; + // no use for app context } @PostConstruct public void initController() { debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"initASDCUtilsController"); - - //Done debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"ASDCUtilsController started"); } diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Blueprinter.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Blueprinter.java index 3e78d38..4e5349f 100644 --- a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Blueprinter.java +++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Blueprinter.java @@ -10,7 +10,6 @@ import org.onap.sdc.common.onaplog.Enums.LogLevel; import org.onap.sdc.dcae.catalog.commons.Action; import org.onap.sdc.dcae.catalog.commons.Future; import org.onap.sdc.dcae.catalog.commons.Http; -import org.json.JSONArray; import org.springframework.util.Base64Utils; @@ -26,51 +25,41 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @Scope("singleton") @ConfigurationProperties(prefix="blueprinter") public class Blueprinter { + private URI serviceUri; + private OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); + public void setUri(URI theUri) { + this.serviceUri = theUri; + } - private URI serviceUri; - private OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); + public BlueprintAction generateBlueprint() { + return new BlueprintAction(); + } + public class BlueprintAction implements Action<String> { - public Blueprinter() { - } + private JSONObject body = new JSONObject(); - public void setUri(URI theUri) { - this.serviceUri = theUri; - } + protected BlueprintAction() { + } - public BlueprintAction generateBlueprint() { - return new BlueprintAction(); - } + public BlueprintAction withModelInfo(JSONObject theModelInfo) { + body.append("models", theModelInfo); + return this; + } - public class BlueprintAction implements Action<String> { + public BlueprintAction withTemplateData(byte[] theData) { + body.put("template", Base64Utils.encodeToString(theData)); + return this; + } - private JSONObject body = new JSONObject(); + public Future<String> execute() { - - protected BlueprintAction() { - } - - public BlueprintAction withModelData(byte[] theSchema, byte[] theTemplate, byte[] theTranslation) { - return this; - } - - public BlueprintAction withModelInfo(JSONObject theModelInfo) { - body.append("models", theModelInfo); - return this; - } - - public BlueprintAction withTemplateData(byte[] theData) { - body.put("template", Base64Utils.encodeToString(theData)); - return this; - } - - public Future<String> execute() { - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Blueprinter::execute() | PAYLOAD to TOSCA_LAB={}", body.toString()); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); - return Http.exchange(serviceUri.toString(), HttpMethod.POST, new HttpEntity<String>(body.toString(), headers), String.class); - } - } + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Blueprinter::execute() | PAYLOAD to TOSCA_LAB={}", body.toString()); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + return Http.exchange(serviceUri.toString(), HttpMethod.POST, new HttpEntity<>(body.toString(), headers), String.class); + } + } } diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Cloudify.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Cloudify.java deleted file mode 100644 index 3208bd2..0000000 --- a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Cloudify.java +++ /dev/null @@ -1,249 +0,0 @@ -package org.onap.sdc.dcae.catalog.asdc; - -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.stream.Stream; - -import org.apache.commons.jxpath.JXPathContext; -import org.apache.commons.jxpath.Pointer; -import org.onap.sdc.common.onaplog.OnapLoggerDebug; -import org.onap.sdc.common.onaplog.OnapLoggerError; -import org.onap.sdc.common.onaplog.Enums.LogLevel; -import org.onap.sdc.dcae.catalog.commons.ListBuilder; -import org.onap.sdc.dcae.catalog.commons.MapBuilder; -import org.onap.sdc.dcae.checker.Catalog; -import org.onap.sdc.dcae.checker.Construct; -import org.onap.sdc.dcae.checker.Target; - -import com.google.common.collect.Lists; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; - - -public class Cloudify { - - private static OnapLoggerError errLogger = OnapLoggerError.getInstance(); - private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); - - Catalog catalog; - - public Cloudify(Catalog c) - { - catalog = c; - } - public class ModelTemplate { - public Map<String, Map> template; - public JXPathContext jx; - public String node; - public ModelTemplate(Map<String, Map> t, JXPathContext j, String node_name) - { - template = t; - jx = j; - node = node_name; - } - - public Object getPropValue(JXPathContext jx_src, String name) - { - try{ - Object ret = jx_src.getValue("properties/"+name+"/get_input"); - if (ret==null) - return jx_src.getValue("properties/"+name); - return getDefaultPropValue((String)ret); - } - catch (RuntimeException e) { - - } - try{ - return jx_src.getValue("properties/"+name+""); - } - catch (RuntimeException e) { - return null; - } - } - - public Object getDefaultPropValue(String name) { - try { - return jx.getValue("//"+name+"/default"); - } - catch (RuntimeException e) { - return null; - } - - } - } - - public class ModelTranslate { - public Map<String, Map> template; - public JXPathContext jx; - public String node; - - public ModelTranslate(Map<String, Map> t, JXPathContext j, String node_name) - { - template = t; - jx = j; - node = node_name; - } - - public String getTranslateName() - { - Map<String, Object> node_temp = (Map<String, Object>)jx.getValue("//node_templates"); - Iterator it = node_temp.keySet().iterator(); - if (it.hasNext()) - return node + "_"+ it.next(); - else - return null; - } - - public Map<String, Object> translate(JXPathContext jx_src, Map<String, Map> model_lib, String node_name) - { - for (Iterator prop_iter = jx.iteratePointers("//*[@get_input]"); prop_iter.hasNext();) { - - Pointer p = (Pointer)prop_iter.next(); - JXPathContext prop_path = jx.getRelativeContext(p); - - ModelTemplate src_model =(ModelTemplate) model_lib.get(node_name).get("model"); - - Object temp_o = src_model.getPropValue(jx_src, (String) prop_path.getValue("get_input")); - //prop_path.setValue(".", temp_o); - jx.setValue(p.asPath(), temp_o); - } - -// JXPathContext jx_src = JXPathContext.newContext(src); - for (Iterator req_iter = jx_src.iteratePointers("//*/node"); req_iter.hasNext();) { - Pointer p = (Pointer)req_iter.next(); - String req_node_name = (String)jx_src.getValue(p.asPath()); - - for (Iterator it = model_lib.keySet().iterator(); it.hasNext();) { - String key = (String) it.next(); - if (key.indexOf(req_node_name) <0 ) - continue; - ModelTranslate tt = (ModelTranslate) model_lib.get(key).get("translate"); - if (tt == null) - req_node_name = null; - else - { - req_node_name = tt.getTranslateName(); - } - break; - } - - } - - String tn_name = getTranslateName(); - - if (tn_name == null) - return (Map<String, Object>)jx.getValue("//node_templates"); - else - return (new MapBuilder<String, Object>().put(tn_name, jx.getValue("//node_templates/*")).build()); - } - - } - - public ModelTranslate findTranslateTemplate(String ty, String node) { - for (Target t: catalog.targets()) { - - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "findTranslateTemplate: target {}", t.getName()); - if (t.getName().startsWith("translat") == false) { - continue; - } - - Map<String, Map>temp = (Map<String, Map>)t.getTarget(); - - JXPathContext jxroot = JXPathContext.newContext(temp); - try{ - String sub_type = (String)jxroot.getValue("topology_template/substitution_mappings/node_type"); - if (sub_type != null && sub_type.equals(ty)) { - return new ModelTranslate(temp, jxroot, node); - } - } - catch (RuntimeException e) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "translate template {} does not have substitution mapping section", t.getName()); - } - } - return null; - } - - public ModelTemplate findModelTemplate(String ty, String node) { - for (Target t: catalog.targets()) { - - if (t.getName().startsWith("templat") == false) - continue; - Map<String, Map>temp = (Map<String, Map>)t.getTarget(); - - JXPathContext jxroot = JXPathContext.newContext(temp); - for (Iterator it = jxroot.iterate("topology_template/node_templates/*/type"); it.hasNext();) { - String node_type = (String)it.next(); - if (node_type != null && node_type.equals(ty)) { - return new ModelTemplate(temp, jxroot, node); - } - } - } - return null; - } - - public Map<String, Object> createBlueprint() { - - Map<String, Map> target_temp = null; - for (Target t: catalog.targets()) { - - if (t.getName().equals("cdump")) { - target_temp = catalog.getTargetTemplates(t, Construct.Node); - } - } - - JXPathContext jxroot = JXPathContext.newContext(target_temp); - - Map<String, Object> output_temp = new HashMap<String, Object>(); - Map<String, Map> model_lib = new HashMap<String, Map>(); - - for (Iterator iter = target_temp.keySet().iterator(); iter.hasNext();) - { - String node_key = (String)iter.next(); - //jxroot.getVariables().declareVariable("name", target_temp.get(node_key)); - //String node_type = (String)jxroot.getValue("$name/type"); - String node_type = (String)jxroot.getValue(node_key+"/type"); - - ModelTranslate t_temp = findTranslateTemplate(node_type, node_key); - ModelTemplate t_model = findModelTemplate(node_type, node_key); - - model_lib.put(node_key, new MapBuilder() - .put("model", t_model) - .put("translate", t_temp) - .build()); - } - - for (Iterator iter = model_lib.keySet().iterator(); iter.hasNext();) { - String node_key = (String) iter.next(); - ModelTranslate t = (ModelTranslate) model_lib.get(node_key).get("translate"); - JXPathContext jxnode = jxroot.getRelativeContext(jxroot.getPointer(node_key)); - if (t != null) { - Map<String, Object> t_output =t.translate(jxnode, model_lib, node_key); - if (t_output != null) - output_temp.putAll(t_output); - } - - } - - return new MapBuilder<String, Object>() - .put("tosca_definitions_version", new String("cloudify_dsl_1_3")) - .put("imports", new ListBuilder() - .add(new MapBuilder() - .put("cloudify", - "http://www.getcloudify.org/spec/cloudify/3.4/types.yaml") - .build()) - .build()) - .put("node_templates", output_temp) - .build(); - - } - - public String createBlueprintDocument() { - DumperOptions options = new DumperOptions(); - options.setWidth(1000000); - Yaml yaml = new Yaml(options); - return yaml.dump(createBlueprint()); - } -} diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/ISdcClient.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/ISdcClient.java index 554991a..c389d75 100644 --- a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/ISdcClient.java +++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/ISdcClient.java @@ -1,47 +1,48 @@ package org.onap.sdc.dcae.client; +import com.fasterxml.jackson.core.JsonProcessingException; import org.onap.sdc.dcae.composition.restmodels.CreateVFCMTRequest; -import org.onap.sdc.dcae.composition.restmodels.sdc.*; import org.onap.sdc.dcae.composition.restmodels.ReferenceUUID; -import org.onap.sdc.dcae.enums.AssetType; +import org.onap.sdc.dcae.composition.restmodels.sdc.*; import java.util.List; public interface ISdcClient { - ResourceDetailed getResource(String uuid, String requestId) throws Exception; + ResourceDetailed getResource(String uuid, String requestId); + + ServiceDetailed getService(String uuid, String requestId); - ServiceDetailed getService(String uuid, String requestId) throws Exception; + ServiceDetailed getAssetMetadata(String contextType, String uuid, String requestId); - List<Resource> getResources(String resourceType, String category, String subcategory, String requestId) throws Exception; + List<Resource> getResources(String resourceType, String category, String subcategory, String requestId); - List<Service> getServices(String requestId) throws Exception; + List<Service> getServices(String requestId); - String addExternalMonitoringReference(String userId, CreateVFCMTRequest resource, ReferenceUUID vfiUuid, String requestId); + String addExternalMonitoringReference(String userId, String contextType, String serviceUuid, String vfiName, ReferenceUUID vfcmtUuid, String requestId); - void deleteExternalMonitoringReference(String userId, String context, String uuid, String vfiName, String vfcmtUuid, String requestId); + String addExternalMonitoringReference(String userId, CreateVFCMTRequest resource, ReferenceUUID vfcmtUuid, String requestId); - ResourceDetailed createResource(String userId, CreateVFCMTRequest resource, String requestId) throws Exception; + void deleteExternalMonitoringReference(String userId, String contextType, String uuid, String vfiName, String vfcmtUuid, String requestId); - ResourceDetailed changeResourceLifecycleState(String userId, String uuid, String lifecycleOperation, String userRemarks, String requestId) throws Exception; + ResourceDetailed createResource(String userId, CreateVFCMTRequest resource, String requestId); - ServiceDetailed changeServiceLifecycleState(String userId, String uuid, String lifecycleOperation, String userRemarks, String requestId) throws Exception; + ResourceDetailed changeResourceLifecycleState(String userId, String uuid, String lifecycleOperation, String userRemarks, String requestId); - Asset changeAssetLifecycleState(String userId, String uuid, String lifecycleOperation, String userRemarks, AssetType assetType, String requestId) throws Exception; + String getResourceArtifact(String resourceUuid, String artifactUuid, String requestId); - String getResourceArtifact(String resourceUuid, String artifactUuid, String requestId) throws Exception; + Artifact createResourceArtifact(String userId, String resourceUuid, Artifact artifact, String requestId) throws JsonProcessingException; - Artifact createResourceArtifact(String userId, String resourceUuid, Artifact artifact, String requestId) throws Exception; + Artifact updateResourceArtifact(String userId, String resourceUuid, Artifact artifact, String requestId) throws JsonProcessingException; - Artifact updateResourceArtifact(String userId, String resourceUuid, Artifact artifact, String requestId) throws Exception; + void deleteResourceArtifact(String userId, String resourceUuid, String artifactId, String requestId); - void deleteResourceArtifact(String userId, String resourceUuid, String artifactId, String requestId) throws Exception; + Artifact createInstanceArtifact(String userId, String contextType, String serviceUuid, String normalizedInstanceName, Artifact artifact, String requestId) throws JsonProcessingException; - Artifact createVfInstanceArtifact(String userId, String serviceUuid, String normalizedInstanceName, Artifact artifact, String requestId) throws Exception; + Artifact updateInstanceArtifact(String userId, String contextType, String serviceUuid, String normalizedInstanceName, Artifact artifact, String requestId) throws JsonProcessingException; - Artifact updateVfInstanceArtifact(String userId, String serviceUuid, String normalizedInstanceName, Artifact artifact, String requestId) throws Exception; + ExternalReferencesMap getMonitoringReferences(String contextType, String uuid, String version, String requestId); - ExternalReferencesMap getMonitoringReferences(String context, String uuid, String version, String requestId); + void deleteInstanceArtifact(String userId, String contextType, String serviceUuid, String normalizedVfiName, String artifactUuid, String requestId); - void deleteInstanceResourceArtifact(String userId, String context, String serviceUuid, String normalizedVfiName, String artifactUuid, String requestId); } diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/SdcRestClient.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/SdcRestClient.java index 058d9c7..b07126e 100644 --- a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/SdcRestClient.java +++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/SdcRestClient.java @@ -1,9 +1,12 @@ package org.onap.sdc.dcae.client; +import com.fasterxml.jackson.core.JsonProcessingException; import org.apache.commons.codec.digest.DigestUtils; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicHeader; +import org.onap.sdc.common.onaplog.Enums.LogLevel; +import org.onap.sdc.common.onaplog.OnapLoggerDebug; import org.onap.sdc.dcae.composition.restmodels.CreateVFCMTRequest; import org.onap.sdc.dcae.composition.restmodels.ReferenceUUID; import org.onap.sdc.dcae.composition.restmodels.sdc.*; @@ -14,18 +17,22 @@ import org.onap.sdc.dcae.enums.SdcConsumerInfo; import org.onap.sdc.dcae.utils.Normalizers; import org.onap.sdc.dcae.utils.SDCResponseErrorHandler; import org.onap.sdc.dcae.utils.SdcRestClientUtils; -import org.onap.sdc.common.onaplog.OnapLoggerDebug; -import org.onap.sdc.common.onaplog.Enums.LogLevel; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.*; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.stereotype.Component; import org.springframework.util.Base64Utils; -import org.springframework.web.client.*; +import org.springframework.web.client.RestTemplate; import javax.annotation.PostConstruct; import java.net.URI; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumMap; +import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -39,8 +46,6 @@ public class SdcRestClient implements ISdcClient { private static final String ECOMP_INSTANCE_ID_HEADER = "X-ECOMP-InstanceID"; private static final String ECOMP_REQUEST_ID_HEADER = "X-ECOMP-RequestID"; private static final String USER_ID_HEADER = "USER_ID"; - private static final String RESOURCES_PATH = "resources"; - private static final String SERVICES_PATH = "services"; private static final String ARTIFACTS_PATH = "artifacts"; private static final String CONTENT_MD5_HEADER = "Content-MD5"; private static final String RESOURCE_INSTANCES_PATH = "resourceInstances"; @@ -76,117 +81,110 @@ public class SdcRestClient implements ISdcClient { return headers; } + public ServiceDetailed getAssetMetadata(String contextType, String uuid, String requestId) { + String url = buildRequestPath(AssetType.getSdcContextPath(contextType), uuid, METADATA_PATH); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Get asset metadata from SDC. URL={}", url); + return getObject(url, requestId, ServiceDetailed.class); + } + public ResourceDetailed getResource(String uuid, String requestId) { - String url = buildRequestPath(RESOURCES_PATH, uuid, METADATA_PATH); + String url = buildRequestPath(AssetType.RESOURCE.getSdcContextPath(), uuid, METADATA_PATH); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Get resource from SDC. URL={}", url); return getObject(url, requestId, ResourceDetailed.class); } public ServiceDetailed getService(String uuid, String requestId) { - String url = buildRequestPath(SERVICES_PATH, uuid, METADATA_PATH); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Get service from SDC. URL={}", url); - return getObject(url, requestId, ServiceDetailed.class); + return getAssetMetadata(AssetType.SERVICE.name(), uuid, requestId); } public List<Resource> getResources(String resourceType, String category, String subcategory, String requestId) { - String url = buildRequestPath(RESOURCES_PATH, SdcRestClientUtils.buildResourceFilterQuery(resourceType, category, subcategory)); + String url = buildRequestPath(AssetType.RESOURCE.getSdcContextPath(), SdcRestClientUtils.buildResourceFilterQuery(resourceType, category, subcategory)); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Get resources from SDC. URL={}", url); return Arrays.asList(getObject(url, requestId, Resource[].class)); } public List<Service> getServices(String requestId) { - String url = buildRequestPath(SERVICES_PATH); + String url = buildRequestPath(AssetType.SERVICE.getSdcContextPath()); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Get services from SDC. URL={}", url); return Arrays.asList(getObject(url, requestId, Service[].class)); } - public String addExternalMonitoringReference(String userId, CreateVFCMTRequest resource, ReferenceUUID vfcmtUuid, String requestId) { - String url = buildRequestPath(resource.getContextType(), resource.getServiceUuid(), RESOURCE_INSTANCES_PATH, - Normalizers.normalizeComponentInstanceName(resource.getVfiName()), MONITORING_REFERENCES_PATH); - - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Connecting service id {} name {} to vfcmt {} URL={}", - resource.getServiceUuid(), resource.getVfiName(), vfcmtUuid.getReferenceUUID(), url); + public String addExternalMonitoringReference(String userId, String contextType, String serviceUuid, String vfiName, ReferenceUUID vfcmtUuid, String requestId) { + String url = buildRequestPath(AssetType.getSdcContextPath(contextType), serviceUuid, RESOURCE_INSTANCES_PATH, Normalizers.normalizeComponentInstanceName(vfiName), MONITORING_REFERENCES_PATH); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Creating external monitoring reference from service id {} vfi name {} to vfcmt {} URL={}", serviceUuid, vfiName, vfcmtUuid.getReferenceUUID(), url); + return client.postForObject(url, new HttpEntity<>(vfcmtUuid, postResourceHeaders(userId, requestId)), String.class); + } - return client.postForObject(url, new HttpEntity<>(vfcmtUuid, postResourceHeaders(userId, requestId)), - String.class); + public String addExternalMonitoringReference(String userId, CreateVFCMTRequest resource, ReferenceUUID vfcmtUuid, String requestId) { + return addExternalMonitoringReference(userId, resource.getContextType(), resource.getServiceUuid(), resource.getVfiName(), vfcmtUuid, requestId); } - public void deleteExternalMonitoringReference(String userId, String context, String uuid, String normalizeVfiName, String vfcmtUuid, String requestId) { - String url = buildRequestPath(context, uuid, RESOURCE_INSTANCES_PATH, - normalizeVfiName, MONITORING_REFERENCES_PATH, vfcmtUuid); + public void deleteExternalMonitoringReference(String userId, String contextType, String serviceUuid, String normalizeVfiName, String vfcmtUuid, String requestId) { + String url = buildRequestPath(AssetType.getSdcContextPath(contextType), serviceUuid, RESOURCE_INSTANCES_PATH, normalizeVfiName, MONITORING_REFERENCES_PATH, vfcmtUuid); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Delete external monitoring reference from SDC asset. URL={}", url); client.exchange(url, HttpMethod.DELETE, new HttpEntity(postResourceHeaders(userId, requestId)), String.class); } public ResourceDetailed createResource(String userId, CreateVFCMTRequest resource, String requestId) { - String url = buildRequestPath(RESOURCES_PATH); + String url = buildRequestPath(AssetType.RESOURCE.getSdcContextPath()); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Create SDC resource with name {} URL={}", resource.getName(), url); return client.postForObject(url, new HttpEntity<>(resource, postResourceHeaders(userId, requestId)), ResourceDetailed.class); } public ResourceDetailed changeResourceLifecycleState(String userId, String uuid, String lifecycleOperation, String userRemarks, String requestId) { - String url = buildRequestPath(RESOURCES_PATH, uuid, LIFECYCLE_STATE_PATH); + String url = buildRequestPath(AssetType.RESOURCE.getSdcContextPath(), uuid, LIFECYCLE_STATE_PATH); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Change SDC resource lifecycle state ({}). URL={}", lifecycleOperation, url); return client.postForObject(url, new HttpEntity<>(SdcRestClientUtils.buildUserRemarksObject(userRemarks), postResourceHeaders(userId, requestId)), ResourceDetailed.class, lifecycleOperation); } - public ServiceDetailed changeServiceLifecycleState(String userId, String uuid, String lifecycleOperation, String userRemarks, String requestId) { - String url = buildRequestPath(SERVICES_PATH, uuid, LIFECYCLE_STATE_PATH); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Change SDC service lifecycle state ({}). URL={}", lifecycleOperation, url); - return client.postForObject(url, new HttpEntity<>(SdcRestClientUtils.buildUserRemarksObject(userRemarks), postResourceHeaders(userId, requestId)), ServiceDetailed.class, lifecycleOperation); - } - - public Asset changeAssetLifecycleState(String userId, String uuid, String lifecycleOperation, String userRemarks, AssetType assetType, String requestId) { - return AssetType.RESOURCE == assetType ? changeResourceLifecycleState(userId, uuid, lifecycleOperation, userRemarks, requestId) : changeServiceLifecycleState(userId, uuid, lifecycleOperation, userRemarks, requestId); - } - public String getResourceArtifact(String resourceUuid, String artifactUuid, String requestId) { - String url = buildRequestPath(RESOURCES_PATH, resourceUuid, ARTIFACTS_PATH, artifactUuid); + String url = buildRequestPath(AssetType.RESOURCE.getSdcContextPath(), resourceUuid, ARTIFACTS_PATH, artifactUuid); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Get resource artifact from SDC. URL={}", url); return getObject(url, requestId, String.class); } - public Artifact createResourceArtifact(String userId, String resourceUuid, Artifact artifact, String requestId) throws Exception { - String url = buildRequestPath(RESOURCES_PATH, resourceUuid, ARTIFACTS_PATH); + public Artifact createResourceArtifact(String userId, String resourceUuid, Artifact artifact, String requestId) throws JsonProcessingException { + String url = buildRequestPath(AssetType.RESOURCE.getSdcContextPath(), resourceUuid, ARTIFACTS_PATH); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Create SDC resource artifact. URL={}", url); String artifactData = SdcRestClientUtils.artifactToString(artifact); return client.postForObject(url, new HttpEntity<>(artifactData, postArtifactHeaders(userId, artifactData, requestId)), Artifact.class); } - public Artifact updateResourceArtifact(String userId, String resourceUuid, Artifact artifact, String requestId) throws Exception { - String url = buildRequestPath(RESOURCES_PATH, resourceUuid, ARTIFACTS_PATH, artifact.getArtifactUUID()); + public Artifact updateResourceArtifact(String userId, String resourceUuid, Artifact artifact, String requestId) throws JsonProcessingException { + String url = buildRequestPath(AssetType.RESOURCE.getSdcContextPath(), resourceUuid, ARTIFACTS_PATH, artifact.getArtifactUUID()); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Update SDC resource artifact. URL={}", url); String artifactData = SdcRestClientUtils.artifactToString(artifact); return client.postForObject(url, new HttpEntity<>(artifactData, postArtifactHeaders(userId, artifactData, requestId)), Artifact.class); } public void deleteResourceArtifact(String userId, String resourceUuid, String artifactId, String requestId) { - String url = buildRequestPath(RESOURCES_PATH, resourceUuid, ARTIFACTS_PATH, artifactId); + String url = buildRequestPath(AssetType.RESOURCE.getSdcContextPath(), resourceUuid, ARTIFACTS_PATH, artifactId); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Delete SDC resource artifact. URL={}", url); client.exchange(url, HttpMethod.DELETE, new HttpEntity(postResourceHeaders(userId, requestId)), Artifact.class); } - public Artifact createVfInstanceArtifact(String userId, String serviceUuid, String normalizedInstanceName, Artifact artifact, String requestId) throws Exception { - String url = buildRequestPath(SERVICES_PATH, serviceUuid, RESOURCE_INSTANCES_PATH, normalizedInstanceName, ARTIFACTS_PATH); + public Artifact createInstanceArtifact(String userId, String contextType, String serviceUuid, String normalizedInstanceName, Artifact artifact, String requestId) throws JsonProcessingException { + String url = buildRequestPath(AssetType.getSdcContextPath(contextType), serviceUuid, RESOURCE_INSTANCES_PATH, normalizedInstanceName, ARTIFACTS_PATH); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Create SDC resource instance artifact. URL={}", url); String artifactData = SdcRestClientUtils.artifactToString(artifact); return client.postForObject(url, new HttpEntity<>(artifactData, postArtifactHeaders(userId, artifactData, requestId)), Artifact.class); } - public Artifact updateVfInstanceArtifact(String userId, String serviceUuid, String normalizedInstanceName, Artifact artifact, String requestId) throws Exception { - String url = buildRequestPath(SERVICES_PATH, serviceUuid, RESOURCE_INSTANCES_PATH, normalizedInstanceName, ARTIFACTS_PATH, artifact.getArtifactUUID()); + public Artifact updateInstanceArtifact(String userId, String contextType, String serviceUuid, String normalizedInstanceName, Artifact artifact, String requestId) throws JsonProcessingException { + String url = buildRequestPath(AssetType.getSdcContextPath(contextType), serviceUuid, RESOURCE_INSTANCES_PATH, normalizedInstanceName, ARTIFACTS_PATH, artifact.getArtifactUUID()); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Update SDC resource instance artifact. URL={}", url); String artifactData = SdcRestClientUtils.artifactToString(artifact); return client.postForObject(url, new HttpEntity<>(artifactData, postArtifactHeaders(userId, artifactData, requestId)), Artifact.class); } - public ExternalReferencesMap getMonitoringReferences(String context, String uuid, String version, String requestId) { - String url = buildRequestPath(context, uuid, VERSION_PATH, version, MONITORING_REFERENCES_PATH); + public ExternalReferencesMap getMonitoringReferences(String contextType, String uuid, String version, String requestId) { + String url = buildRequestPath(AssetType.getSdcContextPath(contextType), uuid, VERSION_PATH, version, MONITORING_REFERENCES_PATH); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Get SDC service monitoring references. URL={}", url); return getObject(url, requestId, ExternalReferencesMap.class); } - public void deleteInstanceResourceArtifact(String userId, String context, String serviceUuid, String normalizedVfiName, String artifactUuid, String requestId) { - String url = buildRequestPath(context, serviceUuid, RESOURCE_INSTANCES_PATH, normalizedVfiName, ARTIFACTS_PATH, artifactUuid); + public void deleteInstanceArtifact(String userId, String contextType, String serviceUuid, String normalizedVfiName, String artifactUuid, String requestId) { + String url = buildRequestPath(AssetType.getSdcContextPath(contextType), serviceUuid, RESOURCE_INSTANCES_PATH, normalizedVfiName, ARTIFACTS_PATH, artifactUuid); debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Delete SDC instance resource artifact. URL={}", url); client.exchange(url, HttpMethod.DELETE, new HttpEntity(postResourceHeaders(userId, requestId)), Artifact.class); } diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/AssetType.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/AssetType.java index 576643f..647349f 100644 --- a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/AssetType.java +++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/AssetType.java @@ -1,5 +1,32 @@ package org.onap.sdc.dcae.enums; public enum AssetType { - RESOURCE, SERVICE + + RESOURCE(SdcContextPath.RESOURCES), + SERVICE(SdcContextPath.SERVICES), + VFCMT(SdcContextPath.RESOURCES), + VF(SdcContextPath.RESOURCES); + + private String sdcContextPath; + + AssetType(SdcContextPath sdcContextPath) { + this.sdcContextPath = sdcContextPath.name().toLowerCase(); + } + + public String getSdcContextPath() { + return sdcContextPath; + } + + // passing an invalid type will result in an IllegalArgumentException, which is fine as the 'type' value is an SDC enum value passed from SDC pluggable UI + public static AssetType getAssetTypeByName(String type) { + return AssetType.valueOf(type.toUpperCase()); + } + + public static String getSdcContextPath(String type) { + return getAssetTypeByName(type).getSdcContextPath(); + } + + private enum SdcContextPath { + RESOURCES, SERVICES + } } diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/BaseException.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/BaseException.java index b559634..17c25b2 100644 --- a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/BaseException.java +++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/BaseException.java @@ -7,55 +7,53 @@ import org.springframework.web.client.HttpClientErrorException; public class BaseException extends HttpClientErrorException { - private static Gson gson = new Gson(); - - protected RequestError requestError; - - public RequestError getRequestError() { - return requestError; - } - - public void setRequestError(RequestError requestError) { - this.requestError = requestError; - } - - public BaseException(HttpClientErrorException theError) { - super(theError.getStatusCode()); - String body = theError.getResponseBodyAsString(); - if (body != null) { - requestError = extractRequestError(body); - } - } - - public BaseException(HttpStatus status, RequestError re){ - super(status); - requestError = re; - } - - private RequestError extractRequestError(String error) { - ResponseFormat responseFormat = gson.fromJson(error, ResponseFormat.class); - return responseFormat.getRequestError(); - } - - @JsonIgnore - public String getMessageId() { - return requestError.getMessageId(); - } - - @JsonIgnore - public String[] getVariables() { - return requestError.getVariables(); - } - - @JsonIgnore - public String getText(){ - return requestError.getText(); - } - - @Override - @JsonIgnore - public String getMessage() { - return requestError.getFormattedMessage(); - } + private static final Gson gson = new Gson(); + + protected final transient RequestError requestError; + + public BaseException(HttpClientErrorException theError) { + super(theError.getStatusCode()); + String body = theError.getResponseBodyAsString(); + if (body != null) { + requestError = extractRequestError(body); + } else { + requestError = null; + } + } + + public BaseException(HttpStatus status, RequestError re){ + super(status); + requestError = re; + } + + public RequestError getRequestError() { + return requestError; + } + + private RequestError extractRequestError(String error) { + ResponseFormat responseFormat = gson.fromJson(error, ResponseFormat.class); + return responseFormat.getRequestError(); + } + + @JsonIgnore + public String getMessageId() { + return requestError.getMessageId(); + } + + @JsonIgnore + public String[] getVariables() { + return requestError.getVariables(); + } + + @JsonIgnore + public String getText(){ + return requestError.getText(); + } + + @Override + @JsonIgnore + public String getMessage() { + return requestError.getFormattedMessage(); + } }
\ No newline at end of file diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/OkResponseInfo.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/OkResponseInfo.java index 53bdf3e..f2a7f9a 100644 --- a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/OkResponseInfo.java +++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/OkResponseInfo.java @@ -2,7 +2,7 @@ package org.onap.sdc.dcae.errormng; public class OkResponseInfo extends AbstractSdncException { - public OkResponseInfo(String messageId, String text, String[] variables) { + OkResponseInfo(String messageId, String text, String[] variables) { super(messageId, text, variables); } } diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/PolicyException.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/PolicyException.java index 3fc2d71..8a4aec9 100644 --- a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/PolicyException.java +++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/PolicyException.java @@ -5,7 +5,4 @@ public class PolicyException extends AbstractSdncException { public PolicyException(String messageId, String text, String[] variables) { super(messageId, text, variables); } - - public PolicyException() { - } } diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/RequestError.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/RequestError.java index 00fe3f2..7207916 100644 --- a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/RequestError.java +++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/RequestError.java @@ -9,25 +9,16 @@ public class RequestError { private PolicyException policyException; private ServiceException serviceException; private OkResponseInfo okResponseInfo; - private List<ServiceException> serviceExceptions; - - public PolicyException getPolicyException() { - return policyException; - } public ServiceException getServiceException() { return serviceException; } - public OkResponseInfo getOkResponseInfo() { - return okResponseInfo; - } - public void setPolicyException(PolicyException policyException) { this.policyException = policyException; } - void setServiceException(ServiceException serviceException) { + public void setServiceException(ServiceException serviceException) { this.serviceException = serviceException; } @@ -35,12 +26,8 @@ public class RequestError { this.okResponseInfo = okResponseInfo; } - public List<ServiceException> getServiceExceptions() { - return serviceExceptions; - } - void setServiceExceptions(List<ServiceException> serviceExceptions) { - this.serviceExceptions = serviceExceptions; + // no one asks for these exception ever } String getFormattedMessage() { @@ -60,6 +47,11 @@ public class RequestError { } AbstractSdncException getError() { - return null != serviceException ? serviceException : null != policyException ? policyException : okResponseInfo; + if (null != policyException) { + return (null != serviceException) ? serviceException : policyException; + } + else { + return (null != serviceException) ? serviceException : okResponseInfo; + } } }
\ No newline at end of file diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/ServiceException.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/ServiceException.java index 163a07f..68e646c 100644 --- a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/ServiceException.java +++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/ServiceException.java @@ -1,12 +1,7 @@ package org.onap.sdc.dcae.errormng; public class ServiceException extends AbstractSdncException { - public ServiceException(String messageId, String text, String[] variables) { super(messageId, text, variables); } - - public ServiceException() { - } - }
\ No newline at end of file diff --git a/dcaedt_catalog/asdc/src/test/org/onap/sdc/dcae/utils/NormalizersTest.java b/dcaedt_catalog/asdc/src/test/java/org/onap/sdc/dcae/utils/NormalizersTest.java index bf06e22..5a9b5f5 100644 --- a/dcaedt_catalog/asdc/src/test/org/onap/sdc/dcae/utils/NormalizersTest.java +++ b/dcaedt_catalog/asdc/src/test/java/org/onap/sdc/dcae/utils/NormalizersTest.java @@ -1,11 +1,7 @@ package org.onap.sdc.dcae.utils; -import static org.assertj.core.api.Assertions.*; - import org.assertj.core.api.Assertions; import org.junit.Test; -import org.onap.sdc.dcae.utils.Normalizers; - public class NormalizersTest { diff --git a/dcaedt_catalog/asdc/src/test/java/org/onap/sdc/dcae/utils/SDCResponseErrorHandlerTest.java b/dcaedt_catalog/asdc/src/test/java/org/onap/sdc/dcae/utils/SDCResponseErrorHandlerTest.java new file mode 100644 index 0000000..f17e18f --- /dev/null +++ b/dcaedt_catalog/asdc/src/test/java/org/onap/sdc/dcae/utils/SDCResponseErrorHandlerTest.java @@ -0,0 +1,93 @@ +package org.onap.sdc.dcae.utils; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpServerErrorException; + +import java.io.IOException; +import java.io.InputStream; + +@RunWith(MockitoJUnitRunner.class) +public class SDCResponseErrorHandlerTest { + @InjectMocks + private SDCResponseErrorHandler classUnderTest; + private ClientHttpResponse clientHttpResponse; + private HttpStatus httpStatus; + + @Before + public void setup() { + clientHttpResponse = new ClientHttpResponse() { + @Override + public HttpStatus getStatusCode() throws IOException { + return httpStatus; + } + + @Override + public int getRawStatusCode() throws IOException { + return 0; + } + + @Override + public String getStatusText() throws IOException { + return null; + } + + @Override + public void close() { + + } + + @Override + public InputStream getBody() throws IOException { + return null; + } + + @Override + public HttpHeaders getHeaders() { + return new HttpHeaders(); + } + }; + } + + @Test(expected = HttpClientErrorException.class) + public void handleError_haveError_throwsClientException() throws IOException { + httpStatus = HttpStatus.EXPECTATION_FAILED; + classUnderTest.handleError(clientHttpResponse); + } + + @Test(expected = HttpServerErrorException.class) + public void handleError_haveError_throwsServerException() throws IOException { + httpStatus = HttpStatus.BAD_GATEWAY; + classUnderTest.handleError(clientHttpResponse); + } + + @Test + public void hasError_haveClientError_returnTrue() throws IOException { + httpStatus = HttpStatus.EXPECTATION_FAILED; + boolean result = classUnderTest.hasError(clientHttpResponse); + Assert.assertTrue(result); + } + + @Test + public void hasError_haveServerError_returnTrue() throws IOException { + httpStatus = HttpStatus.BAD_GATEWAY; + boolean result = classUnderTest.hasError(clientHttpResponse); + Assert.assertTrue(result); + } + + @Test + public void hasError_200OK_returnFalse() throws IOException { + httpStatus = HttpStatus.OK; + boolean result = classUnderTest.hasError(clientHttpResponse); + Assert.assertFalse(result); + } + +}
\ No newline at end of file diff --git a/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Futures.java b/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Futures.java index ffaf42b..a405932 100644 --- a/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Futures.java +++ b/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Futures.java @@ -8,9 +8,6 @@ import java.util.concurrent.CountDownLatch; import java.util.function.Function; import org.onap.sdc.common.onaplog.OnapLoggerDebug; -import org.onap.sdc.common.onaplog.OnapLoggerError; -import org.onap.sdc.dcae.catalog.commons.Future; -import org.onap.sdc.dcae.catalog.commons.FutureHandler; import org.onap.sdc.common.onaplog.Enums.LogLevel; @@ -196,16 +193,13 @@ public class Futures<T> { return this; } } - - /** */ + public static class Accumulator<T> extends BasicFuture<List<T>> implements Future<List<T>> { - protected List<Future<T>> futures = new LinkedList<Future<T>>(); - //protected List<T> results = new LinkedList<T>(); - protected BasicHandler<T> handler = null; + protected List<Future<T>> futures = new LinkedList<Future<T>>(); + protected BasicHandler<T> accumulatorHandler = null; - private static OnapLoggerError errLogger = OnapLoggerError.getInstance(); private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); public Accumulator() { @@ -228,7 +222,7 @@ public class Futures<T> { public Future<List<T>> accumulate() { this.futures = Collections.unmodifiableList(this.futures); - this.handler = new BasicHandler<T>(new CountDownLatch(this.futures.size())) { + this.accumulatorHandler = new BasicHandler<T>(new CountDownLatch(this.futures.size())) { protected void process(Future<T> theResult) { if (theResult.failed()) { Accumulator.this.cause = theResult.cause(); @@ -246,7 +240,7 @@ public class Futures<T> { } }; futures.stream() - .forEach(f -> f.setHandler(this.handler)); + .forEach(f -> f.setHandler(this.accumulatorHandler)); return this; } diff --git a/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Proxies.java b/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Proxies.java index 8983599..0b13def 100644 --- a/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Proxies.java +++ b/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Proxies.java @@ -19,10 +19,6 @@ public class Proxies { public static <T> T build(Map theData, Class<T> theType) { return builder.build(new JSONObject(theData), theType); } - - public static <T> T build(Map theData, Map theContextData, Class<T> theType) { - return builder.build(new JSONObject(theData), theContextData, theType); - } public static <T> T build(JSONObject theData, Class<T> theType) { return builder.build(theData, theType); diff --git a/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Proxy.java b/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Proxy.java index d368886..bdce9c3 100644 --- a/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Proxy.java +++ b/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Proxy.java @@ -1,30 +1,14 @@ package org.onap.sdc.dcae.catalog.commons; import java.util.List; -import java.util.LinkedList; -import java.util.Map; -import java.util.Collections; - -import java.util.stream.Collectors; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; - -import java.lang.reflect.Type; import java.lang.reflect.Method; -import java.lang.reflect.Array; import java.lang.reflect.Constructor; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; - import java.lang.invoke.MethodHandles; -import com.google.common.reflect.Invokable; -import org.onap.sdc.dcae.catalog.commons.Proxy; -import org.onap.sdc.dcae.catalog.commons.ProxyBuilder; import com.google.common.reflect.AbstractInvocationHandler; import org.apache.commons.beanutils.ConvertUtils; @@ -37,13 +21,13 @@ public class Proxy extends AbstractInvocationHandler { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) - public static @interface DataMap { + public @interface DataMap { - public String map() default ""; + String map() default ""; - public boolean proxy() default false; + boolean proxy() default false; - public Class elementType() default Void.class; + Class elementType() default Void.class; } @@ -51,12 +35,10 @@ public class Proxy extends AbstractInvocationHandler { static { try { - lookupHandleConstructor = - MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, - int.class); + lookupHandleConstructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class); if (!lookupHandleConstructor.isAccessible()) { - lookupHandleConstructor.setAccessible(true); + lookupHandleConstructor.setAccessible(true); } } catch (Exception x) { @@ -64,7 +46,6 @@ public class Proxy extends AbstractInvocationHandler { } } - private JSONObject data; private ProxyBuilder builder; @@ -81,11 +62,9 @@ public class Proxy extends AbstractInvocationHandler { return this.builder; } - protected Object handleInvocation( - Object theProxy,Method theMethod,Object[] theArgs) - throws Throwable { + protected Object handleInvocation(Object theProxy,Method theMethod,Object[] theArgs) throws Throwable { if (theMethod.isDefault()) { - final Class<?> declaringClass = theMethod.getDeclaringClass(); + final Class<?> declaringClass = theMethod.getDeclaringClass(); return lookupHandleConstructor .newInstance(declaringClass, MethodHandles.Lookup.PRIVATE) @@ -96,28 +75,35 @@ public class Proxy extends AbstractInvocationHandler { String key = theMethod.getName(); - Proxy.DataMap dataMap = (Proxy.DataMap)theMethod.getAnnotation(Proxy.DataMap.class); + Proxy.DataMap dataMap = theMethod.getAnnotation(Proxy.DataMap.class); if (dataMap != null) { String dataKey = dataMap.map(); - if (dataKey != null && !"".equals(dataKey)) + if (!"".equals(dataKey)) { key = dataKey; + } } //this is ugly, can this be done through an extension mechanism such as plugging in functions? - if ( builder.hasExtension(key) ) + if ( builder.hasExtension(key) ) { return this.builder.extension(key).apply(this, theArgs); + } //we give priority to the context (because of the 'catalog' property issue in catalog service) but //how natural is this? Object val = this.builder.context(key); - if (val == null) + if (val == null) { val = this.data.opt(key); + } - if (val == null) + if (val == null) { return null; + } + return getProxies(theMethod, dataMap, val); + } -//as we create proxies here we should store them back in the 'data' so that we do not do it again -//can we always 'recognize' them? + private Object getProxies(Method theMethod, DataMap dataMap, Object val) throws InstantiationException, IllegalAccessException { + //as we create proxies here we should store them back in the 'data' so that we do not do it again + //can we always 'recognize' them? if (val instanceof String && String.class != theMethod.getReturnType()) { //??This will yield a POJO .. @@ -128,7 +114,7 @@ public class Proxy extends AbstractInvocationHandler { return builder.build((JSONObject)val, theMethod.getReturnType()); } } - else if (val instanceof JSONArray&& dataMap != null && + else if (val instanceof JSONArray && dataMap != null && dataMap.proxy() && List.class.isAssignableFrom(theMethod.getReturnType())) { diff --git a/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/ProxyBuilder.java b/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/ProxyBuilder.java index e3a422a..8b6e6d1 100644 --- a/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/ProxyBuilder.java +++ b/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/ProxyBuilder.java @@ -21,40 +21,18 @@ public class ProxyBuilder { public ProxyBuilder() { } -/* - public <T> T build(Map theData, Class<T> theType) { - return build(theData, this.context, theType); - } - - public <T> T build(Map theData, Map theContextData, Class<T> theType) { - return (T)java.lang.reflect.Proxy.newProxyInstance( - ProxyBuilder.class.getClassLoader(), - new Class[] { theType }, - new Proxy(theData, this)); - } -*/ + public <T> T build(Map theData, Class<T> theType) { return build(new JSONObject(theData), theType); } - - public <T> T build(Map theData, Map theContextData, Class<T> theType) { - return build(new JSONObject(theData), theContextData, theType); - } public <T> T build(JSONObject theData, Class<T> theType) { - return build(theData, this.context, theType); - } - - public <T> T build(JSONObject theData, Map theContextData, Class<T> theType) { return (T)java.lang.reflect.Proxy.newProxyInstance( - ProxyBuilder.class.getClassLoader(), - new Class[] { theType }, - new Proxy(theData, this)); + ProxyBuilder.class.getClassLoader(), + new Class[] { theType }, + new Proxy(theData, this)); } - - - public ProxyBuilder withConverter(final Function<Object, ?> theConverter, Class theType) { ConvertUtils.register(new Converter() { public Object convert(Class theToType, Object theValue) { diff --git a/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Recycler.java b/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Recycler.java index 3493cb1..f6ea6ad 100644 --- a/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Recycler.java +++ b/dcaedt_catalog/commons/src/main/java/org/onap/sdc/dcae/catalog/commons/Recycler.java @@ -138,26 +138,26 @@ public class Recycler { } } String type = (String)theSpec.get("type"); - if (value != null && type != null) { + if (value != null && type != null && !"string".equals(type)) { value = getValueByType(value, type); } return value; } private Object getValueByType(Object value, String type) { - Object returnValue = null; + try { if ("map".equals(type) && !(value instanceof Map)) { - returnValue = new ObjectMapper().readValue(value.toString(), new TypeReference<Map>(){}); + return new ObjectMapper().readValue(value.toString(), new TypeReference<Map>(){}); } - else if ("list".equals(type) && !(value instanceof List)) { - returnValue = new ObjectMapper().readValue(value.toString(), new TypeReference<List>(){}); + if ("list".equals(type) && !(value instanceof List)) { + return new ObjectMapper().readValue(value.toString(), new TypeReference<List>(){}); } - else if ("integer".equals(type) && (value instanceof String)) { - returnValue = Integer.valueOf((String)value); + if ("integer".equals(type) && (value instanceof String)) { + return Integer.valueOf((String)value); } - else if ("float".equals(type) && (value instanceof String)) { - returnValue = Double.valueOf((String)value); //double because that's how the yaml parser would encode it + if ("float".equals(type) && (value instanceof String)) { + return Double.valueOf((String)value); //double because that's how the yaml parser would encode it } } catch (NumberFormatException nfx) { @@ -166,7 +166,7 @@ public class Recycler { catch (IOException iox) { debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Failed to process {} representation of a collection: {}", value.getClass().getName(), iox); } - return returnValue; + return value; } /* */ diff --git a/dcaedt_catalog/service/Dockerfile b/dcaedt_catalog/service/Dockerfile new file mode 100644 index 0000000..c99dc32 --- /dev/null +++ b/dcaedt_catalog/service/Dockerfile @@ -0,0 +1,19 @@ +FROM java:8u40-jre +MAINTAINER Arthur Martella <am153x@att.com> +ENV insdir /opt/app/catalog +RUN \ + mkdir -p ${insdir}/lib \ + && mkdir -p ${insdir}/etc \ + && mkdir -p ${insdir}/log \ + && useradd -d ${insdir} catalog \ + && chown -R catalog:catalog ${insdir} +WORKDIR ${insdir} +USER catalog +COPY target/ASC-Catalog*.jar ${insdir}/lib/ASC-Catalog.jar +#COPY target/deps/*.jar ${insdir}/lib/ +COPY src/main/resources/log4j.properties ${insdir}/etc/log4j.properties +#COPY src/main/resources/config.json ${insdir}/etc/config.json +#COPY src/main/resources/cluster.xml ${insdir}/etc/cluster.xml +VOLUME ${insdir}/log +EXPOSE 7575 +CMD ["/usr/bin/java","-jar","lib/ASC-Catalog.jar","--spring.profiles.active=default"] diff --git a/dcaedt_catalog/service/src/main/java/org/onap/sdc/dcae/catalog/engine/CatalogController.java b/dcaedt_catalog/service/src/main/java/org/onap/sdc/dcae/catalog/engine/CatalogController.java index 3e71c88..90994f6 100644 --- a/dcaedt_catalog/service/src/main/java/org/onap/sdc/dcae/catalog/engine/CatalogController.java +++ b/dcaedt_catalog/service/src/main/java/org/onap/sdc/dcae/catalog/engine/CatalogController.java @@ -18,41 +18,27 @@ under the License. */ package org.onap.sdc.dcae.catalog.engine; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; - -import static org.onap.sdc.dcae.catalog.Catalog.*; - -import java.net.URI; -import java.net.URISyntaxException; - import org.json.JSONObject; +import org.onap.sdc.common.onaplog.Enums.LogLevel; import org.onap.sdc.common.onaplog.OnapLoggerDebug; import org.onap.sdc.common.onaplog.OnapLoggerError; -import org.onap.sdc.common.onaplog.Enums.LogLevel; import org.onap.sdc.dcae.catalog.Catalog; import org.onap.sdc.dcae.catalog.asdc.ASDCCatalog; import org.onap.sdc.dcae.catalog.commons.Future; import org.onap.sdc.dcae.catalog.commons.FutureHandler; import org.onap.sdc.dcae.composition.util.DcaeBeConstants; import org.onap.sdc.dcae.composition.util.SystemProperties; -import org.json.JSONArray; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RestController; - import org.springframework.web.context.request.async.DeferredResult; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.web.bind.annotation.CrossOrigin; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; /** * All requests body: @@ -69,23 +55,23 @@ import org.springframework.web.bind.annotation.CrossOrigin; * } * * If a non-2xx reponse is provided and error occured at catalog engine processing level. - * If error has occured in data retrieval then the response error object is not empty. + * If error has occured in data retrieval then the response error object is not empty. * * Available uris * /catalog * /elements : roots of the catalog; request body is optional but can specify a label under 'startingLabel' * response contains items under 'data/elements' - * /{itemId}/elements : catalog descendants of the given item, possibly a mix of folders and items + * /{itemId}/elements : catalog descendants of the given item, possibly a mix of folders and items * response contains items under 'data/elements' * /lookup.by.name : lookup catalog entries by name. The request body must contain a 'selector' entry with a 'name' criteria * response contains items under 'data/elements' * Example: '{"id":"5d0c1cf4-11aa-11e6-a148-3e1d05defe78","selector":{"name":"Firewall"}}' * /lookup.by.annotation - The request body must contain a 'annotation' entry and it can have a 'selector' entry + The request body must contain a 'annotation' entry and it can have a 'selector' entry * with a multiple annotation property criteria * response contains items under 'data/elements' - * /lookup.by.model.property.value : + * /lookup.by.model.property.value : * The request must contain a "selector" entry as a JSONObject containing the selection criteria * (property name with values) and desired output properties (null values). Example: * "selector":{"att-part-number":"L-CSR-50M-APP-3Y", @@ -104,9 +90,7 @@ import org.springframework.web.bind.annotation.CrossOrigin; @RestController -//@RequestMapping(value="/catalog",method=RequestMethod.POST) @CrossOrigin(origins="*") -//@ConfigurationProperties(prefix="catalogController") public class CatalogController { private static OnapLoggerError errLogger = OnapLoggerError.getInstance(); @@ -116,9 +100,7 @@ public class CatalogController { @Autowired private SystemProperties systemProperties; - - private boolean enableCORS = false; - private URI defaultCatalog; + private URI defaultCatalog; private static Map<URI, Catalog> catalogs = new HashMap<URI, Catalog>(); @@ -127,375 +109,11 @@ public class CatalogController { this.defaultCatalog = theUri; } - public void setEnableCORS(boolean doEnable) { - this.enableCORS = doEnable; - } - -// @RequestMapping(value="/elements",method={RequestMethod.POST, RequestMethod.GET}, produces = "application/json") -// public DeferredResult<CatalogResponse> items(@RequestBody(required=false) ItemsRequest theRequest) { -// -// final ItemsRequest request = (theRequest == null) ? ItemsRequest.EMPTY_REQUEST : theRequest; -// -// Catalog catalog = getCatalog(request.getCatalog()); -// DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout()); -// -// catalog.rootsByLabel(request.getStartingLabel()) -// //catalog.roots() -// .setHandler( -// new CatalogHandler<Folders>(request, result) { -// public CatalogResponse handleData(Folders theFolders) { -// JSONArray ja = new JSONArray(); -// if (theFolders != null) { -// for (Folder folder : theFolders) { -// ja.put(patchData(catalog, folder.data())); -// } -// } -// CatalogResponse response = new CatalogResponse(this.request); -// response.data() -// .put("elements", ja); -// return response; -// } -// }); -// return result; -// } -// -// @RequestMapping(value="/{theItemId}/elements",method={RequestMethod.POST,RequestMethod.GET}, produces = "application/json") -// public DeferredResult<CatalogResponse> items(@RequestBody(required=false) ItemsRequest theRequest, @PathVariable String theItemId) { -// -// final ItemsRequest request = (theRequest == null) ? ItemsRequest.EMPTY_REQUEST : theRequest; -// -// Catalog catalog = getCatalog(request.getCatalog()); -// DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout()); -// -// catalog -//// .fetchFolderByItemId(theItemId) -// .folder(theItemId) -// .withParts() -// .withPartAnnotations() -// .withItems() -// .withItemAnnotations() -// .withItemModels() -// .execute() -// .setHandler( -// new CatalogHandler<Folder>(request, result) { -// public CatalogResponse handleData(Folder theFolder) { -// CatalogResponse response = new CatalogResponse(this.request); -// if (theFolder == null) { -// return response; -// } -// -// try { -// Elements folders = theFolder.elements("parts",Folders.class); -// if (folders != null) { -// for (Object folder: folders) { -// patchData(catalog, ((Element)folder).data()); -// //lots of ephemere proxies created here .. -// Elements annotations = -// ((Element)folder).elements("annotations", Annotations.class); -// if (annotations != null) { -// for (Object a: annotations) { -// patchData(catalog, ((Annotation)a).data()); -// } -// } -// } -// } -// Elements items = theFolder.elements("items",Items.class); -// if (items != null) { -// for (Object i: items) { -// patchData(catalog, ((Element)i).data()); -// //lots of ephemere proxies created here .. -// Elements annotations = -// ((Element)i).elements("annotations", Annotations.class); -// if (annotations != null) { -// for (Object a: annotations){ -// patchData(catalog, ((Annotation)a).data()); -// } -// } -// } -// } -// } -// catch(Exception x) { -//x.printStackTrace(); -// return new CatalogError(this.request, "", x); -// } -// -// response.data() -// .put("element", theFolder.data()); -// return response; -// } -// }); -// -// return result; -// } -// -// @RequestMapping(value="/lookup.by.name",method=RequestMethod.POST, produces = "application/json") -// public DeferredResult<CatalogResponse> elementsByName(@RequestBody ElementsLookup theRequest) { -// -// Catalog catalog = getCatalog(theRequest.getCatalog()); -// DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(theRequest.getTimeout()); -// -// catalog -// .lookup(new JSONObject(theRequest.getSelector())) -// .setHandler( -// new CatalogHandler<Mixels>(theRequest, result) { -// public CatalogResponse handleData(Mixels theElems) { -// JSONArray ja = new JSONArray(); -// if (theElems != null) { -// for (Object elem : theElems) { -// ja.put(patchData(catalog, ((Element)elem).data())); -// } -// } -// CatalogResponse response = new CatalogResponse(theRequest); -// response.data() -// .put("elements", ja); -// return response; -// } -// }); -// -// return result; -// } -// -// @RequestMapping(value="/lookup.by.annotation",method=RequestMethod.POST, produces = "application/json") -// public DeferredResult<CatalogResponse> elementsByAnnotation(@RequestBody ElementsLookup theRequest) { -// -// Catalog catalog = getCatalog(theRequest.getCatalog()); -// DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(theRequest.getTimeout()); -// -// catalog -// .lookup(theRequest.getAnnotation(), -// new JSONObject(theRequest.getSelector())) -// .setHandler( -// new CatalogHandler<Mixels>(theRequest, result) { -// public CatalogResponse handleData(Mixels theElems) { -// JSONArray ja = new JSONArray(); -// if (theElems != null) { -// for (Object elem : theElems) { -// ja.put(patchData(catalog, ((Element)elem).data())); -// } -// } -// CatalogResponse response = new CatalogResponse(this.request); -// response.data() -// .put("elements", ja); -// return response; -// } -// }); -// -// return result; -// } - - /** - * NeoCatalog specific - *//* - @RequestMapping(value="/lookup.by.model.property.value",method=RequestMethod.POST, produces = "application/json") - public DeferredResult<CatalogResponse> elementsByModelPropertyValue(@RequestBody ElementsLookup theRequest) { - - DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(theRequest.getTimeout()); - - NeoCatalog catalog = asNeo(getCatalog(theRequest.getCatalog())); - if (catalog == null) { - result.setErrorResult( - new CatalogError( - theRequest,"The selected catalog is not capable of handling this request (lookup.by.model.property.value)")); - return result; - } - - catalog - .lookupItemsByToscaNodePropertyValue(theRequest.getJSONSelector()) - .setHandler( - new CatalogHandler<Items>(theRequest, result) { - public CatalogResponse handleData(Items theItems) { - JSONArray ja = new JSONArray(); - if (theItems != null) { - for (Item item : theItems) { - ja.put(patchData(catalog, item.data())); - } - } - CatalogResponse response = new CatalogResponse(this.request); - response.data() - .put("elements", ja); - return response; - } - }); - - return result; - } -*/ - /** - * This follows the current convention that each item will have a single model - 2 stage - */ -// @RequestMapping(value="/{theItemId}/model",method={RequestMethod.POST,RequestMethod.GET}, produces = "application/json") -// //public DeferredResult<CatalogResponse> model(@RequestBody ElementRequest theRequest) { -// public DeferredResult<CatalogResponse> model(@RequestBody(required=false) ElementRequest theRequest, @PathVariable String theItemId) { -// final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest; -// -// Catalog catalog = getCatalog(request.getCatalog()); -// DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout()); -// -// catalog -//// .fetchItemByItemId(/*theRequest.getProductId()*/theItemId) -// .item(theItemId) -// .withModels() -// .execute() -// .setHandler( -// new CatalogHandler<Item>(request, result) { -// public CatalogResponse handleData(Item theItem) { -// if (theItem == null) { -// return new CatalogError(this.request, "No such item"); -// } -// Templates models = null; -// try { -// models = (Templates)theItem.elements("models", Templates.class); -// } -// catch (Exception x) { -// return new CatalogError(this.request, "Failed to decode templates from result", x); -// } -// -// if (models == null || models.size() == 0) { -// return new CatalogError(this.request, "Item has no models"); -// } -// if (models.size() > 1) { -// return new CatalogError(this.request, "Item has more than one model !?"); -// } -// try{ -// catalog.template(models.get(0).id()) -// .withInputs() -// .withOutputs() -// .withNodes() -// .withNodeProperties() -// .withNodePropertiesAssignments() -// .withNodeRequirements() -// .withNodeCapabilities() -// .withNodeCapabilityProperties() -// .withNodeCapabilityPropertyAssignments() -// .withPolicies() -// .withPolicyProperties() -// .withPolicyPropertiesAssignments() -// .execute() -// .setHandler( -// new CatalogHandler<Template>(this.request, this.result) { -// public CatalogResponse handleData(Template theTemplate) { -// CatalogResponse response = new CatalogResponse(this.request); -// if (theTemplate != null) { -// response.data() -// .put("model", patchData(catalog, theTemplate.data())); -// } -// return response; -// } -// }); -// } -// catch (Exception x) { -// x.printStackTrace(); -// } -// return null; -// } -// }); -// -// return result; -// } - -// @RequestMapping(value="/{theItemId}/type/{theTypeName}",method={RequestMethod.POST,RequestMethod.GET}, produces = "application/json") -// public DeferredResult<CatalogResponse> model(@RequestBody(required=false) ElementRequest theRequest, @PathVariable String theItemId, @PathVariable String theTypeName) { -// final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest; -// -// Catalog catalog = getCatalog(request.getCatalog()); -// DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout()); -// -// catalog.type(theItemId, theTypeName) -// .withHierarchy() -// .withCapabilities() -// .withRequirements() -// .execute() -// .setHandler( -// new CatalogHandler<Type>(request, result) { -// public CatalogResponse handleData(Type theType) { -// CatalogResponse response = new CatalogResponse(this.request); -// if (theType != null) { -// response.data() -// .put("type", patchData(catalog, theType.data())); -// } -// return response; -// } -// }); -// -// return result; -// } - -/* - @RequestMapping(value="/referents",method=RequestMethod.POST, produces = "application/json") - public DeferredResult<CatalogResponse> referents(@RequestBody(required=false) ElementRequest theRequest) { - final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest; - DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout()); - - NeoCatalog catalog = asNeo(getCatalog(theRequest.getCatalog())); - if (catalog == null) { - result.setErrorResult( - new CatalogError( - theRequest,"The selected catalog is not capable of handling this request (referents)")); - return result; - } - - catalog - .defaultRecommendations() - .setHandler( - new CatalogHandler<Mixels>(request, result) { - public CatalogResponse handleData(Mixels theElems) { - JSONArray ja = new JSONArray(); - if (theElems != null) { - for (Element elem : theElems) { - ja.put(patchData(catalog, elem.data())); - } - } - CatalogResponse response = new CatalogResponse(this.request); - response.data() - .put("elements", ja); - return response; - } - }); - - return result; - } -*/ - -/* @RequestMapping(value="/{theItemId}/referents",method=RequestMethod.POST, produces = "application/json") - public DeferredResult<CatalogResponse> referents(@RequestBody(required=false) ElementRequest theRequest, @PathVariable String theItemId) { - final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest; - DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout()); - - NeoCatalog catalog = asNeo(getCatalog(theRequest.getCatalog())); - if (catalog == null) { - result.setErrorResult( - new CatalogError( - theRequest,"The selected catalog is not capable of handling this request (item referents)")); - return result; - } - - catalog - .recommendationsForItemId(theItemId) - .setHandler( - new CatalogHandler<Mixels>(request, result) { - public CatalogResponse handleData(Mixels theElems) { - JSONArray ja = new JSONArray(); - if (theElems != null) { - for (Element elem : theElems) { - ja.put(patchData(catalog, elem.data())); - } - } - CatalogResponse response = new CatalogResponse(this.request); - response.data() - .put("elements", ja); - return response; - } - }); - - return result; - } -*/ @PostConstruct public void initCatalog() { // Dump some info and construct our configuration objects debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "initCatalog"); - + this.defaultCatalog = URI.create(systemProperties.getProperties().getProperty(DcaeBeConstants.Config.ASDC_CATALOG_URL)); // Initialize default catalog connection debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "default catalog at {}", this.defaultCatalog); @@ -518,7 +136,7 @@ public class CatalogController { Catalog cat = catalogs.get(theCatalogUri); if (cat == null && theCatalogUri != null) { String scheme = theCatalogUri.getScheme(); - URI catalogUri = null; + URI catalogUri; try { catalogUri = new URI(theCatalogUri.getSchemeSpecificPart() + "#" + theCatalogUri.getFragment()); } @@ -539,15 +157,6 @@ public class CatalogController { return cat; } -/* private NeoCatalog asNeo(Catalog theCatalog) { - try { - return (NeoCatalog)theCatalog; - } - catch (ClassCastException ccx) { - return null; - } - }*/ - public JSONObject patchData(Catalog theCat, JSONObject theData) { theData.put("catalog", theCat.getUri()); theData.put("catalogId", theData.optLong("id")); @@ -582,7 +191,7 @@ public class CatalogController { else { debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "handle, got: {}", theEvent.result()); CatalogResponse response = handleData(theEvent.result()); - //a null result allows the handler to pass the processing onto some other async processing stage + //a null result allows the accumulatorHandler to pass the processing onto some other async processing stage if (response != null) { if (!this.result.setResult(response)) { this.result.setErrorResult(new CatalogError(this.request, "Catalog API call succesful but late")); @@ -591,4 +200,4 @@ public class CatalogController { } } } -} +} diff --git a/dcaedt_tools/src/main/java/json/templateInfo/NodeToDelete.java b/dcaedt_tools/src/main/java/json/templateInfo/NodeToDelete.java new file mode 100644 index 0000000..f79be40 --- /dev/null +++ b/dcaedt_tools/src/main/java/json/templateInfo/NodeToDelete.java @@ -0,0 +1,30 @@ +package json.templateInfo; + +import com.google.gson.annotations.SerializedName; + +import javax.annotation.Generated; + +@Generated("net.hexar.json2pojo") +public class NodeToDelete { + + @SerializedName("type") + private String type; + @SerializedName("nodeName") + private String nodeName; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getNodeName() { + return nodeName; + } + + public void setNodeName(String nodeName) { + this.nodeName = nodeName; + } +} diff --git a/dcaedt_tools/src/main/java/json/templateInfo/TemplateInfo.java b/dcaedt_tools/src/main/java/json/templateInfo/TemplateInfo.java index c34aaef..c7e69db 100644 --- a/dcaedt_tools/src/main/java/json/templateInfo/TemplateInfo.java +++ b/dcaedt_tools/src/main/java/json/templateInfo/TemplateInfo.java @@ -17,8 +17,12 @@ public class TemplateInfo { private String Description; @SerializedName("name") private String Name; + @SerializedName("flowType") + private String FlowType; @SerializedName("relations") private List<Relation> Relations; + @SerializedName("nodesToDelete") + private List<NodeToDelete> NodesToDelete; @SerializedName("subCategory") private String SubCategory; @SerializedName("updateIfExist") @@ -56,6 +60,22 @@ public class TemplateInfo { Name = name; } + public String getFlowType() { + return FlowType; + } + + public void setFlowType(String flowType) { + FlowType = flowType; + } + + public List<NodeToDelete> getNodesToDelete() { + return NodesToDelete; + } + + public void setNodesToDelete(List<NodeToDelete> nodesToDelete) { + NodesToDelete = nodesToDelete; + } + public List<Relation> getRelations() { return Relations; } diff --git a/dcaedt_tools/src/main/java/tools/DeployTemplate.java b/dcaedt_tools/src/main/java/tools/DeployTemplate.java index d5c368f..d319542 100644 --- a/dcaedt_tools/src/main/java/tools/DeployTemplate.java +++ b/dcaedt_tools/src/main/java/tools/DeployTemplate.java @@ -29,10 +29,18 @@ public class DeployTemplate { } public void deploy(Map<TemplateInfo, JsonObject> templateInfoToJsonObjectMap) { - List<ResourceDetailed> vfcmtList = dcaeRestClient.getAllVfcmts(); + ArrayList<ResourceDetailed> vfcmtList = new ArrayList(); + List<ResourceDetailed> regularVfcmtList = dcaeRestClient.getAllVfcmts(); + if (regularVfcmtList != null) { + vfcmtList.addAll(regularVfcmtList); + } + List<ResourceDetailed> baseVfcmtList = dcaeRestClient.getAllBaseVfcmts(); + if (baseVfcmtList != null) { + vfcmtList.addAll(baseVfcmtList); + } List<TemplateInfo> updatedTemplateInfos = new ArrayList<>(); - vfcmtList.stream().forEach(vfcmt -> + vfcmtList.forEach(vfcmt -> templateInfoToJsonObjectMap.keySet().stream().filter(templateInfo -> templateInfo.getName().equalsIgnoreCase(vfcmt.getName())).forEach(templateInfo -> { update(vfcmt, templateInfo, templateInfoToJsonObjectMap.get(templateInfo)); updatedTemplateInfos.add(templateInfo); @@ -47,9 +55,17 @@ public class DeployTemplate { private void verify(Map<TemplateInfo, JsonObject> templateInfoToJsonObjectMap) { AtomicInteger foundCount = new AtomicInteger(); debugLogger.log("Starting verify deployment"); - List<ResourceDetailed> vfcmtList = dcaeRestClient.getAllVfcmts(); + ArrayList<ResourceDetailed> vfcmtList = new ArrayList(); + List<ResourceDetailed> regularVfcmtList = dcaeRestClient.getAllVfcmts(); + if (regularVfcmtList != null) { + vfcmtList.addAll(regularVfcmtList); + } + List<ResourceDetailed> baseVfcmtList = dcaeRestClient.getAllBaseVfcmts(); + if (baseVfcmtList != null) { + vfcmtList.addAll(baseVfcmtList); + } - templateInfoToJsonObjectMap.keySet().stream() + templateInfoToJsonObjectMap.keySet() .forEach(templateInfo -> vfcmtList.stream() .filter(vfcmt -> vfcmt.getName().equalsIgnoreCase(templateInfo.getName())) .forEach(vfcmt -> foundCount.getAndIncrement())); @@ -73,8 +89,6 @@ public class DeployTemplate { createVFCMTRequest.setCategory(templateInfo.getCategory()); ResourceDetailed vfcmt = dcaeRestClient.createResource(createVFCMTRequest); - jsonObject.addProperty("cid", vfcmt.getUuid()); - saveAndCertify(jsonObject, vfcmt); } catch (HttpServerErrorException e) { @@ -87,13 +101,13 @@ public class DeployTemplate { private void update(ResourceDetailed vfcmt, TemplateInfo templateInfo, JsonObject jsonObject) { ResourceDetailed checkedoutVfcmt = vfcmt; try { - Boolean checkoutChecking = checkUserIfResourceCheckedOut(dcaeRestClient.getUserId(), vfcmt); - if (checkoutChecking != null && checkoutChecking) { + boolean vfcmtIsCheckedOut = isCheckedOut(vfcmt); + if (vfcmtIsCheckedOut && differentUserCannotCheckout(dcaeRestClient.getUserId(), vfcmt)){ report.addErrorMessage(FAILED_UPDATE_VFCMT + vfcmt.getName() + ", cannot checkout vfcmt"); return; } if (templateInfo.getUpdateIfExist()) { - if (checkoutChecking == null) { + if (!vfcmtIsCheckedOut) { checkedoutVfcmt = dcaeRestClient.checkoutVfcmt(vfcmt.getUuid()); } if (checkedoutVfcmt != null) { @@ -114,6 +128,7 @@ public class DeployTemplate { } private void saveAndCertify(JsonObject jsonObject, ResourceDetailed checkedoutVfcmt) { + jsonObject.addProperty("cid", checkedoutVfcmt.getUuid()); if (saveCompositionAndCertify(checkedoutVfcmt, jsonObject)) { report.addUpdatedMessage("vfcmt: " + checkedoutVfcmt.getName() + " updated successfully"); } else { @@ -140,18 +155,19 @@ public class DeployTemplate { return true; } - private Boolean checkUserIfResourceCheckedOut(String userId, ResourceDetailed asset) { - if (DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT == DcaeBeConstants.LifecycleStateEnum.findState(asset.getLifecycleState())) { - String lastUpdaterUserId = asset.getLastUpdaterUserId(); - if (lastUpdaterUserId != null && !lastUpdaterUserId.equals(userId)) { - String msg = "User conflicts. Operation not allowed for user "+userId+" on resource checked out by "+lastUpdaterUserId; - report.addErrorMessage(msg); - errLogger.log(msg); - return true; - } else { - return false; - } + private boolean isCheckedOut(ResourceDetailed asset) { + return DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT == DcaeBeConstants.LifecycleStateEnum.findState(asset.getLifecycleState()); + } + + private Boolean differentUserCannotCheckout(String userId, ResourceDetailed asset) { + String lastUpdaterUserId = asset.getLastUpdaterUserId(); + if (lastUpdaterUserId != null && !lastUpdaterUserId.equals(userId)) { + String msg = "User conflicts. Operation not allowed for user "+userId+" on resource checked out by "+lastUpdaterUserId; + report.addErrorMessage(msg); + errLogger.log(msg); + return true; + } else { + return false; } - return null; } } diff --git a/dcaedt_tools/src/main/java/tools/ItemAndAlias.java b/dcaedt_tools/src/main/java/tools/ItemAndAlias.java new file mode 100644 index 0000000..e282a58 --- /dev/null +++ b/dcaedt_tools/src/main/java/tools/ItemAndAlias.java @@ -0,0 +1,20 @@ +package tools; + +import json.response.ItemsResponse.Item; + +public class ItemAndAlias { + private final Item item; + private final String alias; + public ItemAndAlias(Item item, String alias) { + this.item = item; + this.alias = alias; + } + + public Item getItem() { + return item; + } + + public String getAlias() { + return alias; + } +} diff --git a/dcaedt_tools/src/main/java/tools/LoggerError.java b/dcaedt_tools/src/main/java/tools/LoggerError.java index 325bfc1..9ec985b 100644 --- a/dcaedt_tools/src/main/java/tools/LoggerError.java +++ b/dcaedt_tools/src/main/java/tools/LoggerError.java @@ -10,4 +10,9 @@ public class LoggerError { public void log(String logLine) { System.err.println(logLine); } + + public void log(String logLine, Exception e) { + System.err.println(logLine); + e.printStackTrace(); + } } diff --git a/dcaedt_tools/src/main/java/tools/Main.java b/dcaedt_tools/src/main/java/tools/Main.java index 72b6e42..bf02c44 100644 --- a/dcaedt_tools/src/main/java/tools/Main.java +++ b/dcaedt_tools/src/main/java/tools/Main.java @@ -61,11 +61,11 @@ public class Main { debugLogger.log( "VFCMT template deployment completed successfully"); } catch (RuntimeException e) { - errLogger.log("ERROR - Template deployment failed with error " + e); + errLogger.log("ERROR - Template deployment failed with error " + e, e); } catch (ConnectException e) { - errLogger.log( "ERROR - Failed connection to server, are you on AT&T network? {}" + e); + errLogger.log( "ERROR - Failed connection to server, are you on AT&T network? {}" + e, e); } catch (IOException e) { - errLogger.log( "ERROR - Fatal Error! " + e); + errLogger.log( "ERROR - Fatal Error! " + e, e); } finally { debugLogger.log(report.toString()); } diff --git a/dcaedt_tools/src/main/java/tools/NodeData.java b/dcaedt_tools/src/main/java/tools/NodeData.java index f89105b..e9043de 100644 --- a/dcaedt_tools/src/main/java/tools/NodeData.java +++ b/dcaedt_tools/src/main/java/tools/NodeData.java @@ -9,13 +9,15 @@ public class NodeData { private final JsonArray properties; private final JsonObject typeInfo; private final String nodeName; + private final String aliasBelong; - NodeData(JsonArray capabilities, JsonArray requirements, JsonArray properties, JsonObject typeInfo, String nodeName) { + NodeData(JsonArray capabilities, JsonArray requirements, JsonArray properties, JsonObject typeInfo, String nodeName, String aliasBelong) { this.capabilities = capabilities; this.requirements = requirements; this.properties = properties; this.typeInfo = typeInfo; this.nodeName = nodeName; + this.aliasBelong = aliasBelong; } public JsonArray getCapabilities() { @@ -37,4 +39,12 @@ public class NodeData { public String getName() { return nodeName; } + + public String getNameWithAlias() { + return aliasBelong + "." + nodeName; + } + + public String getAliasBelong() { + return aliasBelong; + } } diff --git a/dcaedt_tools/src/main/java/tools/TemplateContainer.java b/dcaedt_tools/src/main/java/tools/TemplateContainer.java index ee16d22..a5bca1f 100644 --- a/dcaedt_tools/src/main/java/tools/TemplateContainer.java +++ b/dcaedt_tools/src/main/java/tools/TemplateContainer.java @@ -6,6 +6,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import json.response.ItemsResponse.Item; import json.templateInfo.Composition; +import json.templateInfo.NodeToDelete; import json.templateInfo.Relation; import json.templateInfo.TemplateInfo; import org.apache.commons.lang3.StringUtils; @@ -19,6 +20,7 @@ import java.util.concurrent.atomic.AtomicReference; public class TemplateContainer { private static final String NODES = "nodes"; private static final String RELATIONSHIP = "relationship"; + public static final String ASSIGNMENT = "assignment"; private static long nidCounter = 0; private final IReport report; private final IDcaeRestClient dcaeRestClient; @@ -34,12 +36,12 @@ public class TemplateContainer { this.elementsByFolderNames = elementsByFolderNames; } - private List<Item> findTemplate(TemplateInfo templateInfo) { - AtomicReference<List<Item>> items = new AtomicReference<>(); + private List<ItemAndAlias> findTemplate(TemplateInfo templateInfo) { + AtomicReference<List<ItemAndAlias>> items = new AtomicReference<>(); items.set(new ArrayList<>()); elementsByFolderNames.keySet().stream() .forEach(folderName -> { - List<Item> itemList = returnMatchedTemplate(folderName, templateInfo); + List<ItemAndAlias> itemList = returnMatchedTemplate(folderName, templateInfo); items.get().addAll(itemList); }); if (items.get().size() == templateInfo.getComposition().size()) { @@ -48,13 +50,13 @@ public class TemplateContainer { return new ArrayList<>(); } - private List<Item> returnMatchedTemplate(String folderName, TemplateInfo templateInfo) { - List<Item> items = new ArrayList<>(); + private List<ItemAndAlias> returnMatchedTemplate(String folderName, TemplateInfo templateInfo) { + List<ItemAndAlias> items = new ArrayList<>(); elementsByFolderNames.get(folderName).stream() .forEach(item -> templateInfo.getComposition().stream().forEach(composition -> { if (composition.getType().equalsIgnoreCase(item.getName())) { - items.add(item); + items.add(new ItemAndAlias(item, composition.getAlias())); } })); return items; @@ -64,7 +66,7 @@ public class TemplateContainer { public Map<TemplateInfo, JsonObject> getCdumps() { Map<TemplateInfo, JsonObject> templateInfoToJsonObjectMap = new HashMap<>(); for (TemplateInfo templateInfo : templateInfos) { - List<Item> items = findTemplate(templateInfo); + List<ItemAndAlias> items = findTemplate(templateInfo); if (items == null || items.isEmpty()) { report.addErrorMessage("vfcmt: " + templateInfo.getName() + ". DCAE Component not found"); continue; @@ -74,37 +76,35 @@ public class TemplateContainer { return templateInfoToJsonObjectMap; } - private JsonObject getCdumpJsonObject(List<Item> items, TemplateInfo templateInfo) { + private JsonObject getCdumpJsonObject(List<ItemAndAlias> ItemsAndAlias, TemplateInfo templateInfo) { JsonObject cdumpJsonObject = generateCdumpInput(templateInfo); - Map<Item, Map<String, NodeData>> itemMapHashMap = new HashMap<>(); + Map<ItemAndAlias, Map<String, NodeData>> itemMapHashMap = new HashMap<>(); JsonArray relationsJsonArray = new JsonArray(); - for (Item item : items) { + for (ItemAndAlias itemAndAlias : ItemsAndAlias) { + Item item = itemAndAlias.getItem(); debugLogger.log("Creating cdump for item: " + item.getName()); JsonArray jsonArrayNode = cdumpJsonObject.getAsJsonArray(NODES); JsonParser jsonParser = new JsonParser(); JsonArray allNodeTemplates = jsonParser.parse(dcaeRestClient.getItemModel(item.getItemId())).getAsJsonObject().get("data").getAsJsonObject().get("model").getAsJsonObject().get(NODES).getAsJsonArray(); Map<String, NodeData> stringRelationsDataMap = new HashMap<>(); for (JsonElement nodeElement : allNodeTemplates) { + if (checkIfNeedToSkip(templateInfo.getNodesToDelete(), nodeElement, item.getName())) { + continue; + } JsonObject responseModelJson = nodeElement.getAsJsonObject(); JsonObject responseTypeInfoJson = jsonParser.parse(dcaeRestClient.getItemType(item.getItemId(), responseModelJson.get("type").getAsString())).getAsJsonObject().get("data").getAsJsonObject().get("type").getAsJsonObject(); - JsonObject jsonObjectElement = newVfcmtJSON(responseModelJson.get("name").getAsString(), item.getModels().get(0).getItemId()); + String nodeName = itemAndAlias.getAlias() + "." + responseModelJson.get("name").getAsString(); + JsonObject jsonObjectElement = newNodeTemplate(nodeName, item.getModels().get(0).getItemId()); jsonObjectElement.addProperty("id", responseTypeInfoJson.get("itemId").getAsString().split("/")[0]); String nid = "n." + new Date().getTime() + "." + nidCounter++; jsonObjectElement.addProperty("nid", nid); - NodeData nodeData = createNodeData(responseModelJson, responseTypeInfoJson, responseModelJson.get("name").getAsString()); + NodeData nodeData = createNodeData(responseModelJson, responseTypeInfoJson, responseModelJson.get("name").getAsString(), itemAndAlias.getAlias()); + fillPropertiesValue(nodeData); stringRelationsDataMap.put(nid, nodeData); - jsonObjectElement.add("capabilities", nodeData.getCapabilities()); - jsonObjectElement.add("requirements", nodeData.getRequirements()); - jsonObjectElement.add("properties", nodeData.getProperties()); - jsonObjectElement.add("typeinfo", nodeData.getTypeInfo()); - JsonObject typeJsonObject = new JsonObject(); - typeJsonObject.addProperty("name", responseModelJson.get("type").getAsString()); - jsonObjectElement.add("type", typeJsonObject); - JsonElement ndataElement = createNData(responseModelJson.get("name").getAsString(), nid); - jsonObjectElement.add("ndata", ndataElement); + addCdumpData(responseModelJson, jsonObjectElement, nid, nodeData); jsonArrayNode.add(jsonObjectElement); } - itemMapHashMap.put(item, stringRelationsDataMap); + itemMapHashMap.put(itemAndAlias, stringRelationsDataMap); } JsonElement jsonElement = createTemplateInfoRelations(templateInfo, itemMapHashMap); if (jsonElement != null && jsonElement.isJsonArray()) { @@ -123,6 +123,56 @@ public class TemplateContainer { return cdumpJsonObject; } + private void addCdumpData(JsonObject responseModelJson, JsonObject jsonObjectElement, String nid, NodeData nodeData) { + jsonObjectElement.add("capabilities", nodeData.getCapabilities()); + jsonObjectElement.add("requirements", nodeData.getRequirements()); + jsonObjectElement.add("properties", nodeData.getProperties()); + jsonObjectElement.add("typeinfo", nodeData.getTypeInfo()); + JsonObject typeJsonObject = new JsonObject(); + typeJsonObject.addProperty("name", responseModelJson.get("type").getAsString()); + jsonObjectElement.add("type", typeJsonObject); + JsonElement ndataElement = createNData(responseModelJson.get("name").getAsString(), nid); + jsonObjectElement.add("ndata", ndataElement); + } + + private void fillPropertiesValue(NodeData nodeData) { + for (Iterator<JsonElement> iterator = nodeData.getProperties().iterator(); iterator.hasNext(); ) { + JsonElement property = iterator.next(); + if (!property.isJsonObject()) { + continue; + } + if (property.getAsJsonObject().has("value")) { + continue; + } + JsonElement jsonElement = new JsonObject(); + if (property.getAsJsonObject().has(ASSIGNMENT) && + property.getAsJsonObject().get(ASSIGNMENT).getAsJsonObject().has("value")) { + jsonElement = property.getAsJsonObject().get(ASSIGNMENT).getAsJsonObject().get("value"); + } else if (property.getAsJsonObject().has("default")) { + jsonElement = property.getAsJsonObject().get("default"); + } else if (property.getAsJsonObject().has(ASSIGNMENT) && + property.getAsJsonObject().get(ASSIGNMENT).getAsJsonObject().has("input") && + property.getAsJsonObject().get(ASSIGNMENT).getAsJsonObject().get("input").getAsJsonObject().has("default")) { + jsonElement = property.getAsJsonObject().get(ASSIGNMENT).getAsJsonObject().get("input").getAsJsonObject().get("default"); + } + property.getAsJsonObject().add("value", jsonElement); + } + + } + + private boolean checkIfNeedToSkip(List<NodeToDelete> nodesToDelete, JsonElement nodeElement, String itemName) { + return nodesToDelete != null && nodesToDelete.stream().anyMatch(nodeToDelete -> { + if (nodeToDelete.getType().equalsIgnoreCase(itemName)) { + String nodeName = nodeElement.getAsJsonObject().get("name").toString().replace("\"", ""); + if (nodeToDelete.getNodeName().equalsIgnoreCase(nodeName)) { + debugLogger.log("Skipping node: " + nodeToDelete.getNodeName() + ", Item name: " + itemName); + return true; + } + } + return false; + }); + } + //We need it only for printing the relations (front end requirement) private JsonElement createNData(String name, String nid) { JsonObject ndataElement = new JsonObject(); @@ -138,9 +188,9 @@ public class TemplateContainer { return ndataElement; } - private JsonElement createSelfRelations(Map<Item, Map<String, NodeData>> nodeDataByNidByItem) { + private JsonElement createSelfRelations(Map<ItemAndAlias, Map<String, NodeData>> nodeDataByNidByItem) { JsonArray jsonArrayRelations = new JsonArray(); - for (Item item : nodeDataByNidByItem.keySet()) { + for (ItemAndAlias item : nodeDataByNidByItem.keySet()) { Map<String, NodeData> nodeDataByNid = nodeDataByNidByItem.get(item); if (nodeDataByNid.size() < 2) { continue; @@ -173,12 +223,12 @@ public class TemplateContainer { NodeData fromNode = nodeDataByNidByItem.get(item).get(nidListByRequirement.get(requirement)); relationElement.addProperty("rid", "ink." + nidListByRequirement.get(requirement) + "." + nidCounter++); relationElement.addProperty("n1", nidListByRequirement.get(requirement)); - relationElement.addProperty("name1", fromNode.getName()); + relationElement.addProperty("name1", fromNode.getNameWithAlias()); JsonObject metaData = new JsonObject(); metaData.addProperty("n1", nidListByRequirement.get(requirement)); metaData.addProperty("p1", requirement.get("name").toString().replaceAll("\"", "")); relationElement.addProperty("n2", toNId); - relationElement.addProperty("name2", toNodeName); + relationElement.addProperty("name2", fromNode.getAliasBelong() + "." + toNodeName); metaData.addProperty("n2", toNId); String capabilityFullName = requirement.get("capability").getAsJsonObject().get("name").toString(); String capabilityShortName = StringUtils.substringAfterLast(capabilityFullName, "."); @@ -202,14 +252,14 @@ public class TemplateContainer { return jsonArrayRelations; } - private NodeData createNodeData(JsonObject responseModelJson, JsonObject responseTypeInfoJson, String nodeName) { + private NodeData createNodeData(JsonObject responseModelJson, JsonObject responseTypeInfoJson, String nodeName, String aliasBelong) { JsonArray capabilities = responseModelJson.get("capabilities").getAsJsonArray(); JsonArray requirements = responseModelJson.get("requirements").getAsJsonArray(); JsonArray properties = responseModelJson.get("properties").getAsJsonArray(); - return new NodeData(capabilities, requirements, properties, responseTypeInfoJson, nodeName); + return new NodeData(capabilities, requirements, properties, responseTypeInfoJson, nodeName, aliasBelong); } - private JsonArray createTemplateInfoRelations(TemplateInfo templateInfo, Map<Item, Map<String, NodeData>> nodeDataByNidByItem) { + private JsonArray createTemplateInfoRelations(TemplateInfo templateInfo, Map<ItemAndAlias, Map<String, NodeData>> nodeDataByNidByItem) { JsonArray jsonArrayRelations = new JsonArray(); if (templateInfo.getRelations() == null) { @@ -226,19 +276,26 @@ public class TemplateContainer { String toComponentNodeName = StringUtils.substringAfterLast(toComponent, "."); boolean findTo = false; boolean findFrom = false; - for (Item item : nodeDataByNidByItem.keySet()) { + for (ItemAndAlias item : nodeDataByNidByItem.keySet()) { Map<String, NodeData> nodeDataByNid = nodeDataByNidByItem.get(item); for (String nid : nodeDataByNid.keySet()) { NodeData currentNodeData = nodeDataByNid.get(nid); Optional<Composition> isFoundComposition = templateInfo.getComposition().stream() - .filter(element -> fromComponentAlias.equalsIgnoreCase(element.getAlias()) && element.getType().equalsIgnoreCase(item.getName()) && fromComponentNodeName.equalsIgnoreCase(currentNodeData.getName())).findAny(); + .filter(element -> fromComponentAlias.equalsIgnoreCase(element.getAlias()) + && element.getAlias().equalsIgnoreCase(currentNodeData.getAliasBelong()) + && element.getAlias().equalsIgnoreCase(item.getAlias()) + && element.getType().equalsIgnoreCase(item.getItem().getName()) + && fromComponentNodeName.equalsIgnoreCase(currentNodeData.getName())).findAny(); if (isFoundComposition.isPresent()) { boolean isFound = findNode(relation.getFromRequirement(), currentNodeData.getRequirements()); if (isFound) { + if (findFrom) { + report.addErrorMessage("Found 2 match nodes, using the second one. from relation: " + relation.getFromRequirement()); + } relationElement.addProperty("rid", "ink." + nid + "." + nidCounter++); relationElement.addProperty("n1", nid); - relationElement.addProperty("name1", currentNodeData.getName()); + relationElement.addProperty("name1", currentNodeData.getNameWithAlias()); metaData.addProperty("n1", nid); metaData.addProperty("p1", relation.getFromRequirement()); JsonArray relationship = new JsonArray(); @@ -257,12 +314,19 @@ public class TemplateContainer { } isFoundComposition = templateInfo.getComposition().stream() - .filter(element -> toComponentAlias.equalsIgnoreCase(element.getAlias()) && element.getType().equalsIgnoreCase(item.getName()) && toComponentNodeName.equalsIgnoreCase(currentNodeData.getName())).findAny(); + .filter(element -> toComponentAlias.equalsIgnoreCase(element.getAlias()) + && element.getAlias().equalsIgnoreCase(currentNodeData.getAliasBelong()) + && element.getAlias().equalsIgnoreCase(item.getAlias()) + && element.getType().equalsIgnoreCase(item.getItem().getName()) + && toComponentNodeName.equalsIgnoreCase(currentNodeData.getName())).findAny(); if (isFoundComposition.isPresent()) { boolean isFound = findNode(relation.getToCapability(), currentNodeData.getCapabilities()); if (isFound) { + if (findTo) { + report.addErrorMessage("Found 2 match nodes, using the second one. to relation: " + relation.getToCapability()); + } relationElement.addProperty("n2", nid); - relationElement.addProperty("name2", currentNodeData.getName()); + relationElement.addProperty("name2", currentNodeData.getNameWithAlias()); metaData.addProperty("n2", nid); metaData.addProperty("p2", relation.getToCapability()); findTo = true; @@ -307,7 +371,7 @@ public class TemplateContainer { return false; } - private JsonObject newVfcmtJSON(String name, String description) { + private JsonObject newNodeTemplate(String name, String description) { JsonObject json = new JsonObject(); json.addProperty("name", name); json.addProperty("description", description); @@ -317,7 +381,7 @@ public class TemplateContainer { private JsonObject generateCdumpInput(TemplateInfo templateInfo) { JsonObject json = new JsonObject(); json.addProperty("version", 0); - json.addProperty("flowType", templateInfo.getName()); + json.addProperty("flowType", templateInfo.getFlowType()); json.add(NODES, new JsonArray()); json.add("inputs", new JsonArray()); diff --git a/dcaedt_tools/src/main/java/utilities/DcaeRestClient.java b/dcaedt_tools/src/main/java/utilities/DcaeRestClient.java index 5e81038..7e991d7 100644 --- a/dcaedt_tools/src/main/java/utilities/DcaeRestClient.java +++ b/dcaedt_tools/src/main/java/utilities/DcaeRestClient.java @@ -17,6 +17,7 @@ import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import javax.annotation.PostConstruct; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -74,6 +75,12 @@ public class DcaeRestClient implements IDcaeRestClient { } @Override + public List<ResourceDetailed> getAllBaseVfcmts() { + String url = buildRequestPath("/getResourcesByMonitoringTemplateCategory"); + return Arrays.asList(client.getForObject(url, ResourceDetailed[].class)); + } + + @Override public ResourceDetailed createResource(CreateVFCMTRequest resource) { String url = buildRequestPath(CREATE_VFCMT); return client.postForObject(url, new HttpEntity<>(resource, postResourceHeaders(credential.getUsername())), ResourceDetailed.class); diff --git a/dcaedt_tools/src/main/java/utilities/IDcaeRestClient.java b/dcaedt_tools/src/main/java/utilities/IDcaeRestClient.java index 677175b..bfe3595 100644 --- a/dcaedt_tools/src/main/java/utilities/IDcaeRestClient.java +++ b/dcaedt_tools/src/main/java/utilities/IDcaeRestClient.java @@ -15,6 +15,8 @@ public interface IDcaeRestClient { List<ResourceDetailed> getAllVfcmts(); + List<ResourceDetailed> getAllBaseVfcmts(); + ResourceDetailed createResource(CreateVFCMTRequest resource); ResourceDetailed checkoutVfcmt(String vfcmtUuid); diff --git a/dcaedt_tools/src/main/resources/conf/config.json b/dcaedt_tools/src/main/resources/conf/config.json index 5b0f542..4ca81cc 100644 --- a/dcaedt_tools/src/main/resources/conf/config.json +++ b/dcaedt_tools/src/main/resources/conf/config.json @@ -1,51 +1,207 @@ { "templateInfo": [{ - "name": "SNMP Fault", - "description": "SNMP FM with Map-Supplement-Enrich", - "category": "Template", - "subCategory":"Base Monitoring Template", - "updateIfExist": "true", - "composition": [{ - "type": "Map", - "alias": "mapper" - }, { - "type": "Supplement", - "alias": "sup" - }, { - "type": "Enrich", - "alias": "enrich" - }] - }, - { - "name": "FOI", - "description": "FOI SFTP with FOI-Collector and Docker-Map", - "category": "Template", - "subCategory":"Base Monitoring Template", - "updateIfExist": "true", - "composition": [{ - "type": "foi", - "alias": "collector" - }, { - "type": "DockerMap", - "alias": "map" - }], - "relations": [{ - "fromComponent": "collector.foi", - "fromRequirement": "stream_publish_0", - "toComponent": "map.feed0", - "toCapability": "feed" - }] - }, - { - "name": "Syslog non-VES Collector", - "description": "Syslog flow with Syslog Collector", - "category": "Template", - "subCategory": "Base Monitoring Template", - "updateIfExist": "true", - "composition": [{ - "type": "Syslog", - "alias": "collector" - }] - } - ] + "name": "Syslog Collector Template", + "flowType": "Syslog Collector", + "description": "Syslog Collector", + "category": "Template", + "subCategory":"Base Monitoring Template", + "updateIfExist": "false", + "composition": [{ + "type": "SyslogCollector", + "alias": "Syslog" + }, { + "type": "Existing Topic", + "alias": "eTopic" + }], + "relations": [{ + "fromComponent": "Syslog.SyslogCollector", + "fromRequirement": "stream_publish_0", + "toComponent": "eTopic.topic", + "toCapability": "topic" + }], + "nodesToDelete": [ + { + "type": "SyslogCollector", + "nodeName": "topic0" + }] + },{ + "name": "Syslog MSEA Template", + "flowType": "Syslog MSEA", + "description": "Syslog MSEA", + "category": "Template", + "subCategory":"Base Monitoring Template", + "updateIfExist": "false", + "composition": [{ + "type": "Map", + "alias": "Map" + }, { + "type": "Supplement", + "alias": "Sup" + }, { + "type": "Enrich", + "alias": "Enr" + }, { + "type": "Alert", + "alias": "Ale" + }], + "relations": [{ + "fromComponent": "Sup.Supplement", + "fromRequirement": "dependency", + "toComponent": "Map.Map", + "toCapability": "feature" + },{ + "fromComponent": "Enr.Enrich", + "fromRequirement": "dependency", + "toComponent": "Sup.Supplement", + "toCapability": "feature" + },{ + "fromComponent": "Ale.Alert", + "fromRequirement": "dependency", + "toComponent": "Enr.Enrich", + "toCapability": "feature" + }] + },{ + "name": "Status Poller Collector Template", + "flowType": "Status Poller Collector", + "description": "Status Poller Collector", + "category": "Template", + "subCategory":"Base Monitoring Template", + "updateIfExist": "false", + "composition": [{ + "type": "StatusPoller", + "alias": "sPoller" + }, { + "type": "Existing Topic", + "alias": "eTopic0" + }], + "relations": [{ + "fromComponent": "sPoller.StatusPoller", + "fromRequirement": "stream_publish_0", + "toComponent": "eTopic0.topic", + "toCapability": "topic" + }], + "nodesToDelete": [ + { + "type": "StatusPoller", + "nodeName": "topic0" + }] + }, { + "name": "Status Poller MSE Template", + "flowType": "Status Poller MSE", + "description": "Status Poller MSE", + "category": "Template", + "subCategory":"Base Monitoring Template", + "updateIfExist": "false", + "composition": [{ + "type": "Map", + "alias": "Map" + }, { + "type": "Supplement", + "alias": "Sup" + }, { + "type": "Enrich", + "alias": "Enr" + }], + "relations": [{ + "fromComponent": "Sup.Supplement", + "fromRequirement": "dependency", + "toComponent": "Map.Map", + "toCapability": "feature" + },{ + "fromComponent": "Enr.Enrich", + "fromRequirement": "dependency", + "toComponent": "Sup.Supplement", + "toCapability": "feature" + }] + }, { + "name": "FOI Collector Template", + "flowType": "FOI Collector", + "description": "FOI Collector", + "category": "Template", + "subCategory":"Base Monitoring Template", + "updateIfExist": "false", + "composition": [{ + "type": "FOICollector", + "alias": "fCollector" + }, { + "type": "Existing Feed", + "alias": "eFeed" + }], + "relations": [{ + "fromComponent": "fCollector.FoiSftp", + "fromRequirement": "stream_publish_0", + "toComponent": "eFeed.feed", + "toCapability": "feed" + }], + "nodesToDelete": [ + { + "type": "FOICollector", + "nodeName": "feed0" + }] + }, { + "name": "SNMP MSE Template", + "flowType": "SNMP MSE", + "description": "SNMP MSE", + "category": "Template", + "subCategory":"Base Monitoring Template", + "updateIfExist": "false", + "composition": [{ + "type": "Map", + "alias": "Map" + }, { + "type": "Supplement", + "alias": "Sup" + }, { + "type": "Enrich", + "alias": "Enr" + }], + "relations": [{ + "fromComponent": "Sup.Supplement", + "fromRequirement": "dependency", + "toComponent": "Map.Map", + "toCapability": "feature" + },{ + "fromComponent": "Enr.Enrich", + "fromRequirement": "dependency", + "toComponent": "Sup.Supplement", + "toCapability": "feature" + }] + }, { + "name": "Docker Map Template", + "flowType": "Docker Map", + "description": "Docker Map", + "category": "Template", + "subCategory":"Base Monitoring Template", + "updateIfExist": "false", + "composition": [{ + "type": "DockerMap", + "alias": "dMp" + }, { + "type": "Existing Feed", + "alias": "eFeed" + }, { + "type": "Existing Topic", + "alias": "eTopic" + }], + "relations": [{ + "fromComponent": "dMp.DockerMap", + "fromRequirement": "stream_subscribe_0", + "toComponent": "eFeed.feed", + "toCapability": "feed" + }, { + "fromComponent": "dMp.DockerMap", + "fromRequirement": "stream_publish_0", + "toComponent": "eTopic.topic", + "toCapability": "topic" + }], + "nodesToDelete": [ + { + "type": "DockerMap", + "nodeName": "feed0" + }, + { + "type": "DockerMap", + "nodeName": "topic0" + }] + }] }
\ No newline at end of file diff --git a/dcaedt_tools/src/test/java/BaseTest.java b/dcaedt_tools/src/test/java/BaseTest.java index 49534a5..f618f2d 100644 --- a/dcaedt_tools/src/test/java/BaseTest.java +++ b/dcaedt_tools/src/test/java/BaseTest.java @@ -21,6 +21,7 @@ import static org.mockito.Mockito.when; abstract class BaseTest { static final String USER_ID = "userId"; static final String TEMPLATE_INFO_NAME = "templateInfoName"; + static final String TEMPLATE_INFO_FLOWTYPE = "templateInfoFlowType"; static final String VFCMT_NAME1 = "my vfcmt1"; static final String UUID1 = "my uuid1"; static final String VFCMT_NAME2 = "my vfcmt2"; @@ -127,25 +128,26 @@ abstract class BaseTest { resourceDetailed.setUuid(UUID3); resourceDetaileds.add(resourceDetailed); - List<ResourceDetailed> resourceDetaileds2 = new ArrayList<>(); + List<ResourceDetailed> resourceDetailed2 = new ArrayList<>(); resourceDetailed = new ResourceDetailed(); resourceDetailed.setName(VFCMT_NAME1); resourceDetailed.setUuid(UUID1); resourceDetailed.setLifecycleState("NOT_CERTIFIED_CHECKOUT"); resourceDetailed.setLastUpdaterUserId(USER_ID); - resourceDetaileds2.add(resourceDetailed); + resourceDetailed2.add(resourceDetailed); resourceDetailed = new ResourceDetailed(); resourceDetailed.setName(VFCMT_NAME2); resourceDetailed.setUuid(UUID2); - resourceDetaileds2.add(resourceDetailed); + resourceDetailed2.add(resourceDetailed); resourceDetailed = new ResourceDetailed(); resourceDetailed.setName(VFCMT_NAME3); resourceDetailed.setUuid(UUID3); - resourceDetaileds2.add(resourceDetailed); + resourceDetailed2.add(resourceDetailed); resourceDetailed = new ResourceDetailed(); resourceDetailed.setName(TEMPLATE_INFO_NAME); resourceDetailed.setUuid(UUID3); - resourceDetaileds2.add(resourceDetailed); - when(dcaeRestClient.getAllVfcmts()).thenReturn(resourceDetaileds, resourceDetaileds2); + resourceDetailed2.add(resourceDetailed); + when(dcaeRestClient.getAllVfcmts()).thenReturn(resourceDetaileds, resourceDetailed2); + when(dcaeRestClient.getAllBaseVfcmts()).thenReturn(new ArrayList<>()); } } diff --git a/dcaedt_tools/src/test/java/DeployTemplateTest.java b/dcaedt_tools/src/test/java/DeployTemplateTest.java index 3fe0a7d..6a8a019 100644 --- a/dcaedt_tools/src/test/java/DeployTemplateTest.java +++ b/dcaedt_tools/src/test/java/DeployTemplateTest.java @@ -26,6 +26,7 @@ public class DeployTemplateTest extends BaseTest { templateInfoToJsonObjectMap = new HashMap<>(); TemplateInfo templateInfo = new TemplateInfo(); templateInfo.setName(VFCMT_NAME1); + templateInfo.setFlowType(TEMPLATE_INFO_FLOWTYPE); templateInfo.setCategory("category"); templateInfo.setSubCategory("subCategory"); templateInfo.setDescription("description"); @@ -33,6 +34,7 @@ public class DeployTemplateTest extends BaseTest { templateInfoToJsonObjectMap.put(templateInfo, new JsonObject()); templateInfo = new TemplateInfo(); templateInfo.setName(TEMPLATE_INFO_NAME); + templateInfo.setFlowType(TEMPLATE_INFO_FLOWTYPE); templateInfo.setCategory("category"); templateInfo.setSubCategory("subCategory"); templateInfo.setDescription("description"); diff --git a/dcaedt_tools/src/test/java/TemplateContainerTest.java b/dcaedt_tools/src/test/java/TemplateContainerTest.java index 7c3d287..b4ddc17 100644 --- a/dcaedt_tools/src/test/java/TemplateContainerTest.java +++ b/dcaedt_tools/src/test/java/TemplateContainerTest.java @@ -2,6 +2,7 @@ import com.google.gson.JsonObject; import json.response.ItemsResponse.Item; import json.response.ItemsResponse.Model; import json.templateInfo.Composition; +import json.templateInfo.NodeToDelete; import json.templateInfo.Relation; import json.templateInfo.TemplateInfo; import org.junit.Assert; @@ -28,6 +29,7 @@ public class TemplateContainerTest extends BaseTest { templateInfos = new ArrayList<>(); TemplateInfo templateInfo = new TemplateInfo(); templateInfo.setName(TEMPLATE_INFO_NAME); + templateInfo.setFlowType(TEMPLATE_INFO_FLOWTYPE); Composition composition = new Composition(); composition.setType(ELEMENT_NAME3); composition.setAlias(ALIAS_NAME3); @@ -84,10 +86,28 @@ public class TemplateContainerTest extends BaseTest { } @Test + public void getCdumpsWithDeleteNode_returnOneCdumpWithDeletedNode() { + NodeToDelete nodeToDelete = new NodeToDelete(); + nodeToDelete.setNodeName("SomeNameFromRequirement"); + nodeToDelete.setType("my element3"); + templateInfos.get(0).setNodesToDelete(Collections.singletonList(nodeToDelete)); + templateContainer = new TemplateContainer(report, dcaeRestClient, templateInfos, elementsByFolderNames); + + Map<TemplateInfo, JsonObject> templateInfoJsonObjectMap = templateContainer.getCdumps(); + JsonObject jsonObject = templateInfoJsonObjectMap.get(templateInfos.get(0)); + String result = jsonObject.toString(); + + verifyDeletedNodeCdump(result); + verify(report, times(0)).addErrorMessage(anyString()); + Assert.assertTrue(templateInfoJsonObjectMap.size() == 1); + } + + @Test public void getChumps_returnOneChumpWithRelations() { templateInfos = new ArrayList<>(); TemplateInfo templateInfo = new TemplateInfo(); templateInfo.setName(TEMPLATE_INFO_NAME); + templateInfo.setFlowType(TEMPLATE_INFO_FLOWTYPE); List<Composition> compositionList = new ArrayList<>(); Composition composition = new Composition(); composition.setType(ELEMENT_NAME3); @@ -141,17 +161,23 @@ public class TemplateContainerTest extends BaseTest { Assert.assertTrue(result.contains("\"relationship\":[")); Assert.assertTrue(result.contains("\"n1\":\"n.")); Assert.assertTrue(result.contains("\"relations\":[{")); - Assert.assertTrue(result.contains("\"name1\":\"SomeNameFromRequirement\"")); + Assert.assertTrue(result.contains(",\"name2\":\"my alias2.SomeNameToCapability\",")); + Assert.assertTrue(result.contains(",\"name1\":\"my alias3.SomeNameFromRequirement\",")); Assert.assertTrue(result.contains("\"n2\":\"n.")); Assert.assertTrue(result.contains("\"p1\":\"SomeNameFromRequirement\"")); } private void verifyCdump(String result) { - String expectedResultStart = "{\"version\":0,\"flowType\":\"templateInfoName\",\"nodes\":[{\"name\":\"SomeNameFromRequirement\",\"description\":\"\",\"id\":\"e45ec9d7-01df-4cb1-896f-aff2a6ca5a8b\",\"nid\":\"n."; - String expectedResultMid = "\",\"capabilities\":[{\"name\":\"SomeNameToCapability\"}],\"requirements\":[{\"name\":\"SomeNameFromRequirement\"}],\"properties\":[{}],\"typeinfo\":{\"itemId\":\"e45ec9d7-01df-4cb1-896f-aff2a6ca5a8b/tosca.dcae.nodes.cdapApp.Map\",\"typeinfo\":\"typeInfo\"},\"type\":{\"name\":\"type\"},\"ndata\":{\"name\":\"n."; + String expectedResultStart = "{\"version\":0,\"flowType\":\"templateInfoFlowType\",\"nodes\":[{\"name\":\"my alias3.SomeNameFromRequirement\",\"description\":\"\",\"id\":\"e45ec9d7-01df-4cb1-896f-aff2a6ca5a8b\",\"nid\":\"n."; + String expectedResultMid = "\",\"capabilities\":[{\"name\":\"SomeNameToCapability\"}],\"requirements\":[{\"name\":\"SomeNameFromRequirement\"}],\"properties\":[{\"value\":{}}],\"typeinfo\":{\"itemId\":\"e45ec9d7-01df-4cb1-896f-aff2a6ca5a8b/tosca.dcae.nodes.cdapApp.Map\",\"typeinfo\":\"typeInfo\"},\"type\":{\"name\":\"type\"},\"ndata\":{\"name\":\"n."; String expectedResultEnd = "\",\"label\":\"SomeNameFromRequirement\",\"x\":438,\"y\":435,\"px\":437,\"py\":434,\"ports\":[],\"radius\":30}}],\"inputs\":[],\"outputs\":[],\"relations\":[]}"; Assert.assertTrue(result.startsWith(expectedResultStart)); Assert.assertTrue(result.contains(expectedResultMid)); Assert.assertTrue(result.endsWith(expectedResultEnd)); } + + private void verifyDeletedNodeCdump(String result) { + String expectedResult = "{\"version\":0,\"flowType\":\"templateInfoFlowType\",\"nodes\":[],\"inputs\":[],\"outputs\":[],\"relations\":[]}"; + Assert.assertEquals(expectedResult, result); + } } diff --git a/dcaedt_validator/Dockerfile b/dcaedt_validator/Dockerfile new file mode 100644 index 0000000..bcb4074 --- /dev/null +++ b/dcaedt_validator/Dockerfile @@ -0,0 +1,28 @@ +# +# Oracle Java 8 Dockerfile +# +# +# Image built by Thomas Nelson See Docker Github +# Pull base image. +FROM jdk-8u101_ubuntu:16.04 + +# Define commonly used ENV variables +#ENV JAVA_HOME /usr/lib/jvm/java-8-oracle +#ENV PATH $PATH:$JAVA_HOME/bin:/opt/apache-tomcat-8.0.37/bin +ENV INSDIR /opt/app/validator +ENV LOGS ${INSDIR}/logs + +RUN mkdir -p $INSDIR + +RUN mkdir ${INSDIR}/ssl && \ + mkdir $LOGS +COPY service/target/ASC-Validator-*.jar ${INSDIR}/ASC-Validator.jar +COPY service/target/classes/application.properties ${INSDIR}/ +COPY configure-and-run.sh /usr/local/bin/ +# Define working directory. +WORKDIR $INSDIR +VOLUME $LOGS + +# Define default command. +CMD ["/usr/local/bin/configure-and-run.sh"] + diff --git a/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Catalog.java b/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Catalog.java index 1512e56..bdddce3 100644 --- a/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Catalog.java +++ b/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Catalog.java @@ -23,7 +23,6 @@ import com.google.common.collect.Iterators; import com.google.common.collect.Table; import com.google.common.collect.HashBasedTable; import org.onap.sdc.common.onaplog.OnapLoggerDebug; -import org.onap.sdc.common.onaplog.OnapLoggerError; import org.onap.sdc.common.onaplog.Enums.LogLevel; /* @@ -33,250 +32,249 @@ import org.onap.sdc.common.onaplog.Enums.LogLevel; */ public class Catalog { - private static OnapLoggerError errLogger = OnapLoggerError.getInstance(); - private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); + private static final String DERIVED_FROM = "derived_from"; + private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); - /* Type hierarchies are stored as maps from a type name to its definition + + /* tracks imports, i.e.targets */ + private LinkedHashMap<URI, Target> targets = + new LinkedHashMap<>(); + /* tracks dependencies between targets, i.e. the 'adjency' matrix defined by + * the 'import' relationship */ + private Table<Target,Target,Boolean> imports = HashBasedTable.create(); + + + /* Type hierarchies are stored as maps from a type name to its definition * Not the best but easy to follow hierarchies towards their root .. */ private EnumMap<Construct, Map<String,Map>> types = - new EnumMap<Construct, Map<String,Map>>(Construct.class); - /* track templates: we track templates (tye instances) first per target then per contruct. - * This allows us to share the catalog among multiple templates sharign the same type set + new EnumMap<>(Construct.class); + /* track templates: we track templates (tye instances) first per target then per contruct. + * This allows us to share the catalog among multiple templates sharign the same type set */ private Map<Target, EnumMap<Construct, Map<String,Map>>> templates = - new HashMap<Target, EnumMap<Construct, Map<String,Map>>>(); - - private Catalog parent; - - public Catalog(Catalog theParent) { - this.parent = theParent; - /* there are no requirement types, they are the same as capability types */ - types.put(Construct.Data, new LinkedHashMap<String, Map>()); - types.put(Construct.Capability, new LinkedHashMap<String, Map>()); - types.put(Construct.Relationship, new LinkedHashMap<String, Map>()); - types.put(Construct.Artifact, new LinkedHashMap<String, Map>()); - types.put(Construct.Interface, new LinkedHashMap<String, Map>()); - types.put(Construct.Node, new LinkedHashMap<String, Map>()); - types.put(Construct.Group, new LinkedHashMap<String, Map>()); - types.put(Construct.Policy, new LinkedHashMap<String, Map>()); + new HashMap<>(); + + private Catalog parent; + + public Catalog(Catalog theParent) { + this.parent = theParent; + /* there are no requirement types, they are the same as capability types */ + types.put(Construct.Data, new LinkedHashMap<>()); + types.put(Construct.Capability, new LinkedHashMap<>()); + types.put(Construct.Relationship, new LinkedHashMap<>()); + types.put(Construct.Artifact, new LinkedHashMap<>()); + types.put(Construct.Interface, new LinkedHashMap<>()); + types.put(Construct.Node, new LinkedHashMap<>()); + types.put(Construct.Group, new LinkedHashMap<>()); + types.put(Construct.Policy, new LinkedHashMap<>()); - } - - public Catalog() { - this(null); - } - - public boolean addType(Construct theConstruct, String theName, Map theDef) { - if (hasType(theConstruct, theName)) { - return false; - } - getConstructTypes(theConstruct).put(theName, theDef); - return true; + } + + public Catalog() { + this(null); + } + + public boolean addType(Construct theConstruct, String theName, Map theDef) { + if (hasType(theConstruct, theName)) { + return false; + } + getConstructTypes(theConstruct).put(theName, theDef); + return true; } - public Map getTypeDefinition(Construct theConstruct, String theName) { - Map<String, Map> constructTypes = getConstructTypes(theConstruct); - Map typeDef = constructTypes.get(theName); - if (typeDef == null && this.parent != null) { - return this.parent.getTypeDefinition(theConstruct, theName); - } - return typeDef; - } + public Map getTypeDefinition(Construct theConstruct, String theName) { + Map<String, Map> constructTypes = getConstructTypes(theConstruct); + Map typeDef = constructTypes.get(theName); + if (typeDef == null && this.parent != null) { + return this.parent.getTypeDefinition(theConstruct, theName); + } + return typeDef; + } public boolean hasType(Construct theConstruct, String theName) { - Map<String, Map> constructTypes = getConstructTypes(theConstruct); - boolean res = constructTypes.containsKey(theName); - if (!res && this.parent != null) { - res = this.parent.hasType(theConstruct, theName); - } - return res; - } - - protected Map<String, Map> getConstructTypes(Construct theConstruct) { - Map<String, Map> constructTypes = this.types.get(theConstruct); - if (null == constructTypes) { - throw new RuntimeException("Something worse is cooking here!", - new CatalogException("No types for construct " + theConstruct)); - } - return constructTypes; - } - - protected Iterator<Map.Entry<String,Map>> - typesIterator(Construct theConstruct) { - List<Map.Entry<String,Map>> constructTypes = - new ArrayList<Map.Entry<String,Map>>( - this.types.get(theConstruct).entrySet()); - Collections.reverse(constructTypes); - return (this.parent == null) - ? constructTypes.iterator() - : Iterators.concat(constructTypes.iterator(), - this.parent.typesIterator(theConstruct)); - } - - /* this will iterate through the type hierarchy for the given type, included. - */ - public Iterator<Map.Entry<String,Map>> - hierarchy(Construct theConstruct, final String theName) { - return Iterators.filter(typesIterator(theConstruct), + Map<String, Map> constructTypes = getConstructTypes(theConstruct); + boolean res = constructTypes.containsKey(theName); + if (!res && this.parent != null) { + res = this.parent.hasType(theConstruct, theName); + } + return res; + } + + protected Map<String, Map> getConstructTypes(Construct theConstruct) { + Map<String, Map> constructTypes = this.types.get(theConstruct); + if (null == constructTypes) { + throw new RuntimeException("Something worse is cooking here!", + new CatalogException("No types for construct " + theConstruct)); + } + return constructTypes; + } + + private Iterator<Map.Entry<String,Map>> + typesIterator(Construct theConstruct) { + List<Map.Entry<String,Map>> constructTypes = + new ArrayList<>( + this.types.get(theConstruct).entrySet()); + Collections.reverse(constructTypes); + return (this.parent == null) + ? constructTypes.iterator() + : Iterators.concat(constructTypes.iterator(), + this.parent.typesIterator(theConstruct)); + } + + + // this will iterate through the type hierarchy for the given type, included. + public Iterator<Map.Entry<String,Map>> + hierarchy(Construct theConstruct, final String theName) { + return Iterators.filter(typesIterator(theConstruct), new Predicate<Map.Entry<String,Map>>() { Object next = theName; public boolean apply(Map.Entry<String,Map> theEntry) { if (next != null && next.equals(theEntry.getKey())) { - next = theEntry.getValue().get("derived_from"); + next = theEntry.getValue().get(DERIVED_FROM); return true; + } else { + return false; } - else - return false; } }); } - public boolean isDerivedFrom(Construct theConstruct, String theType, String theBaseType) { - - Iterator<Map.Entry<String,Map>> hierachyIterator = - hierarchy(theConstruct, theType); - while (hierachyIterator.hasNext()) { - Map.Entry<String,Map> typeDef = hierachyIterator.next(); - - if (typeDef.getKey().equals(theBaseType)) { - return true; - } - } - return false; - } - - /* We go over the type hierarchy and retain only an iterator over the - * elements of the given facet for each type in the hierarchy. - * We concatenate these iterators and filter out duplicates. - * TODO: cannot just filter out duplicates - a redefinition can refine the one in the base construct so we - * should merge them! - */ - public Iterator<Map.Entry> facets(Construct theConstruct, - final Facet theFacet, - final String theName) { - return - Iterators.filter( - Iterators.concat( - Iterators.transform( - hierarchy(theConstruct, theName), - new Function<Map.Entry<String,Map>, Iterator<Map.Entry>>() { - public Iterator<Map.Entry> apply(Map.Entry<String,Map> theEntry) { - Map m = (Map)theEntry.getValue().get(theFacet.name()); - return m == null - ? Collections.emptyIterator() - : m.entrySet().iterator(); - } - } - ) - ), + public boolean isDerivedFrom(Construct theConstruct, String theType, String theBaseType) { + + Iterator<Map.Entry<String,Map>> hierachyIterator = + hierarchy(theConstruct, theType); + while (hierachyIterator.hasNext()) { + Map.Entry<String,Map> typeDef = hierachyIterator.next(); + + if (typeDef.getKey().equals(theBaseType)) { + return true; + } + } + return false; + } + + /* We go over the type hierarchy and retain only an iterator over the + * elements of the given facet for each type in the hierarchy. + * We concatenate these iterators and filter out duplicates. + * TODO: cannot just filter out duplicates - a redefinition can refine the one in the base construct so we + * should merge them! + */ + public Iterator<Map.Entry> facets(Construct theConstruct, final Facet theFacet, final String theName) { + return + Iterators.filter( + Iterators.concat( + Iterators.transform( + hierarchy(theConstruct, theName), + (Function<Map.Entry<String, Map>, Iterator<Map.Entry>>) theEntry -> { + Map m = (Map)theEntry.getValue().get(theFacet.name()); + return m == null + ? Collections.emptyIterator() + : m.entrySet().iterator(); + } + ) + ), new Predicate<Map.Entry>() { - Set insts = new HashSet(); - public boolean apply(Map.Entry theEntry) { - return !insts.contains(theEntry.getKey()); - } - } - ); - } - - //no need to specify a construct, only nodes can have requirements - public Iterator<Map.Entry> requirements(final String theName) { - return - Iterators.concat( - Iterators.transform( - hierarchy(Construct.Node, theName), - new Function<Map.Entry<String,Map>, Iterator<Map.Entry>>() { - public Iterator<Map.Entry> apply(Map.Entry<String,Map> theEntry) { - List<Map> l = (List<Map>)theEntry.getValue().get("requirements"); - return l == null - ? Collections.emptyIterator() - : Iterators.concat( - Iterators.transform( - l.iterator(), - new Function<Map, Iterator<Map.Entry>> () { - public Iterator<Map.Entry> apply(Map theEntry) { - return theEntry.entrySet().iterator(); - } - } - ) - ); - } - } - ) - ); - } - - /* Example: find the definition of property 'port' of the node type - * tosca.nodes.Database (properties being a facet of the node construct) - * - * Note: the definition of a facet is cumulative, i.e. more specialized - * definitions contribute (by overwriting) to the - */ - public Map getFacetDefinition(Construct theConstruct, - String theConstructTypeName, - Facet theFacet, - String theName) { - Map def = null; - Iterator<Map.Entry<String,Map>> ti = hierarchy(theConstruct, theConstructTypeName); - while (ti.hasNext()) { - //this is where requirements would yield a List .. - Map<String,Map> fset = (Map<String,Map>)ti.next().getValue().get(theFacet.name()); - if (fset != null) { - def = def == null ? fset.get(theName) - : mergeDefinitions(def, fset.get(theName)); - } - } - return def; - } - - public Map getRequirementDefinition(Construct theConstruct, - String theConstructTypeName, - String theName) { - Iterator<Map.Entry<String,Map>> ti = hierarchy(theConstruct, theConstructTypeName); - while (ti.hasNext()) { - //this is where requirements yield a List .. - List<Map> reqs = (List<Map>)ti.next().getValue().get("requirements"); - - if(reqs!=null){ - for (Map req: reqs) { - Map.Entry reqe = (Map.Entry)req.entrySet().iterator().next(); - if (theName.equals(reqe.getKey())) { - return (Map)reqe.getValue(); - } - } - }else{ - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Avoiding adding requirment block since it doesn't exists on the template...."); - } - } - return null; - } + Set insts = new HashSet(); + public boolean apply(Map.Entry theEntry) { + return !insts.contains(theEntry.getKey()); + } + } + ); + } + + //no need to specify a construct, only nodes can have requirements + public Iterator<Map.Entry> requirements(final String theName) { + return + Iterators.concat( + Iterators.transform( + hierarchy(Construct.Node, theName), + theEntry -> { + List<Map> l = (List<Map>)theEntry.getValue().get("requirements"); + return l == null + ? Collections.emptyIterator() + : Iterators.concat( + Iterators.transform( + l.iterator(), + (Function<Map, Iterator<Map.Entry>>) theEntry1 -> theEntry1.entrySet().iterator() + ) + ); + } + ) + ); + } + + /* Example: find the definition of property 'port' of the node type + * tosca.nodes.Database (properties being a facet of the node construct) + * + * Note: the definition of a facet is cumulative, i.e. more specialized + * definitions contribute (by overwriting) to the + */ + public Map getFacetDefinition(Construct theConstruct, + String theConstructTypeName, + Facet theFacet, + String theName) { + Map def = null; + Iterator<Map.Entry<String,Map>> ti = hierarchy(theConstruct, theConstructTypeName); + while (ti.hasNext()) { + //this is where requirements would yield a List .. + Map<String,Map> fset = (Map<String,Map>)ti.next().getValue().get(theFacet.name()); + if (fset != null) { + def = def == null ? fset.get(theName) + : mergeDefinitions(def, fset.get(theName)); + } + } + return def; + } + + public Map getRequirementDefinition(Construct theConstruct, + String theConstructTypeName, + String theName) { + Iterator<Map.Entry<String,Map>> ti = hierarchy(theConstruct, theConstructTypeName); + while (ti.hasNext()) { + //this is where requirements yield a List .. + List<Map> reqs = (List<Map>)ti.next().getValue().get("requirements"); + + if(reqs!=null) { + for (Map req: reqs) { + Map.Entry reqe = (Map.Entry)req.entrySet().iterator().next(); + if (theName.equals(reqe.getKey())) { + return (Map)reqe.getValue(); + } + } + } else { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Avoiding adding requirment block since it doesn't exists on the template...."); + } + } + return null; + } /* */ private EnumMap<Construct,Map<String,Map>> getTemplates(Target theTarget) { - EnumMap<Construct, Map<String,Map>> targetTemplates = templates.get(theTarget); - if (targetTemplates == null) { - targetTemplates = new EnumMap<Construct,Map<String,Map>>(Construct.class); - targetTemplates.put(Construct.Data, new LinkedHashMap<String, Map>()); - targetTemplates.put(Construct.Relationship, new LinkedHashMap<String, Map>()); - targetTemplates.put(Construct.Node, new LinkedHashMap<String, Map>()); - targetTemplates.put(Construct.Group, new LinkedHashMap<String, Map>()); - targetTemplates.put(Construct.Policy, new LinkedHashMap<String, Map>()); - - templates.put(theTarget, targetTemplates); - } - return targetTemplates; - } - - public Map<String,Map> getTargetTemplates(Target theTarget, Construct theConstruct) { - return getTemplates(theTarget).get(theConstruct); - } - - public void addTemplate(Target theTarget, Construct theConstruct, String theName, Map theDef) - throws CatalogException { - Map<String, Map> constructTemplates = getTargetTemplates(theTarget, theConstruct); - if (null == constructTemplates) { + EnumMap<Construct, Map<String,Map>> targetTemplates = templates.get(theTarget); + if (targetTemplates == null) { + targetTemplates = new EnumMap<>(Construct.class); + targetTemplates.put(Construct.Data, new LinkedHashMap<>()); + targetTemplates.put(Construct.Relationship, new LinkedHashMap<>()); + targetTemplates.put(Construct.Node, new LinkedHashMap<>()); + targetTemplates.put(Construct.Group, new LinkedHashMap<>()); + targetTemplates.put(Construct.Policy, new LinkedHashMap<>()); + + templates.put(theTarget, targetTemplates); + } + return targetTemplates; + } + + public Map<String,Map> getTargetTemplates(Target theTarget, Construct theConstruct) { + return getTemplates(theTarget).get(theConstruct); + } + + public void addTemplate(Target theTarget, Construct theConstruct, String theName, Map theDef) + throws CatalogException { + Map<String, Map> constructTemplates = getTargetTemplates(theTarget, theConstruct); + if (null == constructTemplates) { throw new CatalogException("No such thing as " + theConstruct + " templates"); - } + } if (constructTemplates.containsKey(theName)) { throw new CatalogException(theConstruct + " template '" + theName + "' re-declaration"); } @@ -286,159 +284,159 @@ public class Catalog { public boolean hasTemplate(Target theTarget, Construct theConstruct, String theName) { Map<String, Map> constructTemplates = getTargetTemplates(theTarget, theConstruct); return constructTemplates != null && - constructTemplates.containsKey(theName); + constructTemplates.containsKey(theName); } public Map getTemplate(Target theTarget, Construct theConstruct, String theName) { Map<String, Map> constructTemplates = getTargetTemplates(theTarget, theConstruct); - if (constructTemplates != null) - return constructTemplates.get(theName); - else - return null; + if (constructTemplates != null) { + return constructTemplates.get(theName); + } else { + return null; + } } - public static Map mergeDefinitions(Map theAggregate, Map theIncrement) { - if (theIncrement == null) - return theAggregate; - - for(Map.Entry e: (Set<Map.Entry>)theIncrement.entrySet()) { - theAggregate.putIfAbsent(e.getKey(), e.getValue()); - } - return theAggregate; - } + public static Map mergeDefinitions(Map theAggregate, Map theIncrement) { + if (theIncrement == null) { + return theAggregate; + } - /* tracks imports, i.e.targets */ - private LinkedHashMap<URI, Target> targets = - new LinkedHashMap<URI, Target>(); - /* tracks dependencies between targets, i.e. the 'adjency' matrix defined by - * the 'import' relationship */ - private Table<Target,Target,Boolean> imports = HashBasedTable.create(); + for(Map.Entry e: (Set<Map.Entry>)theIncrement.entrySet()) { + theAggregate.putIfAbsent(e.getKey(), e.getValue()); + } + return theAggregate; + } - /* + /* * theParent contains an 'include/import' statement pointing to the Target */ - public boolean addTarget(Target theTarget, Target theParent) { - boolean cataloged = targets.containsKey(theTarget.getLocation()); - - if(!cataloged) { - targets.put(theTarget.getLocation(), theTarget); - } - - if (theParent != null) { - imports.put(theParent, theTarget, Boolean.TRUE); - } - - return !cataloged; - } - - public Target getTarget(URI theLocation) { - return targets.get(theLocation); - } - - public Collection<Target> targets() { - return targets.values(); - } - - /* Targets that no other targets depend on */ - public Collection<Target> topTargets() { - return targets.values() - .stream() - .filter(t -> !imports.containsColumn(t)) - .collect(Collectors.toList()); - - } - - public String importString(Target theTarget) { - return importString(theTarget, " "); - } - - private String importString(Target theTarget, String thePrefix) { - StringBuilder sb = new StringBuilder(""); - Map<Target,Boolean> parents = imports.column(theTarget); - if (parents != null) { - for (Target p: parents.keySet()) { - sb.append(thePrefix) - .append("from ") - .append(p.getLocation()) - .append("\n") - .append(importString(p, thePrefix + " ")); - } - //we only keep the positive relationships - } - return sb.toString(); - } - - /* */ - private class TargetComparator implements Comparator<Target> { - - /* @return 1 if there is a dependency path from TargetOne to TargetTwo, -1 otherwise */ - public int compare(Target theTargetOne, Target theTargetTwo) { - if (hasPath(theTargetTwo, theTargetOne)) - return -1; - - if (hasPath(theTargetOne, theTargetTwo)) - return 1; - - return 0; - } - - public boolean hasPath(Target theStart, Target theEnd) { - Map<Target,Boolean> deps = imports.row(theStart); - if (deps.containsKey(theEnd)) - return true; - for (Target dep: deps.keySet()) { - if (hasPath(dep, theEnd)) - return true; - } - return false; - } - } - - public Collection<Target> sortedTargets() { - List keys = new ArrayList(this.targets.values()); - Collections.sort(keys, new TargetComparator()); - return keys; - } - - public static void main(String[] theArgs) throws Exception { - - Catalog cat = new Catalog(); - - Target a = new Target("a", new URI("a")), - b = new Target("b", new URI("b")), - c = new Target("c", new URI("c")), - d = new Target("d", new URI("d")); - - cat.addTarget(a, null); - cat.addTarget(b, null); - cat.addTarget(c, null); - cat.addTarget(d, null); - - cat.addTarget(b, c); - cat.addTarget(a, c); - cat.addTarget(c, d); - cat.addTarget(a, b); - - for (Target t: cat.sortedTargets()) - debugLogger.log(LogLevel.DEBUG, Catalog.class.getName(), t.toString()); - - Catalog root = new Catalog(); - root.addType(Construct.Node, "_a", Collections.emptyMap()); - root.addType(Construct.Node, "__a", Collections.singletonMap("derived_from", "_a")); - root.addType(Construct.Node, "___a", Collections.singletonMap("derived_from", "_a")); - - Catalog base = new Catalog(root); - base.addType(Construct.Node, "_b", Collections.singletonMap("derived_from", "__a")); - base.addType(Construct.Node, "__b", Collections.singletonMap("derived_from", "_b")); - base.addType(Construct.Node, "__b_", Collections.singletonMap("derived_from", "_a")); - - if (theArgs.length > 0) { - Iterator<Map.Entry<String, Map>> ti = - base.hierarchy(Construct.Node, theArgs[0]); - while (ti.hasNext()) { + public boolean addTarget(Target theTarget, Target theParent) { + boolean cataloged = targets.containsKey(theTarget.getLocation()); + + if(!cataloged) { + targets.put(theTarget.getLocation(), theTarget); + } + + if (theParent != null) { + imports.put(theParent, theTarget, Boolean.TRUE); + } + + return !cataloged; + } + + public Target getTarget(URI theLocation) { + return targets.get(theLocation); + } + + public Collection<Target> targets() { + return targets.values(); + } + + /* Targets that no other targets depend on */ + public Collection<Target> topTargets() { + return targets.values() + .stream() + .filter(t -> !imports.containsColumn(t)) + .collect(Collectors.toList()); + + } + + public String importString(Target theTarget) { + return importString(theTarget, " "); + } + + private String importString(Target theTarget, String thePrefix) { + StringBuilder sb = new StringBuilder(""); + Map<Target,Boolean> parents = imports.column(theTarget); + if (parents != null) { + for (Target p: parents.keySet()) { + sb.append(thePrefix) + .append("from ") + .append(p.getLocation()) + .append("\n") + .append(importString(p, thePrefix + " ")); + } + //we only keep the positive relationships + } + return sb.toString(); + } + + /* */ + private class TargetComparator implements Comparator<Target> { + + /* @return 1 if there is a dependency path from TargetOne to TargetTwo, -1 otherwise */ + public int compare(Target theTargetOne, Target theTargetTwo) { + if (hasPath(theTargetTwo, theTargetOne)) { + return -1; + } + + if (hasPath(theTargetOne, theTargetTwo)) { + return 1; + } + + return 0; + } + + boolean hasPath(Target theStart, Target theEnd) { + Map<Target,Boolean> deps = imports.row(theStart); + if (deps.containsKey(theEnd)) { + return true; + } + for (Target dep: deps.keySet()) { + if (hasPath(dep, theEnd)) { + return true; + } + } + return false; + } + } + + public Collection<Target> sortedTargets() { + List keys = new ArrayList(this.targets.values()); + Collections.sort(keys, new TargetComparator()); + return keys; + } + + public static void main(String[] theArgs) throws Exception { + + Catalog cat = new Catalog(); + + Target a = new Target("a", new URI("a")), + b = new Target("b", new URI("b")), + c = new Target("c", new URI("c")), + d = new Target("d", new URI("d")); + + cat.addTarget(a, null); + cat.addTarget(b, null); + cat.addTarget(c, null); + cat.addTarget(d, null); + + cat.addTarget(b, c); + cat.addTarget(a, c); + cat.addTarget(c, d); + cat.addTarget(a, b); + + for (Target t: cat.sortedTargets()) { + debugLogger.log(LogLevel.DEBUG, Catalog.class.getName(), t.toString()); + } + + Catalog root = new Catalog(); + root.addType(Construct.Node, "_a", Collections.emptyMap()); + root.addType(Construct.Node, "__a", Collections.singletonMap(DERIVED_FROM, "_a")); + root.addType(Construct.Node, "___a", Collections.singletonMap(DERIVED_FROM, "_a")); + + Catalog base = new Catalog(root); + base.addType(Construct.Node, "_b", Collections.singletonMap(DERIVED_FROM, "__a")); + base.addType(Construct.Node, "__b", Collections.singletonMap(DERIVED_FROM, "_b")); + base.addType(Construct.Node, "__b_", Collections.singletonMap(DERIVED_FROM, "_a")); + + if (theArgs.length > 0) { + Iterator<Map.Entry<String, Map>> ti = + base.hierarchy(Construct.Node, theArgs[0]); + while (ti.hasNext()) { debugLogger.log(LogLevel.DEBUG, Catalog.class.getName(), "> {}", ti.next().getKey()); - } - } - } + } + } + } } diff --git a/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Checker.java b/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Checker.java index fee617f..bf1843e 100644 --- a/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Checker.java +++ b/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Checker.java @@ -87,6 +87,7 @@ public class Checker { private static final String WAS_DEFINED_FOR_THE_NODE_TYPE = " was defined for the node type "; private static final String UNKNOWN = "Unknown "; private static final String TYPE = " type "; + public static final String IMPORTED_FROM = "',imported from "; private Target target = null; //what we're validating at the moment @@ -2404,9 +2405,7 @@ public class Checker { return false; } - for (Iterator<Map.Entry<String, Map>> ai = augs.entrySet().iterator(); ai.hasNext(); ) { - Map.Entry<String, Map> ae = ai.next(); - + for (Map.Entry<String, Map> ae : augs.entrySet()) { //make sure it was declared by the type Map facetDef = catalog.getFacetDefinition(theConstruct, theSpecType, theFacet, ae.getKey()); if (facetDef == null) { @@ -2715,7 +2714,7 @@ public class Checker { private String patchWhitespaces(String thePath) { String[] elems = thePath.split("/"); - StringBuffer path = new StringBuffer(); + StringBuilder path = new StringBuilder(); for (int i = 0; i < elems.length; i++) { if (spacePattern.matcher(elems[i]).find()) { path.append("[@name='") @@ -2836,7 +2835,7 @@ public class Checker { hookHandler = Invokable.from(m); } catch (NoSuchMethodException nsmx) { //that's ok, not every rule has to have a handler - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), getClass().getName(), "That's ok, not every rule has to have a handler. Method name =", theHookName); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), getClass().getName(), "That's ok, not every rule has to have a handler. Method name is:{}. Exception:{}", theHookName,nsmx); } if (hookHandler != null) { @@ -3120,7 +3119,7 @@ substitute the canonical form for the short form so that checking does not have debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), getClass().getName(), "entering range_definition {}", theContext.getPath()); - assert theRule.getType().equals("seq"); + assert "seq".equals(theRule.getType()); List bounds = (List) theValue; if (bounds.size() != 2) { @@ -3148,10 +3147,10 @@ substitute the canonical form for the short form so that checking does not have * early processing (validation time) of the imports allows us to catalog * their types before those declared in the main document. */ - protected void imports_post_validation_handler(Object theValue, Rule theRule, - Validator.ValidationContext theContext) { + protected void imports_post_validation_handler(Object theValue, Rule theRule, Validator.ValidationContext theContext) { debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "entering imports {}", theContext.getPath()); - assert theRule.getType().equals("seq"); + + assert "seq".equals(theRule.getType()); Target tgt = ((TOSCAValidator) theContext.getValidator()).getTarget(); @@ -3179,8 +3178,9 @@ substitute the canonical form for the short form so that checking does not have try { List<Target> tgtis = parseTarget(tgti); - if (tgtis.isEmpty()) - continue; + if (tgtis.isEmpty()) { + continue; + } if (tgtis.size() > 1) { theContext.addError( @@ -3191,21 +3191,20 @@ substitute the canonical form for the short form so that checking does not have tgti = tgtis.get(0); - // tgti = parseTarget(tgti); if (tgt.getReport().hasErrors()) { - theContext.addError("Failure parsing import '" + tgti + "',imported from " + tgt, theRule, null, + theContext.addError("Failure parsing import '" + tgti + IMPORTED_FROM + tgt, theRule, null, null); continue; } validateTarget(tgti); if (tgt.getReport().hasErrors()) { - theContext.addError("Failure validating import '" + tgti + "',imported from " + tgt, theRule, + theContext.addError("Failure validating import '" + tgti + IMPORTED_FROM + tgt, theRule, null, null); continue; } } catch (CheckerException cx) { - theContext.addError("Failure validating import '" + tgti + "',imported from " + tgt, theRule, cx, + theContext.addError("Failure validating import '" + tgti + IMPORTED_FROM + tgt, theRule, cx, null); } } @@ -3222,7 +3221,7 @@ substitute the canonical form for the short form so that checking does not have Validator.ValidationContext theContext) { debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "entering node_templates_post_validation_handler {}", theContext.getPath()); - assert theRule.getType().equals("map"); + assert "map".equals(theRule.getType()); Map<String, Map> nodeTemplates = (Map<String, Map>) theValue; for (Iterator<Map.Entry<String, Map>> i = nodeTemplates.entrySet().iterator(); i.hasNext();) { Map.Entry<String, Map> node = i.next(); @@ -3267,17 +3266,18 @@ substitute the canonical form for the short form so that checking does not have private void process(String theProcessorSpec) throws CheckerException { String[] spec = theProcessorSpec.split(" "); - if (spec.length == 0) - throw new IllegalArgumentException("Incomplete processor specification"); + if (spec.length == 0) { + throw new IllegalArgumentException("Incomplete processor specification"); + } - Class processorClass = null; + Class processorClass; try { processorClass = Class.forName(spec[0]); } catch (ClassNotFoundException cnfx) { throw new CheckerException("Cannot find processor implementation", cnfx); } - Processor proc = null; + Processor proc; try { proc = (Processor) ConstructorUtils.invokeConstructor(processorClass, Arrays.copyOfRange(spec, 1, spec.length)); @@ -3296,8 +3296,9 @@ substitute the canonical form for the short form so that checking does not have return; } // check artifact type - if (!checkType(Construct.Artifact, theDef, theContext)) - return; + if (!checkType(Construct.Artifact, theDef, theContext)) { + return; + } } finally { theContext.exit(); } @@ -3312,8 +3313,8 @@ substitute the canonical form for the short form so that checking does not have return; } - if (theDefinition.containsKey("properties")) { - check_properties((Map<String, Map>) theDefinition.get("properties"), theContext); + if (theDefinition.containsKey(PROPERTIES)) { + check_properties((Map<String, Map>) theDefinition.get(PROPERTIES), theContext); checkTypeConstructFacet(Construct.Policy, theName, theDefinition, Facet.properties, theContext); } @@ -3347,8 +3348,8 @@ substitute the canonical form for the short form so that checking does not have return; } - if (theDefinition.containsKey("properties")) { - check_properties((Map<String, Map>) theDefinition.get("properties"), theContext); + if (theDefinition.containsKey(PROPERTIES)) { + check_properties((Map<String, Map>) theDefinition.get(PROPERTIES), theContext); checkTypeConstructFacet(Construct.Group, theName, theDefinition, Facet.properties, theContext); } @@ -3385,8 +3386,8 @@ substitute the canonical form for the short form so that checking does not have return; } - if (theDefinition.containsKey("properties")) { - check_properties((Map<String, Map>) theDefinition.get("properties"), theContext); + if (theDefinition.containsKey(PROPERTIES)) { + check_properties((Map<String, Map>) theDefinition.get(PROPERTIES), theContext); checkTypeConstructFacet(Construct.Node, theName, theDefinition, Facet.properties, theContext); } @@ -3401,8 +3402,8 @@ substitute the canonical form for the short form so that checking does not have } // capabilities - if (theDefinition.containsKey("capabilities")) { - check_capabilities((Map<String, Map>) theDefinition.get("capabilities"), theContext); + if (theDefinition.containsKey(CAPABILITIES)) { + check_capabilities((Map<String, Map>) theDefinition.get(CAPABILITIES), theContext); } // interfaces: @@ -3470,8 +3471,8 @@ substitute the canonical form for the short form so that checking does not have return; } - if (theDefinition.containsKey("properties")) { - check_properties((Map<String, Map>) theDefinition.get("properties"), theContext); + if (theDefinition.containsKey(PROPERTIES)) { + check_properties((Map<String, Map>) theDefinition.get(PROPERTIES), theContext); checkTypeConstructFacet(Construct.Relationship, theName, theDefinition, Facet.properties, theContext); } @@ -3490,9 +3491,9 @@ substitute the canonical form for the short form so that checking does not have theContext.exit(); } - if (theDefinition.containsKey("valid_target_types")) { + if (theDefinition.containsKey(VALID_TARGET_TYPES)) { checkTypeReference(Construct.Capability, theContext, - ((List<String>) theDefinition.get("valid_target_types")).toArray(EMPTY_STRING_ARRAY)); + ((List<String>) theDefinition.get(VALID_TARGET_TYPES)).toArray(EMPTY_STRING_ARRAY)); } } finally { theContext.exit(); @@ -3508,8 +3509,8 @@ substitute the canonical form for the short form so that checking does not have return; } - if (theDefinition.containsKey("properties")) { - check_properties((Map<String, Map>) theDefinition.get("properties"), theContext); + if (theDefinition.containsKey(PROPERTIES)) { + check_properties((Map<String, Map>) theDefinition.get(PROPERTIES), theContext); checkTypeConstructFacet(Construct.Capability, theName, theDefinition, Facet.properties, theContext); } @@ -3539,8 +3540,8 @@ substitute the canonical form for the short form so that checking does not have return; } - if (theDefinition.containsKey("properties")) { - check_properties((Map<String, Map>) theDefinition.get("properties"), theContext); + if (theDefinition.containsKey(PROPERTIES)) { + check_properties((Map<String, Map>) theDefinition.get(PROPERTIES), theContext); checkTypeConstructFacet(Construct.Data, theName, theDefinition, Facet.properties, theContext); } } finally { @@ -3594,8 +3595,9 @@ substitute the canonical form for the short form so that checking does not have public void check_attributes(Map<String, Map> theDefinitions, CheckContext theContext) { theContext.enter("attributes"); try { - if (!checkDefinition("attributes", theDefinitions, theContext)) - return; + if (!checkDefinition("attributes", theDefinitions, theContext)) { + return; + } for (Iterator<Map.Entry<String, Map>> i = theDefinitions.entrySet().iterator(); i.hasNext();) { Map.Entry<String, Map> e = i.next(); @@ -3625,10 +3627,11 @@ substitute the canonical form for the short form so that checking does not have } public void check_properties(Map<String, Map> theDefinitions, CheckContext theContext) { - theContext.enter("properties"); + theContext.enter(PROPERTIES); try { - if (!checkDefinition("properties", theDefinitions, theContext)) - return; + if (!checkDefinition(PROPERTIES, theDefinitions, theContext)) { + return; + } for (Iterator<Map.Entry<String, Map>> i = theDefinitions.entrySet().iterator(); i.hasNext();) { Map.Entry<String, Map> e = i.next(); diff --git a/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/CommonLocator.java b/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/CommonLocator.java index 295a1f2..acc0a4a 100644 --- a/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/CommonLocator.java +++ b/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/CommonLocator.java @@ -20,125 +20,128 @@ import org.onap.sdc.common.onaplog.Enums.LogLevel; public class CommonLocator implements TargetLocator { - private static OnapLoggerError errLogger = OnapLoggerError.getInstance(); - private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); - - private Set<URI> searchPaths = new LinkedHashSet(); - - /* will create a locator with 2 default search paths: the file directory - * from where the app was and the jar from which this checker (actually this - * class) was loaded */ - public CommonLocator() { - addSearchPath( - Paths.get(".").toAbsolutePath().normalize().toUri()); - } - - public CommonLocator(String... theSearchPaths) { - for (String path: theSearchPaths) { - addSearchPath(path); - } - } - - public boolean addSearchPath(URI theURI) { - - if (!theURI.isAbsolute()) { - errLogger.log(LogLevel.WARN, this.getClass().getName(), "Search paths must be absolute uris: {}", theURI); - return false; - } - - return searchPaths.add(theURI); - } - - public boolean addSearchPath(String thePath) { - URI suri = null; - try { - suri = new URI(thePath); - } - catch(URISyntaxException urisx) { - errLogger.log(LogLevel.WARN, this.getClass().getName(), "Invalid search path: {} {}", thePath, urisx); - return false; - } - - return addSearchPath(suri); - } - - public Iterable<URI> searchPaths() { - return Iterables.unmodifiableIterable(this.searchPaths); - } - - /** - * Takes the given path and first URI resolves it and then attempts to open - * it (a way of verifying its existence) against each search path and stops - * at the first succesful test. - */ - public Target resolve(String theName) { - URI puri = null; - InputStream pis = null; - - //try classpath - URL purl = getClass().getClassLoader().getResource(theName); - if (purl != null) { - try { - return new Target(theName, purl.toURI()); - } - catch (URISyntaxException urisx) { - errLogger.log(LogLevel.ERROR, this.getClass().getName(), "The file {} wasn't found {}", theName, urisx); - } - } - - //try absolute - try { - puri = new URI(theName); - if (puri.isAbsolute()) { - try { - pis = puri.toURL().openStream(); - } - catch (IOException iox) { - errLogger.log(LogLevel.WARN, this.getClass().getName(), "The path {} is an absolute uri but it cannot be opened {}", theName, iox); - return null; - } - } - } - catch(URISyntaxException urisx) { - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "TargetResolver failed attempting {} {}", puri, urisx); - //keep it silent but what are the chances .. - } - - //try relative to the search paths - for (URI suri: searchPaths) { - try { - puri = suri.resolve(theName); - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "TargetResolver trying {}", puri); - pis = puri.toURL().openStream(); - return new Target(theName, puri.normalize()); - } - catch (Exception x) { - debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "TargetResolver failed attempting {} {}", puri, x); - continue; - } - finally { - if (pis!= null) { - try { - pis.close(); - } - catch (IOException iox) { - } - } - } - } - - return null; - } - - public String toString() { - return "CommonLocator(" + this.searchPaths + ")"; - } - - - public static void main(String[] theArgs) { - TargetLocator tl = new CommonLocator(); - tl.addSearchPath(java.nio.file.Paths.get("").toUri()); - tl.addSearchPath("file:///"); - debugLogger.log(LogLevel.DEBUG, CommonLocator.class.getName(), tl.resolve(theArgs[0]).toString()); - } + private static OnapLoggerError errLogger = OnapLoggerError.getInstance(); + private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); + + private Set<URI> searchPaths = new LinkedHashSet<>(); + + /* will create a locator with 2 default search paths: the file directory + * from where the app was and the jar from which this checker (actually this + * class) was loaded */ + CommonLocator() { + addSearchPath( + Paths.get(".").toAbsolutePath().normalize().toUri()); + } + + public boolean addSearchPath(URI theURI) { + + if (!theURI.isAbsolute()) { + errLogger.log(LogLevel.WARN, this.getClass().getName(), "Search paths must be absolute uris: {}", theURI); + return false; + } + + return searchPaths.add(theURI); + } + + public boolean addSearchPath(String thePath) { + URI suri; + try { + suri = new URI(thePath); + } + catch(URISyntaxException urisx) { + errLogger.log(LogLevel.WARN, this.getClass().getName(), "Invalid search path: {} {}", thePath, urisx); + return false; + } + + return addSearchPath(suri); + } + + public Iterable<URI> searchPaths() { + return Iterables.unmodifiableIterable(this.searchPaths); + } + + /** + * Takes the given path and first URI resolves it and then attempts to open + * it (a way of verifying its existence) against each search path and stops + * at the first succesful test. + */ + public Target resolve(String theName) { + URI puri = null; + InputStream pis = null; + + //try classpath + URL purl = getClass().getClassLoader().getResource(theName); + if (purl != null) { + try { + return new Target(theName, purl.toURI()); + } + catch (URISyntaxException urisx) { + errLogger.log(LogLevel.ERROR, this.getClass().getName(), "The file {} wasn't found {}", theName, urisx); + } + } + + //try absolute + try { + puri = new URI(theName); + if (puri.isAbsolute()) { + pis = getPathInputStream(puri,theName); + if (pis == null){ + return null; + } + } + } + catch(URISyntaxException urisx) { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "TargetResolver failed attempting {} {}", theName, urisx); + //keep it silent but what are the chances .. + } + + //try relative to the search paths + for (URI suri: searchPaths) { + try { + puri = suri.resolve(theName); + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "TargetResolver trying {}", puri); + pis = puri.toURL().openStream(); + return new Target(theName, puri.normalize()); + } + catch (Exception x) { + debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "TargetResolver failed attempting {} {}", puri, x); + } + finally { + if (pis!= null) { + try { + pis.close(); + } + catch (IOException iox) { + debugLogger.log(LogLevel.ERROR, this.getClass().getName(),"Error closing input stream {}", iox); + } + } + } + } + + return null; + } + + private InputStream getPathInputStream(URI puri, String theName){ + InputStream res = null; + try (InputStream pis = puri.toURL().openStream()){ + res = pis; + } + catch (IOException iox) { + errLogger.log(LogLevel.WARN, this.getClass().getName(), "The path {} is an absolute uri but it cannot be opened {}", theName, iox); + } + return res; + } + + + public String toString() { + return "CommonLocator(" + this.searchPaths + ")"; + } + + + public static void main(String[] theArgs) { + TargetLocator tl = new CommonLocator(); + tl.addSearchPath(java.nio.file.Paths.get("").toUri()); + tl.addSearchPath("file:///"); + debugLogger.log(LogLevel.DEBUG, CommonLocator.class.getName(), tl.resolve(theArgs[0]).toString()); + } } diff --git a/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Construct.java b/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Construct.java index b05cff9..76dfca3 100644 --- a/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Construct.java +++ b/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Construct.java @@ -8,15 +8,15 @@ package org.onap.sdc.dcae.checker; */ public enum Construct { Data, - Requirement, + Requirement, Capability, Relationship, Artifact, Interface, Node, - Group, - Policy, - Workflow + Group, + Policy, + Workflow } diff --git a/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Data.java b/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Data.java index 70552bb..879e5dc 100644 --- a/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Data.java +++ b/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Data.java @@ -14,45 +14,33 @@ import java.util.regex.PatternSyntaxException; import com.google.common.collect.Table; import com.google.common.collect.HashBasedTable; import org.onap.sdc.common.onaplog.OnapLoggerDebug; -import org.onap.sdc.common.onaplog.OnapLoggerError; import org.onap.sdc.common.onaplog.Enums.LogLevel; /* * String -- 'primitive tosca type' converters, used in verifying valuations */ public class Data { - private static OnapLoggerError errLogger = OnapLoggerError.getInstance(); private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); private Data() { } - - /* - */ + + @FunctionalInterface public static interface Evaluator { - public boolean eval(Object theExpr, Map theDef, Checker.CheckContext theCtx); } /* data type processing */ - private static Map<String,Type> typesByName = new HashMap<String,Type>(); + private static Map<String,Type> typesByName = new HashMap<>(); static { - //CoreType.String.toString(); - //CoreFunction.concat.toString(); - //Constraint.equal.toString(); } - public static Data.Type typeByName(String theName) { return typesByName.getOrDefault(theName, userType); } -/* - public static Evaluator getTypeEvaluator(Type theType) { - } -*/ /* Needs a better name ?? RValue?? * This is not an rvalue (C def) per se but the construct who's instances @@ -101,7 +89,7 @@ public class Data { (expr,def,ctx) -> Data.valueOf(ctx, expr, Boolean.class), Data::evalScalarConstraints), Null("null", - (expr,def,ctx) -> expr.equals("null"), + (expr,def,ctx) -> "null".equals(expr), null), Timestamp("timestamp", (expr,def,ctx) -> timestampRegex.matcher(expr.toString()).matches(), @@ -114,7 +102,7 @@ public class Data { /* use a scanner and check that the upper bound is indeed greater than * the lower bound */ Range("range", - (expr,def,ctx) -> { return rangeRegex.matcher(expr.toString()).matches();}, + (expr,def,ctx) -> rangeRegex.matcher(expr.toString()).matches(), null ), Size("scalar-unit.size", (expr,def,ctx) -> sizeRegex.matcher(expr.toString()).matches(), @@ -128,20 +116,25 @@ public class Data { private String toscaName; - private Evaluator valueEvaluator, - constraintsEvaluator; + private Evaluator valueEvaluator, constraintsEvaluator; + + private CoreType(String theName, Evaluator theValueEvaluator, Evaluator theConstraintsEvaluator) { this.toscaName = theName; this.valueEvaluator = theValueEvaluator; this.constraintsEvaluator = theConstraintsEvaluator; - if (typesByName == null) + if (typesByName == null) { throw new RuntimeException("No type index available!"); + } typesByName.put(this.toscaName, this); } + + + @Override public String toString() { return this.toscaName; } @@ -260,8 +253,9 @@ public class Data { Checker.CheckContext theCtx) { Data.Type entryType = null; Map entryTypeDef = (Map)theDef.get("entry_schema"); - if (null != entryTypeDef) - entryType = typeByName((String)entryTypeDef.get("type")); + if (null != entryTypeDef) { + entryType = typeByName((String) entryTypeDef.get("type")); + } boolean res = true; for (Object val: theVals) { @@ -271,39 +265,32 @@ public class Data { f.evaluator().eval(val, entryTypeDef, theCtx)) { res = false; } - else if (entryType != null && - !entryType.evaluator().eval(val, entryTypeDef, theCtx)) { - res= false; - //the error should hav been reported by the particular evaluator - //theCtx.addError("Value " + val + " failed evaluation", null); + else if (entryType != null && !entryType.evaluator().eval(val, entryTypeDef, theCtx)) { + res = false; } } return res; } - public static boolean evalListConstraints(Object theVal, - Map theDef, - Checker.CheckContext theCtx) { + public static boolean evalListConstraints(Object theVal, Map theDef, Checker.CheckContext theCtx) { return evalCollectionConstraints((List)theVal, theDef, theCtx); } - public static boolean evalMapConstraints(Object theVal, - Map theDef, - Checker.CheckContext theCtx) { + public static boolean evalMapConstraints(Object theVal, Map theDef, Checker.CheckContext theCtx) { return evalCollectionConstraints(((Map)theVal).values(), theDef, theCtx); } - private static boolean evalCollectionConstraints(Collection theVals, - Map theDef, - Checker.CheckContext theCtx) { + private static boolean evalCollectionConstraints(Collection theVals, Map theDef, Checker.CheckContext theCtx) { //should check overall constraints - if (theVals == null) + if (theVals == null) { return true; + } Map entryTypeDef = (Map)theDef.get("entry_schema"); - if (null == entryTypeDef) + if (null == entryTypeDef) { return true; + } String entryTypeName = (String)entryTypeDef.get("type"); Data.Type entryType = typeByName(entryTypeName); @@ -311,11 +298,8 @@ public class Data { boolean res = true; for (Object val: theVals) { Evaluator entryEvaluator = entryType.constraintsEvaluator(); - if (entryEvaluator != null && - !entryEvaluator.eval(val, entryTypeDef, theCtx)) { + if (entryEvaluator != null && !entryEvaluator.eval(val, entryTypeDef, theCtx)) { res= false; - //the constraints evaluator should have already added an error, but it also adds some context - //theCtx.addError("Value " + val + " failed evaluation", null); } } return res; @@ -371,16 +355,12 @@ public class Data { if (propVal != null) { Data.Type propType = typeByName((String)propDef.get("type")); - if (propType.constraintsEvaluator() != null && - !propType.constraintsEvaluator().eval(propVal, propDef, theCtx)) { + if (propType.constraintsEvaluator() != null && !propType.constraintsEvaluator().eval(propVal, propDef, theCtx)) { res= false; - //the constraints evaluator should have already added an error - //theCtx.addError("Property " + propEntry.getKey() + " failed evaluation for " + propVal, null); } } else { - if (Boolean.TRUE == (Boolean)propDef.getOrDefault("required", Boolean.FALSE) && - !propDef.containsKey("default")) { + if (Boolean.TRUE == propDef.getOrDefault("required", Boolean.FALSE) && !propDef.containsKey("default")) { theCtx.addError("Property " + propEntry.getKey() + " failed 'required' constraint; definition is " + propDef, null); res = false; } @@ -402,26 +382,6 @@ public class Data { return false; } -/* - private static boolean valueOf(Class theTarget, - String theExpr, - Checker.CheckContext theCtx) { - try { - theTarget.getMethod("valueOf", new Class[] {String.class}) - .invoke(null, theExpr); - return true; - } - catch (InvocationTargetException itx) { - theCtx.addError("Failed to parse " + theExpr + " as a " + theTarget.getName(), itx.getCause()); - return false; - } - catch (Exception x) { - theCtx.addError("Failed to valueOf " + theExpr + " as a " + theTarget.getName(), x); - return false; - } - } -*/ - /* * Function e(valuation) * ? @@ -499,18 +459,15 @@ public class Data { } } - private static boolean evalConcat( - Object theVal, Map theDef, Checker.CheckContext theCtx) { + private static boolean evalConcat(Object theVal, Map theDef, Checker.CheckContext theCtx) { return true; } - private static boolean evalToken( - Object theVal, Map theDef, Checker.CheckContext theCtx) { + private static boolean evalToken(Object theVal, Map theDef, Checker.CheckContext theCtx) { return true; } - private static boolean evalGetInput( - Object theVal, Map theDef, Checker.CheckContext theCtx) { + private static boolean evalGetInput(Object theVal, Map theDef, Checker.CheckContext theCtx) { Map val = (Map)theVal; Map.Entry entry = (Map.Entry)val.entrySet().iterator().next(); @@ -527,8 +484,9 @@ public class Data { return false; } - if (theDef == null) + if (theDef == null) { return true; + } //the output must be type compatible with the input String targetType = (String)theDef.get("type"); @@ -554,24 +512,24 @@ public class Data { Object theVal, Map theDef, EnumSet<Facet> theFacets, Checker.CheckContext theCtx) { - Map val = (Map)theVal; - Map.Entry entry = (Map.Entry)val.entrySet().iterator().next(); + Map val = (Map) theVal; + Map.Entry entry = (Map.Entry) val.entrySet().iterator().next(); if (!(entry.getValue() instanceof List)) { - theCtx.addError("get_property: argument must be a List" ,null); + theCtx.addError("get_property: argument must be a List", null); return false; } - List args = (List)entry.getValue(); + List args = (List) entry.getValue(); if (args.size() < 2) { theCtx.addError("'get_property' has at least 2 arguments", null); return false; } //the first argument is a node or relationship template - String tmpl = (String)args.get(0); - Construct tmplConstruct = null; - Map tmplSpec = null; + String tmpl = (String) args.get(0); + Construct tmplConstruct; + Map tmplSpec; if ("SELF".equals(tmpl)) { tmpl = theCtx.enclosingConstruct(Construct.Node); @@ -580,27 +538,23 @@ public class Data { if (tmpl == null) { theCtx.addError("'get_property' invalid SELF reference: no node or relationship template in scope at " + theCtx.getPath(), null); return false; - } - else { + } else { tmplConstruct = Construct.Relationship; } - } - else { + } else { tmplConstruct = Construct.Node; } tmplSpec = theCtx.catalog().getTemplate(theCtx.target(), tmplConstruct, tmpl); - } - else if ("SOURCE".equals("tmpl")) { + } else if ("SOURCE".equals("tmpl")) { //we are in the scope of a relationship template and this is the source node template. tmpl = theCtx.enclosingConstruct(Construct.Relationship); if (tmpl == null) { theCtx.addError("'get_property' invalid SOURCE reference: no relationship template in scope at " + theCtx.getPath(), null); return false; } - + return true; - } - else if ("TARGET".equals("tmpl")) { + } else if ("TARGET".equals("tmpl")) { //we are in the scope of a relationship template and this is the target node template. tmpl = theCtx.enclosingConstruct(Construct.Relationship); if (tmpl == null) { @@ -609,8 +563,7 @@ public class Data { } return true; - } - else if ("HOST".equals("tmpl")) { + } else if ("HOST".equals("tmpl")) { tmpl = theCtx.enclosingConstruct(Construct.Node); if (tmpl == null) { theCtx.addError("'get_property' invalid HOST reference: no node template in scope at " + theCtx.getPath(), null); @@ -618,8 +571,7 @@ public class Data { } return true; - } - else { + } else { //try node template first tmplSpec = theCtx.catalog().getTemplate(theCtx.target(), Construct.Node, tmpl); if (tmplSpec == null) { @@ -628,20 +580,18 @@ public class Data { if (tmplSpec == null) { theCtx.addError("'get_data' invalid template reference '" + tmpl + "': no node or relationship template with this name", null); return false; - } - else { + } else { tmplConstruct = Construct.Relationship; } - } - else { + } else { tmplConstruct = Construct.Node; } } int facetNameIndex = 1; Construct facetConstruct = tmplConstruct; //who's construct the facet is supposed to belong to - Map facetConstructSpec = null; - String facetConstructType = null; + Map facetConstructSpec = null; + String facetConstructType = null; if (tmplConstruct.equals(Construct.Node) && args.size() > 2) { @@ -654,62 +604,56 @@ public class Data { //while the spec does not make it explicit this can only take place //if the first argument turned out to be a node template (as relationship //templates/types do not have capabilities/requirements - String secondArg = (String)args.get(1); + String secondArg = (String) args.get(1); if ((facetConstructSpec = theCtx.catalog().getFacetDefinition( - tmplConstruct, - (String)tmplSpec.get("type"), - Facet.capabilities, - secondArg)) != null) { + tmplConstruct, + (String) tmplSpec.get("type"), + Facet.capabilities, + secondArg)) != null) { facetNameIndex = 2; facetConstruct = Construct.Capability; - facetConstructType = (String)facetConstructSpec.get("type"); - } - else if ((facetConstructSpec = theCtx.catalog().getRequirementDefinition( - tmplConstruct, - (String)tmplSpec.get("type"), - secondArg)) != null) { + facetConstructType = (String) facetConstructSpec.get("type"); + } else if ((facetConstructSpec = theCtx.catalog().getRequirementDefinition( + tmplConstruct, + (String) tmplSpec.get("type"), + secondArg)) != null) { facetNameIndex = 2; facetConstruct = Construct.Capability; - + //find the specof the capability this requirement points to //TODO: check, can the capability reference be anything else but a capability tyep? - facetConstructType = (String)facetConstructSpec.get("capability"); + facetConstructType = (String) facetConstructSpec.get("capability"); } - } - else { + } else { //we'll attempt to handle it as a property of the node template facetConstruct = Construct.Node; facetConstructSpec = tmplSpec; - facetConstructType = (String)facetConstructSpec.get("type"); + facetConstructType = (String) facetConstructSpec.get("type"); } - + //validate the facet name Map facetSpec = null; - { - String facetName = (String)args.get(facetNameIndex); - for (Facet facet: theFacets) { - facetSpec = theCtx.catalog() - .getFacetDefinition( - facetConstruct, - facetConstructType, - facet, - facetName); - if (facetSpec != null) - break; - } - if (facetSpec == null) { -//TODO: not the greatest message if the call strated with a requirement .. - theCtx.addError("'get_data' invalid reference, '" + facetConstruct + "' " + facetConstructType + " has no " + theFacets + " with name " + facetName, null); - return false; + String facetName = (String) args.get(facetNameIndex); + for (Facet facet : theFacets) { + facetSpec = theCtx.catalog() + .getFacetDefinition( + facetConstruct, + facetConstructType, + facet, + facetName); + if (facetSpec != null) { + break; } } - //the rest of the arguments have to resolve to a field of the property's - //data type; the propertySpec contains the type specification - for (int i = facetNameIndex + 1; i < args.size(); i++) { + if (facetSpec == null) { +//TODO: not the greatest message if the call strated with a requirement .. + theCtx.addError("'get_data' invalid reference, '" + facetConstruct + "' " + facetConstructType + " has no " + theFacets + " with name " + facetName, null); + return false; } + return true; } @@ -777,13 +721,15 @@ public class Data { private static Object getConstraintValue(Map theDef, Constraint theConstraint) { List<Map> constraints = (List<Map>)theDef.get("constraints"); - if (null == constraints) + if (null == constraints) { return null; + } for(Map constraint: constraints) { Object val = constraint.get(theConstraint.toString()); - if (val != null) + if (val != null) { return val; + } } return null; } @@ -802,24 +748,20 @@ public class Data { pattern; } - /* hold the constraint evaluators for pairs of type/constraint. * If a pair is not present than the given constraint does not apply * to the type. */ - private static Table<Type,Constraint,Evaluator> typeConstraintEvaluator =null; + private static Table<Type,Constraint,Evaluator> typeConstraintEvaluator = null; - public static Evaluator - getTypeConstraintEvaluator(Type theType, Constraint theConstraint) { + public static Evaluator getTypeConstraintEvaluator(Type theType, Constraint theConstraint) { if (typeConstraintEvaluator == null) { typeConstraintEvaluator = HashBasedTable.create(); typeConstraintEvaluator.put(CoreType.String, Constraint.equal, (val,def,ctx) -> val.equals(getConstraintValue(def,Constraint.equal))); typeConstraintEvaluator.put(CoreType.String, Constraint.valid_values, - (val,def,ctx) -> { - return ((List)getConstraintValue(def,Constraint.valid_values)).contains(val); - }); + (val,def,ctx) -> ((List)getConstraintValue(def,Constraint.valid_values)).contains(val)); typeConstraintEvaluator.put(CoreType.String, Constraint.length, (val,def,ctx) -> ((String)val).length() == ((Number)getConstraintValue(def,Constraint.length)).intValue()); typeConstraintEvaluator.put(CoreType.String, Constraint.min_length, diff --git a/dcaedt_validator/kwalify/src/main/java/kwalify/Defaultable.java b/dcaedt_validator/kwalify/src/main/java/kwalify/Defaultable.java index f1de3fc..a2acfee 100644 --- a/dcaedt_validator/kwalify/src/main/java/kwalify/Defaultable.java +++ b/dcaedt_validator/kwalify/src/main/java/kwalify/Defaultable.java @@ -8,6 +8,6 @@ package kwalify; * interface to have default value */ public interface Defaultable { - Object getDefault(); - void setDefault(Object value); + Rule getDefault(); + void setDefault(Rule value); } diff --git a/dcaedt_validator/kwalify/src/main/java/kwalify/DefaultableHashMap.java b/dcaedt_validator/kwalify/src/main/java/kwalify/DefaultableHashMap.java index c2c625c..5846f1b 100644 --- a/dcaedt_validator/kwalify/src/main/java/kwalify/DefaultableHashMap.java +++ b/dcaedt_validator/kwalify/src/main/java/kwalify/DefaultableHashMap.java @@ -4,7 +4,6 @@ package kwalify; -import java.io.Serializable; import java.util.HashMap; /** @@ -14,18 +13,18 @@ public class DefaultableHashMap extends HashMap implements Defaultable { private static final long serialVersionUID = -5224819562023897380L; - private Object defaultValue = null; + private Rule defaultValue; public DefaultableHashMap() { super(); } - public Object getDefault() { return defaultValue; } + public Rule getDefault() { return defaultValue; } - public void setDefault(Object value) { defaultValue = value; } + public void setDefault(Rule value) { defaultValue = value; } @Override public Object get(Object key) { - return containsKey(key) ? super.get(key) : defaultValue; + return containsKey(key) ? (Rule)super.get(key) : defaultValue; } } diff --git a/dcaedt_validator/kwalify/src/main/java/kwalify/Messages.java b/dcaedt_validator/kwalify/src/main/java/kwalify/Messages.java index b77f04b..e0bafb1 100644 --- a/dcaedt_validator/kwalify/src/main/java/kwalify/Messages.java +++ b/dcaedt_validator/kwalify/src/main/java/kwalify/Messages.java @@ -1,25 +1,22 @@ /* - * @(#)Messages.java $Rev: 4 $ $Release: 0.5.1 $ - * * copyright(c) 2005 kuwata-lab all rights reserved. */ package kwalify; import java.util.ResourceBundle; -//import java.util.Locale; /** * set of utility methods around messages. * - * @revision $Rev: 4 $ - * @release $Release: 0.5.1 $ */ public class Messages { - private static final String __basename = "kwalify.messages"; - private static ResourceBundle __messages = ResourceBundle.getBundle(__basename); - //private static ResourceBundle __messages = ResourceBundle.getBundle(__basename, Locale.getDefault()); + private static final String KWALIFY_MESSAGES = "kwalify.messages"; + private static ResourceBundle __messages = ResourceBundle.getBundle(KWALIFY_MESSAGES); + + // So that no one instantiate Messages and make sonar happy + private Messages(){} public static String message(String key) { return __messages.getString(key); @@ -31,10 +28,9 @@ public class Messages { public static String buildMessage(String key, Object value, Object[] args) { String msg = message(key); - assert msg != null; if (args != null) { - for (int i = 0; i < args.length; i++) { // don't use MessageFormat - msg = msg.replaceFirst("%[sd]", escape(args[i])); + for (Object arg : args) { // don't use MessageFormat + msg = msg.replaceFirst("%[sd]", escape(arg)); } } if (value != null && !Types.isCollection(value)) { @@ -44,8 +40,6 @@ public class Messages { } private static String escape(Object obj) { - //return obj.toString().replaceAll("\\", "\\\\").replace("\n", "\\n"); // J2SK1.4 doesn't support String#replace(CharSequence, CharSequence)! return obj.toString().replaceAll("\\\\", "\\\\\\\\").replaceAll("\\n", "\\\\n"); } - } diff --git a/dcaedt_validator/kwalify/src/main/java/kwalify/MetaValidator.java b/dcaedt_validator/kwalify/src/main/java/kwalify/MetaValidator.java index c8c21a7..8c4d6a2 100644 --- a/dcaedt_validator/kwalify/src/main/java/kwalify/MetaValidator.java +++ b/dcaedt_validator/kwalify/src/main/java/kwalify/MetaValidator.java @@ -1,126 +1,138 @@ /* - * @(#)MetaValidator.java $Rev: 4 $ $Release: 0.5.1 $ - * * copyright(c) 2005 kuwata-lab all rights reserved. */ package kwalify; -import org.onap.sdc.common.onaplog.OnapLoggerDebug; import org.onap.sdc.common.onaplog.OnapLoggerError; import org.onap.sdc.common.onaplog.Enums.LogLevel; import java.util.Map; import java.util.List; -import java.util.Iterator; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.regex.PatternSyntaxException; /** * meta validator to validate schema definition - * - * @revision $Rev: 4 $ - * @release $Release: 0.5.1 $ */ public class MetaValidator extends Validator { + private static final String RANGE = "range"; + private static final String MAX_EX = "max-ex"; + private static final String MIN_EX = "min-ex"; + private static final String LENGTH = "length"; + private static final String SEQUENCE = "sequence"; + private static final String ENUM_CONFLICT = "enum.conflict"; + private static final String SCALAR_CONFLICT = "scalar.conflict"; + private static final String IDENT = "ident"; + private static final String IDENT1 = "ident:"; + private static final String MAPPING = "mapping"; + private static final String PATTERN = "pattern:"; + private static final String PATTERN1 = "pattern"; + private static final String TYPE_MAP = " type: map\n"; + private static final String TYPE_STR = " type: str\n"; + private static final String TYPE_BOOL = " type: bool\n"; + private static final String MAPPING1 = " mapping:\n"; + private static final String TYPE_SCALAR = " type: scalar\n"; + private static final String TYPE_INT = " type: int\n"; + private static OnapLoggerError errLogger = OnapLoggerError.getInstance(); - private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); - public static final String META_SCHEMA = "" - + "name: MAIN\n" - + "type: map\n" - + "required: yes\n" - + "mapping: &main-rule\n" - + " \"name\":\n" - + " type: str\n" - + " \"desc\":\n" - + " type: str\n" - + " \"type\":\n" - + " type: str\n" - + " #required: yes\n" - + " enum:\n" - + " - seq\n" - + " #- sequence\n" - + " #- list\n" - + " - map\n" - + " #- mapping\n" - + " #- hash\n" - + " - str\n" - + " #- string\n" - + " - int\n" - + " #- integer\n" - + " - float\n" - + " - number\n" - + " #- numeric\n" - + " - bool\n" - + " #- boolean\n" - + " - text\n" - + " - date\n" - + " - time\n" - + " - timestamp\n" - + " #- object\n" - + " - any\n" - + " - scalar\n" - + " #- collection\n" - + " \"required\":\n" - + " type: bool\n" - + " \"enum\":\n" - + " type: seq\n" - + " sequence:\n" - + " - type: scalar\n" - + " unique: yes\n" - + " \"pattern\":\n" - + " type: str\n" - + " \"assert\":\n" - + " type: str\n" - + " pattern: /\\bval\\b/\n" - + " \"range\":\n" - + " type: map\n" - + " mapping:\n" - + " \"max\":\n" - + " type: scalar\n" - + " \"min\":\n" - + " type: scalar\n" - + " \"max-ex\":\n" - + " type: scalar\n" - + " \"min-ex\":\n" - + " type: scalar\n" - + " \"length\":\n" - + " type: map\n" - + " mapping:\n" - + " \"max\":\n" - + " type: int\n" - + " \"min\":\n" - + " type: int\n" - + " \"max-ex\":\n" - + " type: int\n" - + " \"min-ex\":\n" - + " type: int\n" - + " \"ident\":\n" - + " type: bool\n" - + " \"unique\":\n" - + " type: bool\n" - + " \"sequence\":\n" - + " name: SEQUENCE\n" - + " type: seq\n" - + " sequence:\n" - + " - type: map\n" - + " mapping: *main-rule\n" - + " name: MAIN\n" - + " #required: yes\n" - + " \"mapping\":\n" - + " name: MAPPING\n" - + " type: map\n" - + " mapping:\n" - + " =:\n" - + " type: map\n" - + " mapping: *main-rule\n" - + " name: MAIN\n" - + " #required: yes\n" - ; + private static final String META_SCHEMA = new StringBuilder(). + append(""). + append("name: MAIN\n"). + append("type: map\n"). + append("required: yes\n"). + append("mapping: &main-rule\n"). + append(" \"name\":\n"). + append(TYPE_STR). + append(" \"desc\":\n"). + append(TYPE_STR). + append(" \"type\":\n"). + append(TYPE_STR). + append(" #required: yes\n"). + append(" enum:\n"). + append(" - seq\n"). + append(" #- sequence\n"). + append(" #- list\n"). + append(" - map\n"). + append(" #- mapping\n"). + append(" #- hash\n"). + append(" - str\n"). + append(" #- string\n"). + append(" - int\n"). + append(" #- integer\n"). + append(" - float\n"). + append(" - number\n"). + append(" #- numeric\n"). + append(" - bool\n"). + append(" #- boolean\n"). + append(" - text\n"). + append(" - date\n"). + append(" - time\n"). + append(" - timestamp\n"). + append(" #- object\n"). + append(" - any\n"). + append(" - scalar\n"). + append(" #- collection\n"). + append(" \"required\":\n"). + append(TYPE_BOOL). + append(" \"enum\":\n"). + append(" type: seq\n"). + append(" sequence:\n"). + append(" - type: scalar\n"). + append(" unique: yes\n"). + append(" \"pattern\":\n"). + append(TYPE_STR). + append(" \"assert\":\n"). + append(TYPE_STR). + append(" pattern: /\\bval\\b/\n"). + append(" \"range\":\n"). + append(TYPE_MAP). + append(MAPPING1). + append(" \"max\":\n"). + append(TYPE_SCALAR). + append(" \"min\":\n"). + append(TYPE_SCALAR). + append(" \"max-ex\":\n"). + append(TYPE_SCALAR). + append(" \"min-ex\":\n"). + append(TYPE_SCALAR). + append(" \"length\":\n"). + append(TYPE_MAP). + append(MAPPING1). + append(" \"max\":\n"). + append(TYPE_INT). + append(" \"min\":\n"). + append(TYPE_INT). + append(" \"max-ex\":\n"). + append(TYPE_INT). + append(" \"min-ex\":\n"). + append(TYPE_INT). + append(" \"ident\":\n"). + append(TYPE_BOOL). + append(" \"unique\":\n"). + append(TYPE_BOOL). + append(" \"sequence\":\n"). + append(" name: SEQUENCE\n"). + append(" type: seq\n"). + append(" sequence:\n"). + append(" - type: map\n"). + append(" mapping: *main-rule\n"). + append(" name: MAIN\n"). + append(" #required: yes\n"). + append(" \"mapping\":\n"). + append(" name: MAPPING\n"). + append(TYPE_MAP). + append(MAPPING1). + append(" =:\n"). + append(" type: map\n"). + append(" mapping: *main-rule\n"). + append(" name: MAIN\n"). + append(" #required: yes\n"). + toString(); /** * @@ -140,6 +152,11 @@ public class MetaValidator extends Validator { private static Validator __instance; + private MetaValidator(Map schema) { + super(schema); + } + + public static Validator instance() { synchronized (MetaValidator.class) { if (__instance == null) { @@ -147,6 +164,7 @@ public class MetaValidator extends Validator { Map schema = (Map) YamlUtil.load(META_SCHEMA); __instance = new MetaValidator(schema); } catch (SyntaxException ex) { + errLogger.log(LogLevel.INFO,"MetaValidator","Failed validating schema: {}",ex); assert false; } } @@ -155,291 +173,224 @@ public class MetaValidator extends Validator { return __instance; } - private MetaValidator(Map schema) { - super(schema); - } - + @Override public void postValidationHook(Object value, Rule rule, ValidationContext theContext) { if (value == null) { - return; // realy? + return; // really? } if (! "MAIN".equals(rule.getName())) { return; } - // assert value instanceof Map; Map map = (Map)value; String type = (String)map.get("type"); if (type == null) { type = Types.getDefaultType(); } - //Class type_class = Types.typeClass(type); - //if (type_class == null) { - // theContext.addError(validationError("type.unknown", rule, path + "/type", type, null)); - //} - // - //String pattern; - //if ((pattern = (String)map.get("pattern")) != null) { - if (map.containsKey("pattern")) { - String pattern = (String)map.get("pattern"); + + if (map.containsKey(PATTERN1)) { + String pattern = (String)map.get(PATTERN1); Matcher m = Util.matcher(pattern, "\\A\\/(.*)\\/([mi]?[mi]?)\\z"); String pat = m.find() ? m.group(1) : pattern; try { Pattern.compile(pat); } catch (PatternSyntaxException ex) { - theContext.addError("pattern.syntaxerr", rule, "pattern", pattern, null); + errLogger.log(LogLevel.INFO,"MetaValidator","pattern.syntaxerr: {}",ex); + theContext.addError("pattern.syntaxerr", rule, PATTERN1, pattern, null); } } - // - //List enum_list; - //if ((enum_list = (List)map.get("enum")) != null) { if (map.containsKey("enum")) { - List enum_list = (List)map.get("enum"); + List enumList = (List)map.get("enum"); if (Types.isCollectionType(type)) { theContext.addError("enum.notscalar", rule, "enum:", (Object[])null); } else { - for (Iterator it = enum_list.iterator(); it.hasNext(); ) { - Object elem = it.next(); - if (! Types.isCorrectType(elem, type)) { - theContext.addError("enum.type.unmatch", rule, "enum", elem, new Object[] { Types.typeName(type) }); - } - } + checkEnum(rule, theContext, type, enumList); } } - // - //String assert_str; - //if ((assert_str = (String)map.get("assert")) != null) { if (map.containsKey("assert")) { errLogger.log(LogLevel.ERROR, this.getClass().getName(), "*** warning: sorry, 'assert:' is not supported in current version of Kwalify-java."); - //String assert_str = (String)map.get("assert"); - //if (! Util.matches(assert_str, "\\bval\\b")) { - // theContext.addError(validationError("assert.noval", rule, path + "/assert", assert_str, null); - //} - //try { - // Expression.parse(assert_str); - //} catch (InvalidExpressionException ex) { - // theContext.addError(validationError("assert.syntaxerr", rule, path + "/assert", assert_str, null)); - //} + } - // - //Map range; - //if ((range = (Map)map.get("range")) != null) { - if (map.containsKey("range")) { - Map range = (Map)map.get("range"); - //if (! (range instanceof Map)) { - // theContext.addError(validtionError("range.notmap", rule, path + "/range", range, null)); - //} else - if (Types.isCollectionType(type) || type.equals("bool") || type.equals("any")) { + + if (map.containsKey(RANGE)) { + Map range = (Map)map.get(RANGE); + + if (Types.isCollectionType(type) || "bool".equals(type) || "any".equals(type)) { theContext.addError("range.notscalar", rule, "range:", null, null); } else { - for (Iterator it = range.keySet().iterator(); it.hasNext(); ) { - String k = (String)it.next(); - Object v = range.get(k); - if (! Types.isCorrectType(v, type)) { - theContext.addError("range.type.unmatch", rule, "range/" + k, v, new Object[] { Types.typeName(type) }); - } - } + rangeCheck(rule, theContext, type, range); } - if (range.containsKey("max") && range.containsKey("max-ex")) { - theContext.addError("range.twomax", rule, "range", null, null); + if (range.containsKey("max") && range.containsKey(MAX_EX)) { + theContext.addError("range.twomax", rule, RANGE, null, null); } - if (range.containsKey("min") && range.containsKey("min-ex")) { - theContext.addError("range.twomin", rule, "range", null, null); + if (range.containsKey("min") && range.containsKey(MIN_EX)) { + theContext.addError("range.twomin", rule, RANGE, null, null); } Object max = range.get("max"); Object min = range.get("min"); - Object max_ex = range.get("max-ex"); - Object min_ex = range.get("min-ex"); - Object[] args = null; - //String error_symbol = null; + Object maxEx = range.get(MAX_EX); + Object minEx = range.get(MIN_EX); + Object[] args; if (max != null) { if (min != null && Util.compareValues(max, min) < 0) { args = new Object[] { max, min }; - theContext.addError("range.maxltmin", rule, "range", null, args); - } else if (min_ex != null && Util.compareValues(max, min_ex) <= 0) { - args = new Object[] { max, min_ex }; - theContext.addError("range.maxleminex", rule, "range", null, args); + theContext.addError("range.maxltmin", rule, RANGE, null, args); + } else if (minEx != null && Util.compareValues(max, minEx) <= 0) { + args = new Object[] { max, minEx }; + theContext.addError("range.maxleminex", rule, RANGE, null, args); } - } else if (max_ex != null) { - if (min != null && Util.compareValues(max_ex, min) <= 0) { - args = new Object[] { max_ex, min }; - theContext.addError("range.maxexlemin", rule, "range", null, args); - } else if (min_ex != null && Util.compareValues(max_ex, min_ex) <= 0) { - args = new Object[] { max_ex, min_ex }; - theContext.addError("range.maxexleminex", rule, "range", null, args); + } else if (maxEx != null) { + if (min != null && Util.compareValues(maxEx, min) <= 0) { + args = new Object[] { maxEx, min }; + theContext.addError("range.maxexlemin", rule, RANGE, null, args); + } else if (minEx != null && Util.compareValues(maxEx, minEx) <= 0) { + args = new Object[] { maxEx, minEx }; + theContext.addError("range.maxexleminex", rule, RANGE, null, args); } } } - // - //Map length; - //if ((length = (Map)map.get("length")) != null) { - if (map.containsKey("length")) { - Map length = (Map)map.get("length"); - //if (! (length instanceof Map)) { - // theContext.addError(validtionError("length.notmap", rule, path + "/length", length, null)); - //} else - if (! (type.equals("str") || type.equals("text"))) { + if (map.containsKey(LENGTH)) { + Map length = (Map)map.get(LENGTH); + + if (! ("str".equals(type) || "text".equals(type))) { theContext.addError("length.nottext", rule, "length:", (Object[])null); } - //for (Iterator it = length.keySet().iterator(); it.hasNext(); ) { - // String k = (String)it.next(); - // Object v = length.get(k); - // if (k == null || ! (k.equals("max") || k.equals("min") || k.equals("max-ex") || k.equals("min-ex"))) { - // theContext.addError(validationError("length.undefined", rule, path + "/length/" + k, "" + k + ":", null)); - // } else if (! (v instanceof Integer)) { - // theContext.addError(validationError("length.notint", rule, path + "/length/" + k, v, null)); - // } - //} - if (length.containsKey("max") && length.containsKey("max-ex")) { - theContext.addError("length.twomax", rule, "length", (Object[])null); + + if (length.containsKey("max") && length.containsKey(MAX_EX)) { + theContext.addError("length.twomax", rule, LENGTH, (Object[])null); } - if (length.containsKey("min") && length.containsKey("min-ex")) { - theContext.addError("length.twomin", rule, "length", (Object[])null); + if (length.containsKey("min") && length.containsKey(MIN_EX)) { + theContext.addError("length.twomin", rule, LENGTH, (Object[])null); } Integer max = (Integer)length.get("max"); Integer min = (Integer)length.get("min"); - Integer max_ex = (Integer)length.get("max-ex"); - Integer min_ex = (Integer)length.get("min-ex"); - Object[] args = null; - //String error_symbol = null; + Integer maxEx = (Integer)length.get(MAX_EX); + Integer minEx = (Integer)length.get(MIN_EX); + Object[] args; if (max != null) { if (min != null && max.compareTo(min) < 0) { args = new Object[] { max, min }; - theContext.addError("length.maxltmin", rule, "length", null, args); - } else if (min_ex != null && max.compareTo(min_ex) <= 0) { - args = new Object[] { max, min_ex }; - theContext.addError("length.maxleminex", rule, "length", null, args); + theContext.addError("length.maxltmin", rule, LENGTH, null, args); + } else if (minEx != null && max.compareTo(minEx) <= 0) { + args = new Object[] { max, minEx }; + theContext.addError("length.maxleminex", rule, LENGTH, null, args); } - } else if (max_ex != null) { - if (min != null && max_ex.compareTo(min) <= 0) { - args = new Object[] { max_ex, min }; - theContext.addError("length.maxexlemin", rule, "length", null, args); - } else if (min_ex != null && max_ex.compareTo(min_ex) <= 0) { - args = new Object[] { max_ex, min_ex }; - theContext.addError("length.maxexleminex", rule, "length", null, args); + } else if (maxEx != null) { + if (min != null && maxEx.compareTo(min) <= 0) { + args = new Object[] { maxEx, min }; + theContext.addError("length.maxexlemin", rule, LENGTH, null, args); + } else if (minEx != null && maxEx.compareTo(minEx) <= 0) { + args = new Object[] { maxEx, minEx }; + theContext.addError("length.maxexleminex", rule, LENGTH, null, args); } } } - // - //Boolean unique; - //if ((unique = (Boolean)map.get("unique")) != null) { + if (map.containsKey("unique")) { Boolean unique = (Boolean)map.get("unique"); - if (unique.booleanValue() == true && Types.isCollectionType(type)) { + if (unique && Types.isCollectionType(type)) { theContext.addError("unique.notscalar", rule, "unique:", (Object[])null); } if (theContext.getPath().length() == 0) { theContext.addError("unique.onroot", rule, "", "unique:", null); } } - // - //Boolean ident; - //if ((ident = (Boolean)map.get("ident")) != null) { - if (map.containsKey("ident")) { - Boolean ident = (Boolean)map.get("ident"); - if (ident.booleanValue() == true && Types.isCollectionType(type)) { - theContext.addError("ident.notscalar", rule, "ident:", (Object[])null); + + if (map.containsKey(IDENT)) { + Boolean ident = (Boolean)map.get(IDENT); + if (ident && Types.isCollectionType(type)) { + theContext.addError("ident.notscalar", rule, IDENT1, (Object[])null); } if (theContext.getPath().length() == 0) { - theContext.addError("ident.onroot", rule, "/", "ident:", (Object[])null); + theContext.addError("ident.onroot", rule, "/", IDENT1, null); } } - // - //List seq; - //if ((seq = (List)map.get("sequence")) != null) { - if (map.containsKey("sequence")) { - List seq = (List)map.get("sequence"); - //if (! (seq instanceof List)) { - // theContext.addError(validationError("sequence.notseq", rule, path + "/sequence", seq, null)); - //} else - if (seq == null || seq.size() == 0) { - theContext.addError("sequence.noelem", rule, "sequence", seq, null); + + if (map.containsKey(SEQUENCE)) { + List seq = (List)map.get(SEQUENCE); + + if (seq == null || seq.isEmpty()) { + theContext.addError("sequence.noelem", rule, SEQUENCE, seq, null); } else if (seq.size() > 1) { - theContext.addError("sequence.toomany", rule, "sequence", seq, null); + theContext.addError("sequence.toomany", rule, SEQUENCE, seq, null); } else { Object item = seq.get(0); assert item instanceof Map; Map m = (Map)item; - Boolean ident2 = (Boolean)m.get("ident"); - if (ident2 != null && ident2.booleanValue() == true && ! "map".equals(m.get("type"))) { - theContext.addError("ident.notmap", null, "sequence/0", "ident:", null); + Boolean ident2 = (Boolean)m.get(IDENT); + if (ident2 != null && ident2 && ! "map".equals(m.get("type"))) { + theContext.addError("ident.notmap", null, "sequence/0", IDENT1, null); } } } - // - //Map mapping; - //if ((mapping = (Map)map.get("mapping")) != null) { - if (map.containsKey("mapping")) { - Map mapping = (Map)map.get("mapping"); - //if (mapping != null && ! (mapping instanceof Map)) { - // theContext.addError(validationError("mapping.notmap", rule, path + "/mapping", mapping, null)); - //} else - Object default_value = null; + if (map.containsKey(MAPPING)) { + Map mapping = (Map)map.get(MAPPING); + + Object defaultValue = null; if (mapping != null && mapping instanceof Defaultable) { - default_value = ((Defaultable)mapping).getDefault(); + defaultValue = ((Defaultable)mapping).getDefault(); } - if (mapping == null || (mapping.size() == 0 && default_value == null)) { - theContext.addError("mapping.noelem", rule, "mapping", mapping, null); + if (mapping == null || (mapping.size() == 0 && defaultValue == null)) { + theContext.addError("mapping.noelem", rule, MAPPING, mapping, null); } } - // - if (type.equals("seq")) { - if (! map.containsKey("sequence")) { + if ("seq".equals(type)) { + if (! map.containsKey(SEQUENCE)) { theContext.addError("seq.nosequence", rule, null, (Object[])null); } - //if (map.containsKey("enum")) { - // theContext.addError(validationError("seq.conflict", rule, path, "enum:", null)); - //} - if (map.containsKey("pattern")) { - theContext.addError("seq.conflict", rule, "pattern:", (Object[])null); + if (map.containsKey(PATTERN1)) { + theContext.addError("seq.conflict", rule, PATTERN, (Object[])null); } - if (map.containsKey("mapping")) { + if (map.containsKey(MAPPING)) { theContext.addError("seq.conflict", rule, "mapping:", (Object[])null); } - //if (map.containsKey("range")) { - // theContext.addError(validationError("seq.conflict", rule, path, "range:", null)); - //} - //if (map.containsKey("length")) { - // theContext.addError(validationError("seq.conflict", rule, path, "length:", null)); - //} - } else if (type.equals("map")) { - if (! map.containsKey("mapping")) { + } else if ("map".equals(type)) { + if (! map.containsKey(MAPPING)) { theContext.addError("map.nomapping", rule, null, (Object[])null); } - //if (map.containsKey("enum")) { - // theContext.addError(validationError("map.conflict", rule, path, "enum:", null)); - //} - if (map.containsKey("pattern")) { - theContext.addError("map.conflict", rule, "pattern:", (Object[])null); + if (map.containsKey(PATTERN1)) { + theContext.addError("map.conflict", rule, PATTERN, (Object[])null); } - if (map.containsKey("sequence")) { + if (map.containsKey(SEQUENCE)) { theContext.addError("map.conflict", rule, "sequence:", (Object[])null); } - //if (map.containsKey("range")) { - // theContext.addError(validationError("map.conflict", rule, path, "range:", null)); - //} - //if (map.containsKey("length")) { - // theContext.addError(validationError("map.conflict", rule, path, "length:", null)); - //} } else { - if (map.containsKey("sequence")) { - theContext.addError("scalar.conflict", rule, "sequence:", (Object[])null); + if (map.containsKey(SEQUENCE)) { + theContext.addError(SCALAR_CONFLICT, rule, "sequence:", (Object[])null); } - if (map.containsKey("mapping")) { - theContext.addError("scalar.conflict", rule, "mapping:", (Object[])null); + if (map.containsKey(MAPPING)) { + theContext.addError(SCALAR_CONFLICT, rule, "mapping:", (Object[])null); } if (map.containsKey("enum")) { - if (map.containsKey("range")) { - theContext.addError("enum.conflict", rule, "range:", (Object[])null); + if (map.containsKey(RANGE)) { + theContext.addError(ENUM_CONFLICT, rule, "range:", (Object[])null); } - if (map.containsKey("length")) { - theContext.addError("enum.conflict", rule, "length:", (Object[])null); + if (map.containsKey(LENGTH)) { + theContext.addError(ENUM_CONFLICT, rule, "length:", (Object[])null); } - if (map.containsKey("pattern")) { - theContext.addError("enum.conflict", rule, "pattern:", (Object[])null); + if (map.containsKey(PATTERN1)) { + theContext.addError(ENUM_CONFLICT, rule, PATTERN, (Object[])null); } } } } + private void checkEnum(Rule rule, ValidationContext theContext, String type, List enumList) { + for (Object elem : enumList) { + if (!Types.isCorrectType(elem, type)) { + theContext.addError("enum.type.unmatch", rule, "enum", elem, new Object[]{Types.typeName(type)}); + } + } + } + + private void rangeCheck(Rule rule, ValidationContext theContext, String type, Map range) { + for (Object o : range.keySet()) { + String k = (String) o; + Object v = range.get(k); + if (!Types.isCorrectType(v, type)) { + theContext.addError("range.type.unmatch", rule, "range/" + k, v, new Object[]{Types.typeName(type)}); + } + } + } + } diff --git a/dcaedt_validator/kwalify/src/main/java/kwalify/PlainYamlParser.java b/dcaedt_validator/kwalify/src/main/java/kwalify/PlainYamlParser.java index 5f23a19..dd44403 100644 --- a/dcaedt_validator/kwalify/src/main/java/kwalify/PlainYamlParser.java +++ b/dcaedt_validator/kwalify/src/main/java/kwalify/PlainYamlParser.java @@ -85,17 +85,13 @@ public class PlainYamlParser implements Parser { seq.set(index, value); } - Map createMapping() { - return new DefaultableHashMap(); - } - private void setMappingValueWith(Map map, Object key, Object value) { map.put(key, value); } void setMappingDefault(Map map, Object value) { if (map instanceof Defaultable) { - ((Defaultable)map).setDefault(value); + ((Defaultable)map).setDefault((Rule)value); } } @@ -316,14 +312,14 @@ public class PlainYamlParser implements Parser { private Map parseFlowMapping(int depth) throws SyntaxException { assert currentChar() == '{'; - Map map = createMapping(); + Map map = new DefaultableHashMap(); int ch = getChar(); if (ch != '}') { Object[] pair = parseFlowMappingItem(depth + 1); Object key = pair[0]; Object value = pair[1]; setMappingValueWith(map, key, value); - while ((ch = currentChar()) == ',') { + while ((currentChar()) == ',') { ch = getChar(); if (ch == '}') { throw syntaxError("mapping item required (or last comman is extra."); @@ -368,7 +364,8 @@ public class PlainYamlParser implements Parser { scalar = sb.toString(); } else { sb.append((char)ch); - while ((ch = getCurrentCharacter()) >= 0 && ch != ':' && ch != ',' && ch != ']' && ch != '}') { + String lookup = ":,]}"; + while ((ch = getCurrentCharacter()) >= 0 && lookup.indexOf(ch) == -1) { sb.append((char)ch); } scalar = toScalar(sb.toString().trim()); @@ -543,15 +540,7 @@ public class PlainYamlParser implements Parser { } else if (slen < indent) { throw syntaxError("invalid indent in block text."); } else { - if (n > 0) { - if (blockChar == '>' && sb.length() > 0) { - sb.deleteCharAt(sb.length() - 1); - } - for (int i = 0; i < n; i++) { - sb.append('\n'); - } - n = 0; - } + n = indentHandler(blockChar, sb, n); str = currentLine.substring(indent); } } @@ -563,6 +552,11 @@ public class PlainYamlParser implements Parser { if (currentLine != null && Util.matches(currentLine, "^ *#")) { getLine(); } + processIndicator(blockChar, indicator, sep, sb, n); + return createScalar(text + sb.toString()); + } + + private void processIndicator(char blockChar, char indicator, char sep, StringBuilder sb, int n) { switch (indicator) { case '+': handlePlus(blockChar, sb, n); @@ -575,7 +569,19 @@ public class PlainYamlParser implements Parser { sb.setCharAt(sb.length() - 1, '\n'); } } - return createScalar(text + sb.toString()); + } + + private int indentHandler(char blockChar, StringBuilder sb, int indent) { + if (indent > 0) { + if (blockChar == '>' && sb.length() > 0) { + sb.deleteCharAt(sb.length() - 1); + } + for (int i = 0; i < indent; i++) { + sb.append('\n'); + } + return 0; + } + return indent; } private void handleMinus(char sep, StringBuilder sb) { @@ -637,7 +643,7 @@ public class PlainYamlParser implements Parser { private Map parseMapping(int column, String value) throws SyntaxException { assert Util.matches(value, REGEXP2); - Map map = createMapping(); + Map map = new DefaultableHashMap(); while (true) { Matcher m = Util.matcher(value, REGEXP2); if (! m.find()) { @@ -670,16 +676,23 @@ public class PlainYamlParser implements Parser { Matcher m2 = Util.matcher(currentLine, REGEXP1); m2.find(); int indent = m2.group(1).length(); - if (indent < column) { + if (checkIndent(column, indent)) { break; - } else if (indent > column) { - throw syntaxError("invalid indent of mapping."); } value = m2.group(2); } return map; } + private boolean checkIndent(int column, int indent) throws SyntaxException { + if (indent < column) { + return true; + } else if (indent > column) { + throw syntaxError("invalid indent of mapping."); + } + return false; + } + private Object parseScalar(String value) { Object data = createScalar(toScalar(value)); @@ -690,38 +703,66 @@ public class PlainYamlParser implements Parser { private Object toScalar(String value) { Matcher m; - if ((m = Util.matcher(value, "^\"(.*)\"([ \t]*#.*$)?")).find()) { + m = Util.matcher(value, "^\"(.*)\"([ \t]*#.*$)?"); + if (m.find()) { return m.group(1); - } else if ((m = Util.matcher(value, "^'(.*)'([ \t]*#.*$)?")).find()) { + } + + m = Util.matcher(value, "^'(.*)'([ \t]*#.*$)?"); + if (m.find()) { return m.group(1); - } else if ((m = Util.matcher(value, "^(.*\\S)[ \t]*#")).find()) { + } + + m = Util.matcher(value, "^(.*\\S)[ \t]*#"); + if (m.find()) { value = m.group(1); } if (Util.matches(value, "^-?0x\\d+$")) { return Integer.parseInt(value, 16); - } else if (Util.matches(value, "^-?0\\d+$")) { + } + + if (Util.matches(value, "^-?0\\d+$")) { return Integer.parseInt(value, 8); - } else if (Util.matches(value, "^-?\\d+$")) { + } + + if (Util.matches(value, "^-?\\d+$")) { return Integer.parseInt(value, 10); - } else if (Util.matches(value, "^-?\\d+\\.\\d+$")) { + } + + if (Util.matches(value, "^-?\\d+\\.\\d+$")) { return Double.parseDouble(value); - } else if (Util.matches(value, "^(true|yes|on)$")) { + } + + if (Util.matches(value, "^(true|yes|on)$")) { return Boolean.TRUE; - } else if (Util.matches(value, "^(false|no|off)$")) { + } + + if (Util.matches(value, "^(false|no|off)$")) { return Boolean.FALSE; - } else if (Util.matches(value, "^(null|~)$")){ + } + + if (Util.matches(value, "^(null|~)$")){ return null; - } else if (Util.matches(value, "^:(\\w+)$")) { + } + + if (Util.matches(value, "^:(\\w+)$")) { return value; - } else if ((m = Util.matcher(value, "^(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)$")).find()) { + } + + m = Util.matcher(value, "^(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)$"); + if (m.find()) { int year = Integer.parseInt(m.group(1)); int month = Integer.parseInt(m.group(2)); int day = Integer.parseInt(m.group(3)); Calendar cal = Calendar.getInstance(); + //noinspection MagicConstant cal.set(year, month, day, 0, 0, 0); return cal.getTime(); - } else if ((m = Util.matcher(value, "^(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)(?:[Tt]|[ \t]+)(\\d\\d?):(\\d\\d):(\\d\\d)(\\.\\d*)?(?:Z|[ \t]*([-+]\\d\\d?)(?::(\\d\\d))?)?$")).find()) { + } + + m = Util.matcher(value, "^(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)(?:[Tt]|[ \t]+)(\\d\\d?):(\\d\\d):(\\d\\d)(\\.\\d*)?(?:Z|[ \t]*([-+]\\d\\d?)(?::(\\d\\d))?)?$"); + if (m.find()) { int year = Integer.parseInt(m.group(1)); int month = Integer.parseInt(m.group(2)); int day = Integer.parseInt(m.group(3)); @@ -731,12 +772,13 @@ public class PlainYamlParser implements Parser { String timezone = "GMT" + m.group(8) + ":" + m.group(9); Calendar cal = Calendar.getInstance(); + //noinspection MagicConstant cal.set(year, month, day, hour, min, sec); cal.setTimeZone(TimeZone.getTimeZone(timezone)); return cal.getTime(); - } else { - return value; } + + return value; } } diff --git a/dcaedt_validator/kwalify/src/main/java/kwalify/Rule.java b/dcaedt_validator/kwalify/src/main/java/kwalify/Rule.java index 8dbe0b7..29a0fb5 100644 --- a/dcaedt_validator/kwalify/src/main/java/kwalify/Rule.java +++ b/dcaedt_validator/kwalify/src/main/java/kwalify/Rule.java @@ -5,12 +5,7 @@ package kwalify; import java.io.Serializable; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.Iterator; +import java.util.*; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.regex.PatternSyntaxException; @@ -88,32 +83,32 @@ public class Rule implements Serializable{ private static final String UNIQUE3 = "unique: "; private static final String ENUM2 = "enum:\n"; private static final String RANGE3 = "range: { "; - private static final String NAME = "name"; - private static final String DESC = "desc"; + private static final String NAME_CONSTANT = "name"; + private static final String DESC_CONSTANT = "desc"; private static final String SHORT = "short"; - private static final String REQUIRED = "required"; + private static final String REQUIRED_CONSTANT = "required"; private static final String TYPE = "type"; - private static final String PATTERN = "pattern"; - private static final String SEQUENCE = "sequence"; + private static final String PATTERN_CONSTANT = "pattern"; + private static final String SEQUENCE_CONSTANT = "sequence"; private static final String MAPPING = "mapping"; private static final String ASSERT = "assert"; - private static final String RANGE = "range"; - private static final String LENGTH = "length"; - private static final String IDENT = "ident"; - private static final String UNIQUE = "unique"; + private static final String RANGE_CONSTANT = "range"; + private static final String LENGTH_CONSTANT = "length"; + private static final String IDENT_CONSTANT = "ident"; + private static final String UNIQUE_CONSTANT = "unique"; private static final String ENUM = "enum:"; private static final String ENUM1 = "/enum"; - public static final String MAX = "max"; - public static final String MIN = "min"; + private static final String MAX = "max"; + private static final String MIN = "min"; private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); private Rule parent; private String name = null; private String desc = null; - private String _short = null; //added by jora: only used for map types + private String shortValue = null; //added by jora: only used for map types private boolean required = false; - private String _type = null; + private String typeValue = null; private Class typeClass = null; private String pattern = null; private Pattern patternRegexp = null; @@ -126,20 +121,20 @@ public class Rule implements Serializable{ private boolean ident = false; private boolean unique = false; - private static final int CODE_NAME = NAME.hashCode(); - private static final int CODE_DESC = DESC.hashCode(); + private static final int CODE_NAME = NAME_CONSTANT.hashCode(); + private static final int CODE_DESC = DESC_CONSTANT.hashCode(); private static final int CODE_SHORT = SHORT.hashCode(); - private static final int CODE_REQUIRED = REQUIRED.hashCode(); + private static final int CODE_REQUIRED = REQUIRED_CONSTANT.hashCode(); private static final int CODE_TYPE = TYPE.hashCode(); - private static final int CODE_PATTERN = PATTERN.hashCode(); - private static final int CODE_LENGTH = LENGTH.hashCode(); - private static final int CODE_RANGE = RANGE.hashCode(); + private static final int CODE_PATTERN = PATTERN_CONSTANT.hashCode(); + private static final int CODE_LENGTH = LENGTH_CONSTANT.hashCode(); + private static final int CODE_RANGE = RANGE_CONSTANT.hashCode(); private static final int CODE_ASSERT = ASSERT.hashCode(); - private static final int CODE_IDENT = IDENT.hashCode(); - private static final int CODE_UNIQUE = UNIQUE.hashCode(); + private static final int CODE_IDENT = IDENT_CONSTANT.hashCode(); + private static final int CODE_UNIQUE = UNIQUE_CONSTANT.hashCode(); private static final int CODE_ENUM = ENUM.hashCode(); private static final int CODE_MAPPING = MAPPING.hashCode(); - private static final int CODE_SEQUENCE = SEQUENCE.hashCode(); + private static final int CODE_SEQUENCE = SEQUENCE_CONSTANT.hashCode(); public Rule(Object schema, Rule parent) { if (schema != null) { @@ -175,21 +170,23 @@ public class Rule implements Serializable{ public String getName() { return name; } public void setName(String name) { this.name = name; } - public String getShort() { return _short; } - public void setShort(String key) { _short = key; } + public String getShort() { return shortValue; } + public void setShort(String key) { shortValue = key; } public boolean isRequired() { return required; } public void setRequired(boolean required) { this.required = required; } - public String getType() { return _type; } - public void setType(String type) { this._type = type; } + public String getType() { return typeValue; } + public void setType(String type) { this.typeValue = type; } public String getPattern() { return pattern; } public void setPattern(String pattern) { this.pattern = pattern; } public Pattern getPatternRegexp() { return patternRegexp; } - public List getEnum() { return enumList; } + public List getEnum() { + return enumList; + } public void setEnum(List enumList) { this.enumList = enumList; } public List getSequence() { return sequence; } @@ -245,29 +242,29 @@ public class Rule implements Serializable{ if (code == CODE_TYPE && key.equals(TYPE)) { // done - } else if (code == CODE_NAME && key.equals(NAME)) { + } else if (code == CODE_NAME && key.equals(NAME_CONSTANT)) { initNameValue(value); - } else if (code == CODE_DESC && key.equals(DESC)) { + } else if (code == CODE_DESC && key.equals(DESC_CONSTANT)) { initDescValue(value); } else if (code == CODE_SHORT && key.equals(SHORT)) { initShortValue(value, rule, path); - } else if (code == CODE_REQUIRED && key.equals(REQUIRED)) { + } else if (code == CODE_REQUIRED && key.equals(REQUIRED_CONSTANT)) { initRequiredValue(value, rule, path); - } else if (code == CODE_PATTERN && key.equals(PATTERN)) { + } else if (code == CODE_PATTERN && key.equals(PATTERN_CONSTANT)) { initPatternValue(value, rule, path); } else if (code == CODE_ENUM && key.equals(ENUM)) { initEnumValue(value, rule, path); } else if (code == CODE_ASSERT && key.equals(ASSERT)) { initAssertValue(value, rule, path); - } else if (code == CODE_RANGE && key.equals(RANGE)) { + } else if (code == CODE_RANGE && key.equals(RANGE_CONSTANT)) { initRangeValue(value, rule, path); - } else if (code == CODE_LENGTH && key.equals(LENGTH)) { + } else if (code == CODE_LENGTH && key.equals(LENGTH_CONSTANT)) { initLengthValue(value, rule, path); - } else if (code == CODE_IDENT && key.equals(IDENT)) { + } else if (code == CODE_IDENT && key.equals(IDENT_CONSTANT)) { initIdentValue(value, rule, path); - } else if (code == CODE_UNIQUE && key.equals(UNIQUE)) { + } else if (code == CODE_UNIQUE && key.equals(UNIQUE_CONSTANT)) { initUniqueValue(value, rule, path); - } else if (code == CODE_SEQUENCE && key.equals(SEQUENCE)) { + } else if (code == CODE_SEQUENCE && key.equals(SEQUENCE_CONSTANT)) { rule = initSequenceValue(value, rule, path, ruleTable); } else if (code == CODE_MAPPING && key.equals(MAPPING)) { rule = initMappingValue(value, rule, path, ruleTable); @@ -282,12 +279,12 @@ public class Rule implements Serializable{ value = Types.getDefaultType(); } if (! (value instanceof String)) { - throw schemaError(TYPE_NOTSTR, rule, path + TYPE1, _type, null); + throw schemaError(TYPE_NOTSTR, rule, path + TYPE1, typeValue, null); } - _type = (String)value; - typeClass = Types.typeClass(_type); - if (! Types.isBuiltinType(_type)) { - throw schemaError(TYPE_UNKNOWN, rule, path + TYPE1, _type, null); + typeValue = (String)value; + typeClass = Types.typeClass(typeValue); + if (! Types.isBuiltinType(typeValue)) { + throw schemaError(TYPE_UNKNOWN, rule, path + TYPE1, typeValue, null); } } @@ -305,12 +302,12 @@ public class Rule implements Serializable{ //the short form specification is to be interpreted as key if the type is a map or as an //index if the target is a sequence (as index 0 actually) - if (!Types.isCollectionType(_type)) { + if (!Types.isCollectionType(typeValue)) { throw schemaError("range.notcollection", rule, path + "/short", value, null); } //we should also verify that it points to a declared key of the mapping .. not really, as it would //fail the overall grammar - _short = value.toString(); + shortValue = value.toString(); } private void initRequiredValue(Object value, Rule rule, String path) { @@ -353,14 +350,14 @@ public class Rule implements Serializable{ throw schemaError("enum.notseq", rule, path + ENUM1, value, null); } enumList = (List)value; - if (Types.isCollectionType(_type)) { + if (Types.isCollectionType(typeValue)) { throw schemaError("enum.notscalar", rule, path, ENUM, null); } Map elemTable = new HashMap(); for (Iterator it = enumList.iterator(); it.hasNext(); ) { Object elem = it.next(); if (! Util.isInstanceOf(elem, typeClass)) { - throw schemaError("enum.type.unmatch", rule, path + ENUM1, elem, new Object[] { Types.typeName(_type) }); + throw schemaError("enum.type.unmatch", rule, path + ENUM1, elem, new Object[] { Types.typeName(typeValue) }); } if (elemTable.containsKey(elem)) { throw schemaError("enum.duplicate", rule, path + ENUM1, elem, null); @@ -385,7 +382,7 @@ public class Rule implements Serializable{ if (! (value instanceof Map)) { throw schemaError("range.notmap", rule, path + RANGE1, value, null); } - if (Types.isCollectionType(_type) || "bool".equals(_type)) { + if (Types.isCollectionType(typeValue) || "bool".equals(typeValue)) { throw schemaError("range.notscalar", rule, path, RANGE2, null); } range = (Map)value; @@ -394,7 +391,7 @@ public class Rule implements Serializable{ Object rval = range.get(rkey); if (MAX.equals(rkey) || MIN.equals(rkey) || rkey.equals(MAX_EX) || rkey.equals(MIN_EX)) { if (! Util.isInstanceOf(rval, typeClass)) { - String typename = Types.typeName(_type); + String typename = Types.typeName(typeValue); throw schemaError("range.type.unmatch", rule, path + "/range/" + rkey, rval, new Object[] { typename }); } } else { @@ -439,7 +436,7 @@ public class Rule implements Serializable{ throw schemaError("length.notmap", rule, path + LENGTH1, value, null); } length = (Map)value; - if (! ("str".equals(_type) || "text".equals(_type))) { + if (! ("str".equals(typeValue) || "text".equals(typeValue))) { throw schemaError("length.nottext", rule, path, LENGTH2, null); } for (String k : length.keySet()) { @@ -490,7 +487,7 @@ public class Rule implements Serializable{ } ident = (Boolean) value; required = true; - if (Types.isCollectionType(_type)) { + if (Types.isCollectionType(typeValue)) { throw schemaError(IDENT_NOTSCALAR, rule, path, IDENT1, null); } if (EMPTY_STRING.equals(path)) { @@ -507,7 +504,7 @@ public class Rule implements Serializable{ throw schemaError(UNIQUE_NOTBOOL, rule, path + UNIQUE2, value, null); } unique = (Boolean) value; - if (Types.isCollectionType(_type)) { + if (Types.isCollectionType(typeValue)) { throw schemaError(UNIQUE_NOTSCALAR, rule, path, UNIQUE1, null); } if (path.equals(EMPTY_STRING)) { @@ -557,6 +554,7 @@ public class Rule implements Serializable{ } // create hash of rule _mapping = new DefaultableHashMap(); + if (defaultValue != null) { rule = (Rule)ruleTable.get(defaultValue); if (rule == null) { @@ -565,15 +563,20 @@ public class Rule implements Serializable{ } _mapping.setDefault(rule); } + // put rules into _mapping - Map map = (Map)value; - for (Iterator it = map.keySet().iterator(); it.hasNext(); ) { - Object k = it.next(); - Object v = map.get(k); // DefaultableHashMap + rule = putRulesIntoMap((Map) value, rule, path, ruleTable); + return rule; + } + + private Rule putRulesIntoMap(Map value, Rule rule, String path, Map ruleTable) { + Map map = value; + for (Object k : map.keySet()) { + Object v = map.get(k); if (v == null) { v = new DefaultableHashMap(); } - rule = (Rule)ruleTable.get(v); + rule = (Rule) ruleTable.get(v); if (rule == null) { rule = new Rule(null, this); rule.init(v, path + MAPPING4 + k, ruleTable); @@ -589,8 +592,8 @@ public class Rule implements Serializable{ private void checkConfliction(Map hash, Rule rule, String path) { - if ("seq".equals(_type)) { - if (! hash.containsKey(SEQUENCE)) { + if ("seq".equals(typeValue)) { + if (! hash.containsKey(SEQUENCE_CONSTANT)) { throw schemaError("seq.nosequence", rule, path, null, null); } if (enumList != null) { @@ -608,7 +611,7 @@ public class Rule implements Serializable{ if (length != null) { throw schemaError(SEQ_CONFLICT, rule, path, LENGTH2, null); } - } else if (_type.equals(MAP)) { + } else if (typeValue.equals(MAP)) { if (! hash.containsKey(MAPPING)) { throw schemaError("map.nomapping", rule, path, null, null); } @@ -665,8 +668,8 @@ public class Rule implements Serializable{ if (desc != null) { sb.append(indent).append(DESC1).append(desc).append("\n"); } - if (_type != null) { - sb.append(indent).append(TYPE2).append(_type).append("\n"); + if (typeValue != null) { + sb.append(indent).append(TYPE2).append(typeValue).append("\n"); } if (required) { sb.append(indent).append(REQUIRED2).append(required).append("\n"); diff --git a/dcaedt_validator/kwalify/src/main/java/kwalify/Validator.java b/dcaedt_validator/kwalify/src/main/java/kwalify/Validator.java index e0f5af0..9129c53 100644 --- a/dcaedt_validator/kwalify/src/main/java/kwalify/Validator.java +++ b/dcaedt_validator/kwalify/src/main/java/kwalify/Validator.java @@ -77,6 +77,7 @@ public class Validator { } protected void postValidationHook(Object value, Rule rule, ValidationContext context) { + // nothing } private void _validateRule(Object value, Rule rule, ValidationContext context) { diff --git a/dcaedt_validator/kwalify/src/main/java/kwalify/YamlParser.java b/dcaedt_validator/kwalify/src/main/java/kwalify/YamlParser.java index b5789d3..7192e5d 100644 --- a/dcaedt_validator/kwalify/src/main/java/kwalify/YamlParser.java +++ b/dcaedt_validator/kwalify/src/main/java/kwalify/YamlParser.java @@ -94,7 +94,7 @@ public class YamlParser extends PlainYamlParser { } protected Map createMapping() { - Map map = super.createMapping(); + Map map = new DefaultableHashMap(); linenumsTable.put(map, new HashMap()); return map; } diff --git a/docker/docker_be/chef-solo/cookbooks/Deploy-DCAE/files/default/truststore b/docker/docker_be/chef-solo/cookbooks/Deploy-DCAE/files/default/traststore Binary files differindex c408393..c408393 100644 --- a/docker/docker_be/chef-solo/cookbooks/Deploy-DCAE/files/default/truststore +++ b/docker/docker_be/chef-solo/cookbooks/Deploy-DCAE/files/default/traststore diff --git a/docker/docker_be/chef-solo/cookbooks/Deploy-DCAE/templates/default/dcae-error-configuration.erb b/docker/docker_be/chef-solo/cookbooks/Deploy-DCAE/templates/default/dcae-error-configuration.erb index 7ab42b6..03fb423 100644 --- a/docker/docker_be/chef-solo/cookbooks/Deploy-DCAE/templates/default/dcae-error-configuration.erb +++ b/docker/docker_be/chef-solo/cookbooks/Deploy-DCAE/templates/default/dcae-error-configuration.erb @@ -275,4 +275,10 @@ errors: code: 400, message: "Please fill the %1 field of %2 action to %3", messageId: "SVC6117" + } +#---------SVC6118----------------------------- + DELETE_BLUEPRINT_FAILED: { + code: 400, + message: "The request was partially successful. Removing the attached Blueprint from the service has failed. You must manually delete the artifact.", + messageId: "SVC6118" }
\ No newline at end of file |