private CSARDependency getDependencyByName(String dependencyName) { for (CSARDependency d : dependencies) { if (d.getName().equals(dependencyName)) { return d; } } return null; }
private CSARDependency getDependencyWithName(String archiveName) { Iterator<Map.Entry<CSARDependency, Set<String>>> dependencyIterator = dependenciesMap.entrySet().iterator(); while (dependencyIterator.hasNext()) { Map.Entry<CSARDependency, Set<String>> entry = dependencyIterator.next(); if (entry.getKey().getName().equals(archiveName)) { return entry.getKey(); } } return null; }
private boolean isFrom(AbstractToscaType element, CSARDependency dependency) { return Objects.equals(element.getArchiveName(), dependency.getName()) /* && Objects.equals(element.getArchiveVersion(), dependency.getVersion()) */; }
public static String generateImports(Set<CSARDependency> dependencies) { StringBuilder sb = new StringBuilder(); safe(dependencies).forEach(d -> { if (sb.length() != 0) { sb.append("\n"); } sb.append(" - "); sb.append(d.getName()); sb.append(":"); sb.append(d.getVersion()); }); return sb.toString(); } }
private boolean hasDependency(CSARDependency dependency) { for (CSARDependency existDependency : this.dependencies) { if (existDependency.getName().equals(dependency.getName())) { return existDependency.getVersion().equals(dependency.getVersion()) && Objects.equals(existDependency.getHash(), dependency.getHash()); } } return false; }
@SneakyThrows private boolean isTopologyUsingArchive(String archiveName, String archiveVersion, String topologyId) { for (CSARDependency dependency : contextCache.get(topologyId).getToscaContext().getDependencies()) { if (archiveName.equals(dependency.getName()) && archiveVersion.equals(dependency.getVersion())) { return true; } } return false; }
/** * Compute a list of transitive dependency conflicts from the Context. * * @param context the EditionContext of the Topology being built. * @return a list of dependency conflicts. */ private List<DependencyConflictDTO> getDependencyConflictDTOs(EditionContext context) { // Generate a map with all transitive dependency conflict for each dependency in the context. final Set<CSARDependency> dependencies = context.getToscaContext().getDependencies(); Map<CSARDependency, Set<CSARDependency>> dependencyConflictMap = new HashMap<>(); dependencies.forEach(source -> { final Set<CSARDependency> transitives = Optional.ofNullable(ToscaContext.get().getArchive(source.getName(), source.getVersion()).getDependencies()) .orElse(Collections.emptySet()).stream().filter(o -> !dependencies.contains(o)).collect(Collectors.toSet()); if (!transitives.isEmpty()) { dependencyConflictMap.put(source, transitives); } }); final ArrayList<DependencyConflictDTO> dependencyConflicts = new ArrayList<>(); dependencyConflictMap.forEach((source, conflicts) -> conflicts.forEach(conflict -> { String actualVersion = dependencies.stream().filter(d -> d.getName().equals(conflict.getName())).findFirst().map(CSARDependency::getVersion) .orElse(""); dependencyConflicts.add(new DependencyConflictDTO(source.getName(), conflict.getName() + ":" + conflict.getVersion(), actualVersion)); })); return dependencyConflicts; }
@SneakyThrows private ParsingResult<ArchiveRoot> parse(CSARDependency dependency) { String archiveFileName = dependency.getName().concat("-").concat(dependency.getVersion()).concat(".csar"); Path archivePath = localRepositoryPath.resolve(dependency.getName()).resolve(dependency.getVersion()).resolve(archiveFileName); ParsingContextExecution.Context previousContext = ParsingContextExecution.get(); try { ParsingContextExecution.init(); return toscaArchiveParser.parse(archivePath); } finally { ParsingContextExecution.destroy(); if (previousContext != null) { ParsingContextExecution.set(previousContext); } } } }
CSARDependency existingDependency = getDependencyByName(removedDependency.getName()); if (existingDependency != null) { dependencies.remove(existingDependency); if (entry.getValue().getArchiveName().equals(existingDependency.getName()) && entry.getValue().getArchiveVersion().equals(existingDependency.getVersion())) { toRemove.add(entry.getKey()); Csar csar = new Csar(removedDependency.getName(), removedDependency.getVersion()); archivesMap.remove(csar.getId()); log.debug("Removed dependency {} from the TOSCA context.", removedDependency);
/** * Check dependencies for version conflicts, and add a warning if one is found. * * @param dependency The dependency to verify. * @param dependencies The set of dependencies it belongs to. * @return <code>true</code> if the given dependency is present in the Set in a newer version. */ private boolean dependencyConflictsWithLatest(CSARDependency dependency, Set<CSARDependency> dependencies) { return dependencies.stream().anyMatch(csarDependency -> { if (Objects.equals(dependency.getName(), csarDependency.getName()) && VersionUtil.compare(dependency.getVersion(), csarDependency.getVersion()) < 0) { ParsingContextExecution.getParsingErrors() .add(new ParsingError(ParsingErrorLevel.WARNING, ErrorCode.DEPENDENCY_VERSION_CONFLICT, AlienUtils.prefixWith(":", dependency.getVersion(), dependency.getName()), null, AlienUtils.prefixWith(":", csarDependency.getVersion(), csarDependency.getName()), null, null)); return true; } else { return false; } }); }
/** * Check for dependency conflicts between a transitive and a set of direct dependencies. * * @param transitiveDependency The dependency to check * @param dependencies The set of dependency to validate it against - assuming those are direct dependencies. * @return <code>true</code> if the given dependency is present in the Set in a different version. */ private boolean dependencyConflictsWithDirect(CSARDependency transitiveDependency, Set<CSARDependency> dependencies) { return dependencies.stream() .filter(directDep -> Objects.equals(directDep.getName(), transitiveDependency.getName()) && !Objects.equals(directDep.getVersion(), transitiveDependency.getVersion())) .findFirst() // As we resolved direct dependencies conflicts earlier, there can only be one direct dependency that conflicts .map(conflictingDependency -> { // Log the dependency conflict as a warning. ParsingContextExecution.getParsingErrors() .add(new ParsingError(ParsingErrorLevel.WARNING, ErrorCode.TRANSITIVE_DEPENDENCY_VERSION_CONFLICT, AlienUtils.prefixWith(":", conflictingDependency.getVersion(), conflictingDependency.getName()), null, AlienUtils.prefixWith(":", transitiveDependency.getVersion(), transitiveDependency.getName()), null, conflictingDependency.getVersion())); // Resolve conflict by using the direct dependency version - delete the transitive dependency return true; }).orElse(false); }
/** * Check that the topology can be associated to a release version, actually : check that the topology doesn't reference SNAPSHOT * dependencies. * * @throws @{@link ReleaseReferencingSnapshotException} if the topology references SNAPSHOT dependencies * version. */ private void checkTopologyReleasable(Topology topology) { if (topology.getDependencies() != null) { for (CSARDependency dep : topology.getDependencies()) { // we allow SNAPSHOTS only for tosca-normative-types (we don't expect to have a release soon !) if (VersionUtil.isSnapshot(dep.getVersion()) && !dep.getName().equals("tosca-normative-types")) { throw new ReleaseReferencingSnapshotException(String.format("Can not release: %s dependency is a snapshot", dep.getName())); } } } }
/** * Update the ToscaContext to take in account the new dependencies. * * @param newDependencies The new list of dependencies for this context. */ public void resetDependencies(Set<CSARDependency> newDependencies) { Map<String, CSARDependency> dependenciesByName = Maps.newHashMap(); for (CSARDependency dependency : dependencies) { dependenciesByName.put(dependency.getName(), dependency); } // now add/ update /remove dependencies to match the new dependencies. for (CSARDependency dependency : newDependencies) { CSARDependency previous = dependenciesByName.remove(dependency.getName()); if (previous == null) { addDependency(dependency); } else if (!previous.getVersion().equals(dependency.getVersion())) { updateDependency(dependency); } } for (CSARDependency dependency : dependenciesByName.values()) { removeDependency(dependency); } }
/** * Add a dependency * * @param dependency * @param type * @return True if the dependecy has been upgraded into the topology. False if not. */ private boolean addNewDependency(CSARDependency dependency, String type) { CSARDependency currentDependency = getDependencyWithName(dependency.getName()); // New dependency that never exists before if (currentDependency == null) { dependenciesMap.put(dependency, Sets.newHashSet(type)); return false; } // Dependency that already existed, // The new version is more recent, we will override with new version with warning if (VersionUtil.compare(dependency.getVersion(), currentDependency.getVersion()) > 0) { Set<String> typesLoadedByConflictingArchive = dependenciesMap.remove(currentDependency); typesLoadedByConflictingArchive.add(type); dependenciesMap.put(dependency, typesLoadedByConflictingArchive); log.warn("Version conflicting for archive [" + dependency.getName() + "] override current version [" + currentDependency.getVersion() + "] with [" + dependency.getVersion() + "]"); return true; } log.warn("Version conflicting for archive [" + dependency.getName() + "] do not override and use current version [" + currentDependency.getVersion() + "] ignore old version [" + dependency.getVersion() + "]"); dependenciesMap.get(currentDependency).add(type); return false; }
/** * Add a dependency to the current context. * * @param dependency The dependency to add. */ public void addDependency(CSARDependency dependency) { log.debug("Add dependency to context", dependency); if (dependency.getHash() == null) { // we should try to get the hash from the repository Csar csar = getArchive(dependency.getName(), dependency.getVersion()); dependency.setHash(csar.getHash()); } dependencies.add(dependency); }
/** * Update a dependency according to what is currently in the repository * * @param initialDependency * @return */ private CSARDependency getUpdatedDependencyIfNeeded(CSARDependency initialDependency) { CSARDependency updatedDependency = null; Csar csar = csarService.getOrFail(initialDependency.getName(), initialDependency.getVersion()); if ((StringUtils.isNotBlank(initialDependency.getHash()) || StringUtils.isNotBlank(csar.getHash())) && !Objects.equals(initialDependency.getHash(), csar.getHash())) { updatedDependency = new CSARDependency(csar.getName(), csar.getVersion(), csar.getHash()); } return updatedDependency; }
public void updateDependencies(EditionContext context, CSARDependency newDependency) { final Set<CSARDependency> oldDependencies = new HashSet<>(context.getTopology().getDependencies()); final Set<CSARDependency> newDependencies = csarDependencyLoader.getDependencies(newDependency.getName(), newDependency.getVersion()); newDependencies.add(newDependency); // Update context with the new dependencies. newDependencies.forEach(csarDependency -> context.getToscaContext().updateDependency(csarDependency)); // Validate that the dependency change does not induce missing types. try { this.checkForMissingTypes(context.getTopology()); } catch (NotFoundException e) { // Revert changes made to the Context then throw. context.getToscaContext().resetDependencies(oldDependencies); context.getTopology().setDependencies(oldDependencies); throw new VersionConflictException("Changing the dependency [" + newDependency.getName() + "] to version [" + newDependency.getVersion() + "] induces missing types in the topology. Not found : [" + e.getMessage() + "].", e); } // Perform the dependency update on the topology. context.getTopology().setDependencies(new HashSet<>(context.getToscaContext().getDependencies())); }
@Override public CSARDependency parse(Node node, ParsingContextExecution context) { CSARDependency dependency = laxImportParser.parse(node, context); if (dependency == null) { return null; } String valueAsString = dependency.getName() + ":" + dependency.getVersion(); String currentArchiveVersion = context.<ArchiveRoot> getRootObj().getArchive().getVersion(); Csar csar = ToscaContext.get().getArchive(dependency.getName(), dependency.getVersion()); log.debug("Import {} {} {}", dependency.getName(), dependency.getVersion(), csar); if (csar == null) { // error is not a blocker, as long as no type is missing we just mark it as a warning. context.getParsingErrors().add(new ParsingError(ParsingErrorLevel.WARNING, ErrorCode.MISSING_DEPENDENCY, "Import definition is not valid", node.getStartMark(), "Specified dependency is not found in Alien 4 Cloud repository.", node.getEndMark(), valueAsString)); return null; } else { if (!VersionUtil.isSnapshot(currentArchiveVersion) && VersionUtil.isSnapshot(dependency.getVersion())) { // the current archive is a released version but depends on a snapshot version context.getParsingErrors().add(new ParsingError(ParsingErrorLevel.ERROR, ErrorCode.SNAPSHOT_DEPENDENCY, "Import definition is not valid", node.getStartMark(), "A released archive cannot depends on snapshots archives.", node.getEndMark(), valueAsString)); } dependency.setHash(csar.getHash()); ToscaContext.get().addDependency(dependency); return dependency; } }
/** * Build an elasticsearch query to get data tosca elements based on a set of dependencies. * * @param dependencies The set of dependencies. * @param keyValueFilters List of key1, value1, key2, value2 to add term filters to the query for each dependency. * @return */ private BoolQueryBuilder getDependencyQuery(Set<CSARDependency> dependencies, String... keyValueFilters) { BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); for (CSARDependency dependency : dependencies) { BoolQueryBuilder dependencyQuery = QueryBuilders.boolQuery(); dependencyQuery.must(QueryBuilders.termQuery("archiveName", dependency.getName())) .must(QueryBuilders.termQuery("archiveVersion", dependency.getVersion())); if (keyValueFilters != null) { for (int i = 0; i < keyValueFilters.length; i += 2) { dependencyQuery.must(QueryBuilders.termQuery(keyValueFilters[i], keyValueFilters[i + 1])); } } boolQueryBuilder.should(dependencyQuery); } return boolQueryBuilder; }
@Override protected void processServiceResourceReplacement(Topology topology, Map<String, NodeTemplate> topologyTemplateMap, String nodeId, String serviceResourceId) { ServiceResource serviceResource = getServiceResourceService().getOrFail(serviceResourceId); NodeTemplate serviceNodeTemplate = serviceResource.getNodeInstance().getNodeTemplate(); ServiceNodeTemplate substitutionNodeTemplate = new ServiceNodeTemplate(serviceNodeTemplate.getType(), serviceNodeTemplate.getProperties(), serviceNodeTemplate.getAttributes(), serviceNodeTemplate.getRelationships(), serviceNodeTemplate.getRequirements(), serviceNodeTemplate.getCapabilities(), serviceNodeTemplate.getInterfaces(), serviceNodeTemplate.getArtifacts()); substitutionNodeTemplate.setServiceResourceId(serviceResource.getId()); substitutionNodeTemplate.setAttributeValues(serviceResource.getNodeInstance().getAttributeValues()); NodeTemplate abstractTopologyNode = topologyTemplateMap.put(nodeId, substitutionNodeTemplate); substitutionNodeTemplate.setName(abstractTopologyNode.getName()); substitutionNodeTemplate.setRelationships(abstractTopologyNode.getRelationships()); // add all the necessary dependencies to the topology Csar csar = getToscaTypeSearchService().getArchive(serviceResource.getDependency().getName(), serviceResource.getDependency().getVersion()); Set<CSARDependency> dependencies = Sets.newHashSet(); if (csar.getDependencies() != null) { dependencies.addAll(csar.getDependencies()); } dependencies.add(new CSARDependency(csar.getName(), csar.getVersion())); topology.getDependencies().addAll(dependencies); } }