diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2021-10-21 18:02:08 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-21 18:02:08 +0200 |
commit | c6b1d441fd9ee02e6213ed4b240b721ac1bb4666 (patch) | |
tree | 5e26420309d8eb71a1457484dacfbfb311d76ddb | |
parent | e67760622daa2a26290a4d6f05f5ec73a9a827da (diff) | |
parent | 66f1b3f9e0df0c18043ff357597fee30737bd1f0 (diff) |
Merge branch 'master' into balder/upper-limit-before-commit
56 files changed, 408 insertions, 184 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java index 9bcc4c05f29..2c51aa89c66 100644 --- a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java +++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java @@ -102,6 +102,7 @@ public interface ModelContext { @ModelFeatureFlag(owners = {"bjorncs"}) default int maxConnectionLifeInHosted() { return 45; } @ModelFeatureFlag(owners = {"geirst", "vekterli"}) default int distributorMergeBusyWait() { return 10; } @ModelFeatureFlag(owners = {"vekterli", "geirst"}) default boolean distributorEnhancedMaintenanceScheduling() { return false; } + @ModelFeatureFlag(owners = {"arnej"}) default boolean forwardIssuesAsErrors() { return true; } } /** Warning: As elsewhere in this package, do not make backwards incompatible changes that will break old config models! */ diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/Schema.java b/config-model/src/main/java/com/yahoo/searchdefinition/Schema.java index b2d4f0592fe..36d4ba9699e 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/Schema.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/Schema.java @@ -609,7 +609,7 @@ public class Schema implements ImmutableSchema { Map<String, SummaryField> summaryFields = inherited.isPresent() ? requireInherited().getSummaryFields(field) : new java.util.LinkedHashMap<>(); for (DocumentSummary documentSummary : summaries.values()) { - for (SummaryField summaryField : documentSummary.getSummaryFields()) { + for (SummaryField summaryField : documentSummary.getSummaryFields().values()) { if (summaryField.hasSource(field.getName())) { summaryFields.put(summaryField.getName(), summaryField); } @@ -628,7 +628,7 @@ public class Schema implements ImmutableSchema { Map<String, SummaryField> summaryFields = inherited.isPresent() ? requireInherited().getUniqueNamedSummaryFields() : new java.util.LinkedHashMap<>(); for (DocumentSummary documentSummary : summaries.values()) { - for (SummaryField summaryField : documentSummary.getSummaryFields()) { + for (SummaryField summaryField : documentSummary.getSummaryFields().values()) { summaryFields.put(summaryField.getName(), summaryField); } } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/derived/SummaryClass.java b/config-model/src/main/java/com/yahoo/searchdefinition/derived/SummaryClass.java index 5f88ddba5f5..68966d39d7d 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/derived/SummaryClass.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/derived/SummaryClass.java @@ -63,7 +63,7 @@ public class SummaryClass extends Derived { } private void deriveFields(Schema schema, DocumentSummary summary) { - for (SummaryField summaryField : summary.getSummaryFields()) { + for (SummaryField summaryField : summary.getSummaryFields().values()) { if (!accessingDiskSummary && schema.isAccessingDiskSummary(summaryField)) { accessingDiskSummary = true; } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/derived/SummaryMap.java b/config-model/src/main/java/com/yahoo/searchdefinition/derived/SummaryMap.java index cf182a1afbc..c65ed7dc762 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/derived/SummaryMap.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/derived/SummaryMap.java @@ -39,7 +39,7 @@ public class SummaryMap extends Derived implements SummarymapConfig.Producer { } private void derive(DocumentSummary documentSummary) { - for (SummaryField summaryField : documentSummary.getSummaryFields()) { + for (SummaryField summaryField : documentSummary.getSummaryFields().values()) { if (summaryField.getTransform()== SummaryTransform.NONE) continue; if (summaryField.getTransform()==SummaryTransform.ATTRIBUTE || diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/derived/VsmSummary.java b/config-model/src/main/java/com/yahoo/searchdefinition/derived/VsmSummary.java index a2c90bc92f5..4ce486e13ba 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/derived/VsmSummary.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/derived/VsmSummary.java @@ -18,7 +18,7 @@ import java.util.*; */ public class VsmSummary extends Derived implements VsmsummaryConfig.Producer { - private Map<SummaryField, List<String>> summaryMap = new java.util.LinkedHashMap<>(1); + private final Map<SummaryField, List<String>> summaryMap = new java.util.LinkedHashMap<>(1); public VsmSummary(Schema schema) { derive(schema); @@ -31,8 +31,8 @@ public class VsmSummary extends Derived implements VsmsummaryConfig.Producer { } private void derive(Schema schema, DocumentSummary documentSummary) { - if (documentSummary==null) return; - for (SummaryField summaryField : documentSummary.getSummaryFields()) { + if (documentSummary == null) return; + for (SummaryField summaryField : documentSummary.getSummaryFields().values()) { List<String> from = toStringList(summaryField.sourceIterator()); if (doMapField(schema, summaryField)) { diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddExtraFieldsToDocument.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddExtraFieldsToDocument.java index 9ade1786e37..57d5a9c8e75 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddExtraFieldsToDocument.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddExtraFieldsToDocument.java @@ -39,7 +39,7 @@ public class AddExtraFieldsToDocument extends Processor { addSdField(schema, document, field, validate); } //TODO Vespa 8 or sooner we should avoid the dirty addition of fields from dirty 'default' summary to document at all - for (SummaryField field : schema.getSummary("default").getSummaryFields()) { + for (SummaryField field : schema.getSummary("default").getSummaryFields().values()) { if (dirtyLegalFieldNameCheck(field.getName())) { addSummaryField(schema, document, field, validate); } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/AdjustPositionSummaryFields.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/AdjustPositionSummaryFields.java index 176fcf2130f..983942f87c3 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/AdjustPositionSummaryFields.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/AdjustPositionSummaryFields.java @@ -33,26 +33,26 @@ public class AdjustPositionSummaryFields extends Processor { } private void scanSummary(DocumentSummary summary) { - for (SummaryField summaryField : summary.getSummaryFields()) { - if (isPositionDataType(summaryField.getDataType())) { - String originalSource = summaryField.getSingleSource(); - if (originalSource.indexOf('.') == -1) { // Eliminate summary fields with pos.x or pos.y as source - ImmutableSDField sourceField = schema.getField(originalSource); - if (sourceField != null) { - String zCurve = null; - if (sourceField.getDataType().equals(summaryField.getDataType())) { - zCurve = PositionDataType.getZCurveFieldName(originalSource); - } else if (sourceField.getDataType().equals(makeZCurveDataType(summaryField.getDataType())) && - hasZCurveSuffix(originalSource)) { - zCurve = originalSource; - } - if (zCurve != null) { - if (hasPositionAttribute(zCurve)) { - Source source = new Source(zCurve); - adjustPositionField(summary, summaryField, source); - } else if (sourceField.isImportedField() || !summaryField.getName().equals(originalSource)) { - fail(summaryField, "No position attribute '" + zCurve + "'"); - } + for (SummaryField summaryField : summary.getSummaryFields().values()) { + if ( ! isPositionDataType(summaryField.getDataType())) continue; + + String originalSource = summaryField.getSingleSource(); + if (originalSource.indexOf('.') == -1) { // Eliminate summary fields with pos.x or pos.y as source + ImmutableSDField sourceField = schema.getField(originalSource); + if (sourceField != null) { + String zCurve = null; + if (sourceField.getDataType().equals(summaryField.getDataType())) { + zCurve = PositionDataType.getZCurveFieldName(originalSource); + } else if (sourceField.getDataType().equals(makeZCurveDataType(summaryField.getDataType())) && + hasZCurveSuffix(originalSource)) { + zCurve = originalSource; + } + if (zCurve != null) { + if (hasPositionAttribute(zCurve)) { + Source source = new Source(zCurve); + adjustPositionField(summary, summaryField, source); + } else if (sourceField.isImportedField() || !summaryField.getName().equals(originalSource)) { + fail(summaryField, "No position attribute '" + zCurve + "'"); } } } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/ImplicitSummaryFields.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/ImplicitSummaryFields.java index ff0a0d07102..e11f7d370c5 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/ImplicitSummaryFields.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/ImplicitSummaryFields.java @@ -23,7 +23,7 @@ public class ImplicitSummaryFields extends Processor { @Override public void process(boolean validate, boolean documentsOnly) { for (DocumentSummary docsum : schema.getSummariesInThis().values()) { - if (docsum.getInherited() != null) continue; // Implicit fields are added to inheriting summaries through their parent + if (docsum.inherited().isPresent()) continue; // Implicit fields are added to inheriting summaries through their parent addField(docsum, new SummaryField("rankfeatures", DataType.STRING, SummaryTransform.RANKFEATURES), validate); addField(docsum, new SummaryField("summaryfeatures", DataType.STRING, SummaryTransform.SUMMARYFEATURES), validate); } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/MatchedElementsOnlyResolver.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/MatchedElementsOnlyResolver.java index 709c79cd79b..c2fe4e875b8 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/MatchedElementsOnlyResolver.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/MatchedElementsOnlyResolver.java @@ -33,8 +33,8 @@ public class MatchedElementsOnlyResolver extends Processor { public void process(boolean validate, boolean documentsOnly) { for (var entry : schema.getSummaries().entrySet()) { var summary = entry.getValue(); - for (var field : summary.getSummaryFields()) { - if (field.getTransform().equals(SummaryTransform.MATCHED_ELEMENTS_FILTER)) { + for (var field : summary.getSummaryFields().values()) { + if (field.getTransform() == SummaryTransform.MATCHED_ELEMENTS_FILTER) { processSummaryField(summary, field, validate); } } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/ReferenceFieldsProcessor.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/ReferenceFieldsProcessor.java index ed23b1ca606..19bfb41289d 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/ReferenceFieldsProcessor.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/ReferenceFieldsProcessor.java @@ -35,7 +35,7 @@ public class ReferenceFieldsProcessor extends Processor { private void clearSummaryAttributeAspectForExplicitSummaryFields() { for (DocumentSummary docSum : schema.getSummaries().values()) { - docSum.getSummaryFields().stream() + docSum.getSummaryFields().values().stream() .filter(summaryField -> summaryField.getDataType() instanceof ReferenceDataType) .forEach(summaryField -> summaryField.setTransform(SummaryTransform.NONE)); } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryConsistency.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryConsistency.java index 80f9a15f1e5..8b86674e4d0 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryConsistency.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryConsistency.java @@ -33,7 +33,7 @@ public class SummaryConsistency extends Processor { for (DocumentSummary summary : schema.getSummaries().values()) { if (summary.getName().equals("default")) continue; - for (SummaryField summaryField : summary.getSummaryFields() ) { + for (SummaryField summaryField : summary.getSummaryFields().values()) { assertConsistency(summaryField, schema, validate); makeAttributeTransformIfAppropriate(summaryField, schema); makeAttributeCombinerTransformIfAppropriate(summaryField, schema); diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryDiskAccessValidator.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryDiskAccessValidator.java index 4bc553b1669..6a64202686f 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryDiskAccessValidator.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryDiskAccessValidator.java @@ -37,7 +37,7 @@ public class SummaryDiskAccessValidator extends Processor { if (documentsOnly) return; for (DocumentSummary summary : schema.getSummaries().values()) { - for (SummaryField summaryField : summary.getSummaryFields()) { + for (SummaryField summaryField : summary.getSummaryFields().values()) { for (SummaryField.Source source : summaryField.getSources()) { ImmutableSDField field = schema.getField(source.getName()); if (field == null) @@ -47,9 +47,9 @@ public class SummaryDiskAccessValidator extends Processor { source + ", but this field does not exist"); if ( ! isInMemory(field, summaryField) && ! summary.isFromDisk()) { deployLogger.logApplicationPackage(Level.WARNING, summaryField + " in " + summary + " references " + - source + ", which is not an attribute: Using this " + - "summary will cause disk accesses. " + - "Set 'from-disk' on this summary class to silence this warning."); + source + ", which is not an attribute: Using this " + + "summary will cause disk accesses. " + + "Set 'from-disk' on this summary class to silence this warning."); } } } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryFieldsMustHaveValidSource.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryFieldsMustHaveValidSource.java index 2e2144b819d..c6f5b35aaa8 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryFieldsMustHaveValidSource.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryFieldsMustHaveValidSource.java @@ -26,7 +26,7 @@ public class SummaryFieldsMustHaveValidSource extends Processor { if ( ! validate) return; for (DocumentSummary summary : schema.getSummaries().values()) { - for (SummaryField summaryField : summary.getSummaryFields()) { + for (SummaryField summaryField : summary.getSummaryFields().values()) { if (summaryField.getSources().isEmpty()) { if ((summaryField.getTransform() != SummaryTransform.RANKFEATURES) && (summaryField.getTransform() != SummaryTransform.SUMMARYFEATURES)) diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryNamesFieldCollisions.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryNamesFieldCollisions.java index 1c6f8d54ea3..2d0afe88281 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryNamesFieldCollisions.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/SummaryNamesFieldCollisions.java @@ -32,7 +32,7 @@ public class SummaryNamesFieldCollisions extends Processor { Map<String, Pair<String, String>> fieldToClassAndSource = new HashMap<>(); for (DocumentSummary summary : schema.getSummaries().values()) { if ("default".equals(summary.getName())) continue; - for (SummaryField summaryField : summary.getSummaryFields() ) { + for (SummaryField summaryField : summary.getSummaryFields().values()) { if (summaryField.isImplicit()) continue; Pair<String, String> prevClassAndSource = fieldToClassAndSource.get(summaryField.getName()); for (Source source : summaryField.getSources()) { diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/ValidateFieldTypes.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/ValidateFieldTypes.java index 0d4bfd09677..68bf2511a4b 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/ValidateFieldTypes.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/ValidateFieldTypes.java @@ -48,7 +48,7 @@ public class ValidateFieldTypes extends Processor { } final protected void verifySummaryFields(String searchName, Map<String, DataType> seenFields) { for (DocumentSummary summary : schema.getSummaries().values()) { - for (SummaryField field : summary.getSummaryFields()) { + for (SummaryField field : summary.getSummaryFields().values()) { checkFieldType(searchName, "summary field", field.getName(), field.getDataType(), seenFields); } } diff --git a/config-model/src/main/java/com/yahoo/vespa/documentmodel/DocumentSummary.java b/config-model/src/main/java/com/yahoo/vespa/documentmodel/DocumentSummary.java index 967e662dc6b..3dda498b0be 100644 --- a/config-model/src/main/java/com/yahoo/vespa/documentmodel/DocumentSummary.java +++ b/config-model/src/main/java/com/yahoo/vespa/documentmodel/DocumentSummary.java @@ -6,8 +6,12 @@ import com.yahoo.searchdefinition.Schema; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.logging.Level; /** @@ -19,7 +23,7 @@ public class DocumentSummary extends FieldView { private boolean fromDisk = false; private boolean omitSummaryFeatures = false; - private String inherited; + private Optional<String> inherited = Optional.empty(); private final Schema owner; @@ -57,20 +61,15 @@ public class DocumentSummary extends FieldView { public SummaryField getSummaryField(String name) { var field = (SummaryField)get(name); if (field != null) return field; - if (getInherited() == null) return null; - return getInherited().getSummaryField(name); + if (inherited().isEmpty()) return null; + return inherited().get().getSummaryField(name); } - // TODO: This does not handle overriding in child summaries correctly - public Collection<SummaryField> getSummaryFields() { - var fields = new ArrayList<SummaryField>(getFields().size()); - var parent = getInherited(); - if (parent != null) { - fields.addAll(parent.getSummaryFields()); - } - for (var field : getFields()) { - fields.add((SummaryField) field); - } + public Map<String, SummaryField> getSummaryFields() { + var fields = new LinkedHashMap<String, SummaryField>(getFields().size()); + inherited().ifPresent(inherited -> fields.putAll(inherited.getSummaryFields())); + for (var field : getFields()) + fields.put(field.getName(), (SummaryField) field); return fields; } @@ -83,7 +82,7 @@ public class DocumentSummary extends FieldView { */ public void purgeImplicits() { List<SummaryField> falseImplicits = new ArrayList<>(); - for (SummaryField summaryField : getSummaryFields() ) { + for (SummaryField summaryField : getSummaryFields().values()) { if (summaryField.isImplicit()) continue; for (Iterator<SummaryField.Source> j = summaryField.sourceIterator(); j.hasNext(); ) { String sourceName = j.next().getName(); @@ -101,12 +100,12 @@ public class DocumentSummary extends FieldView { /** Sets the parent of this. Both summaries must be present in the same search definition */ public void setInherited(String inherited) { - this.inherited = inherited; + this.inherited = Optional.of(inherited); } - /** Returns the parent of this, or null if none is inherited */ - public DocumentSummary getInherited() { - return owner.getSummary(inherited); + /** Returns the parent of this, if any */ + public Optional<DocumentSummary> inherited() { + return inherited.map(name -> owner.getSummary(name)); } @Override @@ -115,14 +114,14 @@ public class DocumentSummary extends FieldView { } public void validate(DeployLogger logger) { - if (inherited != null) { - if ( ! owner.getSummaries().containsKey(inherited)) { + if (inherited.isPresent()) { + if ( ! owner.getSummaries().containsKey(inherited.get())) { logger.log(Level.WARNING, - this + " inherits " + inherited + " but this" + " is not present in " + owner); + this + " inherits " + inherited.get() + " but this" + " is not present in " + owner); logger.logApplicationPackage(Level.WARNING, - this + " inherits " + inherited + " but this" + " is not present in " + owner); + this + " inherits " + inherited.get() + " but this" + " is not present in " + owner); // TODO: When safe, replace the above by - // throw new IllegalArgumentException(this + " inherits " + inherited + " but this" + + // throw new IllegalArgumentException(this + " inherits " + inherited.get() + " but this" + // " is not present in " + owner); // ... and update SummaryTestCase.testValidationOfInheritedSummary } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java index 1200b7467b4..ff9db4a10bf 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java @@ -68,6 +68,7 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> private final double defaultFeedConcurrency; private final double defaultDiskBloatFactor; private final int defaultDocStoreCompressionLevel; + private final boolean forwardIssuesToQrs; /** Whether the nodes of this cluster also hosts a container cluster in a hosted system */ private final boolean combined; @@ -210,11 +211,12 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> this.syncTransactionLog = syncTransactionLog; this.combined = combined; - feedSequencerType = convertFeedSequencerType(featureFlags.feedSequencerType()); - feedTaskLimit = featureFlags.feedTaskLimit(); - defaultFeedConcurrency = featureFlags.feedConcurrency(); - defaultDocStoreCompressionLevel = featureFlags.docstoreCompressionLevel(); - defaultDiskBloatFactor = featureFlags.diskBloatFactor(); + this.feedSequencerType = convertFeedSequencerType(featureFlags.feedSequencerType()); + this.feedTaskLimit = featureFlags.feedTaskLimit(); + this.defaultFeedConcurrency = featureFlags.feedConcurrency(); + this.defaultDiskBloatFactor = featureFlags.diskBloatFactor(); + this.defaultDocStoreCompressionLevel = featureFlags.docstoreCompressionLevel(); + this.forwardIssuesToQrs = featureFlags.forwardIssuesAsErrors(); } public void setVisibilityDelay(double delay) { @@ -411,6 +413,7 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> builder.flush.memory.each.diskbloatfactor(defaultDiskBloatFactor); builder.summary.log.chunk.compression.level(defaultDocStoreCompressionLevel); builder.summary.log.compact.compression.level(defaultDocStoreCompressionLevel); + builder.forward_issues(forwardIssuesToQrs); int numDocumentDbs = builder.documentdb.size(); builder.initialize(new ProtonConfig.Initialize.Builder().threads(numDocumentDbs + 1)); diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/SchemaTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/SchemaTestCase.java index 329d27472c2..8b96779f695 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/SchemaTestCase.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/SchemaTestCase.java @@ -166,7 +166,7 @@ public class SchemaTestCase { assertTrue(child.onnxModels().asMap().containsKey("child_model")); assertNotNull(child.getSummary("parent_summary")); assertNotNull(child.getSummary("child_summary")); - assertEquals("parent_summary", child.getSummary("child_summary").getInherited().getName()); + assertEquals("parent_summary", child.getSummary("child_summary").inherited().get().getName()); assertTrue(child.getSummaries().containsKey("parent_summary")); assertTrue(child.getSummaries().containsKey("child_summary")); assertNotNull(child.getSummaryField("pf1")); diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/SummaryTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/SummaryTestCase.java index e57dcf38fed..dee63f04ad5 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/SummaryTestCase.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/SummaryTestCase.java @@ -10,6 +10,7 @@ import static com.yahoo.config.model.test.TestUtil.joinLines; import java.util.Collection; import java.util.List; +import java.util.Optional; import java.util.logging.Level; import java.util.stream.Collectors; @@ -172,12 +173,12 @@ public class SummaryTestCase { new TestValue(everythingSummary, titleArtistSummary, List.of(List.of(titleField), implicitFields, List.of(artistField, albumField))) ); tests.forEach(testValue -> { - var actualFields = testValue.summary.getSummaryFields().stream() + var actualFields = testValue.summary.getSummaryFields().values().stream() .map(FieldBase::getName) .collect(Collectors.toList()); assertEquals(testValue.summary.getName() + (testValue.parent == null ? " does not inherit anything" : " inherits " + testValue.parent.getName()), - testValue.parent, - testValue.summary.getInherited()); + Optional.ofNullable(testValue.parent), + testValue.summary.inherited()); assertEquals("Summary " + testValue.summary.getName() + " has expected fields", testValue.fields, actualFields); }); } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java index 388aa34c1ab..2752bda3c68 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java @@ -197,6 +197,7 @@ public class ModelContextImpl implements ModelContext { private final double diskBloatFactor; private final boolean distributorEnhancedMaintenanceScheduling; private final int maxUnCommittedMemory; + private final boolean forwardIssuesAsErrors; public FeatureFlags(FlagSource source, ApplicationId appId) { this.defaultTermwiseLimit = flagValue(source, appId, Flags.DEFAULT_TERM_WISE_LIMIT); @@ -232,6 +233,7 @@ public class ModelContextImpl implements ModelContext { this.diskBloatFactor = flagValue(source, appId, Flags.DISK_BLOAT_FACTOR); this.distributorEnhancedMaintenanceScheduling = flagValue(source, appId, Flags.DISTRIBUTOR_ENHANCED_MAINTENANCE_SCHEDULING); this.maxUnCommittedMemory = flagValue(source, appId, Flags.MAX_UNCOMMITTED_MEMORY);; + this.forwardIssuesAsErrors = flagValue(source, appId, PermanentFlags.FORWARD_ISSUES_AS_ERRORS); } @Override public double defaultTermwiseLimit() { return defaultTermwiseLimit; } @@ -269,6 +271,7 @@ public class ModelContextImpl implements ModelContext { @Override public int docstoreCompressionLevel() { return docstoreCompressionLevel; } @Override public boolean distributorEnhancedMaintenanceScheduling() { return distributorEnhancedMaintenanceScheduling; } @Override public int maxUnCommittedMemory() { return maxUnCommittedMemory; } + @Override public boolean forwardIssuesAsErrors() { return forwardIssuesAsErrors; } private static <V> V flagValue(FlagSource source, ApplicationId appId, UnboundFlag<? extends V, ?, ?> flag) { return flag.bindTo(source) diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json index fc642ca7b22..d191659f085 100644 --- a/container-search/abi-spec.json +++ b/container-search/abi-spec.json @@ -1605,6 +1605,24 @@ ], "fields": [] }, + "com.yahoo.prelude.query.TrueItem": { + "superClass": "com.yahoo.prelude.query.Item", + "interfaces": [], + "attributes": [ + "public" + ], + "methods": [ + "public void <init>()", + "public void setIndexName(java.lang.String)", + "public com.yahoo.prelude.query.Item$ItemType getItemType()", + "public java.lang.String getName()", + "protected void appendHeadingString(java.lang.StringBuilder)", + "public int encode(java.nio.ByteBuffer)", + "public int getTermCount()", + "protected void appendBodyString(java.lang.StringBuilder)" + ], + "fields": [] + }, "com.yahoo.prelude.query.UriItem": { "superClass": "com.yahoo.prelude.query.PhraseItem", "interfaces": [], diff --git a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java index a2decd8c42f..99de33aca94 100644 --- a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java @@ -5,7 +5,6 @@ import com.google.inject.Inject; import com.yahoo.component.ComponentId; import com.yahoo.component.chain.dependencies.After; import com.yahoo.component.provider.ComponentRegistry; -import com.yahoo.container.QrConfig; import com.yahoo.container.QrSearchersConfig; import com.yahoo.container.core.documentapi.VespaDocumentAccess; import com.yahoo.container.handler.VipStatus; @@ -34,6 +33,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.FutureTask; @@ -75,7 +75,6 @@ public class ClusterSearcher extends Searcher { ClusterConfig clusterConfig, DocumentdbInfoConfig documentDbConfig, ComponentRegistry<Dispatcher> dispatchers, - QrConfig qrConfig, VipStatus vipStatus, VespaDocumentAccess access) { super(id); @@ -101,12 +100,13 @@ public class ClusterSearcher extends Searcher { } } + String uniqueServerId = UUID.randomUUID().toString(); if (searchClusterConfig.indexingmode() == STREAMING) { - server = vdsCluster(qrConfig.discriminator(), searchClusterIndex, + server = vdsCluster(uniqueServerId, searchClusterIndex, searchClusterConfig, docSumParams, documentDbConfig, access); vipStatus.addToRotation(server.getName()); } else { - server = searchDispatch(searchClusterIndex, searchClusterName, qrConfig.discriminator(), + server = searchDispatch(searchClusterIndex, searchClusterName, uniqueServerId, docSumParams, documentDbConfig, dispatchers); } } diff --git a/container-search/src/main/java/com/yahoo/prelude/query/TrueItem.java b/container-search/src/main/java/com/yahoo/prelude/query/TrueItem.java new file mode 100644 index 00000000000..20aebd124e7 --- /dev/null +++ b/container-search/src/main/java/com/yahoo/prelude/query/TrueItem.java @@ -0,0 +1,41 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.prelude.query; + +import java.nio.ByteBuffer; + +/** + * A query item which matches everything. + * + * @author arnej + */ +public class TrueItem extends Item { + + @Override + public void setIndexName(String index) { + throw new IllegalArgumentException("TrueItem should not have an index name"); + } + + @Override + public ItemType getItemType() { return ItemType.TRUE; } + + @Override + public String getName() { return "TRUE"; } + + /** Override to only return "TRUE" rather than "TRUE " */ + @Override + protected void appendHeadingString(StringBuilder buffer) { + buffer.append(getName()); + } + + @Override + public int encode(ByteBuffer buffer) { + super.encodeThis(buffer); + return 1; + } + + @Override + public int getTermCount() { return 0; } + + @Override + protected void appendBodyString(StringBuilder buffer) { } +} diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/searchcluster/Group.java b/container-search/src/main/java/com/yahoo/search/dispatch/searchcluster/Group.java index 7002d1f7f2f..8ae892bc664 100644 --- a/container-search/src/main/java/com/yahoo/search/dispatch/searchcluster/Group.java +++ b/container-search/src/main/java/com/yahoo/search/dispatch/searchcluster/Group.java @@ -72,7 +72,7 @@ public class Group { boolean balanced = skew <= activeDocs * maxContentSkew; if (!isBalanced.get() || balanced != isBalanced.get()) { if (!isSparse()) - log.info("Content is " + (balanced ? "" : "not ") + "well balanced. Current deviation = " + + log.info("Content in " + this + " is " + (balanced ? "" : "not ") + "well balanced. Current deviation = " + skew * 100 / activeDocs + " %. activeDocs = " + activeDocs + ", skew = " + skew + ", average = " + average); isBalanced.set(balanced); diff --git a/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java b/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java index 012f427a781..897bcde4fc3 100644 --- a/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java +++ b/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java @@ -97,6 +97,7 @@ import com.yahoo.prelude.query.SuffixItem; import com.yahoo.prelude.query.TaggableItem; import com.yahoo.prelude.query.ToolBox; import com.yahoo.prelude.query.ToolBox.QueryVisitor; +import com.yahoo.prelude.query.TrueItem; import com.yahoo.prelude.query.UriItem; import com.yahoo.prelude.query.WandItem; import com.yahoo.prelude.query.WeakAndItem; @@ -484,6 +485,16 @@ public class VespaSerializer { } + private static class TrueSerializer extends Serializer<TrueItem> { + @Override + void onExit(StringBuilder destination, TrueItem item) { } + @Override + boolean serialize(StringBuilder destination, TrueItem item) { + destination.append("true"); + return false; + } + } + private static class FalseSerializer extends Serializer<FalseItem> { @Override void onExit(StringBuilder destination, FalseItem item) { } @@ -1205,6 +1216,7 @@ public class VespaSerializer { dispatchBuilder.put(IntItem.class, new NumberSerializer()); dispatchBuilder.put(GeoLocationItem.class, new GeoLocationSerializer()); dispatchBuilder.put(BoolItem.class, new BoolSerializer()); + dispatchBuilder.put(TrueItem.class, new TrueSerializer()); dispatchBuilder.put(FalseItem.class, new FalseSerializer()); dispatchBuilder.put(MarkerWordItem.class, new WordSerializer()); // gotcha dispatchBuilder.put(NearItem.class, new NearSerializer()); diff --git a/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java b/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java index fa2b9fd14e7..c688f61add0 100644 --- a/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java +++ b/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java @@ -62,6 +62,7 @@ import com.yahoo.prelude.query.TaggableItem; import com.yahoo.prelude.query.TermItem; import com.yahoo.prelude.query.ToolBox; import com.yahoo.prelude.query.ToolBox.QueryVisitor; +import com.yahoo.prelude.query.TrueItem; import com.yahoo.prelude.query.UriItem; import com.yahoo.prelude.query.WandItem; import com.yahoo.prelude.query.WeakAndItem; @@ -450,10 +451,13 @@ public class YqlParser implements Parser { private Item buildLiteral(OperatorNode<ExpressionOperator> ast) { var literal = ast.getArgument(0); + if (Boolean.TRUE.equals(literal)) { + return new TrueItem(); + } if (Boolean.FALSE.equals(literal)) { return new FalseItem(); } - throw newUnexpectedArgumentException(literal, Boolean.FALSE); + throw newUnexpectedArgumentException(literal, Boolean.FALSE, Boolean.TRUE); } private Item buildNearestNeighbor(OperatorNode<ExpressionOperator> ast) { diff --git a/container-search/src/test/java/com/yahoo/prelude/cluster/ClusterSearcherTestCase.java b/container-search/src/test/java/com/yahoo/prelude/cluster/ClusterSearcherTestCase.java index 95929763675..801f7da1939 100644 --- a/container-search/src/test/java/com/yahoo/prelude/cluster/ClusterSearcherTestCase.java +++ b/container-search/src/test/java/com/yahoo/prelude/cluster/ClusterSearcherTestCase.java @@ -5,7 +5,6 @@ import com.google.common.collect.ImmutableList; import com.yahoo.component.ComponentId; import com.yahoo.component.provider.ComponentRegistry; import com.yahoo.concurrent.InThreadExecutorService; -import com.yahoo.container.QrConfig; import com.yahoo.container.QrSearchersConfig; import com.yahoo.container.handler.ClustersStatus; import com.yahoo.container.handler.VipStatus; @@ -530,7 +529,6 @@ public class ClusterSearcherTestCase { clusterConfig.build(), documentDbConfig.build(), dispatchers, - new QrConfig.Builder().build(), vipStatus, null); } diff --git a/container-search/src/test/java/com/yahoo/search/yql/VespaSerializerTestCase.java b/container-search/src/test/java/com/yahoo/search/yql/VespaSerializerTestCase.java index 308907df6b4..cc13658648d 100644 --- a/container-search/src/test/java/com/yahoo/search/yql/VespaSerializerTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/yql/VespaSerializerTestCase.java @@ -143,7 +143,8 @@ public class VespaSerializerTestCase { } @Test - public void testFalse() { + public void testTrueAndFalse() { + parseAndConfirm("true"); parseAndConfirm("false"); } diff --git a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java index e7cba25d1ed..f9005387716 100644 --- a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java @@ -592,8 +592,11 @@ public class YqlParserTestCase { } @Test - public void testFalse() { + public void testTrueAndFalse() { + assertParse("select foo from bar where true;", "TRUE"); assertParse("select foo from bar where false;", "FALSE"); + assertParse("select foo from bar where ((title contains \"foo\") AND true) AND !((title contains \"bar\") or false);", + "+(AND title:foo TRUE) -(OR title:bar FALSE)"); } @Test diff --git a/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java b/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java index ae5317ecb53..2c0614805a9 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java @@ -212,6 +212,13 @@ public class PermanentFlags { ZONE_ID ); + public static final UnboundBooleanFlag FORWARD_ISSUES_AS_ERRORS = defineFeatureFlag( + "forward-issues-as-errors", true, + "When the backend detects a problematic issue with a query, it will by default send it as an error message to the QRS, which adds it in an ErrorHit in the result. May be disabled using this flag.", + "Takes effect immediately", + ZONE_ID, APPLICATION_ID); + + private PermanentFlags() {} private static UnboundBooleanFlag defineFeatureFlag( diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContext.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContext.java index 23a81458134..d26a1fa6019 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContext.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContext.java @@ -45,6 +45,8 @@ public interface NodeAgentContext extends TaskContext { /** @return information about the Vespa user inside the container */ VespaUser vespaUser(); + UserNamespace userNamespace(); + default boolean isDisabled(NodeAgentTask task) { return false; }; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextImpl.java index 0b1f7f24ced..037bbc56d1d 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextImpl.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextImpl.java @@ -104,6 +104,11 @@ public class NodeAgentContextImpl implements NodeAgentContext { } @Override + public UserNamespace userNamespace() { + return containerFs.getUserPrincipalLookupService().userNamespace(); + } + + @Override public boolean isDisabled(NodeAgentTask task) { return disabledNodeAgentTasks.contains(task); } @@ -263,7 +268,7 @@ public class NodeAgentContextImpl implements NodeAgentContext { Objects.requireNonNull(containerStorage, "Must set one of containerStorage or fileSystem"); UserNamespace userNamespace = Optional.ofNullable(this.userNamespace) - .orElseGet(() -> new UserNamespace(100000, 100000)); + .orElseGet(() -> new UserNamespace(100000, 100000, 100000)); VespaUser vespaUser = Optional.ofNullable(this.vespaUser) .orElseGet(() -> new VespaUser("vespa", "vespa", 1000, 100)); ContainerFileSystem containerFs = ContainerFileSystem.create(containerStorage diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/UserNamespace.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/UserNamespace.java index 005452411bd..99529b83374 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/UserNamespace.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/UserNamespace.java @@ -1,33 +1,35 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.node.admin.nodeagent; +import java.util.Objects; + /** * @author valerijf */ public class UserNamespace { - /** Total number of UID/GID that are mapped for each container */ - private static final int ID_RANGE = 65_536; // 2^16 - /** * IDs outside the ID range are translated to the overflow ID before being written to disk: - * https://github.com/torvalds/linux/blob/5bfc75d92efd494db37f5c4c173d3639d4772966/Documentation/admin-guide/sysctl/fs.rst#overflowgid--overflowuid */ + * https://github.com/torvalds/linux/blob/5bfc75d92efd494db37f5c4c173d3639d4772966/Documentation/admin-guide/sysctl/fs.rst#overflowgid--overflowuid + * Real value in /proc/sys/fs/overflowuid or overflowgid, hardcode default value*/ private static final int OVERFLOW_ID = 65_534; private volatile int uidOffset; private volatile int gidOffset; + private final int idRangeSize; - public UserNamespace(int uidOffset, int gidOffset) { + public UserNamespace(int uidOffset, int gidOffset, int idRangeSize) { this.uidOffset = uidOffset; this.gidOffset = gidOffset; + this.idRangeSize = idRangeSize; } - public int userIdOnHost(int containerUid) { return toHostId(containerUid, uidOffset); } - public int groupIdOnHost(int containerGid) { return toHostId(containerGid, gidOffset); } - public int userIdInContainer(int hostUid) { return toContainerId(hostUid, uidOffset); } - public int groupIdInContainer(int hostGid) { return toContainerId(hostGid, gidOffset); } + public int userIdOnHost(int containerUid) { return toHostId(containerUid, uidOffset, idRangeSize); } + public int groupIdOnHost(int containerGid) { return toHostId(containerGid, gidOffset, idRangeSize); } + public int userIdInContainer(int hostUid) { return toContainerId(hostUid, uidOffset, idRangeSize); } + public int groupIdInContainer(int hostGid) { return toContainerId(hostGid, gidOffset, idRangeSize); } - public int idRange() { return ID_RANGE; } + public int idRangeSize() { return idRangeSize; } public int overflowId() { return OVERFLOW_ID; } // Remove after migration to mapped namespaces is complete, make fields final @@ -36,14 +38,36 @@ public class UserNamespace { this.gidOffset = idOffset; } - private static int toHostId(int containerId, int idOffset) { - if (containerId < 0 || containerId > ID_RANGE) + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + UserNamespace that = (UserNamespace) o; + return uidOffset == that.uidOffset && gidOffset == that.gidOffset && idRangeSize == that.idRangeSize; + } + + @Override + public int hashCode() { + return Objects.hash(uidOffset, gidOffset, idRangeSize); + } + + @Override + public String toString() { + return "UserNamespace{" + + "uidOffset=" + uidOffset + + ", gidOffset=" + gidOffset + + ", idRangeSize=" + idRangeSize + + '}'; + } + + private static int toHostId(int containerId, int idOffset, int idRangeSize) { + if (containerId < 0 || containerId > idRangeSize) throw new IllegalArgumentException("Invalid container id: " + containerId); return idOffset + containerId; } - private static int toContainerId(int hostId, int idOffset) { + private static int toContainerId(int hostId, int idOffset, int idRangeSize) { hostId = hostId - idOffset; - return hostId < 0 || hostId >= ID_RANGE ? OVERFLOW_ID : hostId; + return hostId < 0 || hostId >= idRangeSize ? OVERFLOW_ID : hostId; } } diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/UserNamespaceTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/UserNamespaceTest.java index bb02667a550..20e4bad8c31 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/UserNamespaceTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/UserNamespaceTest.java @@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; */ class UserNamespaceTest { - private final UserNamespace userNamespace = new UserNamespace(1000, 2000); + private final UserNamespace userNamespace = new UserNamespace(1000, 2000, 10000); @Test public void translates_between_ids() { diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/fs/ContainerFileSystemTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/fs/ContainerFileSystemTest.java index 242a2458f07..932f56f3a60 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/fs/ContainerFileSystemTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/fs/ContainerFileSystemTest.java @@ -25,7 +25,7 @@ class ContainerFileSystemTest { private final FileSystem fileSystem = TestFileSystem.create(); private final UnixPath containerRootOnHost = new UnixPath(fileSystem.getPath("/data/storage/ctr1")); - private final UserNamespace userNamespace = new UserNamespace(10_000, 11_000); + private final UserNamespace userNamespace = new UserNamespace(10_000, 11_000, 10000); private final VespaUser vespaUser = new VespaUser("vespa", "users", 1000, 100); private final ContainerFileSystem containerFs = ContainerFileSystem.create( containerRootOnHost.createDirectories().toPath(), userNamespace, vespaUser); diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/fs/ContainerUserPrincipalLookupServiceTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/fs/ContainerUserPrincipalLookupServiceTest.java index 9a6e69ce27c..f201f2667cd 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/fs/ContainerUserPrincipalLookupServiceTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/fs/ContainerUserPrincipalLookupServiceTest.java @@ -19,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; */ class ContainerUserPrincipalLookupServiceTest { - private final UserNamespace userNamespace = new UserNamespace(10_000, 11_000); + private final UserNamespace userNamespace = new UserNamespace(10_000, 11_000, 10000); private final VespaUser vespaUser = new VespaUser("vespa", "users", 1000, 100); private final ContainerUserPrincipalLookupService userPrincipalLookupService = new ContainerUserPrincipalLookupService(TestFileSystem.create().getUserPrincipalLookupService(), userNamespace, vespaUser); diff --git a/sd-plugin/README.md b/sd-plugin/README.md index c9cbaded66c..74ca1781596 100644 --- a/sd-plugin/README.md +++ b/sd-plugin/README.md @@ -18,4 +18,8 @@ Now you should have a "gen" folder next to the "java" folder, and it contains al Important note! After any change in one of this 2 files (bnf, flex) you'll need to generate again. The proper way is to delete the "gen" folder and then do 1-2 again. -Now, you can run the gradle task "runIde", open a project with some sd file and see how the plugin works on it.
\ No newline at end of file +Now, you can run the gradle task "intellij/runIde", open a project with some sd file and see how the plugin works on it. + +In order to test the plugin locally (on you IDE, not by running the gradle task "runIde"), you can run the gradle task +"intellij/buildPlugin". It would create a zip file in the directory build\distributions. You can load it to IntelliJ by +clicking the "settings" in preferences/Plugins and click "Install Plugin from disk".
\ No newline at end of file diff --git a/sd-plugin/build.gradle b/sd-plugin/build.gradle index cb696cb6fd1..12e22703580 100644 --- a/sd-plugin/build.gradle +++ b/sd-plugin/build.gradle @@ -7,7 +7,7 @@ plugins { } group 'org.vz.native' -version '1.0.5-SNAPSHOT' +version '1.0.0' sourceCompatibility = 11 // I added that from Simple Plugin @@ -36,8 +36,9 @@ patchPluginXml { version = project.version sinceBuild = '203' untilBuild = '212.*' + // in changeNotes you can add a description of the changes in this version (would appear in the plugin page in preferences\plugins) changeNotes = """ - <em>fixed a casting bug in SdFindUsagesHandler</em>""" + <em></em>""" } test { diff --git a/sd-plugin/src/main/java/org/intellij/sdk/language/SdSyntaxHighlighter.java b/sd-plugin/src/main/java/org/intellij/sdk/language/SdSyntaxHighlighter.java index ae99b58f11f..31acd5ff730 100644 --- a/sd-plugin/src/main/java/org/intellij/sdk/language/SdSyntaxHighlighter.java +++ b/sd-plugin/src/main/java/org/intellij/sdk/language/SdSyntaxHighlighter.java @@ -23,11 +23,9 @@ public class SdSyntaxHighlighter extends SyntaxHighlighterBase { private static final HashSet<IElementType> keyWordsSet = initKeyWordsSet(); private static final HashSet<IElementType> constantsSet = initConstantsSet(); -// private static final HashSet<IElementType> symbols = initSymbolsSet(); - public static final TextAttributesKey IDENTIFIER = - createTextAttributesKey("SD_IDENTIFIER", DefaultLanguageHighlighterColors.INSTANCE_FIELD); + createTextAttributesKey("SD_IDENTIFIER", DefaultLanguageHighlighterColors.IDENTIFIER); public static final TextAttributesKey CONSTANT = createTextAttributesKey("SD_CONSTANT", DefaultLanguageHighlighterColors.CONSTANT); public static final TextAttributesKey KEY = @@ -36,6 +34,8 @@ public class SdSyntaxHighlighter extends SyntaxHighlighterBase { createTextAttributesKey("SD_SYMBOL", DefaultLanguageHighlighterColors.BRACKETS); public static final TextAttributesKey STRING = createTextAttributesKey("SD_STRING", DefaultLanguageHighlighterColors.STRING); + public static final TextAttributesKey NUMBER = + createTextAttributesKey("SD_NUMBER", DefaultLanguageHighlighterColors.NUMBER); public static final TextAttributesKey COMMENT = createTextAttributesKey("SD_COMMENT", DefaultLanguageHighlighterColors.LINE_COMMENT); public static final TextAttributesKey BAD_CHARACTER = @@ -48,6 +48,7 @@ public class SdSyntaxHighlighter extends SyntaxHighlighterBase { private static final TextAttributesKey[] KEY_KEYS = new TextAttributesKey[]{KEY}; private static final TextAttributesKey[] SYMBOL_KEYS = new TextAttributesKey[]{SYMBOL}; private static final TextAttributesKey[] STRING_KEYS = new TextAttributesKey[]{STRING}; + private static final TextAttributesKey[] NUMBER_KEYS = new TextAttributesKey[]{NUMBER}; private static final TextAttributesKey[] COMMENT_KEYS = new TextAttributesKey[]{COMMENT}; private static final TextAttributesKey[] EMPTY_KEYS = new TextAttributesKey[0]; @@ -59,18 +60,16 @@ public class SdSyntaxHighlighter extends SyntaxHighlighterBase { @Override public TextAttributesKey @NotNull [] getTokenHighlights(IElementType tokenType) { - if (tokenType.equals(SdTypes.IDENTIFIER_VAL)) { + if (tokenType.equals(SdTypes.IDENTIFIER_VAL) || tokenType.equals(SdTypes.IDENTIFIER_WITH_DASH_VAL)) { return IDENTIFIER_KEYS; -// } else if (tokenType.equals(SdTypes.KEY)) { -// return KEY_KEYS; -// } else if (tokenType.equals(SdTypes.VALUE)) { -// return VALUE_KEYS; } else if (keyWordsSet.contains(tokenType)) { return KEY_KEYS; } else if (tokenType.equals(SdTypes.SYMBOL)) { return SYMBOL_KEYS; - } else if (tokenType.equals(SdTypes.STRING)) { + } else if (tokenType.equals(SdTypes.STRING_REG)) { return STRING_KEYS; + } else if (tokenType.equals(SdTypes.INTEGER_REG) || tokenType.equals(SdTypes.FLOAT_REG)) { + return NUMBER_KEYS; } else if (tokenType.equals(SdTypes.COMMENT)) { return COMMENT_KEYS; } else if (constantsSet.contains(tokenType)) { @@ -82,34 +81,81 @@ public class SdSyntaxHighlighter extends SyntaxHighlighterBase { } } -// private static HashSet<IElementType> initSymbolsSet() { -// HashSet<IElementType> symbols = new HashSet<>(); -// symbols.add('{'); -// return symbols; -// } - private static HashSet<IElementType> initKeyWordsSet() { HashSet<IElementType> keyWords = new HashSet<>(); - keyWords.add(SdTypes.MACRO); + keyWords.add(SdTypes.SEARCH); + keyWords.add(SdTypes.SCHEMA); keyWords.add(SdTypes.FIELD); keyWords.add(SdTypes.TYPE); - keyWords.add(SdTypes.SEARCH); - keyWords.add(SdTypes.DOCUMENT); + keyWords.add(SdTypes.INDEXING); + keyWords.add(SdTypes.INPUT); + keyWords.add(SdTypes.DOCUMENT_SUMMARY); keyWords.add(SdTypes.INHERITS); + keyWords.add(SdTypes.IMPORT); + keyWords.add(SdTypes.AS); + keyWords.add(SdTypes.FIELDSET); + keyWords.add(SdTypes.FIELDS); + keyWords.add(SdTypes.CONSTANT); + keyWords.add(SdTypes.FILE); + keyWords.add(SdTypes.URI); + keyWords.add(SdTypes.OUTPUT); + keyWords.add(SdTypes.ONNX_MODEL); + keyWords.add(SdTypes.ANNOTATION); + keyWords.add(SdTypes.RANK_PROFILE); + keyWords.add(SdTypes.MATCH_PHASE); + keyWords.add(SdTypes.FIRST_PHASE); + keyWords.add(SdTypes.EXPRESSION); + keyWords.add(SdTypes.SECOND_PHASE); + keyWords.add(SdTypes.RANK_PROPERTIES); + keyWords.add(SdTypes.MACRO); + keyWords.add(SdTypes.FUNCTION); + keyWords.add(SdTypes.INLINE); + keyWords.add(SdTypes.SUMMARY_FEATURES); + keyWords.add(SdTypes.RANK_FEATURES); + keyWords.add(SdTypes.CONSTANTS); + keyWords.add(SdTypes.DOCUMENT); keyWords.add(SdTypes.STRUCT); keyWords.add(SdTypes.STRUCT_FIELD); keyWords.add(SdTypes.MATCH); - keyWords.add(SdTypes.INDEXING); + keyWords.add(SdTypes.DISTANCE_METRIC); + keyWords.add(SdTypes.ALIAS); + keyWords.add(SdTypes.STEMMING); keyWords.add(SdTypes.RANK); keyWords.add(SdTypes.INDEXING_REWRITE); keyWords.add(SdTypes.QUERY_COMMAND); + keyWords.add(SdTypes.BOLDING); + keyWords.add(SdTypes.HNSW); + keyWords.add(SdTypes.SORTING); + keyWords.add(SdTypes.RANK_TYPE); + keyWords.add(SdTypes.WEIGHTEDSET); + keyWords.add(SdTypes.DICTIONARY); + keyWords.add(SdTypes.ID); + keyWords.add(SdTypes.NORMALIZING); + keyWords.add(SdTypes.WEIGHT); + return keyWords; } private static HashSet<IElementType> initConstantsSet() { HashSet<IElementType> constants = new HashSet<>(); - constants.add(SdTypes.SUMMARY); + constants.add(SdTypes.RAW_AS_BASE64_IN_SUMMARY); + constants.add(SdTypes.OMIT_SUMMARY_FEATURES); + constants.add(SdTypes.FROM_DISK); + constants.add(SdTypes.IGNORE_DEFAULT_RANK_FEATURES); constants.add(SdTypes.ATTRIBUTE); + constants.add(SdTypes.ORDER); + constants.add(SdTypes.MAX_HITS); + constants.add(SdTypes.DIVERSITY); + constants.add(SdTypes.MIN_GROUPS); + constants.add(SdTypes.CUTOFF_FACTOR); + constants.add(SdTypes.CUTOFF_STRATEGY); + constants.add(SdTypes.NUM_THREADS_PER_SEARCH); + constants.add(SdTypes.TERMWISE_LIMIT); + constants.add(SdTypes.MIN_HITS_PER_THREAD); + constants.add(SdTypes.NUM_SEARCH_PARTITION); + constants.add(SdTypes.KEEP_RANK_COUNT); + constants.add(SdTypes.RANK_SCORE_DROP_LIMIT); + constants.add(SdTypes.RERANK_COUNT); constants.add(SdTypes.TEXT); constants.add(SdTypes.EXACT); constants.add(SdTypes.EXACT_TERMINATOR); @@ -122,19 +168,40 @@ public class SdSyntaxHighlighter extends SyntaxHighlighterBase { constants.add(SdTypes.MAX_LENGTH); constants.add(SdTypes.GRAM); constants.add(SdTypes.GRAM_SIZE); + constants.add(SdTypes.SUMMARY); constants.add(SdTypes.INDEX); + constants.add(SdTypes.SET_LANGUAGE); constants.add(SdTypes.FAST_SEARCH); constants.add(SdTypes.FAST_ACCESS); - constants.add(SdTypes.ALIAS); - constants.add(SdTypes.SORTING); - constants.add(SdTypes.DISTANCE_METRIC); + constants.add(SdTypes.PAGED); + constants.add(SdTypes.MUTABLE); constants.add(SdTypes.FILTER); constants.add(SdTypes.NORMAL); constants.add(SdTypes.NONE); constants.add(SdTypes.FULL); constants.add(SdTypes.DYNAMIC); + constants.add(SdTypes.SOURCE); + constants.add(SdTypes.TO); constants.add(SdTypes.MATCHED_ELEMENTS_ONLY); - + constants.add(SdTypes.ON); + constants.add(SdTypes.OFF); + constants.add(SdTypes.TRUE); + constants.add(SdTypes.FALSE); + constants.add(SdTypes.ARITY); + constants.add(SdTypes.LOWER_BOUND); + constants.add(SdTypes.UPPER_BOUND); + constants.add(SdTypes.DENSE_POSTING_LIST_THRESHOLD); + constants.add(SdTypes.ENABLE_BM25); + constants.add(SdTypes.MAX_LINKS_PER_NODE); + constants.add(SdTypes.NEIGHBORS_TO_EXPLORE_AT_INSERT); + constants.add(SdTypes.MULTI_THREADED_INDEXING); + constants.add(SdTypes.ASCENDING); + constants.add(SdTypes.DESCENDING); + constants.add(SdTypes.STRENGTH); + constants.add(SdTypes.LOCALE); + constants.add(SdTypes.CREATE_IF_NONEXISTENT); + constants.add(SdTypes.REMOVE_IF_ZERO); + return constants; } } diff --git a/sd-plugin/src/main/java/org/intellij/sdk/language/findUsages/SdFindUsagesProvider.java b/sd-plugin/src/main/java/org/intellij/sdk/language/findUsages/SdFindUsagesProvider.java index 4ec407e580d..d011d34227f 100644 --- a/sd-plugin/src/main/java/org/intellij/sdk/language/findUsages/SdFindUsagesProvider.java +++ b/sd-plugin/src/main/java/org/intellij/sdk/language/findUsages/SdFindUsagesProvider.java @@ -28,7 +28,7 @@ public class SdFindUsagesProvider implements FindUsagesProvider { TokenSet.create(SdTypes.ID_REG, SdTypes.ID_WITH_DASH_REG, SdTypes.IDENTIFIER_VAL, SdTypes.IDENTIFIER_WITH_DASH_VAL), TokenSet.create(SdTypes.COMMENT), - TokenSet.create(SdTypes.STRING, SdTypes.INTEGER_REG, SdTypes.FLOAT_REG)); + TokenSet.create(SdTypes.STRING_REG, SdTypes.INTEGER_REG, SdTypes.FLOAT_REG)); } @Override diff --git a/sd-plugin/src/main/java/org/intellij/sdk/language/parser/SdParserDefinition.java b/sd-plugin/src/main/java/org/intellij/sdk/language/parser/SdParserDefinition.java index 2a169707a79..baf31cde898 100644 --- a/sd-plugin/src/main/java/org/intellij/sdk/language/parser/SdParserDefinition.java +++ b/sd-plugin/src/main/java/org/intellij/sdk/language/parser/SdParserDefinition.java @@ -26,7 +26,7 @@ import org.jetbrains.annotations.NotNull; public class SdParserDefinition implements ParserDefinition { public static final TokenSet WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE); public static final TokenSet COMMENTS = TokenSet.create(SdTypes.COMMENT); - public static final TokenSet STRINGS = TokenSet.create(SdTypes.STRING); + public static final TokenSet STRINGS = TokenSet.create(SdTypes.STRING_REG); public static final IFileElementType FILE = new IFileElementType(SdLanguage.INSTANCE); diff --git a/sd-plugin/src/main/java/org/intellij/sdk/language/parser/sd.bnf b/sd-plugin/src/main/java/org/intellij/sdk/language/parser/sd.bnf index 245975f301c..073673ee30c 100644 --- a/sd-plugin/src/main/java/org/intellij/sdk/language/parser/sd.bnf +++ b/sd-plugin/src/main/java/org/intellij/sdk/language/parser/sd.bnf @@ -35,7 +35,7 @@ NOTE: This grammar does not enforce zero-or-one occurrences of elements (treats ARITHMETIC_OPERATOR = 'regexp:[\-+*/]' INTEGER_REG = 'regexp:[0-9]+' FLOAT_REG = 'regexp:[0-9]+[.][0-9]+[e]?' - STRING = 'regexp:[\"][^\"]*[\"]' + STRING_REG = 'regexp:[\"][^\"]*[\"]' WORD_REG = 'regexp:\w+' ] } @@ -95,7 +95,7 @@ private UriPath ::= ('H'|'h') ('T'|'t') ('T'|'t') ('P'|'p') ('S'|'s')? ':' ('//' OnnxModelDefinition ::= onnx-model IdentifierVal '{' OnnxModelBody '}' OnnxModelBody ::= OnnxModelBodyOptions* private OnnxModelBodyOptions ::= (file ':' FilePath) | (uri ':' UriPath) | - ((input | output) (IdentifierVal | STRING) ':' ('.' | '/' | '(' | ')' | IdentifierWithDashVal | WORD_REG)) + ((input | output) (IdentifierVal | STRING_REG) ':' ('.' | '/' | '(' | ')' | IdentifierWithDashVal | WORD_REG)) SchemaAnnotationDefinition ::= AnnotationDefinition { mixin="org.intellij.sdk.language.psi.impl.SdNamedElementImpl" @@ -168,8 +168,8 @@ private SecondPhaseBodyOptions ::= (rerank-count ':' INTEGER_REG) | ExpressionDe RankPropertiesDefinition ::= rank-properties '{' RankPropertiesBody '}' RankPropertiesBody ::= (RankPropertiesKey ':' RankPropertiesValue)+ -RankPropertiesKey ::= (IdentifierWithDashVal | STRING | '(' | ')' | '.' | ',')+ -RankPropertiesValue ::= (('-')? INTEGER_REG) | (('-')? FLOAT_REG) | WORD_REG | IdentifierVal | STRING +RankPropertiesKey ::= (IdentifierWithDashVal | STRING_REG | '(' | ')' | '.' | ',')+ +RankPropertiesValue ::= (('-')? INTEGER_REG) | (('-')? FLOAT_REG) | WORD_REG | IdentifierVal | STRING_REG FunctionDefinition ::= (function | macro) inline? IdentifierVal '(' (ArgumentDefinition (',' ArgumentDefinition)*)? ')' '{' ExpressionDefinition '}' @@ -235,7 +235,7 @@ DocumentFieldBody ::= DocumentFieldBodyOptions* // Does not support zero-or-one private DocumentFieldBodyOptions ::= StructFieldDefinition | MatchDefinition | IndexingDefinition | AttributeDefinition | AliasDef | RankDefinition | IndexingRewriteState | QueryCommandDefinition | SummaryDefinition | BoldingDefinition | (id ':' INTEGER_REG) | IndexDefinition | (normalizing ':' IdentifierWithDashVal) | - SortingDefinition | StemmingDefinition | (weight ': INTEGER_REG') | WeightedSetDefinition | + SortingDefinition | StemmingDefinition | (weight ':' INTEGER_REG) | WeightedSetDefinition | RankTypeDefinition | DictionaryDefinition //***** Field's body elements ******// @@ -256,7 +256,7 @@ MatchProperty ::= text | exact | exact-terminator | word | prefix | cased | unca IndexingDefinition ::= indexing (':' IndexingStatement) | ('{' IndexingStatement+ '}') IndexingStatement ::= IndexingStatementOptions (('|' IndexingStatementOptions)*) | ((';' IndexingStatementOptions)*) // Does not support zero-or-one occurrences -IndexingStatementOptions ::= summary | attribute | index | "set_language" +IndexingStatementOptions ::= summary | attribute | index | set_language // Attribute AttributeDefinition ::= attribute ((':' SimpleAttributeProperty) | ('{' (SimpleAttributeProperty | ComplexAttributeProperty)+ '}')) SimpleAttributeProperty ::= fast-search | fast-access | paged | mutable // Does not support zero-or-one occurrences @@ -272,7 +272,7 @@ RankingSetting ::= filter | normal // Indexing Rewrite IndexingRewriteState ::= indexing-rewrite ':' none // Query Command -QueryCommandDefinition ::= query-command ':' IdentifierVal | STRING +QueryCommandDefinition ::= query-command ':' IdentifierVal | STRING_REG // Summary SummaryDefinition ::= summary ((':' SummaryBodyOptions) | (IdentifierWithDashVal? (type FieldTypeName)? '{' SummaryBody '}')) { methods=[getName getPresentation] } @@ -330,7 +330,7 @@ KeywordOrIdentifier ::= schema | search | document | struct | field | type | ind bolding | on | off | true | false | id | normalizing | stemming | arity | hnsw | dictionary | hash | btree | fieldset | fields | constant | annotation | attribute | body | header | index | - reference | summary + reference | summary | set_language // Note- in this form, those keywords can't be use as identifier-with-dash! KeywordNotIdentifier ::= struct-field | document-summary | omit-summary-features | from-disk | rank-profile | rank-type | diff --git a/sd-plugin/src/main/java/org/intellij/sdk/language/sd.flex b/sd-plugin/src/main/java/org/intellij/sdk/language/sd.flex index 02c14a53358..ce8fbd091cc 100644 --- a/sd-plugin/src/main/java/org/intellij/sdk/language/sd.flex +++ b/sd-plugin/src/main/java/org/intellij/sdk/language/sd.flex @@ -68,6 +68,7 @@ WORD = \w+ "indexing" { return INDEXING; } "summary" { return SUMMARY; } "attribute" { return ATTRIBUTE; } + "set_language" { return SET_LANGUAGE; } "array" { return ARRAY; } "raw" { return RAW; } @@ -214,7 +215,7 @@ WORD = \w+ {ARITHMETIC_OPERATOR} { return ARITHMETIC_OPERATOR; } {COMPARISON_OPERATOR} { return COMPARISON_OPERATOR; } {WORD} { return WORD_REG; } - {STRING} { return STRING; } + {STRING} { return STRING_REG; } } diff --git a/sd-plugin/src/main/resources/META-INF/plugin.xml b/sd-plugin/src/main/resources/META-INF/plugin.xml index 7e61f0a8b1e..5ca73d416e0 100644 --- a/sd-plugin/src/main/resources/META-INF/plugin.xml +++ b/sd-plugin/src/main/resources/META-INF/plugin.xml @@ -2,17 +2,29 @@ <idea-plugin> <id>org.intellij.sdk.language</id> <name>SdReader</name> + <version>1.0.0</version> <!-- Text to display as company information on Preferences/Settings | Plugin page --> - <vendor email="shahar.ariel@yahooinc.com">Yahoo</vendor> + <vendor>Vespa</vendor> <!-- Product and plugin compatibility requirements --> <depends>com.intellij.java</depends> <!-- Text to display as description on Preferences/Settings | Plugin page --> <description><![CDATA[ - A plugin to recognize sd files and work with them through IntelliJ<br> - <em></em> + <p>Support for reading Vespa's SD files.</p> + <p>Features:</p> + <ul> + <li>Structure View</li> + <li>Find Usages</li> + <li>Call Hierarchy (for functions/macros)</li> + <li>Go To Declaration</li> + <li>Go to Symbol</li> + <li>Refactoring</li> + <li>Syntax Highlighting</li> + <li>Commenter- enable turning lines into a comment with "Code -> Comment with line comment"</li> + </ul> + <p>Find more information on Vespa's SD files <a href="https://docs.vespa.ai/en/reference/schema-reference.html">here</a>.</p> ]]></description> <!-- please see https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html @@ -20,6 +32,7 @@ <depends>com.intellij.modules.platform</depends> <depends>com.intellij.java</depends> + <!-- Extension points defined by the plugin --> <extensions defaultExtensionNs="com.intellij"> <fileType name="Sd File" implementationClass="org.intellij.sdk.language.SdFileType" fieldName="INSTANCE" language="Sd" extensions="sd"/> @@ -41,8 +54,5 @@ <gotoSymbolContributor implementation="org.intellij.sdk.language.SdChooseByNameContributor"/> <callHierarchyProvider language="Sd" implementationClass="org.intellij.sdk.language.hierarchy.SdCallHierarchyProvider"/> </extensions> - - <actions> - <!-- Add your actions here --> - </actions> -</idea-plugin> + +</idea-plugin>
\ No newline at end of file diff --git a/sd-plugin/src/main/resources/META-INF/pluginIcon.svg b/sd-plugin/src/main/resources/META-INF/pluginIcon.svg index 9babe4c4ef4..caacd6a053e 100644 --- a/sd-plugin/src/main/resources/META-INF/pluginIcon.svg +++ b/sd-plugin/src/main/resources/META-INF/pluginIcon.svg @@ -1,19 +1,10 @@ -<svg version="1.2" baseProfile="tiny-ps" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" width="40" height="40"> - <title>pluginIcon</title> +<svg version="1.2" baseProfile="tiny-ps" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32"> + <title>New Project</title> <defs> - <image width="40" height="40" id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoAQMAAAC2MCouAAAAAXNSR0IB2cksfwAAAANQTFRFAAAAp3o92gAAAAF0Uk5TAEDm2GYAAAAMSURBVHicY2AYWQAAAPAAAQaUif0AAAAASUVORK5CYII="/> - <image width="36" height="36" id="img2" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkAQMAAADbzgrbAAAAAXNSR0IB2cksfwAAAANQTFRFuubnWfllrQAAAAxJREFUeJxjYBieAAAA2AABOXA/oAAAAABJRU5ErkJggg=="/> - <image width="34" height="34" id="img3" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAiAQMAAAAAiZmBAAAAAXNSR0IB2cksfwAAAAZQTFRFAAAAP5aZJJgdHgAAAAJ0Uk5TAP9bkSK1AAAAWUlEQVR4nI3Ouw2AMAxF0YcoXGYERsloyWiMwhgUiIsTKxESDS5O49+T7JRXpgm7tMAhreANg0tK3Q3uNghhVfno+In/lum4kKfjY3plsJ4qEkZaX6uuefMBOOp0ufGf8MYAAAAASUVORK5CYII="/> + <image width="30" height="29" id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAMAAACKeiw+AAAAAXNSR0IB2cksfwAAAUpQTFRFAAAAHKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0lOzY/wAAAG50Uk5TAA5Acarj/8dVMgdq1LgjXdzxzbAfO/iV1epHHGO/f9hcFZ3lQiR08oAPeL7CuWkIYKieoI8u9/n69en2/eAX6GY6rljt7MzmWv4ac5jwEO5RM7381k8skCnX3srvyDdB6/N8jNLnBfT7wXqSr7W47lQGAAABpElEQVR4nIVT6z8CQRS9+7qVNk3FKiqUIvJWbSLvjQh5hkgeef//X83s2rb6hfNhZvecmXvP3LkD8AOOF0QJKWyi3cFBO3ocThmbcDl7e1pVzk08Xp+9j333Cy6ieN2t8oA/IA42Iw4FQ+gPW2oIh0fa0o1GomjqnBujYx1mYvFxv9vIP+jFCejEaAi9vfpm0eOkexOTU8npmVmYm19YXEpRA6LCaHAQ4qDTUlrJqFkeJGU5t7KaBwiii/F29LEka+r6xmZ6C7Z3+uJaYZdG3UM7QFEMCCyHpwCQ2s9Tmf6sanQ4QLEIMRtJMTlbCh+yeYfJyhEdjtEWgzJqutUT9fTs3JRz24xCLDdlmCmkoxe/ywCXauQvGVQJDGuWXJGudGvXN9RR1ZAT8i1l7lCqNA+WVmoJtQRwX394fHrmzYM1BKMs2mlpLeMDkF+ymVeS18siNAD4gF5UOMnW3yj7/vGZ/KoBK6rMW1fSCfNKIEi6X6gR9L92AE7u1kwDFiNjZytiqGX1P40MXFAMYPRKoyBVJC2hzAV/PSKGRrFSpogVGxb3De/eO/7N6EMHAAAAAElFTkSuQmCC"/> </defs> <style> tspan { white-space:pre } - .txt0 { font-size: 20px;fill: #efab00;font-weight: 400;font-family: "DejaVuSans", "DejaVu Sans" } </style> - <use id="Background" href="#img1" x="0" y="0" /> - <use id="Layer 1" style="opacity: 0.42" href="#img2" x="2" y="2" /> - <use id="Layer 2" style="opacity: 0.769" href="#img3" x="3" y="3" /> - <text id="SD" style="transform: matrix(1,0,0,1,7,27);paint-order:stroke fill markers;stroke: #826c34;stroke-width: 2;stroke-linejoin: round;" > - <tspan x="0" y="0" class="txt0">S</tspan><tspan y="0" class="txt0">D -</tspan> - </text> + <use id="Layer 2" href="#img1" x="1" y="2" /> </svg>
\ No newline at end of file diff --git a/sd-plugin/src/main/resources/META-INF/pluginIcon_dark.svg b/sd-plugin/src/main/resources/META-INF/pluginIcon_dark.svg index 9babe4c4ef4..caacd6a053e 100644 --- a/sd-plugin/src/main/resources/META-INF/pluginIcon_dark.svg +++ b/sd-plugin/src/main/resources/META-INF/pluginIcon_dark.svg @@ -1,19 +1,10 @@ -<svg version="1.2" baseProfile="tiny-ps" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" width="40" height="40"> - <title>pluginIcon</title> +<svg version="1.2" baseProfile="tiny-ps" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32"> + <title>New Project</title> <defs> - <image width="40" height="40" id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoAQMAAAC2MCouAAAAAXNSR0IB2cksfwAAAANQTFRFAAAAp3o92gAAAAF0Uk5TAEDm2GYAAAAMSURBVHicY2AYWQAAAPAAAQaUif0AAAAASUVORK5CYII="/> - <image width="36" height="36" id="img2" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkAQMAAADbzgrbAAAAAXNSR0IB2cksfwAAAANQTFRFuubnWfllrQAAAAxJREFUeJxjYBieAAAA2AABOXA/oAAAAABJRU5ErkJggg=="/> - <image width="34" height="34" id="img3" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAiAQMAAAAAiZmBAAAAAXNSR0IB2cksfwAAAAZQTFRFAAAAP5aZJJgdHgAAAAJ0Uk5TAP9bkSK1AAAAWUlEQVR4nI3Ouw2AMAxF0YcoXGYERsloyWiMwhgUiIsTKxESDS5O49+T7JRXpgm7tMAhreANg0tK3Q3uNghhVfno+In/lum4kKfjY3plsJ4qEkZaX6uuefMBOOp0ufGf8MYAAAAASUVORK5CYII="/> + <image width="30" height="29" id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAMAAACKeiw+AAAAAXNSR0IB2cksfwAAAUpQTFRFAAAAHKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0HKy0lOzY/wAAAG50Uk5TAA5Acarj/8dVMgdq1LgjXdzxzbAfO/iV1epHHGO/f9hcFZ3lQiR08oAPeL7CuWkIYKieoI8u9/n69en2/eAX6GY6rljt7MzmWv4ac5jwEO5RM7381k8skCnX3srvyDdB6/N8jNLnBfT7wXqSr7W47lQGAAABpElEQVR4nIVT6z8CQRS9+7qVNk3FKiqUIvJWbSLvjQh5hkgeef//X83s2rb6hfNhZvecmXvP3LkD8AOOF0QJKWyi3cFBO3ocThmbcDl7e1pVzk08Xp+9j333Cy6ieN2t8oA/IA42Iw4FQ+gPW2oIh0fa0o1GomjqnBujYx1mYvFxv9vIP+jFCejEaAi9vfpm0eOkexOTU8npmVmYm19YXEpRA6LCaHAQ4qDTUlrJqFkeJGU5t7KaBwiii/F29LEka+r6xmZ6C7Z3+uJaYZdG3UM7QFEMCCyHpwCQ2s9Tmf6sanQ4QLEIMRtJMTlbCh+yeYfJyhEdjtEWgzJqutUT9fTs3JRz24xCLDdlmCmkoxe/ywCXauQvGVQJDGuWXJGudGvXN9RR1ZAT8i1l7lCqNA+WVmoJtQRwX394fHrmzYM1BKMs2mlpLeMDkF+ymVeS18siNAD4gF5UOMnW3yj7/vGZ/KoBK6rMW1fSCfNKIEi6X6gR9L92AE7u1kwDFiNjZytiqGX1P40MXFAMYPRKoyBVJC2hzAV/PSKGRrFSpogVGxb3De/eO/7N6EMHAAAAAElFTkSuQmCC"/> </defs> <style> tspan { white-space:pre } - .txt0 { font-size: 20px;fill: #efab00;font-weight: 400;font-family: "DejaVuSans", "DejaVu Sans" } </style> - <use id="Background" href="#img1" x="0" y="0" /> - <use id="Layer 1" style="opacity: 0.42" href="#img2" x="2" y="2" /> - <use id="Layer 2" style="opacity: 0.769" href="#img3" x="3" y="3" /> - <text id="SD" style="transform: matrix(1,0,0,1,7,27);paint-order:stroke fill markers;stroke: #826c34;stroke-width: 2;stroke-linejoin: round;" > - <tspan x="0" y="0" class="txt0">S</tspan><tspan y="0" class="txt0">D -</tspan> - </text> + <use id="Layer 2" href="#img1" x="1" y="2" /> </svg>
\ No newline at end of file diff --git a/searchcore/src/vespa/searchcore/config/proton.def b/searchcore/src/vespa/searchcore/config/proton.def index c1ec37e5662..e1bdf13fd36 100644 --- a/searchcore/src/vespa/searchcore/config/proton.def +++ b/searchcore/src/vespa/searchcore/config/proton.def @@ -514,3 +514,6 @@ bucketdb.checksumtype enum {LEGACY, XXHASH64} default = LEGACY restart ## FAST_VALUE uses the new and optimized FastValueBuilderFactory instead. ## TODO: Remove when default has been switched to FAST_VALUE. tensor_implementation enum {TENSOR_ENGINE, FAST_VALUE} default = FAST_VALUE + +## Whether to report issues back to the container via protobuf field +forward_issues bool default = true diff --git a/searchcore/src/vespa/searchcore/proton/matchengine/matchengine.cpp b/searchcore/src/vespa/searchcore/proton/matchengine/matchengine.cpp index 3aedd952d1e..5ad4a7ed52b 100644 --- a/searchcore/src/vespa/searchcore/proton/matchengine/matchengine.cpp +++ b/searchcore/src/vespa/searchcore/proton/matchengine/matchengine.cpp @@ -46,6 +46,7 @@ MatchEngine::MatchEngine(size_t numThreads, size_t threadsPerSearch, uint32_t di _distributionKey(distributionKey), _async(async), _closed(false), + _forward_issues(true), _handlers(), _executor(std::max(size_t(1), numThreads / threadsPerSearch), 256_Ki, match_engine_executor), _threadBundlePool(std::max(size_t(1), threadsPerSearch)), @@ -146,7 +147,13 @@ MatchEngine::performSearch(search::engine::SearchRequest::Source req) _threadBundlePool.release(std::move(threadBundle)); } ret->request = req.release(); - ret->my_issues = std::move(my_issues); + if (_forward_issues) { + ret->my_issues = std::move(my_issues); + } else { + my_issues->for_each_message([](const auto &msg){ + LOG(warning, "unhandled issue: %s", msg.c_str()); + }); + } ret->setDistributionKey(_distributionKey); if ((ret->request->trace().getLevel() > 0) && ret->request->trace().hasTrace()) { ret->request->trace().getRoot().setLong("distribution-key", _distributionKey); diff --git a/searchcore/src/vespa/searchcore/proton/matchengine/matchengine.h b/searchcore/src/vespa/searchcore/proton/matchengine/matchengine.h index 74a39a3ec78..b4e32c45003 100644 --- a/searchcore/src/vespa/searchcore/proton/matchengine/matchengine.h +++ b/searchcore/src/vespa/searchcore/proton/matchengine/matchengine.h @@ -21,6 +21,7 @@ private: const uint32_t _distributionKey; bool _async; bool _closed; + std::atomic<bool> _forward_issues; HandlerMap<ISearchHandler> _handlers; vespalib::ThreadStackExecutor _executor; vespalib::SimpleThreadBundle::Pool _threadBundlePool; @@ -137,6 +138,8 @@ public: search::engine::SearchClient &client) override; void get_state(const vespalib::slime::Inserter &inserter, bool full) const override; + + void set_issue_forwarding(bool enable) { _forward_issues = enable; } }; } // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/server/proton.cpp b/searchcore/src/vespa/searchcore/proton/server/proton.cpp index edf68633124..116ce072700 100644 --- a/searchcore/src/vespa/searchcore/proton/server/proton.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/proton.cpp @@ -296,8 +296,10 @@ Proton::init(const BootstrapConfig::SP & configSnapshot) protonConfig.numthreadspersearch, protonConfig.distributionkey, protonConfig.search.async); + _matchEngine->set_issue_forwarding(protonConfig.forwardIssues); _distributionKey = protonConfig.distributionkey; - _summaryEngine= std::make_unique<SummaryEngine>(protonConfig.numsummarythreads, protonConfig.docsum.async); + _summaryEngine = std::make_unique<SummaryEngine>(protonConfig.numsummarythreads, protonConfig.docsum.async); + _summaryEngine->set_issue_forwarding(protonConfig.forwardIssues); _docsumBySlime = std::make_unique<DocsumBySlime>(*_summaryEngine); IFlushStrategy::SP strategy; @@ -385,6 +387,8 @@ Proton::applyConfig(const BootstrapConfig::SP & configSnapshot) // Called by executor thread during reconfig. const ProtonConfig &protonConfig = configSnapshot->getProtonConfig(); setFS4Compression(protonConfig); + _matchEngine->set_issue_forwarding(protonConfig.forwardIssues); + _summaryEngine->set_issue_forwarding(protonConfig.forwardIssues); _queryLimiter.configure(protonConfig.search.memory.limiter.maxthreads, protonConfig.search.memory.limiter.mincoverage, diff --git a/searchcore/src/vespa/searchcore/proton/summaryengine/summaryengine.cpp b/searchcore/src/vespa/searchcore/proton/summaryengine/summaryengine.cpp index ec5c8c9b72d..95643c7d1a8 100644 --- a/searchcore/src/vespa/searchcore/proton/summaryengine/summaryengine.cpp +++ b/searchcore/src/vespa/searchcore/proton/summaryengine/summaryengine.cpp @@ -59,6 +59,7 @@ SummaryEngine::SummaryEngine(size_t numThreads, bool async) : _lock(), _async(async), _closed(false), + _forward_issues(true), _handlers(), _executor(numThreads, 128_Ki, summary_engine_executor), _metrics(std::make_unique<DocsumMetrics>()) @@ -145,7 +146,13 @@ SummaryEngine::getDocsums(DocsumRequest::UP req) reply = std::make_unique<DocsumReply>(); } reply->setRequest(std::move(req)); - reply->setIssues(std::move(my_issues)); + if (_forward_issues) { + reply->setIssues(std::move(my_issues)); + } else { + my_issues->for_each_message([](const auto &msg){ + LOG(warning, "unhandled issue: %s", msg.c_str()); + }); + } return reply; } diff --git a/searchcore/src/vespa/searchcore/proton/summaryengine/summaryengine.h b/searchcore/src/vespa/searchcore/proton/summaryengine/summaryengine.h index 34eebdc839d..7f6d9328491 100644 --- a/searchcore/src/vespa/searchcore/proton/summaryengine/summaryengine.h +++ b/searchcore/src/vespa/searchcore/proton/summaryengine/summaryengine.h @@ -34,6 +34,7 @@ private: std::mutex _lock; bool _async; bool _closed; + std::atomic<bool> _forward_issues; HandlerMap<ISearchHandler> _handlers; vespalib::ThreadStackExecutor _executor; std::unique_ptr<metrics::MetricSet> _metrics; @@ -126,6 +127,8 @@ public: DocsumReply::UP getDocsums(DocsumRequest::UP req) override; metrics::MetricSet & getMetrics() { return *_metrics; } + + void set_issue_forwarding(bool enable) { _forward_issues = enable; } }; } // namespace proton diff --git a/vespalib/src/tests/net/socket_spec/socket_spec_test.cpp b/vespalib/src/tests/net/socket_spec/socket_spec_test.cpp index 508559893c2..6f266ccb9bd 100644 --- a/vespalib/src/tests/net/socket_spec/socket_spec_test.cpp +++ b/vespalib/src/tests/net/socket_spec/socket_spec_test.cpp @@ -6,33 +6,35 @@ using namespace vespalib; void verify(const SocketSpec &spec, bool valid, const vespalib::string &path, const vespalib::string &name, - const vespalib::string &host, int port) + const vespalib::string &host, const vespalib::string &host_with_fallback, + int port) { EXPECT_EQUAL(spec.valid(), valid); EXPECT_EQUAL(spec.path(), path); EXPECT_EQUAL(spec.name(), name); EXPECT_EQUAL(spec.host(), host); + EXPECT_EQUAL(spec.host_with_fallback(), host_with_fallback); EXPECT_EQUAL(spec.port(), port); } void verify_path(const SocketSpec &spec, const vespalib::string &path) { - TEST_DO(verify(spec, true, path, "", "", -1)); + TEST_DO(verify(spec, true, path, "", "", "", -1)); } void verify_name(const SocketSpec &spec, const vespalib::string &name) { - TEST_DO(verify(spec, true, "", name, "", -1)); + TEST_DO(verify(spec, true, "", name, "", "", -1)); } void verify_host_port(const SocketSpec &spec, const vespalib::string &host, int port) { - TEST_DO(verify(spec, true, "", "", host, port)); + TEST_DO(verify(spec, true, "", "", host, host, port)); } void verify_port(const SocketSpec &spec, int port) { - TEST_DO(verify(spec, true, "", "", "", port)); + TEST_DO(verify(spec, true, "", "", "", "localhost", port)); } void verify_invalid(const SocketSpec &spec) { - TEST_DO(verify(spec, false, "", "", "", -1)); + TEST_DO(verify(spec, false, "", "", "", "", -1)); } void verify_spec(const vespalib::string &str, const vespalib::string &expect) { diff --git a/vespalib/src/vespa/vespalib/net/socket_spec.cpp b/vespalib/src/vespa/vespalib/net/socket_spec.cpp index c8d1f6eb04b..10293d80c3e 100644 --- a/vespalib/src/vespa/vespalib/net/socket_spec.cpp +++ b/vespalib/src/vespa/vespalib/net/socket_spec.cpp @@ -10,6 +10,7 @@ namespace { const vespalib::string tcp_prefix("tcp/"); const vespalib::string ipc_path_prefix("ipc/file:"); const vespalib::string ipc_name_prefix("ipc/name:"); +const vespalib::string fallback_host("localhost"); SocketAddress make_address(const char *node, int port, bool server) { if (server) { @@ -20,7 +21,7 @@ SocketAddress make_address(const char *node, int port, bool server) { } SocketAddress make_address(int port, bool server) { - const char *node = server ? nullptr : "localhost"; + const char *node = server ? nullptr : fallback_host.c_str(); return make_address(node, port, server); } @@ -110,4 +111,10 @@ SocketSpec::replace_host(const vespalib::string &new_host) const return SocketSpec(); } +const vespalib::string & +SocketSpec::host_with_fallback() const +{ + return (_type == Type::PORT) ? fallback_host : host(); +} + } // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/net/socket_spec.h b/vespalib/src/vespa/vespalib/net/socket_spec.h index ef41a471480..06206800797 100644 --- a/vespalib/src/vespa/vespalib/net/socket_spec.h +++ b/vespalib/src/vespa/vespalib/net/socket_spec.h @@ -44,6 +44,7 @@ public: const vespalib::string &path() const { return (_type == Type::PATH) ? _node : _empty; } const vespalib::string &name() const { return (_type == Type::NAME) ? _node : _empty; } const vespalib::string &host() const { return (_type == Type::HOST_PORT) ? _node : _empty; } + const vespalib::string &host_with_fallback() const; int port() const { return _port; } SocketAddress client_address() const { return address(false); } SocketAddress server_address() const { return address(true); } diff --git a/vespalib/src/vespa/vespalib/net/tls/impl/openssl_crypto_codec_impl.cpp b/vespalib/src/vespa/vespalib/net/tls/impl/openssl_crypto_codec_impl.cpp index db705e7644a..d504857d5ae 100644 --- a/vespalib/src/vespa/vespalib/net/tls/impl/openssl_crypto_codec_impl.cpp +++ b/vespalib/src/vespa/vespalib/net/tls/impl/openssl_crypto_codec_impl.cpp @@ -258,7 +258,7 @@ void OpenSslCryptoCodecImpl::enable_hostname_validation_if_requested() { if (_peer_spec.valid() && !_ctx->transport_security_options().disable_hostname_validation()) { auto* verify_param = SSL_get0_param(_ssl.get()); // Internal ptr, no refcount bump or alloc. We must not free. LOG_ASSERT(verify_param != nullptr); - vespalib::string host = _peer_spec.host(); + vespalib::string host = _peer_spec.host_with_fallback(); if (X509_VERIFY_PARAM_set1_host(verify_param, host.c_str(), host.size()) != 1) { throw CryptoException("X509_VERIFY_PARAM_set1_host() failed"); } @@ -268,7 +268,7 @@ void OpenSslCryptoCodecImpl::enable_hostname_validation_if_requested() { void OpenSslCryptoCodecImpl::set_server_name_indication_extension() { if (_peer_spec.valid()) { - vespalib::string host = _peer_spec.host(); + vespalib::string host = _peer_spec.host_with_fallback(); // OpenSSL tries to cast const char* to void* in a macro, even on 1.1.1. GCC is not overly impressed, // so to satiate OpenSSL's quirks we pre-cast away the constness. auto* host_cstr_that_trusts_openssl_not_to_mess_up = const_cast<char*>(host.c_str()); |