Search in sources :

Example 6 with VfModule

use of org.onap.so.db.catalog.beans.VfModule in project so by onap.

the class BaseTest method setUpVfModule.

protected VfModule setUpVfModule() {
    VfModule vFModule = new VfModule();
    vFModule.setModelUUID("cb82ffd8-252a-11e7-93ae-92361f002671");
    vFModule.setModelVersion("testModelVersion");
    vFModule.setModelName("testModelName");
    vFModule.setIsBase(false);
    return vFModule;
}
Also used : VfModule(org.onap.so.db.catalog.beans.VfModule)

Example 7 with VfModule

use of org.onap.so.db.catalog.beans.VfModule in project so by onap.

the class RequestHandlerUtils method getIsBaseVfModule.

protected Boolean getIsBaseVfModule(ModelInfo modelInfo, Actions action, String vnfType, String sdcServiceModelVersion, InfraActiveRequests currentActiveReq) throws ApiException {
    // Get VF Module-specific base module indicator
    VfModule vfm = null;
    String modelVersionId = modelInfo.getModelVersionId();
    Boolean isBaseVfModule = false;
    if (modelVersionId != null) {
        vfm = catalogDbClient.getVfModuleByModelUUID(modelVersionId);
    } else if (modelInfo.getModelInvariantId() != null && modelInfo.getModelVersion() != null) {
        vfm = catalogDbClient.getVfModuleByModelInvariantUUIDAndModelVersion(modelInfo.getModelInvariantId(), modelInfo.getModelVersion());
    }
    if (vfm != null) {
        if (vfm.getIsBase()) {
            isBaseVfModule = true;
        }
    } else if (action == Action.createInstance || action == Action.updateInstance) {
        String serviceVersionText = "";
        if (sdcServiceModelVersion != null && !sdcServiceModelVersion.isEmpty()) {
            serviceVersionText = " with version " + sdcServiceModelVersion;
        }
        String errorMessage = "VnfType " + vnfType + " and VF Module Model Name " + modelInfo.getModelName() + serviceVersionText + " not found in MSO Catalog DB";
        ErrorLoggerInfo errorLoggerInfo = new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND, ErrorCode.DataError).errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
        VfModuleNotFoundException vfModuleException = new VfModuleNotFoundException.Builder(errorMessage, HttpStatus.SC_NOT_FOUND, ErrorNumbers.SVC_BAD_PARAMETER).errorInfo(errorLoggerInfo).build();
        updateStatus(currentActiveReq, Status.FAILED, vfModuleException.getMessage());
        throw vfModuleException;
    }
    return isBaseVfModule;
}
Also used : ErrorLoggerInfo(org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo) VfModuleNotFoundException(org.onap.so.apihandlerinfra.exceptions.VfModuleNotFoundException) VfModule(org.onap.so.db.catalog.beans.VfModule)

Example 8 with VfModule

use of org.onap.so.db.catalog.beans.VfModule in project so by onap.

the class RequestHandlerUtils method getVnfOrVfModuleUri.

