// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.content; import com.yahoo.documentmodel.NewDocumentType; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import static java.util.stream.Collectors.joining; /** * Performs the following validations: * - Verify that all global documents have required redundancy * - Verify that all referred documents are present in services.xml * - Verify that all referred documents are global * * @author bjorncs */ public class GlobalDistributionValidator { public void validate(Map documentDefinitions, Set globallyDistributedDocuments) { verifyReferredDocumentsArePresent(documentDefinitions); verifyReferredDocumentsAreGlobal(documentDefinitions, globallyDistributedDocuments); } private static void verifyReferredDocumentsArePresent(Map documentDefinitions) { Set unknowDocuments = getReferencedDocuments(documentDefinitions) .filter(name -> !documentDefinitions.containsKey(name.toString())) .collect(Collectors.toCollection(() -> new LinkedHashSet<>())); if (!unknowDocuments.isEmpty()) { throw new IllegalArgumentException("The following document types are referenced from other documents, " + "but are not listed in services.xml: " + asPrintableString(unknowDocuments.stream())); } } private static void verifyReferredDocumentsAreGlobal(Map documentDefinitions, Set globallyDistributedDocuments) { Set nonGlobalReferencedDocuments = getReferencedDocuments(documentDefinitions) .map(name -> documentDefinitions.get(name.toString())) .filter(documentType -> !globallyDistributedDocuments.contains(documentType)) .collect(Collectors.toCollection(() -> new LinkedHashSet<>())); if (!nonGlobalReferencedDocuments.isEmpty()) { throw new IllegalArgumentException("The following document types are referenced from other documents, " + "but are not globally distributed: " + asPrintableString(toDocumentNameStream(nonGlobalReferencedDocuments))); } } private static Stream getReferencedDocuments(Map documentDefinitions) { return documentDefinitions.values().stream() .map(NewDocumentType::getDocumentReferences) .flatMap(Set::stream); } private static Stream toDocumentNameStream(Set globallyDistributedDocuments) { return globallyDistributedDocuments.stream().map(NewDocumentType::getFullName); } private static String asPrintableString(Stream documentTypes) { return documentTypes.map(name -> "'" + name + "'").collect(joining(", ")); } }