Skip to content

Commit e4f9b6d

Browse files
Merge pull request #569 from iExecBlockchainComputing/feature/expose-version-through-prometheus-endpoint
Expose version through prometheus endpoint and through VersionController
2 parents fa5e4d7 + 50a1530 commit e4f9b6d

File tree

7 files changed

+154
-97
lines changed

7 files changed

+154
-97
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
88

99
- Share code between transaction types in `IexecHubService`. (#556)
1010
- Expose Pre, App & Post-Compute durations. (#559, #560, #561, #562, #563, #565)
11+
- Expose version through prometheus endpoint and through VersionController. (#569)
1112

1213
### Quality
1314

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2023-2023 IEXEC BLOCKCHAIN TECH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.iexec.worker.version;
18+
19+
import io.micrometer.core.instrument.Gauge;
20+
import io.micrometer.core.instrument.Metrics;
21+
import org.springframework.boot.info.BuildProperties;
22+
import org.springframework.http.ResponseEntity;
23+
import org.springframework.web.bind.annotation.GetMapping;
24+
import org.springframework.web.bind.annotation.RestController;
25+
26+
import javax.annotation.PostConstruct;
27+
28+
@RestController
29+
public class VersionController {
30+
31+
public static final String METRIC_INFO_GAUGE_NAME = "iexec.version.info";
32+
public static final String METRIC_INFO_GAUGE_DESC = "A metric to expose version and application name.";
33+
public static final String METRIC_INFO_LABEL_APP_NAME = "iexecAppName";
34+
public static final String METRIC_INFO_LABEL_APP_VERSION = "iexecAppVersion";
35+
36+
private final BuildProperties buildProperties;
37+
38+
public VersionController(BuildProperties buildProperties) {
39+
this.buildProperties = buildProperties;
40+
}
41+
42+
@PostConstruct
43+
void initializeGaugeVersion() {
44+
Gauge.builder(METRIC_INFO_GAUGE_NAME, 1.0, n -> n)
45+
.description(METRIC_INFO_GAUGE_DESC)
46+
.tags(METRIC_INFO_LABEL_APP_VERSION, buildProperties.getVersion(),
47+
METRIC_INFO_LABEL_APP_NAME, buildProperties.getName())
48+
.register(Metrics.globalRegistry);
49+
}
50+
51+
@GetMapping("/version")
52+
public ResponseEntity<String> getVersion() {
53+
return ResponseEntity.ok(buildProperties.getVersion());
54+
}
55+
}

src/main/java/com/iexec/worker/version/VersionService.java

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/main/java/com/iexec/worker/worker/WorkerService.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
import com.iexec.worker.feign.CustomCoreFeignClient;
2626
import com.iexec.worker.tee.scone.TeeSconeService;
2727
import com.iexec.worker.utils.LoggingUtils;
28-
import com.iexec.worker.version.VersionService;
2928
import lombok.extern.slf4j.Slf4j;
29+
import org.springframework.boot.info.BuildProperties;
3030
import org.springframework.cloud.context.restart.RestartEndpoint;
3131
import org.springframework.context.annotation.Bean;
3232
import org.springframework.stereotype.Service;
@@ -43,7 +43,7 @@ public class WorkerService {
4343
private final CoreConfigurationService coreConfigService;
4444
private final PublicConfigurationService publicConfigService;
4545
private final CustomCoreFeignClient customCoreFeignClient;
46-
private final VersionService versionService;
46+
private final BuildProperties buildProperties;
4747
private final TeeSconeService teeSconeService;
4848
private final RestartEndpoint restartEndpoint;
4949
private final DockerService dockerService;
@@ -53,7 +53,7 @@ public WorkerService(
5353
CoreConfigurationService coreConfigService,
5454
PublicConfigurationService publicConfigService,
5555
CustomCoreFeignClient customCoreFeignClient,
56-
VersionService versionService,
56+
BuildProperties buildProperties,
5757
TeeSconeService teeSconeService,
5858
RestartEndpoint restartEndpoint,
5959
DockerService dockerService,
@@ -62,7 +62,7 @@ public WorkerService(
6262
this.coreConfigService = coreConfigService;
6363
this.publicConfigService = publicConfigService;
6464
this.customCoreFeignClient = customCoreFeignClient;
65-
this.versionService = versionService;
65+
this.buildProperties = buildProperties;
6666
this.teeSconeService = teeSconeService;
6767
this.restartEndpoint = restartEndpoint;
6868
this.dockerService = dockerService;
@@ -77,10 +77,10 @@ public boolean registerWorker() {
7777
log.info("Got public configuration from the core [config:{}]", publicConfigService.getPublicConfiguration());
7878

7979
if (!publicConfigService.getRequiredWorkerVersion().isEmpty() &&
80-
!versionService.getVersion().equals(publicConfigService.getRequiredWorkerVersion())) {
80+
!buildProperties.getVersion().equals(publicConfigService.getRequiredWorkerVersion())) {
8181

8282
String badVersion = String.format("Bad version! please upgrade your iexec-worker [current:%s, required:%s]",
83-
versionService.getVersion(), publicConfigService.getRequiredWorkerVersion());
83+
buildProperties.getVersion(), publicConfigService.getRequiredWorkerVersion());
8484

8585
LoggingUtils.printHighlightedMessage(badVersion);
8686
return false;
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright 2023-2023 IEXEC BLOCKCHAIN TECH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.iexec.worker.version;
17+
18+
import io.micrometer.core.instrument.Gauge;
19+
import io.micrometer.core.instrument.Metrics;
20+
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
21+
import org.junit.jupiter.api.AfterEach;
22+
import org.junit.jupiter.api.BeforeAll;
23+
import org.junit.jupiter.api.BeforeEach;
24+
import org.junit.jupiter.api.Test;
25+
import org.junit.jupiter.api.extension.ExtendWith;
26+
import org.springframework.beans.factory.annotation.Autowired;
27+
import org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration;
28+
import org.springframework.boot.info.BuildProperties;
29+
import org.springframework.context.annotation.Import;
30+
import org.springframework.http.ResponseEntity;
31+
import org.springframework.test.context.junit.jupiter.SpringExtension;
32+
33+
import static org.assertj.core.api.Assertions.assertThat;
34+
import static org.junit.jupiter.api.Assertions.assertEquals;
35+
36+
@ExtendWith(SpringExtension.class)
37+
@Import(ProjectInfoAutoConfiguration.class)
38+
class VersionControllerTests {
39+
40+
private VersionController versionController;
41+
42+
@Autowired
43+
private BuildProperties buildProperties;
44+
45+
@BeforeAll
46+
static void initRegistry() {
47+
Metrics.globalRegistry.add(new SimpleMeterRegistry());
48+
}
49+
50+
@BeforeEach
51+
void init() {
52+
versionController = new VersionController(buildProperties);
53+
versionController.initializeGaugeVersion();
54+
}
55+
56+
@AfterEach
57+
void afterEach() {
58+
Metrics.globalRegistry.clear();
59+
}
60+
61+
@Test
62+
void testVersionController() {
63+
assertEquals(ResponseEntity.ok(buildProperties.getVersion()), versionController.getVersion());
64+
}
65+
66+
@Test
67+
void shouldReturnInfoGauge() {
68+
final Gauge info = Metrics.globalRegistry.find(VersionController.METRIC_INFO_GAUGE_NAME).gauge();
69+
assertThat(info)
70+
.isNotNull()
71+
.extracting(Gauge::getId)
72+
.isNotNull()
73+
.extracting(
74+
id -> id.getTag(VersionController.METRIC_INFO_LABEL_APP_NAME),
75+
id -> id.getTag(VersionController.METRIC_INFO_LABEL_APP_VERSION)
76+
)
77+
.containsExactly(buildProperties.getName(), buildProperties.getVersion());
78+
}
79+
}
80+

src/test/java/com/iexec/worker/version/VersionServiceTests.java

Lines changed: 0 additions & 49 deletions
This file was deleted.

src/test/java/com/iexec/worker/worker/WorkerServiceTests.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,26 @@
2323
import com.iexec.worker.docker.DockerService;
2424
import com.iexec.worker.feign.CustomCoreFeignClient;
2525
import com.iexec.worker.tee.scone.TeeSconeService;
26-
import com.iexec.worker.version.VersionService;
2726
import org.junit.jupiter.api.BeforeEach;
2827
import org.junit.jupiter.api.Test;
28+
import org.junit.jupiter.api.extension.ExtendWith;
2929
import org.mockito.ArgumentCaptor;
3030
import org.mockito.Mock;
3131
import org.mockito.MockitoAnnotations;
32+
import org.springframework.beans.factory.annotation.Autowired;
33+
import org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration;
34+
import org.springframework.boot.info.BuildProperties;
3235
import org.springframework.cloud.context.restart.RestartEndpoint;
36+
import org.springframework.context.annotation.Import;
37+
import org.springframework.test.context.junit.jupiter.SpringExtension;
3338

3439
import java.util.Collections;
3540

3641
import static org.assertj.core.api.Assertions.assertThat;
3742
import static org.mockito.Mockito.*;
3843

44+
@ExtendWith(SpringExtension.class)
45+
@Import(ProjectInfoAutoConfiguration.class)
3946
class WorkerServiceTests {
4047
private static final String WORKER_WALLET_ADDRESS = "0x2D29bfBEc903479fe4Ba991918bAB99B494f2bEf";
4148

@@ -48,8 +55,8 @@ class WorkerServiceTests {
4855
private PublicConfigurationService publicConfigService;
4956
@Mock
5057
private CustomCoreFeignClient customCoreFeignClient;
51-
@Mock
52-
private VersionService versionService;
58+
@Autowired
59+
private BuildProperties buildProperties;
5360
@Mock
5461
private TeeSconeService teeSconeService;
5562
@Mock
@@ -66,7 +73,7 @@ void beforeEach() {
6673
coreConfigService,
6774
publicConfigService,
6875
customCoreFeignClient,
69-
versionService,
76+
buildProperties,
7077
teeSconeService,
7178
restartEndpoint,
7279
dockerService,
@@ -76,7 +83,7 @@ void beforeEach() {
7683

7784
@Test
7885
void shouldRegisterWorker() {
79-
String version = "version";
86+
String version = buildProperties.getVersion();
8087
String name = "name";
8188
String os = "os";
8289
String cpu = "cpu";
@@ -85,7 +92,6 @@ void shouldRegisterWorker() {
8592
boolean isTee = true;
8693
boolean isGpu = true;
8794
when(publicConfigService.getRequiredWorkerVersion()).thenReturn(version);
88-
when(versionService.getVersion()).thenReturn(version);
8995
when(workerConfigService.getWorkerName()).thenReturn(name);
9096
when(workerConfigService.getOS()).thenReturn(os);
9197
when(workerConfigService.getCPU()).thenReturn(cpu);
@@ -117,7 +123,6 @@ void shouldRegisterWorker() {
117123
void shouldNotRegisterWorkerSinceBadVersion() {
118124
String version = "version";
119125
when(publicConfigService.getRequiredWorkerVersion()).thenReturn(version);
120-
when(versionService.getVersion()).thenReturn("someOtherVersion");
121126

122127
assertThat(workerService.registerWorker()).isFalse();
123128

0 commit comments

Comments
 (0)