private RecipeLookupResult getVnfOrVfModuleUri(ServiceInstancesRequest servInstReq, Actions action) throws ValidationException {
    ModelInfo modelInfo = servInstReq.getRequestDetails().getModelInfo();
    String vnfComponentType = modelInfo.getModelType().name();
    RelatedInstanceList[] instanceList = null;
    if (servInstReq.getRequestDetails() != null) {
        instanceList = servInstReq.getRequestDetails().getRelatedInstanceList();
    }
    Recipe recipe;
    String defaultSource = getDefaultModel(servInstReq);
    String modelCustomizationId = modelInfo.getModelCustomizationId();
    String modelCustomizationName = modelInfo.getModelCustomizationName();
    String relatedInstanceModelVersionId = null;
    String relatedInstanceModelInvariantId = null;
    String relatedInstanceVersion = null;
    String relatedInstanceModelCustomizationName = null;
    if (instanceList != null) {
        for (RelatedInstanceList relatedInstanceList : instanceList) {
            RelatedInstance relatedInstance = relatedInstanceList.getRelatedInstance();
            ModelInfo relatedInstanceModelInfo = relatedInstance.getModelInfo();
            if (relatedInstanceModelInfo.getModelType().equals(ModelType.service)) {
                relatedInstanceModelVersionId = relatedInstanceModelInfo.getModelVersionId();
                relatedInstanceVersion = relatedInstanceModelInfo.getModelVersion();
            }
            if (relatedInstanceModelInfo.getModelType().equals(ModelType.vnf)) {
                relatedInstanceModelVersionId = relatedInstanceModelInfo.getModelVersionId();
                relatedInstanceModelInvariantId = relatedInstanceModelInfo.getModelInvariantId();
                relatedInstanceVersion = relatedInstanceModelInfo.getModelVersion();
                relatedInstanceModelCustomizationName = relatedInstanceModelInfo.getModelCustomizationName();
            }
        }
        if (modelInfo.getModelType().equals(ModelType.vnf)) {
            // a. For a vnf request (only create, no update currently):
            // i. (v3-v4) If modelInfo.modelCustomizationId is provided, use it to validate catalog DB has record in
            // vnf_resource_customization.model_customization_uuid.
            // ii. (v2-v4) If modelInfo.modelCustomizationId is NOT provided (because it is a pre-1702 ASDC model or
            // pre-v3), then modelInfo.modelCustomizationName must have
            // been provided (else create request should be rejected). APIH should use the
            // relatedInstance.modelInfo[service].modelVersionId** + modelInfo[vnf].modelCustomizationName
            // to “join�? service_to_resource_customizations with vnf_resource_customization to confirm a
            // vnf_resource_customization.model_customization_uuid record exists.
            // **If relatedInstance.modelInfo[service].modelVersionId was not provided, use
            // relatedInstance.modelInfo[service].modelInvariantId + modelVersion instead to lookup modelVersionId
            // (MODEL_UUID) in SERVICE table.
            // iii. Regardless of how the value was provided/obtained above, APIH must always populate
            // vnfModelCustomizationId in bpmnRequest. It would be assumed it was MSO generated
            // during 1707 data migration if VID did not provide it originally on request.
            // iv. Note: continue to construct the “vnf-type�? value and pass to BPMN (must still be populated
            // in A&AI).
            // 1. If modelCustomizationName is NOT provided on a vnf/vfModule request, use modelCustomizationId to
            // look it up in our catalog to construct vnf-type value to pass to BPMN.
            VnfResource vnfResource = null;
            VnfResourceCustomization vrc = null;
            if (modelCustomizationId != null) {
                vrc = catalogDbClient.getVnfResourceCustomizationByModelCustomizationUUID(modelCustomizationId);
                if (vrc != null) {
                    vnfResource = vrc.getVnfResources();
                }
            } else {
                org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(relatedInstanceModelVersionId);
                if (service == null) {
                    service = catalogDbClient.getServiceByModelVersionAndModelInvariantUUID(relatedInstanceVersion, relatedInstanceModelInvariantId);
                }
                if (service == null) {
                    throw new ValidationException("service in relatedInstance");
                }
                for (VnfResourceCustomization vnfResourceCustom : service.getVnfCustomizations()) {
                    if (vnfResourceCustom.getModelInstanceName().equals(modelCustomizationName)) {
                        vrc = vnfResourceCustom;
                    }
                }
                if (vrc != null) {
                    vnfResource = vrc.getVnfResources();
                    modelInfo.setModelCustomizationId(vrc.getModelCustomizationUUID());
                    modelInfo.setModelCustomizationUuid(vrc.getModelCustomizationUUID());
                }
            }
            if (vnfResource == null) {
                throw new ValidationException("vnfResource");
            } else {
                if (modelInfo.getModelVersionId() == null) {
                    modelInfo.setModelVersionId(vnfResource.getModelUUID());
                }
            }
            VnfRecipe vnfRecipe = null;
            if (vrc != null) {
                String nfRole = vrc.getNfRole();
                if (nfRole != null) {
                    vnfRecipe = catalogDbClient.getFirstVnfRecipeByNfRoleAndAction(vrc.getNfRole(), action.toString());
                }
            }
            if (vnfRecipe == null) {
                vnfRecipe = catalogDbClient.getFirstVnfRecipeByNfRoleAndAction(defaultSource, action.toString());
            }
            if (vnfRecipe == null) {
                return null;
            }
            return new RecipeLookupResult(vnfRecipe.getOrchestrationUri(), vnfRecipe.getRecipeTimeout());
        } else {
            /*
                 * (v5-v7) If modelInfo.modelCustomizationId is NOT provided (because it is a pre-1702 ASDC model or
                 * pre-v3), then modelInfo.modelCustomizationName must have // been provided (else create request should
                 * be rejected). APIH should use the relatedInstance.modelInfo[vnf].modelVersionId +
                 * modelInfo[vnf].modelCustomizationName // to join vnf_to_resource_customizations with
                 * vf_resource_customization to confirm a vf_resource_customization.model_customization_uuid record
                 * exists. // Once the vnfs model_customization_uuid has been obtained, use it to find all vfModule
                 * customizations for that vnf customization in the vnf_res_custom_to_vf_module_custom join table. //
                 * For each vf_module_cust_model_customization_uuid value returned, use that UUID to query
                 * vf_module_customization table along with modelInfo[vfModule|volumeGroup].modelVersionId to // confirm
                 * record matches request data (and to identify the modelCustomizationId associated with the vfModule in
                 * the request). This means taking each record found // in vf_module_customization and looking up in
                 * vf_module (using vf_module_customization’s FK into vf_module) to find a match on
                 * MODEL_INVARIANT_UUID (modelInvariantId) // and MODEL_VERSION (modelVersion).
                 */
            VfModuleCustomization vfmc = null;
            VnfResource vnfr;
            VnfResourceCustomization vnfrc;
            VfModule vfModule = null;
            if (modelInfo.getModelCustomizationId() != null) {
                vfmc = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(modelInfo.getModelCustomizationId());
            } else {
                vnfr = catalogDbClient.getVnfResourceByModelUUID(relatedInstanceModelVersionId);
                if (vnfr == null) {
                    vnfr = catalogDbClient.getFirstVnfResourceByModelInvariantUUIDAndModelVersion(relatedInstanceModelInvariantId, relatedInstanceVersion);
                }
                vnfrc = catalogDbClient.getFirstVnfResourceCustomizationByModelInstanceNameAndVnfResources(relatedInstanceModelCustomizationName, vnfr);
                List<VfModuleCustomization> list = vnfrc.getVfModuleCustomizations();
                String vfModuleModelUUID = modelInfo.getModelVersionId();
                for (VfModuleCustomization vf : list) {
                    VfModuleCustomization vfmCustom;
                    if (vfModuleModelUUID != null) {
                        vfmCustom = catalogDbClient.getVfModuleCustomizationByModelCustomizationUUIDAndVfModuleModelUUID(vf.getModelCustomizationUUID(), vfModuleModelUUID);
                        if (vfmCustom != null) {
                            vfModule = vfmCustom.getVfModule();
                        }
                    } else {
                        vfmCustom = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(vf.getModelCustomizationUUID());
                        if (vfmCustom != null) {
                            vfModule = vfmCustom.getVfModule();
                        } else {
                            vfModule = catalogDbClient.getVfModuleByModelInvariantUUIDAndModelVersion(relatedInstanceModelInvariantId, relatedInstanceVersion);
                        }
                    }
                    if (vfModule != null) {
                        modelInfo.setModelCustomizationId(vf.getModelCustomizationUUID());
                        modelInfo.setModelCustomizationUuid(vf.getModelCustomizationUUID());
                        break;
                    }
                }
            }
            if (vfmc == null && vfModule == null) {
                throw new ValidationException("vfModuleCustomization");
            } else if (vfModule == null && vfmc != null) {
                // can't be null as vfModuleModelUUID is not-null property in
                vfModule = vfmc.getVfModule();
            // VfModuleCustomization table
            }
            if (modelInfo.getModelVersionId() == null) {
                modelInfo.setModelVersionId(vfModule.getModelUUID());
            }
            recipe = catalogDbClient.getFirstVnfComponentsRecipeByVfModuleModelUUIDAndVnfComponentTypeAndAction(vfModule.getModelUUID(), vnfComponentType, action.toString());
            if (recipe == null) {
                List<VfModule> vfModuleRecords = catalogDbClient.getVfModuleByModelInvariantUUIDOrderByModelVersionDesc(vfModule.getModelInvariantUUID());
                if (!vfModuleRecords.isEmpty()) {
                    for (VfModule record : vfModuleRecords) {
                        recipe = catalogDbClient.getFirstVnfComponentsRecipeByVfModuleModelUUIDAndVnfComponentTypeAndAction(record.getModelUUID(), vnfComponentType, action.toString());
                        if (recipe != null) {
                            break;
                        }
                    }
                }
            }
            if (recipe == null) {
                recipe = catalogDbClient.getFirstVnfComponentsRecipeByVfModuleModelUUIDAndVnfComponentTypeAndAction(defaultSource, vnfComponentType, action.toString());
                if (recipe == null) {
                    recipe = catalogDbClient.getFirstVnfComponentsRecipeByVnfComponentTypeAndAction(vnfComponentType, action.toString());
                }
                if (recipe == null) {
                    return null;
                }
            }
        }
    } else {
        if (modelInfo.getModelType().equals(ModelType.vnf)) {
            recipe = catalogDbClient.getFirstVnfRecipeByNfRoleAndAction(defaultSource, action.toString());
            if (recipe == null) {
                return null;
            }
        } else {
            recipe = catalogDbClient.getFirstVnfComponentsRecipeByVfModuleModelUUIDAndVnfComponentTypeAndAction(defaultSource, vnfComponentType, action.toString());
            if (recipe == null) {
                return null;
            }
        }
    }
    return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout());
}
Also used : ModelInfo(org.onap.so.serviceinstancebeans.ModelInfo) ValidationException(org.onap.so.exceptions.ValidationException) RelatedInstanceList(org.onap.so.serviceinstancebeans.RelatedInstanceList) VnfRecipe(org.onap.so.db.catalog.beans.VnfRecipe) ServiceRecipe(org.onap.so.db.catalog.beans.ServiceRecipe) Recipe(org.onap.so.db.catalog.beans.Recipe) RelatedInstance(org.onap.so.serviceinstancebeans.RelatedInstance) VfModule(org.onap.so.db.catalog.beans.VfModule) VnfResource(org.onap.so.db.catalog.beans.VnfResource) VnfRecipe(org.onap.so.db.catalog.beans.VnfRecipe) VfModuleCustomization(org.onap.so.db.catalog.beans.VfModuleCustomization) VnfResourceCustomization(org.onap.so.db.catalog.beans.VnfResourceCustomization)

