Skip to content

Commit c5d2801

Browse files
authored
Use bom and pass service and realm to token refresh (#641)
Signed-off-by: Valentin Delaye <jonesbusy@users.noreply.github.com>
1 parent 0d34a85 commit c5d2801

6 files changed

Lines changed: 80 additions & 26 deletions

File tree

pom.xml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@
103103

104104
<dependencyManagement>
105105
<dependencies>
106+
<dependency>
107+
<groupId>io.micrometer</groupId>
108+
<artifactId>micrometer-bom</artifactId>
109+
<version>${micrometer.version}</version>
110+
<type>pom</type>
111+
<scope>import</scope>
112+
</dependency>
106113
<dependency>
107114
<groupId>org.junit</groupId>
108115
<artifactId>junit-bom</artifactId>
@@ -137,11 +144,6 @@
137144
<artifactId>classgraph</artifactId>
138145
<version>${classgraph.version}</version>
139146
</dependency>
140-
<dependency>
141-
<groupId>io.micrometer</groupId>
142-
<artifactId>micrometer-core</artifactId>
143-
<version>${micrometer.version}</version>
144-
</dependency>
145147
<dependency>
146148
<groupId>org.apache.commons</groupId>
147149
<artifactId>commons-compress</artifactId>

src/main/java/land/oras/auth/HttpClient.java

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
package land.oras.auth;
2222

23-
import io.micrometer.core.instrument.Counter;
2423
import io.micrometer.core.instrument.MeterRegistry;
2524
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
2625
import java.io.FileNotFoundException;
@@ -68,11 +67,6 @@ public final class HttpClient {
6867
*/
6968
private static final Logger LOG = LoggerFactory.getLogger(HttpClient.class);
7069

71-
/**
72-
* Metric name for token refresh counter
73-
*/
74-
public static final String TOKEN_REFRESH_METRIC = "oras.auth.token.refresh";
75-
7670
/**
7771
* The pattern for the WWW-Authenticate header value
7872
*/
@@ -103,12 +97,6 @@ public final class HttpClient {
10397
* The meter registry for metrics
10498
*/
10599
private MeterRegistry meterRegistry;
106-
107-
/**
108-
* Counter for token refreshes
109-
*/
110-
private Counter tokenRefreshCounter;
111-
112100
/**
113101
* Hidden constructor
114102
*/
@@ -157,9 +145,6 @@ private void setTlsVerify(boolean skipTlsVerify) {
157145
*/
158146
public HttpClient build() {
159147
this.client = this.builder.build();
160-
this.tokenRefreshCounter = Counter.builder(TOKEN_REFRESH_METRIC)
161-
.description("Number of token refreshes performed against the registry")
162-
.register(meterRegistry);
163148
return this;
164149
}
165150

@@ -463,7 +448,9 @@ public <T> TokenResponse refreshToken(
463448
TokenResponse token = JsonUtils.fromJson(responseWrapper.response(), TokenResponse.class)
464449
.forService(service);
465450
TokenCache.put(newScopes, token);
466-
tokenRefreshCounter.increment();
451+
meterRegistry
452+
.counter(Const.METRIC_TOKEN_REFRESH, Const.METRIC_TAG_SERVICE, service, Const.METRIC_TAG_REALM, realm)
453+
.increment();
467454
return token;
468455
}
469456

src/main/java/land/oras/utils/Const.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,4 +440,19 @@ public static String currentTimestamp() {
440440
* OCI Chunk Minimum Length header
441441
*/
442442
public static final String OCI_CHUNK_MIN_LENGTH_HEADER = "OCI-Chunk-Min-Length";
443+
444+
/**
445+
* Metric name for token refresh counter
446+
*/
447+
public static final String METRIC_TOKEN_REFRESH = "land_oras_auth_token_refresh_total";
448+
449+
/**
450+
* Metric name for token refresh duration
451+
*/
452+
public static final String METRIC_TAG_SERVICE = "service";
453+
454+
/**
455+
* Metric name for token refresh duration
456+
*/
457+
public static final String METRIC_TAG_REALM = "realm";
443458
}

src/test/java/land/oras/DockerIoITCase.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@
2222

2323
import static org.junit.jupiter.api.Assertions.*;
2424

25+
import io.micrometer.core.instrument.Counter;
26+
import io.micrometer.core.instrument.MeterRegistry;
27+
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
2528
import java.nio.file.Path;
29+
import land.oras.utils.Const;
2630
import land.oras.utils.ZotUnsecureContainer;
2731
import org.junit.jupiter.api.Test;
2832
import org.junit.jupiter.api.io.TempDir;
@@ -106,8 +110,12 @@ void shouldPullOneBlob() {
106110
void shouldCopyTagToInternalRegistry() {
107111

108112
// Source registry
109-
Registry sourceRegistry =
110-
Registry.Builder.builder().withParallelism(3).defaults().build();
113+
MeterRegistry meterRegistry = new SimpleMeterRegistry();
114+
Registry sourceRegistry = Registry.Builder.builder()
115+
.withMeterRegistry(meterRegistry)
116+
.withParallelism(3)
117+
.defaults()
118+
.build();
111119

112120
// Copy to this internal registry
113121
Registry targetRegistry = Registry.Builder.builder()
@@ -122,6 +130,12 @@ void shouldCopyTagToInternalRegistry() {
122130

123131
CopyUtils.copy(sourceRegistry, containerSource, targetRegistry, containerTarget, CopyUtils.CopyOptions.deep());
124132
assertTrue(targetRegistry.exists(containerTarget));
133+
134+
assertEquals(
135+
1.0,
136+
meterRegistry.find(Const.METRIC_TOKEN_REFRESH).counters().stream()
137+
.mapToDouble(Counter::count)
138+
.sum());
125139
}
126140

127141
@Test

src/test/java/land/oras/RegistryWireMockTest.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
3232
import com.github.tomakehurst.wiremock.junit5.WireMockTest;
3333
import com.github.tomakehurst.wiremock.stubbing.Scenario;
34+
import io.micrometer.core.instrument.Counter;
35+
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
3436
import java.io.IOException;
3537
import java.io.InputStream;
3638
import java.net.URI;
@@ -584,8 +586,7 @@ void shouldRefreshExpiredToken(WireMockRuntimeInfo wmRuntimeInfo) {
584586
WireMock.ok().withBody("blob-data").withHeader(Const.DOCKER_CONTENT_DIGEST_HEADER, digest)));
585587

586588
// Insecure registry with a custom meter registry to track metrics
587-
io.micrometer.core.instrument.simple.SimpleMeterRegistry meterRegistry =
588-
new io.micrometer.core.instrument.simple.SimpleMeterRegistry();
589+
SimpleMeterRegistry meterRegistry = new SimpleMeterRegistry();
589590
Registry registry = Registry.Builder.builder()
590591
.withAuthProvider(new BearerTokenProvider()) // Already bearer token
591592
.withInsecure(true)
@@ -600,8 +601,21 @@ void shouldRefreshExpiredToken(WireMockRuntimeInfo wmRuntimeInfo) {
600601
// Verify that exactly one token refresh was performed
601602
assertEquals(
602603
1.0,
603-
meterRegistry.counter(HttpClient.TOKEN_REFRESH_METRIC).count(),
604+
meterRegistry
605+
.counter(
606+
Const.METRIC_TOKEN_REFRESH,
607+
Const.METRIC_TAG_SERVICE,
608+
"localhost",
609+
Const.METRIC_TAG_REALM,
610+
"http://localhost:%d/token".formatted(wmRuntimeInfo.getHttpPort()))
611+
.count(),
604612
"Token refresh counter should be 1 after one token refresh");
613+
assertEquals(
614+
1.0,
615+
meterRegistry.find(Const.METRIC_TOKEN_REFRESH).counters().stream()
616+
.mapToDouble(Counter::count)
617+
.sum());
618+
TestUtils.dumpMetrics(meterRegistry);
605619
}
606620

607621
@Test

src/test/java/land/oras/TestUtils.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,38 @@
2020

2121
package land.oras;
2222

23+
import io.micrometer.core.instrument.Meter;
24+
import io.micrometer.core.instrument.MeterRegistry;
2325
import java.io.IOException;
2426
import java.nio.file.Files;
2527
import java.nio.file.Path;
28+
import org.slf4j.Logger;
29+
import org.slf4j.LoggerFactory;
2630
import uk.org.webcompere.systemstubs.environment.EnvironmentVariables;
2731

2832
/**
2933
* Several tests utils
3034
*/
3135
public final class TestUtils {
3236

37+
/**
38+
* Logger
39+
*/
40+
private static final Logger LOG = LoggerFactory.getLogger(TestUtils.class);
41+
42+
/**
43+
* Dump current metrics to console for debug purpose
44+
* @param meterRegistry the meter registry to dump
45+
*/
46+
public static void dumpMetrics(MeterRegistry meterRegistry) {
47+
meterRegistry.getMeters().forEach(meter -> {
48+
Meter.Id id = meter.getId();
49+
LOG.info("{} {}", id.getName(), id.getTags());
50+
51+
meter.measure().forEach(ms -> LOG.info(" {}={}", ms.getStatistic(), ms.getValue()));
52+
});
53+
}
54+
3355
/**
3456
* Create a registries.conf file in the given home directory with the given content.
3557
* @param homeDir the home directory where the .config/containers/registries.conf file will be created

0 commit comments

Comments
 (0)