+ private Either<Map<String, String[]>, ToscaError> buildAddSubstitutionMappingsCapabilities(Map<String, Component> componentsCache, Component component, Map<String, List<CapabilityDefinition>> capabilities) {
+
+ Map<String, String[]> toscaRequirements = new HashMap<>();
+ Either<Map<String, String[]>, ToscaError> result = null;
+ for (Map.Entry<String, List<CapabilityDefinition>> entry : capabilities.entrySet()) {
+ Optional<CapabilityDefinition> failedToAddRequirement = entry.getValue()
+ .stream()
+ .filter(c->!addEntry(componentsCache, toscaRequirements, component, c.getName(), c.getParentName(), c.getPath()))
+ .findAny();
+ if(failedToAddRequirement.isPresent()){
+ logger.error("Failed to convert capalility {} for substitution mappings section of a tosca template of the component {}. ",
+ failedToAddRequirement.get().getName(), component.getName());
+ result = Either.right(ToscaError.NODE_TYPE_CAPABILITY_ERROR);
+ }
+ logger.debug("Finish convert capalilities for the component {}. ", component.getName());
+ }
+ if(result == null){
+ result = Either.left(toscaRequirements);
+ }
+ return result;
+ }
+
+ private boolean addEntry(Map<String,Component> componentsCache, Map<String, String[]> capReqMap, Component component, String name, String parentName, List<String> path){
+
+ SubstituitionEntry entry = new SubstituitionEntry(name, parentName, "");
+
+ if(shouldBuildSubstitutionName(component, path) && !buildSubstitutedNamePerInstance(componentsCache, component, name, path, entry)){
+ return false;
+ }
+ logger.debug("The requirement/capability {} belongs to the component {} ", entry.getFullName(), component.getUniqueId());
+ if (entry.getSourceName() != null) {
+ addEntry(capReqMap, component, path, entry);
+ }
+ logger.debug("Finish convert the requirement/capability {} for the component {}. ", entry.getFullName(), component.getName());
+ return true;
+
+ }
+
+ private boolean shouldBuildSubstitutionName(Component component, List<String> path) {
+ return !ToscaUtils.isComplexVfc(component) && CollectionUtils.isNotEmpty(path) && path.iterator().hasNext();
+ }
+
+ private boolean buildSubstitutedNamePerInstance(Map<String, Component> componentsCache, Component component, String name, List<String> path, SubstituitionEntry entry) {
+ Optional<ComponentInstance> ci = component.getComponentInstances().stream().filter(c->c.getUniqueId().equals(Iterables.getLast(path))).findFirst();
+ if(ci.isPresent()){
+ Either<String, Boolean> buildSubstitutedName = buildSubstitutedName(componentsCache, name, path, ci.get());
+ if(buildSubstitutedName.isRight()){
+ return false;
+ }
+ entry.setFullName(ci.get().getNormalizedName() + '.' + buildSubstitutedName.left().value());
+ entry.setSourceName(buildSubstitutedName.left().value());
+ } else {
+ return false;
+ }
+ return true;
+ }
+
+ private void addEntry(Map<String, String[]> toscaRequirements, Component component, List<String> capPath, SubstituitionEntry entry) {
+ Optional<ComponentInstance> findFirst = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(Iterables.getLast(capPath))).findFirst();
+ if (findFirst.isPresent()) {
+ entry.setOwner(findFirst.get().getNormalizedName());
+ }
+ toscaRequirements.put(entry.getFullName(), new String[] { entry.getOwner(), entry.getSourceName() });
+ }
+
+ private Either<String, Boolean> buildSubstitutedName(Map<String, Component> componentsCache, String name, List<String> path, ComponentInstance instance) {
+
+ Either<String, Boolean> result = null;
+ Either<Component, Boolean> getOriginRes = getOriginComponent(componentsCache, instance);
+ if(getOriginRes.isRight()){
+ logger.debug("Failed to build substituted name for the capability/requirement {}. Failed to get an origin component with uniqueId {}", name, instance.getComponentUid());
+ result = Either.right(false);
+ }
+ if(result == null){
+ result = buildSubstitutedName(componentsCache, getOriginRes.left().value(), Lists.newArrayList(path.subList(0, path.size()-1)), name);
+ }
+ return result;
+ }
+
+ private String getRequirementPath(Component component, RequirementDefinition r) {
+
+ // Evg : for the last in path take real instance name and not "decrypt" unique id. ( instance name can be change and not equal to id..)
+ // dirty quick fix. must be changed as capability redesign
+ List<String> capPath = r.getPath();
+ String lastInPath = capPath.get(capPath.size() - 1);
+ Optional<ComponentInstance> findFirst = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(lastInPath)).findFirst();
+ if (findFirst.isPresent()) {
+ String lastInPathName = findFirst.get().getNormalizedName();
+
+ if (capPath.size() > 1) {
+ List<String> pathArray = Lists.reverse(capPath.stream().map(path -> ValidationUtils.normalizeComponentInstanceName(getSubPathByLastDelimiterAppearance(path))).collect(Collectors.toList()));
+
+ return new StringBuilder().append(lastInPathName).append(PATH_DELIMITER).append(String.join(PATH_DELIMITER, pathArray.subList(1, pathArray.size() ))).append(PATH_DELIMITER).append(r.getName()).toString();
+ }else{
+ return new StringBuilder().append(lastInPathName).append(PATH_DELIMITER).append(r.getName()).toString();
+ }
+ }
+ return "";
+ }
+