Example 9 with VfModule

use of org.onap.so.db.catalog.beans.VfModule in project so by onap.

the class CatalogDbAdapterRest method vfModules.

@GET
@Path("vfModules")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Transactional(readOnly = true)
public Response vfModules(@QueryParam("vfModuleModelName") String vfModuleModelName) {
    QueryVfModule qryResp;
    int respStatus = HttpStatus.SC_OK;
    List<VfModuleCustomization> ret = null;
    try {
        if (vfModuleModelName != null && !"".equals(vfModuleModelName)) {
            VfModule vfModule = vfModuleRepo.findFirstByModelNameOrderByModelVersionDesc(vfModuleModelName);
            if (vfModule != null)
                ret = vfModule.getVfModuleCustomization();
        } else {
            throw (new Exception(NO_MATCHING_PARAMETERS));
        }
        if (ret == null || ret.isEmpty()) {
            logger.debug("vfModules not found");
            respStatus = HttpStatus.SC_NOT_FOUND;
            qryResp = new QueryVfModule();
        } else {
            qryResp = new QueryVfModule(ret);
            if (logger.isDebugEnabled())
                logger.debug("vfModules tojsonstring is: {}", qryResp.JSON2(false, false));
        }
        return Response.status(respStatus).entity(qryResp.JSON2(false, false)).header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON).build();
    } catch (Exception e) {
        logger.error("Exception during query VfModules by vfModuleModuleName: ", e);
        CatalogQueryException excResp = new CatalogQueryException(e.getMessage(), CatalogQueryExceptionCategory.INTERNAL, Boolean.FALSE, null);
        return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(new GenericEntity<CatalogQueryException>(excResp) {
        }).build();
    }
}
Also used : QueryVfModule(org.onap.so.adapters.catalogdb.catalogrest.QueryVfModule) CatalogQueryException(org.onap.so.adapters.catalogdb.catalogrest.CatalogQueryException) VfModuleCustomization(org.onap.so.db.catalog.beans.VfModuleCustomization) VfModule(org.onap.so.db.catalog.beans.VfModule) QueryVfModule(org.onap.so.adapters.catalogdb.catalogrest.QueryVfModule) CatalogQueryException(org.onap.so.adapters.catalogdb.catalogrest.CatalogQueryException) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) Transactional(org.springframework.transaction.annotation.Transactional)

Example 10 with VfModule

use of org.onap.so.db.catalog.beans.VfModule in project so by onap.

the class MsoVnfAdapterImpl method updateVfModule.

