Skip to content

Commit 62179c6

Browse files
pditommasoclaude
andcommitted
Refactor RegistryClient to use npr-api model classes
- Replace manual JSON handling with npr-api models and Jackson ObjectMapper - Use CreatePluginReleaseRequest with fluent API for building requests - Use CreatePluginReleaseResponse for parsing responses - Add Jackson dependencies (jackson-databind and jackson-datatype-jsr310) - Register JavaTimeModule to handle OffsetDateTime fields - Fix test mocks to use proper PluginRelease fields instead of non-existent status field 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> Signed-off-by: Paolo Di Tommaso <[email protected]>
1 parent 82ec31b commit 62179c6

File tree

3 files changed

+29
-20
lines changed

3 files changed

+29
-20
lines changed

build.gradle

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,16 @@ version = file('VERSION').text.trim()
1010

1111
repositories {
1212
mavenCentral()
13+
maven { url = 'https://s3-eu-west-1.amazonaws.com/maven.seqera.io/releases' }
14+
maven { url = 'https://s3-eu-west-1.amazonaws.com/maven.seqera.io/snapshots' }
1315
}
14-
1516
dependencies {
1617
implementation 'commons-io:commons-io:2.18.0'
1718
implementation 'com.github.zafarkhaja:java-semver:0.10.2'
1819
implementation 'com.google.code.gson:gson:2.10.1'
20+
implementation 'io.seqera:npr-api:0.15.0'
21+
implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.2'
22+
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.2'
1923

2024
testImplementation('org.spockframework:spock-core:2.3-groovy-3.0')
2125
testImplementation 'org.wiremock:wiremock:3.5.4'

src/main/groovy/io/nextflow/gradle/registry/RegistryClient.groovy

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package io.nextflow.gradle.registry
22

3-
import groovy.json.JsonOutput
4-
import groovy.json.JsonSlurper
3+
import com.fasterxml.jackson.databind.ObjectMapper
4+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
55
import groovy.transform.CompileStatic
66
import groovy.util.logging.Slf4j
7+
import io.seqera.npr.api.schema.v1.CreatePluginReleaseRequest
8+
import io.seqera.npr.api.schema.v1.CreatePluginReleaseResponse
9+
import io.seqera.npr.api.schema.v1.UploadPluginReleaseResponse
710

811
import java.net.http.HttpClient
912
import java.net.http.HttpRequest
@@ -27,6 +30,8 @@ import java.time.Duration
2730
class RegistryClient {
2831
private final URI url
2932
private final String authToken
33+
private final ObjectMapper objectMapper = new ObjectMapper()
34+
.registerModule(new JavaTimeModule())
3035

3136
/**
3237
* Creates a new registry client.
@@ -131,17 +136,17 @@ class RegistryClient {
131136
def fileBytes = Files.readAllBytes(file.toPath())
132137
def checksum = computeSha512(fileBytes)
133138

134-
// Build JSON request body
135-
def requestBody = [
136-
id: id,
137-
version: version,
138-
checksum: "sha512:${checksum}",
139-
provider: provider
140-
]
141-
def jsonBody = JsonOutput.toJson(requestBody)
139+
// Build request using API model with fluent API
140+
def request = new CreatePluginReleaseRequest()
141+
.id(id)
142+
.version(version)
143+
.checksum("sha512:${checksum}".toString())
144+
.provider(provider)
145+
146+
def jsonBody = objectMapper.writeValueAsString(request)
142147

143148
def requestUri = URI.create(url.toString() + "v1/plugins/release")
144-
def request = HttpRequest.newBuilder()
149+
def httpRequest = HttpRequest.newBuilder()
145150
.uri(requestUri)
146151
.header("Authorization", "Bearer ${authToken}")
147152
.header("Content-Type", "application/json")
@@ -150,21 +155,21 @@ class RegistryClient {
150155
.build()
151156

152157
try {
153-
def response = client.send(request, HttpResponse.BodyHandlers.ofString())
158+
def response = client.send(httpRequest, HttpResponse.BodyHandlers.ofString())
154159

155160
if (response.statusCode() != 200) {
156161
throw new RegistryReleaseException(getErrorMessage(response, requestUri))
157162
}
158163

159-
// Parse JSON response to extract releaseId
160-
def json = new JsonSlurper().parseText(response.body()) as Map
161-
return json.releaseId as Long
164+
// Parse JSON response using API model
165+
def responseObj = objectMapper.readValue(response.body(), CreatePluginReleaseResponse)
166+
return responseObj.getReleaseId()
162167
} catch (InterruptedException e) {
163168
Thread.currentThread().interrupt()
164169
throw new RegistryReleaseException("Plugin draft creation to ${requestUri} was interrupted: ${e.message}", e)
165170
} catch (ConnectException e) {
166171
throw new RegistryReleaseException("Unable to connect to plugin repository at ${requestUri}: Connection refused", e)
167-
} catch (UnknownHostException | IOException e) {
172+
} catch (IOException e) {
168173
throw new RegistryReleaseException("Unable to connect to plugin repository at ${requestUri}: ${e.message}", e)
169174
}
170175
}

src/test/groovy/io/nextflow/gradle/registry/RegistryClientTest.groovy

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,15 @@ class RegistryClientTest extends Specification {
5959
.withRequestBody(containing("\"checksum\""))
6060
.willReturn(aResponse()
6161
.withStatus(200)
62-
.withBody('{"releaseId": 123, "pluginRelease": {"status": "DRAFT"}}')))
62+
.withBody('{"releaseId": 123, "pluginRelease": {"version": "1.0.0", "url": "https://example.com/plugin.zip", "date": "2024-01-01T00:00:00Z", "sha512sum": "abc123", "requires": ">=21.0.0", "dependsOn": [], "downloadCount": 0, "downloadGhCount": 0}}')))
6363

6464
// Step 2: Upload artifact (multipart)
6565
wireMockServer.stubFor(post(urlMatching("/api/v1/plugins/release/.*/upload"))
6666
.withHeader("Authorization", equalTo("Bearer test-token"))
6767
.withRequestBody(containing("payload"))
6868
.willReturn(aResponse()
6969
.withStatus(200)
70-
.withBody('{"pluginRelease": {"status": "PUBLISHED"}}')))
70+
.withBody('{"pluginRelease": {"version": "1.0.0", "url": "https://example.com/plugin.zip", "date": "2024-01-01T00:00:00Z", "sha512sum": "abc123", "requires": ">=21.0.0", "dependsOn": [], "downloadCount": 0, "downloadGhCount": 0}}')))
7171

7272
when:
7373
client.release("test-plugin", "1.0.0", pluginFile, "seqera.io")
@@ -162,7 +162,7 @@ class RegistryClientTest extends Specification {
162162
wireMockServer.stubFor(post(urlEqualTo("/api/v1/plugins/release"))
163163
.willReturn(aResponse()
164164
.withStatus(200)
165-
.withBody('{"releaseId": 456}')))
165+
.withBody('{"releaseId": 456, "pluginRelease": {"version": "2.1.0", "url": "https://example.com/plugin.zip", "date": "2024-01-01T00:00:00Z", "sha512sum": "abc123", "requires": ">=21.0.0", "dependsOn": [], "downloadCount": 0, "downloadGhCount": 0}}')))
166166

167167
// Step 2: Upload artifact (multipart)
168168
wireMockServer.stubFor(post(urlMatching("/api/v1/plugins/release/.*/upload"))

0 commit comments

Comments
 (0)