diff options
author | Arne H Juul <arnej@yahooinc.com> | 2022-01-31 09:51:27 +0000 |
---|---|---|
committer | Arne H Juul <arnej@yahooinc.com> | 2022-01-31 09:51:27 +0000 |
commit | b178c2b33a92d73b05f80fc9e4ae300749350525 (patch) | |
tree | 56b1ace78053bd588b6dd01543a81ab923815d1f | |
parent | b1fbc3981cad81e225390d853a869af7f7d480d3 (diff) | |
parent | a5593d8bee266be77fefafe029dba66398e74926 (diff) |
Merge branch 'master' into arnej/cleanup-some-todos-1
20 files changed, 75 insertions, 152 deletions
diff --git a/config-model/src/main/Makefile b/config-model/src/main/Makefile index 75ad002050e..7b16bedb4c7 100644 --- a/config-model/src/main/Makefile +++ b/config-model/src/main/Makefile @@ -10,7 +10,7 @@ all: ${outputdir} ${outputdir}/services.rng ${outputdir}/hosts.rng ${outputdir}/ ${outputdir}: mkdir -p ${outputdir} -${outputdir}/services.rng: ${srcdir}/services.rnc ${srcdir}/common.rnc ${srcdir}/admin.rnc ${srcdir}/clients.rnc ${srcdir}/docproc.rnc ${srcdir}/routing.rnc ${srcdir}/clients-v2.rnc ${srcdir}/content.rnc ${srcdir}/genericmodule.rnc ${srcdir}/legacygenericcluster.rnc ${srcdir}/genericcluster.rnc ${srcdir}/legacygenericmodule.rnc ${srcdir}/containercluster.rnc +${outputdir}/services.rng: ${srcdir}/services.rnc ${srcdir}/common.rnc ${srcdir}/admin.rnc ${srcdir}/clients.rnc ${srcdir}/docproc.rnc ${srcdir}/routing.rnc ${srcdir}/clients-v2.rnc ${srcdir}/content.rnc ${srcdir}/genericmodule.rnc ${srcdir}/genericcluster.rnc ${srcdir}/legacygenericmodule.rnc ${srcdir}/containercluster.rnc java -jar $(trangjar) -I rnc -O rng ${srcdir}/services.rnc ${outputdir}/services.rng ${outputdir}/services.xsd: ${outputdir}/services.rng diff --git a/config-model/src/main/java/com/yahoo/config/model/ConfigModelRepo.java b/config-model/src/main/java/com/yahoo/config/model/ConfigModelRepo.java index fdb6f772d89..0e0f992952a 100644 --- a/config-model/src/main/java/com/yahoo/config/model/ConfigModelRepo.java +++ b/config-model/src/main/java/com/yahoo/config/model/ConfigModelRepo.java @@ -138,12 +138,9 @@ public class ConfigModelRepo implements ConfigModelRepoAdder, Serializable, Iter continue; } if (tagName.equals("config")) { - // this is only for our own use (system tests etc), undocumented: + // Top level config, mainly to be used by the Vespa team. continue; } - if (tagName.equals("cluster")) { - throw new IllegalArgumentException("<" + tagName + "> on top-level is not allowed anymore"); - } if ((tagName.equals("clients")) && deployState.isHosted()) throw new IllegalArgumentException("<" + tagName + "> is not allowed when running Vespa in a hosted environment"); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/ConsumersConfigGenerator.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/ConsumersConfigGenerator.java index e894fba079d..ae2139be43c 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/ConsumersConfigGenerator.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/ConsumersConfigGenerator.java @@ -8,9 +8,11 @@ import com.yahoo.vespa.model.admin.monitoring.Metric; import com.yahoo.vespa.model.admin.monitoring.MetricSet; import com.yahoo.vespa.model.admin.monitoring.MetricsConsumer; +import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.TreeMap; import java.util.stream.Collectors; /** @@ -71,7 +73,7 @@ class ConsumersConfigGenerator { static Consumer.Builder toConsumerBuilder(MetricsConsumer consumer) { Consumer.Builder builder = new Consumer.Builder().name(consumer.id()); - consumer.metrics().values().forEach(metric -> builder.metric(toConsumerMetricBuilder(metric))); + consumer.metrics().values().stream().sorted(Comparator.comparing(a -> a.name)).forEach(metric -> builder.metric(toConsumerMetricBuilder(metric))); return builder; } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/Metric.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/Metric.java index e5e5a30e34f..c2b0a358a54 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/Metric.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/Metric.java @@ -25,11 +25,11 @@ public class Metric { this.name = name; this.outputName = outputName; this.description = description; - this.dimensions = Collections.unmodifiableMap(dimensions); + this.dimensions = Map.copyOf(dimensions); } public Metric(String name, String outputName, String description) { - this(name, outputName, description, new HashMap<>()); + this(name, outputName, description, new LinkedHashMap<>()); } /** diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/BlockFeedGlobalEndpointsFilter.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/BlockFeedGlobalEndpointsFilter.java index da6da75f409..8e8f02e6773 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/BlockFeedGlobalEndpointsFilter.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/BlockFeedGlobalEndpointsFilter.java @@ -6,13 +6,12 @@ import com.yahoo.component.ComponentSpecification; import com.yahoo.component.chain.dependencies.Dependencies; import com.yahoo.component.chain.model.ChainedComponentModel; import com.yahoo.config.model.api.ContainerEndpoint; -import com.yahoo.config.provision.ApplicationId; import com.yahoo.container.bundle.BundleInstantiationSpecification; import com.yahoo.jdisc.http.filter.security.rule.RuleBasedFilterConfig; -import com.yahoo.path.Path; import com.yahoo.vespa.model.clients.ContainerDocumentApi; import com.yahoo.vespa.model.container.ContainerCluster; +import java.util.Collection; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -43,8 +42,9 @@ public class BlockFeedGlobalEndpointsFilter extends Filter implements RuleBasedF .flatMap(e -> e.names().stream()) .collect(Collectors.toSet()); if(hostNames.size() > 0) { + Collection<String> hostnamesSorted = hostNames.stream().sorted().collect(Collectors.toList()); RuleBasedFilterConfig.Rule.Builder rule = new RuleBasedFilterConfig.Rule.Builder() - .hostNames(hostNames) + .hostNames(hostnamesSorted) .pathExpressions(ContainerCluster.RESERVED_URI_PREFIX + "/{*}") .pathExpressions(ContainerDocumentApi.DOCUMENT_V1_PREFIX + "/{*}") .methods(List.of(PUT, POST, DELETE)) diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java index b7bacb34b05..e3aa5bd517f 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java @@ -10,7 +10,7 @@ import com.yahoo.vespa.model.container.http.ConnectorFactory; import java.time.Duration; import java.util.Collection; import java.util.List; -import java.util.Set; +import java.util.stream.Collectors; /** * Component specification for {@link com.yahoo.jdisc.http.server.jetty.ConnectorFactory} with hosted specific configuration. @@ -88,9 +88,9 @@ public class HostedSslConnectorFactory extends ConnectorFactory { connectorBuilder.ssl.enabledProtocols(List.of("TLSv1.2")); if (!tlsCiphersOverride.isEmpty()) { - connectorBuilder.ssl.enabledCipherSuites(tlsCiphersOverride); + connectorBuilder.ssl.enabledCipherSuites(tlsCiphersOverride.stream().sorted().collect(Collectors.toList())); } else { - connectorBuilder.ssl.enabledCipherSuites(Set.copyOf(TlsContext.ALLOWED_CIPHER_SUITES)); + connectorBuilder.ssl.enabledCipherSuites(TlsContext.ALLOWED_CIPHER_SUITES.stream().sorted().collect(Collectors.toList())); } connectorBuilder diff --git a/config-model/src/main/resources/schema/legacygenericcluster.rnc b/config-model/src/main/resources/schema/legacygenericcluster.rnc deleted file mode 100644 index b00d4ff097b..00000000000 --- a/config-model/src/main/resources/schema/legacygenericcluster.rnc +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -# Generic, application-specific service cluster -# -include "legacygenericmodule.rnc" - -LegacyGenericCluster = element cluster { - attribute name { text } & - attribute command { text } & - attribute hostservice { text }? & - attribute num-hosts { text }? & - GenericConfig* & - LegacyGenericModule* & - element node { - service.attlist & - attribute name { text }? & - LegacyGenericModule* & - GenericConfig* - }* -} - diff --git a/config-model/src/main/resources/schema/services.rnc b/config-model/src/main/resources/schema/services.rnc index c8467898639..3a8ffe30563 100644 --- a/config-model/src/main/resources/schema/services.rnc +++ b/config-model/src/main/resources/schema/services.rnc @@ -7,13 +7,11 @@ include "docproc.rnc" include "routing.rnc" include "containercluster.rnc" include "genericcluster.rnc" -include "legacygenericcluster.rnc" start = element services { attribute version { "1.0" }? & attribute application-type { "hosted-infrastructure" }? & element legacy { element v7-geo-positions { xsd:boolean } }? & - LegacyGenericCluster* & GenericCluster* & GenericConfig* & Admin? & diff --git a/container-core/src/main/java/com/yahoo/container/logging/ConnectionLogEntry.java b/container-core/src/main/java/com/yahoo/container/logging/ConnectionLogEntry.java index 26cdd1597c5..e2eeb5d3517 100644 --- a/container-core/src/main/java/com/yahoo/container/logging/ConnectionLogEntry.java +++ b/container-core/src/main/java/com/yahoo/container/logging/ConnectionLogEntry.java @@ -31,6 +31,8 @@ public class ConnectionLogEntry { private final String sslPeerSubject; private final Instant sslPeerNotBefore; private final Instant sslPeerNotAfter; + private final String sslPeerIssuerSubject; + private final String sslPeerFingerprint; private final String sslSniServerName; private final SslHandshakeFailure sslHandshakeFailure; private final List<String> sslSubjectAlternativeNames; @@ -58,6 +60,8 @@ public class ConnectionLogEntry { this.sslPeerSubject = builder.sslPeerSubject; this.sslPeerNotBefore = builder.sslPeerNotBefore; this.sslPeerNotAfter = builder.sslPeerNotAfter; + this.sslPeerIssuerSubject = builder.sslPeerIssuerSubject; + this.sslPeerFingerprint = builder.sslPeerFingerprint; this.sslSniServerName = builder.sslSniServerName; this.sslHandshakeFailure = builder.sslHandshakeFailure; this.sslSubjectAlternativeNames = builder.sslSubjectAlternativeNames; @@ -88,6 +92,8 @@ public class ConnectionLogEntry { public Optional<String> sslPeerSubject() { return Optional.ofNullable(sslPeerSubject); } public Optional<Instant> sslPeerNotBefore() { return Optional.ofNullable(sslPeerNotBefore); } public Optional<Instant> sslPeerNotAfter() { return Optional.ofNullable(sslPeerNotAfter); } + public Optional<String> sslPeerIssuerSubject() { return Optional.ofNullable(sslPeerIssuerSubject); } + public Optional<String> sslPeerFingerprint() { return Optional.ofNullable(sslPeerFingerprint); } public Optional<String> sslSniServerName() { return Optional.ofNullable(sslSniServerName); } public Optional<SslHandshakeFailure> sslHandshakeFailure() { return Optional.ofNullable(sslHandshakeFailure); } public List<String> sslSubjectAlternativeNames() { return sslSubjectAlternativeNames == null ? List.of() : sslSubjectAlternativeNames; } @@ -140,6 +146,8 @@ public class ConnectionLogEntry { private String sslPeerSubject; private Instant sslPeerNotBefore; private Instant sslPeerNotAfter; + private String sslPeerIssuerSubject; + private String sslPeerFingerprint; private String sslSniServerName; private SslHandshakeFailure sslHandshakeFailure; private List<String> sslSubjectAlternativeNames; @@ -221,6 +229,14 @@ public class ConnectionLogEntry { this.sslPeerNotAfter = sslPeerNotAfter; return this; } + public Builder withSslPeerIssuerSubject(String value) { + this.sslPeerIssuerSubject = value; + return this; + } + public Builder withSslPeerFingerprint(String value) { + this.sslPeerFingerprint = value; + return this; + } public Builder withSslSniServerName(String sslSniServerName) { this.sslSniServerName = sslSniServerName; return this; diff --git a/container-core/src/main/java/com/yahoo/container/logging/JsonConnectionLogWriter.java b/container-core/src/main/java/com/yahoo/container/logging/JsonConnectionLogWriter.java index d686c97249f..6d98c247ca0 100644 --- a/container-core/src/main/java/com/yahoo/container/logging/JsonConnectionLogWriter.java +++ b/container-core/src/main/java/com/yahoo/container/logging/JsonConnectionLogWriter.java @@ -68,20 +68,24 @@ class JsonConnectionLogWriter implements LogWriter<ConnectionLogEntry> { Instant sslPeerNotBefore = unwrap(record.sslPeerNotBefore()); Instant sslPeerNotAfter = unwrap(record.sslPeerNotAfter()); String sslSniServerName = unwrap(record.sslSniServerName()); + String sslPeerIssuerSubject = unwrap(record.sslPeerIssuerSubject()); + String sslPeerFingerprint = unwrap(record.sslPeerFingerprint()); ConnectionLogEntry.SslHandshakeFailure sslHandshakeFailure = unwrap(record.sslHandshakeFailure()); List<String> sslSubjectAlternativeNames = record.sslSubjectAlternativeNames(); if (isAnyValuePresent( sslProtocol, sslSessionId, sslCipherSuite, sslPeerSubject, sslPeerNotBefore, sslPeerNotAfter, - sslSniServerName, sslHandshakeFailure)) { + sslSniServerName, sslHandshakeFailure, sslPeerIssuerSubject, sslPeerFingerprint)) { generator.writeObjectFieldStart("ssl"); writeOptionalString(generator, "protocol", sslProtocol); writeOptionalString(generator, "sessionId", sslSessionId); writeOptionalString(generator, "cipherSuite", sslCipherSuite); writeOptionalString(generator, "peerSubject", sslPeerSubject); + writeOptionalString(generator, "peerIssuerSubject", sslPeerIssuerSubject); writeOptionalTimestamp(generator, "peerNotBefore", sslPeerNotBefore); writeOptionalTimestamp(generator, "peerNotAfter", sslPeerNotAfter); + writeOptionalString(generator, "peerFingerprint", sslPeerFingerprint); writeOptionalString(generator, "sniServerName", sslSniServerName); if (sslHandshakeFailure != null) { diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyConnectionLogger.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyConnectionLogger.java index 451a7dbf10d..4e3fd3f29b3 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyConnectionLogger.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyConnectionLogger.java @@ -30,6 +30,9 @@ import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSession; import javax.net.ssl.StandardConstants; import java.net.InetSocketAddress; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.time.Instant; import java.util.ArrayList; @@ -227,7 +230,6 @@ class JettyConnectionLogger extends AbstractLifeCycle implements Connection.List throw new IllegalArgumentException("Unknown connection endpoint type: " + endpoint.getClass().getName()); } } - @FunctionalInterface private interface ListenerHandler { void run() throws Exception; } private static class ConnectionInfo { @@ -249,6 +251,8 @@ class JettyConnectionLogger extends AbstractLifeCycle implements Connection.List private Date sslPeerNotBefore; private Date sslPeerNotAfter; private List<SNIServerName> sslSniServerNames; + private String sslPeerIssuerSubject; + private byte[] sslPeerEncodedCertificate; private SSLHandshakeException sslHandshakeException; private List<String> sslSubjectAlternativeNames; private String proxyProtocolVersion; @@ -307,8 +311,9 @@ class JettyConnectionLogger extends AbstractLifeCycle implements Connection.List this.sslSubjectAlternativeNames = X509CertificateUtils.getSubjectAlternativeNames(peerCertificate).stream() .map(SubjectAlternativeName::getValue) .collect(Collectors.toList()); - - } catch (SSLPeerUnverifiedException e) { + this.sslPeerIssuerSubject = peerCertificate.getIssuerDN().getName(); + this.sslPeerEncodedCertificate = peerCertificate.getEncoded(); + } catch (SSLPeerUnverifiedException | CertificateEncodingException e) { // Throw if peer is not authenticated (e.g when client auth is disabled) // JSSE provides no means of checking for client authentication without catching this exception } @@ -365,10 +370,13 @@ class JettyConnectionLogger extends AbstractLifeCycle implements Connection.List .findAny() .ifPresent(builder::withSslSniServerName); } - if (sslPeerSubject != null && sslPeerNotAfter != null && sslPeerNotBefore != null) { + if (sslPeerSubject != null && sslPeerNotAfter != null && sslPeerNotBefore != null + && sslPeerIssuerSubject != null && sslPeerEncodedCertificate != null) { builder.withSslPeerSubject(sslPeerSubject) + .withSslPeerIssuerSubject(sslPeerIssuerSubject) .withSslPeerNotAfter(sslPeerNotAfter.toInstant()) - .withSslPeerNotBefore(sslPeerNotBefore.toInstant()); + .withSslPeerNotBefore(sslPeerNotBefore.toInstant()) + .withSslPeerFingerprint(certificateFingerprint(sslPeerEncodedCertificate)); } if (sslSubjectAlternativeNames != null && !sslSubjectAlternativeNames.isEmpty()) { builder.withSslSubjectAlternativeNames(sslSubjectAlternativeNames); @@ -394,6 +402,14 @@ class JettyConnectionLogger extends AbstractLifeCycle implements Connection.List return builder.build(); } + private static String certificateFingerprint(byte[] derEncoded) { + try { + return HexDump.toHexString(MessageDigest.getInstance("SHA-1").digest(derEncoded)); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/archive/CuratorArchiveBucketDb.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/archive/CuratorArchiveBucketDb.java index 8b929cb9d10..2820fce38ed 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/archive/CuratorArchiveBucketDb.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/archive/CuratorArchiveBucketDb.java @@ -47,12 +47,12 @@ public class CuratorArchiveBucketDb { this.system = controller.zoneRegistry().system(); } - public Optional<URI> archiveUriFor(ZoneId zoneId, TenantName tenant) { - if (enabled(zoneId, tenant)) { - return Optional.of(URI.create(Text.format("s3://%s/%s/", findOrAssignBucket(zoneId, tenant), tenant.value()))); - } else { - return Optional.empty(); - } + public Optional<URI> archiveUriFor(ZoneId zoneId, TenantName tenant, boolean createIfMissing) { + if ( ! enabled(zoneId, tenant)) return Optional.empty(); + return getBucketNameFromCache(zoneId, tenant) + .or(() -> findAndUpdateArchiveUriCache(zoneId, tenant, buckets(zoneId))) + .or(() -> createIfMissing ? Optional.of(assignToBucket(zoneId, tenant)) : Optional.empty()) + .map(bucketName -> URI.create(Text.format("s3://%s/%s/", bucketName, tenant.value()))); } private boolean enabled(ZoneId zone, TenantName tenant) { @@ -63,12 +63,6 @@ public class CuratorArchiveBucketDb { .value(); } - private String findOrAssignBucket(ZoneId zoneId, TenantName tenant) { - return getBucketNameFromCache(zoneId, tenant) - .or(() -> findAndUpdateArchiveUriCache(zoneId, tenant, buckets(zoneId))) - .orElseGet(() -> assignToBucket(zoneId, tenant)); - } - private String assignToBucket(ZoneId zoneId, TenantName tenant) { try (var lock = curatorDb.lockArchiveBuckets(zoneId)) { Set<ArchiveBucket> zoneBuckets = new HashSet<>(buckets(zoneId)); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveUriUpdater.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveUriUpdater.java index 045960fdce2..7d7fa71e72c 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveUriUpdater.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveUriUpdater.java @@ -52,7 +52,7 @@ public class ArchiveUriUpdater extends ControllerMaintainer { tenantsByZone.forEach((zone, tenants) -> { Map<TenantName, URI> zoneArchiveUris = nodeRepository.getArchiveUris(zone); for (TenantName tenant : tenants) { - archiveBucketDb.archiveUriFor(zone, tenant) + archiveBucketDb.archiveUriFor(zone, tenant, true) .filter(uri -> !uri.equals(zoneArchiveUris.get(tenant))) .ifPresent(uri -> nodeRepository.setArchiveUri(zone, tenant, uri)); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java index 18c2dd49514..32381e6a123 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java @@ -1439,7 +1439,7 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler { response.setDouble("quota", deployment.quota().rate()); deployment.cost().ifPresent(cost -> response.setDouble("cost", cost)); - controller.archiveBucketDb().archiveUriFor(deploymentId.zoneId(), deploymentId.applicationId().tenant()) + controller.archiveBucketDb().archiveUriFor(deploymentId.zoneId(), deploymentId.applicationId().tenant(), false) .ifPresent(archiveUri -> response.setString("archiveUri", archiveUri.toString())); Cursor activity = response.setObject("activity"); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/archive/CuratorArchiveBucketDbTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/archive/CuratorArchiveBucketDbTest.java index d6ec01a2d57..1a052b6a578 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/archive/CuratorArchiveBucketDbTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/archive/CuratorArchiveBucketDbTest.java @@ -16,7 +16,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; public class CuratorArchiveBucketDbTest { @@ -29,19 +29,22 @@ public class CuratorArchiveBucketDbTest { Set.of(new ArchiveBucket("existingBucket", "keyArn").withTenant(TenantName.defaultName()))); // Finds existing bucket in db - assertEquals(Optional.of(URI.create("s3://existingBucket/default/")), bucketDb.archiveUriFor(ZoneId.defaultId(), TenantName.defaultName())); + assertEquals(Optional.of(URI.create("s3://existingBucket/default/")), bucketDb.archiveUriFor(ZoneId.defaultId(), TenantName.defaultName(), true)); // Assigns to existing bucket while there is space IntStream.range(0, 29).forEach(i -> assertEquals( Optional.of(URI.create("s3://existingBucket/tenant" + i + "/")), bucketDb - .archiveUriFor(ZoneId.defaultId(), TenantName.from("tenant" + i)))); + .archiveUriFor(ZoneId.defaultId(), TenantName.from("tenant" + i), true))); // Creates new bucket when existing buckets are full - assertEquals(Optional.of(URI.create("s3://bucketName/lastDrop/")), bucketDb.archiveUriFor(ZoneId.defaultId(), TenantName.from("lastDrop"))); + assertEquals(Optional.of(URI.create("s3://bucketName/lastDrop/")), bucketDb.archiveUriFor(ZoneId.defaultId(), TenantName.from("lastDrop"), true)); // Creates new bucket when there are no existing buckets in zone - assertEquals(Optional.of(URI.create("s3://bucketName/firstInZone/")), bucketDb.archiveUriFor(ZoneId.from("prod.us-east-3"), TenantName.from("firstInZone"))); + assertEquals(Optional.of(URI.create("s3://bucketName/firstInZone/")), bucketDb.archiveUriFor(ZoneId.from("prod.us-east-3"), TenantName.from("firstInZone"), true)); + + // Does not create bucket if not required + assertEquals(Optional.empty(), bucketDb.archiveUriFor(ZoneId.from("prod.us-east-3"), TenantName.from("newTenant"), false)); // Lists all buckets by zone Set<TenantName> existingBucketTenants = Streams.concat(Stream.of(TenantName.defaultName()), IntStream.range(0, 29).mapToObj(i -> TenantName.from("tenant" + i))).collect(Collectors.toUnmodifiableSet()); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainerTest.java index d6e43c07ec8..fe8dc0b1e29 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ArchiveAccessMaintainerTest.java @@ -35,7 +35,7 @@ public class ArchiveAccessMaintainerTest { createTenantWithAccessRole(tester, "tenant2", tenant2role); ZoneId testZone = ZoneId.from("prod.aws-us-east-1c"); - tester.controller().archiveBucketDb().archiveUriFor(testZone, tenant1); + tester.controller().archiveBucketDb().archiveUriFor(testZone, tenant1, true); var testBucket = new ArchiveBucket("bucketName", "keyArn").withTenant(tenant1); MockArchiveService archiveService = (MockArchiveService) tester.controller().serviceRegistry().archiveService(); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-cloud.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-cloud.json index a214969485d..fd4093ca332 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-cloud.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-cloud.json @@ -37,7 +37,6 @@ }, "status": "complete", "quota": "(ignore)", - "archiveUri": "s3://bucketName/scoober/", "activity": {}, "metrics": { "queriesPerSecond": 0.0, diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/AbstractResource.java b/jdisc_core/src/main/java/com/yahoo/jdisc/AbstractResource.java index a131fc557c4..cabadafa8a0 100644 --- a/jdisc_core/src/main/java/com/yahoo/jdisc/AbstractResource.java +++ b/jdisc_core/src/main/java/com/yahoo/jdisc/AbstractResource.java @@ -5,7 +5,6 @@ import com.yahoo.jdisc.handler.RequestHandler; import com.yahoo.jdisc.refcount.DebugReferencesByContextMap; import com.yahoo.jdisc.refcount.DebugReferencesWithStack; import com.yahoo.jdisc.refcount.DestructableResource; -import com.yahoo.jdisc.refcount.ReferencesByCount; import com.yahoo.jdisc.service.ClientProvider; import com.yahoo.jdisc.service.ServerProvider; import com.yahoo.jdisc.refcount.References; @@ -25,12 +24,10 @@ public abstract class AbstractResource implements SharedResource { protected AbstractResource() { DestructableResource destructable = new WrappedResource(this); - if (debug == Debug.SIMPLE) { - references = new DebugReferencesByContextMap(destructable, this); - } else if (debug == Debug.STACK) { + if (debug == Debug.STACK) { references = new DebugReferencesWithStack(destructable); } else { - references = new ReferencesByCount(destructable); + references = new DebugReferencesByContextMap(destructable, this); } } diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/SharedResource.java b/jdisc_core/src/main/java/com/yahoo/jdisc/SharedResource.java index 051cebee465..654402d181c 100644 --- a/jdisc_core/src/main/java/com/yahoo/jdisc/SharedResource.java +++ b/jdisc_core/src/main/java/com/yahoo/jdisc/SharedResource.java @@ -39,7 +39,7 @@ public interface SharedResource { return Debug.valueOf(val); } catch (IllegalArgumentException e) { } } - return Debug.NO; + return Debug.SIMPLE; } /** diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/refcount/ReferencesByCount.java b/jdisc_core/src/main/java/com/yahoo/jdisc/refcount/ReferencesByCount.java deleted file mode 100644 index 0f417c81a8b..00000000000 --- a/jdisc_core/src/main/java/com/yahoo/jdisc/refcount/ReferencesByCount.java +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.refcount; - -import com.yahoo.jdisc.ResourceReference; -import com.yahoo.jdisc.SharedResource; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Does reference counting by using atomic counting of references - * Default in production - * - * @author baldersheim - */ -public class ReferencesByCount implements References { - private final AtomicInteger refCount; - private final DestructableResource resource; - private final NoDebugResourceReference initialReference; - - public ReferencesByCount(DestructableResource resource) { - refCount = new AtomicInteger(1); - this.resource = resource; - initialReference = new NoDebugResourceReference(this); - } - - @Override - public void release() { - initialReference.close(); - } - - @Override - public int referenceCount() { - return refCount.get(); - } - - @Override - public ResourceReference refer(Object context) { - addRef(1); - return new NoDebugResourceReference(this); - } - - @Override - public String currentState() { - return "Active references: " + refCount.get() + "." - + " Resource reference debugging is turned off. Consider toggling the " - + SharedResource.SYSTEM_PROPERTY_NAME_DEBUG - + " system property to get debugging assistance with reference tracking."; - } - - private void removeRef() { - int refCount = addRef(-1); - if (refCount == 0) { - resource.close(); - } - } - - private int addRef(int value) { - while (true) { - int prev = refCount.get(); - if (prev == 0) { - throw new IllegalStateException(getClass().getName() + ".addRef(" + value + "):" - + " Object is already destroyed." - + " Consider toggling the " + SharedResource.SYSTEM_PROPERTY_NAME_DEBUG - + " system property to get debugging assistance with reference tracking."); - } - int next = prev + value; - if (refCount.compareAndSet(prev, next)) { - return next; - } - } - } - - private static class NoDebugResourceReference extends CloseableOnce { - private final ReferencesByCount resource; - - NoDebugResourceReference(final ReferencesByCount resource) { - this.resource = resource; - } - - @Override final void onClose() { resource.removeRef(); } - @Override References getReferences() { return resource; } - } -} |