public void updateVfModule(String cloudSiteId, String cloudOwner, String tenantId, String vnfType, String vnfVersion, String vnfName, String requestType, String volumeGroupHeatStackId, String baseVfHeatStackId, String vfModuleStackId, String modelCustomizationUuid, Map<String, Object> inputs, MsoRequest msoRequest, Holder<Map<String, String>> outputs, Holder<VnfRollback> rollback) throws VnfException {
    String vfModuleName = vnfName;
    String vfModuleType = vnfType;
    StringBuilder sbInit = new StringBuilder();
    sbInit.append("updateVfModule: \n");
    sbInit.append("cloudOwner=" + cloudOwner + "\n");
    sbInit.append("cloudSiteId=" + cloudSiteId + "\n");
    sbInit.append("tenantId=" + tenantId + "\n");
    sbInit.append("vnfType=" + vnfType + "\n");
    sbInit.append("vnfVersion=" + vnfVersion + "\n");
    sbInit.append("vnfName=" + vnfName + "\n");
    sbInit.append("requestType=" + requestType + "\n");
    sbInit.append("volumeGroupHeatStackId=" + volumeGroupHeatStackId + "\n");
    sbInit.append("baseVfHeatStackId=" + baseVfHeatStackId + "\n");
    sbInit.append("vfModuleStackId=" + vfModuleStackId + "\n");
    sbInit.append("modelCustomizationUuid=" + modelCustomizationUuid + "\n");
    logger.debug(sbInit.toString());
    String mcu = modelCustomizationUuid;
    boolean useMCUuid = false;
    if (mcu != null && !mcu.isEmpty()) {
        if ("null".equalsIgnoreCase(mcu)) {
            logger.debug("modelCustomizationUuid: passed in as the string 'null' - will ignore: {}", modelCustomizationUuid);
            useMCUuid = false;
            mcu = "";
        } else {
            logger.debug("Found modelCustomizationUuid! Will use that: {}", mcu);
            useMCUuid = true;
        }
    }
    String requestTypeString = "";
    if (requestType != null && !"".equals(requestType)) {
        requestTypeString = requestType;
    }
    String nestedStackId = null;
    if (volumeGroupHeatStackId != null && !"".equals(volumeGroupHeatStackId) && !"null".equalsIgnoreCase(volumeGroupHeatStackId)) {
        nestedStackId = volumeGroupHeatStackId;
    }
    String nestedBaseStackId = null;
    if (baseVfHeatStackId != null && !"".equals(baseVfHeatStackId) && !"null".equalsIgnoreCase(baseVfHeatStackId)) {
        nestedBaseStackId = baseVfHeatStackId;
    }
    if (inputs == null) {
        // Create an empty set of inputs
        inputs = new HashMap<>();
        logger.debug("inputs == null - setting to empty");
    }
    boolean isBaseRequest = false;
    boolean isVolumeRequest = false;
    if (requestTypeString.startsWith("VOLUME")) {
        isVolumeRequest = true;
    }
    if ((vfModuleName == null || "".equals(vfModuleName.trim())) && vfModuleStackId != null) {
        vfModuleName = this.getVfModuleNameFromModuleStackId(vfModuleStackId);
    }
    logger.debug("Updating VFModule: " + vfModuleName + " of type " + vfModuleType + "in " + cloudOwner + "/" + cloudSiteId + "/" + tenantId);
    logger.debug("requestTypeString = " + requestTypeString + ", nestedVolumeStackId = " + nestedStackId + ", nestedBaseStackId = " + nestedBaseStackId);
    // Build a default rollback object (no actions performed)
    VnfRollback vfRollback = new VnfRollback();
    vfRollback.setCloudSiteId(cloudSiteId);
    vfRollback.setCloudOwner(cloudOwner);
    vfRollback.setTenantId(tenantId);
    vfRollback.setMsoRequest(msoRequest);
    vfRollback.setRequestType(requestTypeString);
    vfRollback.setVolumeGroupHeatStackId(volumeGroupHeatStackId);
    vfRollback.setBaseGroupHeatStackId(baseVfHeatStackId);
    vfRollback.setIsBase(isBaseRequest);
    vfRollback.setVfModuleStackId(vfModuleStackId);
    vfRollback.setModelCustomizationUuid(mcu);
    StackInfo heatStack;
    logger.debug("UpdateVfModule - querying for {}", vfModuleName);
    try {
        heatStack = msoHeatUtils.queryStack(cloudSiteId, cloudOwner, tenantId, vfModuleName);
    } catch (MsoException me) {
        // Failed to query the Stack due to an openstack exception.
        // Convert to a generic VnfException
        me.addContext("UpdateVFModule");
        String error = "Update VFModule: Query " + vfModuleName + " in " + cloudOwner + "/" + cloudSiteId + "/" + tenantId + ": " + me;
        logger.error(LoggingAnchor.NINE, MessageEnum.RA_QUERY_VNF_ERR.toString(), vfModuleName, cloudOwner, cloudSiteId, tenantId, OPENSTACK, QUERY_STACK, ErrorCode.DataError.getValue(), "Exception - " + QUERY_STACK, me);
        logger.debug(error);
        throw new VnfException(me);
    }
    // TODO - do we need to check for the other status possibilities?
    if (heatStack == null || heatStack.getStatus() == HeatStatus.NOTFOUND) {
        // Not Found
        String error = "Update VF: Stack " + vfModuleName + " does not exist in " + cloudOwner + "/" + cloudSiteId + "/" + tenantId;
        logger.error(LoggingAnchor.NINE, MessageEnum.RA_VNF_NOT_EXIST.toString(), vfModuleName, cloudOwner, cloudSiteId, tenantId, OPENSTACK, QUERY_STACK, ErrorCode.DataError.getValue(), error);
        throw new VnfNotFound(cloudSiteId, cloudOwner, tenantId, vfModuleName);
    } else {
        logger.debug("Found Existing stack, status={}", heatStack.getStatus());
        // Populate the outputs from the existing stack.
        outputs.value = copyStringOutputs(heatStack.getOutputs());
        // Default rollback - no updates performed
        rollback.value = vfRollback;
    }
    // 1604 Cinder Volume support - handle a nestedStackId if sent (volumeGroupHeatStackId):
    StackInfo nestedHeatStack = null;
    if (nestedStackId != null) {
        try {
            logger.debug("Querying for nestedStackId = {}", nestedStackId);
            nestedHeatStack = msoHeatUtils.queryStack(cloudSiteId, cloudOwner, tenantId, nestedStackId);
        } catch (MsoException me) {
            // Failed to query the Stack due to an openstack exception.
            // Convert to a generic VnfException
            me.addContext("UpdateVFModule");
            String error = "Update VF: Attached heatStack ID Query " + nestedStackId + " in " + cloudOwner + "/" + cloudSiteId + "/" + tenantId + ": " + me;
            logger.error(LoggingAnchor.NINE, MessageEnum.RA_QUERY_VNF_ERR.toString(), vnfName, cloudOwner, cloudSiteId, tenantId, OPENSTACK, QUERY_STACK, ErrorCode.DataError.getValue(), "Exception - " + error, me);
            logger.debug("ERROR trying to query nested stack= {}", error);
            throw new VnfException(me);
        }
        if (nestedHeatStack == null || nestedHeatStack.getStatus() == HeatStatus.NOTFOUND) {
            String error = "Update VFModule: Attached volume heatStack ID DOES NOT EXIST " + nestedStackId + " in " + cloudOwner + "/" + cloudSiteId + "/" + tenantId + " " + USER_ERROR;
            logger.error(LoggingAnchor.TEN, MessageEnum.RA_QUERY_VNF_ERR.toString(), vnfName, cloudOwner, cloudSiteId, tenantId, error, OPENSTACK, QUERY_STACK, ErrorCode.DataError.getValue(), error);
            logger.debug(error);
            throw new VnfException(error, MsoExceptionCategory.USERDATA);
        } else {
            logger.debug("Found nested heat stack - copying values to inputs *later*");
            msoHeatUtils.copyStringOutputsToInputs(inputs, nestedHeatStack.getOutputs(), false);
        }
    }
    // handle a nestedBaseStackId if sent - this is the stack ID of the base.
    StackInfo nestedBaseHeatStack = null;
    if (nestedBaseStackId != null) {
        try {
            logger.debug("Querying for nestedBaseStackId = {}", nestedBaseStackId);
            nestedBaseHeatStack = msoHeatUtils.queryStack(cloudSiteId, cloudOwner, tenantId, nestedBaseStackId);
        } catch (MsoException me) {
            // Failed to query the Stack due to an openstack exception.
            // Convert to a generic VnfException
            me.addContext("UpdateVfModule");
            String error = "Update VFModule: Attached baseHeatStack ID Query " + nestedBaseStackId + " in " + cloudOwner + "/" + cloudSiteId + "/" + tenantId + ": " + me;
            logger.error(LoggingAnchor.NINE, MessageEnum.RA_QUERY_VNF_ERR.toString(), vfModuleName, cloudOwner, cloudSiteId, tenantId, OPENSTACK, QUERY_STACK, ErrorCode.DataError.getValue(), "Exception - " + error, me);
            logger.debug("ERROR trying to query nested base stack= {}", error);
            throw new VnfException(me);
        }
        if (nestedBaseHeatStack == null || nestedBaseHeatStack.getStatus() == HeatStatus.NOTFOUND) {
            String error = "Update VFModule: Attached base heatStack ID DOES NOT EXIST " + nestedBaseStackId + " in " + cloudOwner + "/" + cloudSiteId + "/" + tenantId + " " + USER_ERROR;
            logger.error(LoggingAnchor.TEN, MessageEnum.RA_QUERY_VNF_ERR.toString(), vfModuleName, cloudOwner, cloudSiteId, tenantId, error, OPENSTACK, QUERY_STACK, ErrorCode.DataError.getValue(), error);
            logger.debug(error);
            throw new VnfException(error, MsoExceptionCategory.USERDATA);
        } else {
            logger.debug("Found nested base heat stack - copying values to inputs *later*");
            msoHeatUtils.copyStringOutputsToInputs(inputs, nestedBaseHeatStack.getOutputs(), false);
        }
    }
    // Retrieve the VF definition
    VnfResource vnfResource = null;
    VfModule vf = null;
    VfModuleCustomization vfmc = null;
    if (useMCUuid) {
        vfmc = vfModuleCustomRepo.findFirstByModelCustomizationUUIDOrderByCreatedDesc(modelCustomizationUuid);
        vf = vfmc != null ? vfmc.getVfModule() : null;
        if (vf == null) {
            logger.debug("Unable to find a vfModule matching modelCustomizationUuid={}", mcu);
        }
    } else {
        logger.debug("1707 and later - MUST PROVIDE Model Customization UUID!");
    }
    if (vf == null) {
        String error = "Update VfModule: unable to find vfModule with modelCustomizationUuid=" + mcu;
        logger.error(LoggingAnchor.SIX, MessageEnum.RA_VNF_UNKNOWN_PARAM.toString(), "VF Module Type", vfModuleType, OPENSTACK, ErrorCode.DataError.getValue(), error);
        throw new VnfException(error, MsoExceptionCategory.USERDATA);
    }
    logger.debug("Got VF module definition from Catalog: {}", vf.toString());
    if (vf.getIsBase()) {
        isBaseRequest = true;
        logger.debug("This a BASE update request");
    } else {
        logger.debug("This is *not* a BASE VF update request");
        if (!isVolumeRequest && nestedBaseStackId == null) {
            logger.debug("DANGER WILL ROBINSON! This is unexpected - no nestedBaseStackId with this non-base request");
        }
    }
    // if we have a vf Module - then we have to query to get the VnfResource record.
    if (vf.getModelUUID() != null) {
        String vnfResourceModelUuid = vf.getModelUUID();
        vnfResource = vf.getVnfResources();
        if (vnfResource == null) {
            logger.debug("Unable to find vnfResource at ? will not error for now...", vnfResourceModelUuid);
        }
    }
    String minVersionVnf = null;
    String maxVersionVnf = null;
    if (vnfResource != null) {
        try {
            minVersionVnf = vnfResource.getAicVersionMin();
            maxVersionVnf = vnfResource.getAicVersionMax();
        } catch (Exception e) {
            logger.debug("Unable to pull min/max version for this VNF Resource entry", e);
            minVersionVnf = null;
            maxVersionVnf = null;
        }
        if (minVersionVnf != null && "".equals(minVersionVnf)) {
            minVersionVnf = null;
        }
        if (maxVersionVnf != null && "".equals(maxVersionVnf)) {
            maxVersionVnf = null;
        }
    }
    if (minVersionVnf != null && maxVersionVnf != null) {
        MavenLikeVersioning aicV = new MavenLikeVersioning();
        // double check
        if (this.cloudConfig != null) {
            Optional<CloudSite> cloudSiteOpt = this.cloudConfig.getCloudSite(cloudSiteId);
            if (cloudSiteOpt.isPresent()) {
                aicV.setVersion(cloudSiteOpt.get().getCloudVersion());
                boolean moreThanMin = true;
                boolean equalToMin = true;
                boolean moreThanMax = true;
                boolean equalToMax = true;
                boolean doNotTest = false;
                try {
                    moreThanMin = aicV.isMoreRecentThan(minVersionVnf);
                    equalToMin = aicV.isTheSameVersion(minVersionVnf);
                    moreThanMax = aicV.isMoreRecentThan(maxVersionVnf);
                    equalToMax = aicV.isTheSameVersion(maxVersionVnf);
                } catch (Exception e) {
                    logger.debug("An exception occured while trying to test AIC Version {} - will default to not check", e.getMessage(), e);
                    doNotTest = true;
                }
                if (!doNotTest) {
                    if (// aic >= min
                    (moreThanMin || equalToMin) && ((equalToMax) || !(moreThanMax))) {
                        // aic <= max
                        logger.debug("VNF Resource " + vnfResource.getModelName() + " " + VERSION_MIN + " =" + minVersionVnf + " " + VERSION_MAX + " :" + maxVersionVnf + " supported on Cloud: " + cloudSiteId + " with AIC_Version:" + aicV);
                    } else {
                        // ERROR
                        String error = "VNF Resource type: " + vnfResource.getModelName() + " " + VERSION_MIN + " =" + minVersionVnf + " " + VERSION_MAX + " :" + maxVersionVnf + " NOT supported on Cloud: " + cloudSiteId + " with AIC_Version:" + aicV;
                        logger.error(LoggingAnchor.FIVE, MessageEnum.RA_CONFIG_EXC.toString(), error, OPENSTACK, ErrorCode.BusinessProcessError.getValue(), "Exception - setVersion");
                        logger.debug(error);
                        throw new VnfException(error, MsoExceptionCategory.USERDATA);
                    }
                } else {
                    logger.debug("bypassing testing AIC version...");
                }
            }
        // let this error out downstream to avoid introducing uncertainty at this stage
        } else {
            logger.debug("cloudConfig is NULL - cannot check cloud site version");
        }
    } else {
        logger.debug("AIC Version not set in VNF_Resource - do not error for now - not checked.");
    }
    // End Version check 1607
    HeatTemplate heatTemplate = null;
    HeatEnvironment heatEnvironment = null;
    if (isVolumeRequest) {
        heatTemplate = vf.getVolumeHeatTemplate();
        heatEnvironment = vfmc.getVolumeHeatEnv();
    } else {
        heatTemplate = vf.getModuleHeatTemplate();
        heatEnvironment = vfmc.getHeatEnvironment();
    }
    if (heatTemplate == null) {
        String error = "UpdateVF: No Heat Template ID defined in catalog database for " + vfModuleType + ", modelCustomizationUuid=" + mcu + ", vfModuleUuid=" + vf.getModelUUID() + ", reqType=" + requestTypeString;
        logger.error(LoggingAnchor.SIX, MessageEnum.RA_VNF_UNKNOWN_PARAM.toString(), "Heat Template ID", vfModuleType, OPENSTACK, ErrorCode.DataError.getValue(), error);
        throw new VnfException(error, MsoExceptionCategory.INTERNAL);
    } else {
        logger.debug("Got HEAT Template from DB: {}", heatTemplate.getHeatTemplate());
    }
    if (heatEnvironment == null) {
        String error = "Update VNF: undefined Heat Environment. VF=" + vfModuleType + ", modelCustomizationUuid=" + mcu + ", vfModuleUuid=" + vf.getModelUUID() + ", reqType=" + requestTypeString;
        logger.error(LoggingAnchor.FIVE, MessageEnum.RA_VNF_UNKNOWN_PARAM.toString(), "Heat Environment ID", OPENSTACK, ErrorCode.DataError.getValue(), error);
        throw new VnfException(error, MsoExceptionCategory.INTERNAL);
    } else {
        logger.debug("Got Heat Environment from DB: {}", heatEnvironment.getEnvironment());
    }
    logger.debug("In MsoVnfAdapterImpl, about to call db.getNestedTemplates avec templateId={}", heatTemplate.getArtifactUuid());
    List<HeatTemplate> nestedTemplates = heatTemplate.getChildTemplates();
    Map<String, Object> nestedTemplatesChecked = new HashMap<>();
    if (nestedTemplates != null && !nestedTemplates.isEmpty()) {
        // for debugging print them out
        logger.debug("Contents of nestedTemplates - to be added to files: on stack:");
        for (HeatTemplate entry : nestedTemplates) {
            nestedTemplatesChecked.put(entry.getTemplateName(), entry.getTemplateBody());
            logger.debug(entry.getTemplateName() + " -> " + entry.getTemplateBody());
        }
    } else {
        logger.debug("No nested templates found - nothing to do here");
        nestedTemplatesChecked = null;
    }
    // Also add the files: for any get_files associated with this VfModule
    // *if* there are any
    logger.debug("In MsoVnfAdapterImpl.updateVfModule, about to call db.getHeatFiles avec vfModuleId={}", vf.getModelUUID());
    List<HeatFiles> heatFiles = null;
    Map<String, Object> heatFilesObjects = new HashMap<>();
    // Add ability to turn on adding get_files with volume requests (by property).
    boolean addGetFilesOnVolumeReq = false;
    try {
        String propertyString = this.environment.getProperty(MsoVnfAdapterImpl.ADD_GET_FILES_ON_VOLUME_REQ);
        if ("true".equalsIgnoreCase(propertyString) || "y".equalsIgnoreCase(propertyString)) {
            addGetFilesOnVolumeReq = true;
            logger.debug("AddGetFilesOnVolumeReq - setting to true! {}", propertyString);
        }
    } catch (Exception e) {
        logger.debug("An error occured trying to get property {} - default to false", MsoVnfAdapterImpl.ADD_GET_FILES_ON_VOLUME_REQ, e);
    }
    if (!isVolumeRequest || addGetFilesOnVolumeReq) {
        logger.debug("In MsoVnfAdapterImpl updateVfModule, about to call db.getHeatFilesForVfModule avec " + "vfModuleId={}", vf.getModelUUID());
        heatFiles = vf.getHeatFiles();
        if (heatFiles != null && !heatFiles.isEmpty()) {
            // add these to stack - to be done in createStack
            // here, we will map them to Map<String, Object> from Map<String, HeatFiles>
            // this will match the nested templates format
            logger.debug("Contents of heatFiles - to be added to files: on stack:");
            for (HeatFiles heatfile : heatFiles) {
                logger.debug(heatfile.getFileName() + " -> " + heatfile.getFileBody());
                heatFilesObjects.put(heatfile.getFileName(), heatfile.getFileBody());
            }
        } else {
            logger.debug("No heat files found -nothing to do here");
            heatFilesObjects = null;
        }
    }
    // Check that required parameters have been supplied
    String missingParams = null;
    List<String> paramList = new ArrayList<>();
    // New for 1510 - consult the PARAM_ALIAS field to see if we've been
    // supplied an alias. Only check if we don't find it initially.
    // Also new in 1510 - don't flag missing parameters if there's an environment - because they might be there.
    // And also new - add parameter to turn off checking all together if we find we're blocking orders we
    // shouldn't
    boolean checkRequiredParameters = true;
    try {
        String propertyString = this.environment.getProperty(MsoVnfAdapterImpl.CHECK_REQD_PARAMS);
        if ("false".equalsIgnoreCase(propertyString) || "n".equalsIgnoreCase(propertyString)) {
            checkRequiredParameters = false;
            logger.debug("CheckRequiredParameters is FALSE. Will still check but then skip blocking...", MsoVnfAdapterImpl.CHECK_REQD_PARAMS);
        }
    } catch (Exception e) {
        // No problem - default is true
        logger.debug("An exception occured trying to get property {}", MsoVnfAdapterImpl.CHECK_REQD_PARAMS, e);
    }
    // 1604 - Add enhanced environment & parameter checking
    // Part 1: parse envt entries to see if reqd parameter is there (before used a simple grep
    // Part 2: only submit to openstack the parameters in the envt that are in the heat template
    // Note this also removes any comments
    MsoHeatEnvironmentEntry mhee = null;
    if (heatEnvironment != null && heatEnvironment.getEnvironment().toLowerCase().contains("parameters:")) {
        logger.debug("Enhanced environment checking enabled - 1604");
        StringBuilder sb = new StringBuilder(heatEnvironment.getEnvironment());
        mhee = new MsoHeatEnvironmentEntry(sb);
        StringBuilder sb2 = new StringBuilder("\nHeat Template Parameters:\n");
        for (HeatTemplateParam parm : heatTemplate.getParameters()) {
            sb2.append("\t" + parm.getParamName() + ", required=" + parm.isRequired());
        }
        if (!mhee.isValid()) {
            sb2.append("Environment says it's not valid! " + mhee.getErrorString());
        } else {
            sb2.append("\nEnvironment:");
            sb2.append(mhee.toFullString());
        }
        logger.debug(sb2.toString());
    } else {
        logger.debug("NO ENVIRONMENT for this entry");
    }
    // New for 1607 - support params of json type
    HashMap<String, JsonNode> jsonParams = new HashMap<>();
    boolean hasJson = false;
    for (HeatTemplateParam parm : heatTemplate.getParameters()) {
        logger.debug("Parameter:'" + parm.getParamName() + "', isRequired=" + parm.isRequired() + ", alias=" + parm.getParamAlias());
        // handle json
        String parameterType = parm.getParamType();
        if (parameterType == null || "".equals(parameterType.trim())) {
            parameterType = "String";
        }
        JsonNode jsonNode = null;
        if ("json".equalsIgnoreCase(parameterType) && inputs != null) {
            if (inputs.containsKey(parm.getParamName())) {
                hasJson = true;
                String jsonString = null;
                try {
                    jsonString = JSON_MAPPER.writeValueAsString(inputs.get(parm.getParamName()));
                    jsonNode = JSON_MAPPER.readTree(jsonString);
                } catch (JsonParseException jpe) {
                    // TODO - what to do here?
                    // for now - send the error to debug
                    logger.debug("Json Error Converting {} - {}", parm.getParamName(), jpe.getMessage(), jpe);
                    hasJson = false;
                    jsonNode = null;
                } catch (Exception e) {
                    // or here?
                    logger.debug("Json Error Converting {} {}", parm.getParamName(), e.getMessage(), e);
                    hasJson = false;
                    jsonNode = null;
                }
                if (jsonNode != null) {
                    jsonParams.put(parm.getParamName(), jsonNode);
                }
            } else if (inputs.containsKey(parm.getParamAlias())) {
                hasJson = true;
                String jsonString = null;
                try {
                    jsonString = (String) inputs.get(parm.getParamAlias());
                    jsonNode = JSON_MAPPER.readTree(jsonString);
                } catch (JsonParseException jpe) {
                    // TODO - what to do here?
                    // for now - send the error to debug, but just leave it as a String
                    String errorMessage = jpe.getMessage();
                    logger.debug("Json Error Converting " + parm.getParamName() + " - " + errorMessage, jpe);
                    hasJson = false;
                    jsonNode = null;
                } catch (Exception e) {
                    // or here?
                    logger.debug("Json Error Converting " + parm.getParamName() + " " + e.getMessage(), e);
                    hasJson = false;
                    jsonNode = null;
                }
                if (jsonNode != null) {
                    // Notice here - we add it to the jsonParams hashMap with the actual name -
                    // then manipulate the inputs so when we check for aliases below - it will not
                    // get flagged.
                    jsonParams.put(parm.getParamName(), jsonNode);
                    inputs.remove(parm.getParamAlias());
                    inputs.put(parm.getParamName(), jsonString);
                }
            }
        // TODO add a check for the parameter in the env file
        }
        if (parm.isRequired() && (inputs == null || !inputs.containsKey(parm.getParamName()))) {
            if (inputs.containsKey(parm.getParamAlias())) {
                // They've submitted using an alias name. Remove that from inputs, and add back using real name.
                String realParamName = parm.getParamName();
                String alias = parm.getParamAlias();
                Object value = inputs.get(alias);
                logger.debug("*Found an Alias: paramName=" + realParamName + ",alias=" + alias + ",value=" + value);
                inputs.remove(alias);
                inputs.put(realParamName, value);
                logger.debug("{} entry removed from inputs, added back using {}", alias, realParamName);
            } else // enhanced - check if it's in the Environment (note: that method
            if (mhee != null && mhee.containsParameter(parm.getParamName())) {
                logger.debug("Required parameter {} appears to be in environment - do not count as missing", parm.getParamName());
            } else {
                logger.debug("adding to missing parameters list: {}", parm.getParamName());
                if (missingParams == null) {
                    missingParams = parm.getParamName();
                } else {
                    missingParams += "," + parm.getParamName();
                }
            }
        }
        paramList.add(parm.getParamName());
    }
    if (missingParams != null) {
        // Problem - missing one or more required parameters
        if (checkRequiredParameters) {
            String error = "Update VNF: Missing Required inputs: " + missingParams;
            logger.error(LoggingAnchor.FIVE, MessageEnum.RA_MISSING_PARAM.toString(), missingParams, OPENSTACK, ErrorCode.DataError.getValue(), error);
            throw new VnfException(error, MsoExceptionCategory.USERDATA);
        } else {
            logger.debug("found missing parameters - but checkRequiredParameters is false - will not block");
        }
    }
    // Just submit the envt entry as received from the database
    String newEnvironmentString = null;
    if (mhee != null) {
        newEnvironmentString = mhee.getRawEntry().toString();
    }
    // Remove any extraneous parameters (don't throw an error)
    if (inputs != null) {
        List<String> extraParams = new ArrayList<>();
        extraParams.addAll(inputs.keySet());
        // This is not a valid parameter for this template
        extraParams.removeAll(paramList);
        if (!extraParams.isEmpty()) {
            logger.warn(LoggingAnchor.SIX, MessageEnum.RA_VNF_EXTRA_PARAM.toString(), vnfType, extraParams.toString(), OPENSTACK, ErrorCode.DataError.getValue(), "Extra params");
            inputs.keySet().removeAll(extraParams);
        }
    }
    Map<String, Object> goldenInputs = copyStringInputs(inputs);
    // 1607 - when we get here - we have clean inputs. Create inputsTwo in case we have json
    Map<String, Object> inputsTwo = null;
    if (hasJson && jsonParams.size() > 0) {
        inputsTwo = new HashMap<>();
        for (Map.Entry<String, Object> entry : inputs.entrySet()) {
            String keyParamName = entry.getKey();
            Object value = entry.getValue();
            if (jsonParams.containsKey(keyParamName)) {
                inputsTwo.put(keyParamName, jsonParams.get(keyParamName));
            } else {
                inputsTwo.put(keyParamName, value);
            }
        }
        goldenInputs = inputsTwo;
    }
    // "Fix" the template if it has CR/LF (getting this from Oracle)
    String template = heatTemplate.getHeatTemplate();
    template = template.replaceAll("\r\n", "\n");
    // because we already checked for those.
    try {
        heatStack = heatU.updateStack(cloudSiteId, cloudOwner, tenantId, vfModuleName, template, goldenInputs, true, heatTemplate.getTimeoutMinutes(), newEnvironmentString, // heatEnvironmentString,
        nestedTemplatesChecked, heatFilesObjects);
    } catch (MsoException me) {
        me.addContext("UpdateVFModule");
        String error = "Update VFModule " + vfModuleType + " in " + cloudOwner + "/" + cloudSiteId + "/" + tenantId + ": " + me;
        logger.error(LoggingAnchor.EIGHT, MessageEnum.RA_UPDATE_VNF_ERR.toString(), vfModuleType, cloudOwner, cloudSiteId, tenantId, OPENSTACK, ErrorCode.DataError.getValue(), "Exception - " + error, me);
        throw new VnfException(me);
    }
    // Reach this point if updateStack is successful.
    // Populate remaining rollback info and response parameters.
    vfRollback.setVnfId(heatStack.getCanonicalName());
    vfRollback.setVnfCreated(true);
    outputs.value = copyStringOutputs(heatStack.getOutputs());
    rollback.value = vfRollback;
}
Also used : HashMap(java.util.HashMap) HeatEnvironment(org.onap.so.db.catalog.beans.HeatEnvironment) ArrayList(java.util.ArrayList) VnfNotFound(org.onap.so.adapters.vnf.exceptions.VnfNotFound) JsonNode(com.fasterxml.jackson.databind.JsonNode) JsonParseException(com.fasterxml.jackson.core.JsonParseException) VfModule(org.onap.so.db.catalog.beans.VfModule) VnfResource(org.onap.so.db.catalog.beans.VnfResource) VnfRollback(org.onap.so.openstack.beans.VnfRollback) VnfException(org.onap.so.adapters.vnf.exceptions.VnfException) HeatFiles(org.onap.so.db.catalog.beans.HeatFiles) StackInfo(org.onap.so.openstack.beans.StackInfo) MavenLikeVersioning(org.onap.so.db.catalog.utils.MavenLikeVersioning) MsoException(org.onap.so.openstack.exceptions.MsoException) MsoHeatNotFoundException(org.onap.so.openstack.exceptions.MsoHeatNotFoundException) JsonParseException(com.fasterxml.jackson.core.JsonParseException) VnfException(org.onap.so.adapters.vnf.exceptions.VnfException) MsoException(org.onap.so.openstack.exceptions.MsoException) MsoHeatEnvironmentEntry(org.onap.so.openstack.utils.MsoHeatEnvironmentEntry) HeatTemplate(org.onap.so.db.catalog.beans.HeatTemplate) CloudSite(org.onap.so.db.catalog.beans.CloudSite) VfModuleCustomization(org.onap.so.db.catalog.beans.VfModuleCustomization) HashMap(java.util.HashMap) Map(java.util.Map) HeatTemplateParam(org.onap.so.db.catalog.beans.HeatTemplateParam)

