Skip to content

Commit 4a2ab20

Browse files
Merge pull request #122 from iExecBlockchainComputing/feature/expose-version-through-prometheus-endpoint
Expose version through prometheus endpoint and through VersionController
2 parents fd51c20 + 26b4113 commit 4a2ab20

File tree

8 files changed

+220
-95
lines changed

8 files changed

+220
-95
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
99
- Send up to 2 blockchain transactions per block.
1010
With a big enough latency, the nonce is properly computed in web3j library against the pending block. (#111)
1111
- Add `BlockchainAdapterService` class to implement interactions with REST API. (#117 #118 #119)
12+
- Expose version through prometheus endpoint and through VersionController. (#122)
1213

1314
### Bug Fixes
1415

@@ -27,6 +28,7 @@ All notable changes to this project will be documented in this file.
2728
- Upgrade to `eclipse-temurin:11.0.21_9-jre-focal`. (#121)
2829
- Upgrade to Spring Boot 2.7.17. (#120)
2930
- Upgrade to Spring Dependency Management Plugin 1.1.4. (#120)
31+
- Upgrade to Spring Doc OpenAPI 1.7.0. (#122)
3032
- Upgrade to `jenkins-library` 2.7.4. (#116)
3133

3234
## [[8.2.0]](https://github.com/iExecBlockchainComputing/iexec-blockchain-adapter-api/releases/tag/v8.2.0) 2023-09-28

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ dependencies {
6969
implementation 'org.springframework.boot:spring-boot-starter-web'
7070

7171
// Spring Doc
72-
implementation 'org.springdoc:springdoc-openapi-ui:1.6.3'
72+
implementation 'org.springdoc:springdoc-openapi-ui:1.7.0'
7373

7474
// iexec
7575
implementation "com.iexec.commons:iexec-commons-poco:$iexecCommonsPocoVersion"

src/main/java/com/iexec/blockchain/swagger/OpenApiConfig.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020 IEXEC BLOCKCHAIN TECH
2+
* Copyright 2020-2023 IEXEC BLOCKCHAIN TECH
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,23 +16,25 @@
1616

1717
package com.iexec.blockchain.swagger;
1818

19-
20-
import com.iexec.blockchain.version.VersionService;
2119
import io.swagger.v3.oas.models.Components;
2220
import io.swagger.v3.oas.models.OpenAPI;
2321
import io.swagger.v3.oas.models.info.Info;
2422
import io.swagger.v3.oas.models.security.SecurityScheme;
23+
import org.springframework.boot.info.BuildProperties;
2524
import org.springframework.context.annotation.Bean;
2625
import org.springframework.context.annotation.Configuration;
2726

2827
@Configuration
2928
public class OpenApiConfig {
3029
public static final String SWAGGER_BASIC_AUTH = "basicAuth";
30+
public static final String SWAGGER_SECURITY_SCHEME_KEY = "basicScheme";
31+
public static final String SWAGGER_SECURITY_SCHEME = "basic";
32+
public static final String TITLE = "iExec Blockchain Adapter";
3133

32-
private final VersionService versionService;
34+
private final BuildProperties buildProperties;
3335

34-
public OpenApiConfig(VersionService versionService) {
35-
this.versionService = versionService;
36+
public OpenApiConfig(BuildProperties buildProperties) {
37+
this.buildProperties = buildProperties;
3638
}
3739

3840
/*
@@ -43,14 +45,14 @@ public OpenAPI api() {
4345
return new OpenAPI()
4446
.info(
4547
new Info()
46-
.title("iExec Blockchain Adapter")
47-
.version(versionService.getVersion())
48+
.title(TITLE)
49+
.version(buildProperties.getVersion())
4850
)
4951
.components(
5052
new Components().addSecuritySchemes(
51-
"basicScheme", new SecurityScheme()
53+
SWAGGER_SECURITY_SCHEME_KEY, new SecurityScheme()
5254
.type(SecurityScheme.Type.HTTP)
53-
.scheme("basic")
55+
.scheme(SWAGGER_SECURITY_SCHEME)
5456
.in(SecurityScheme.In.HEADER)
5557
.name(SWAGGER_BASIC_AUTH)
5658
)
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+
package com.iexec.blockchain.version;
17+
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/blockchain/version/VersionService.java

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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.blockchain.swagger;
17+
18+
import io.swagger.v3.oas.models.OpenAPI;
19+
import io.swagger.v3.oas.models.info.Info;
20+
import io.swagger.v3.oas.models.security.SecurityScheme;
21+
import org.junit.jupiter.api.BeforeEach;
22+
import org.junit.jupiter.api.Test;
23+
import org.junit.jupiter.api.extension.ExtendWith;
24+
import org.springframework.beans.factory.annotation.Autowired;
25+
import org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration;
26+
import org.springframework.boot.info.BuildProperties;
27+
import org.springframework.context.annotation.Import;
28+
import org.springframework.test.context.junit.jupiter.SpringExtension;
29+
30+
import static org.assertj.core.api.Assertions.assertThat;
31+
32+
@ExtendWith(SpringExtension.class)
33+
@Import(ProjectInfoAutoConfiguration.class)
34+
class OpenApiConfigTests {
35+
36+
@Autowired
37+
private BuildProperties buildProperties;
38+
39+
private OpenApiConfig openApiConfig;
40+
41+
@BeforeEach
42+
void setUp() {
43+
openApiConfig = new OpenApiConfig(buildProperties);
44+
}
45+
46+
@Test
47+
void shouldReturnOpenAPIObjectWithCorrectInfo() {
48+
OpenAPI api = openApiConfig.api();
49+
assertThat(api).isNotNull();
50+
51+
assertThat(api.getInfo()).isNotNull().
52+
extracting(
53+
Info::getVersion,
54+
Info::getTitle
55+
)
56+
.containsExactly(buildProperties.getVersion(), OpenApiConfig.TITLE);
57+
58+
assertThat(api.getComponents()).isNotNull();
59+
SecurityScheme securityScheme = api.getComponents().getSecuritySchemes().get(OpenApiConfig.SWAGGER_SECURITY_SCHEME_KEY);
60+
61+
assertThat(securityScheme)
62+
.isNotNull()
63+
.extracting(
64+
SecurityScheme::getType,
65+
SecurityScheme::getScheme,
66+
SecurityScheme::getIn,
67+
SecurityScheme::getName
68+
)
69+
.containsExactly(SecurityScheme.Type.HTTP, OpenApiConfig.SWAGGER_SECURITY_SCHEME, SecurityScheme.In.HEADER, OpenApiConfig.SWAGGER_BASIC_AUTH);
70+
}
71+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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.blockchain.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+
}

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

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

0 commit comments

Comments
 (0)