Aggregations

VfModule (org.onap.so.db.catalog.beans.VfModule)32 VfModuleCustomization (org.onap.so.db.catalog.beans.VfModuleCustomization)20 Test (org.junit.Test)17 ArrayList (java.util.ArrayList)11 HeatTemplate (org.onap.so.db.catalog.beans.HeatTemplate)10 VnfResource (org.onap.so.db.catalog.beans.VnfResource)10 HeatEnvironment (org.onap.so.db.catalog.beans.HeatEnvironment)9 HashMap (java.util.HashMap)8 VnfResourceCustomization (org.onap.so.db.catalog.beans.VnfResourceCustomization)7 CvnfcCustomization (org.onap.so.db.catalog.beans.CvnfcCustomization)6 HeatTemplateParam (org.onap.so.db.catalog.beans.HeatTemplateParam)6 VnfcCustomization (org.onap.so.db.catalog.beans.VnfcCustomization)6 Transactional (org.springframework.transaction.annotation.Transactional)6 CatalogDbAdapterBaseTest (org.onap.so.adapters.catalogdb.CatalogDbAdapterBaseTest)5 HashSet (java.util.HashSet)4 Metadata (org.onap.sdc.toscaparser.api.elements.Metadata)4 HeatFiles (org.onap.so.db.catalog.beans.HeatFiles)4 JsonParseException (com.fasterxml.jackson.core.JsonParseException)3 Map (java.util.Map)3 Set (java.util.Set)3