Skip to content

Bump 4.14.1 snap #121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Build Workflow Dispatch
uses: convictional/[email protected]
with:
owner: hyperledger-web3j
owner: LFDT-web3j
repo: web3j-openapi
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow_file_name: build.yml
Expand Down
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,21 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

# [4.14.0]() (Upcoming)
# [4.14.1]() (Upcoming)

### Bug Fixes

*

### Features

* Bump SNAPSHOT version to 4.14.1 [#121](https://github.com/hyperledger/web3j-openapi/pull/121)

### BREAKING CHANGES

*

# [4.14.0](https://github.com/LFDT-web3j/web3j-openapi/releases/tag/v4.14.0) (2025-04-11)

### Bug Fixes

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ The easiest way to interact with the generated project is via the generated `Swa
Also, you can use our client implementation via adding the following dependency to your project:
```groovy
dependencies {
implementation "org.web3j.openapi:web3j-openapi-client:4.13.0"
implementation "org.web3j.openapi:web3j-openapi-client:4.14.0"
}
```

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ buildscript {

plugins {
id 'de.undercouch.download' version '4.1.2'
id 'com.diffplug.spotless' version '6.25.0'
id 'com.diffplug.spotless' version '7.0.3'
id 'io.codearte.nexus-staging' version '0.30.0'
id 'de.marcphilipp.nexus-publish' version '0.4.0'
}
Expand Down
68 changes: 34 additions & 34 deletions client/src/main/kotlin/org/web3j/openapi/client/ClientService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,43 +29,43 @@ import java.util.logging.Level
import java.util.logging.Logger

class ClientService
@JvmOverloads
constructor(
val uri: String,
readTimeout: Int = DEFAULT_READ_TIMEOUT,
connectTimeout: Int = DEFAULT_CONNECT_TIMEOUT,
) : AutoCloseable {
private val mapper =
jacksonObjectMapper()
.setDefaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.AS_EMPTY))
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
.enable(SerializationFeature.INDENT_OUTPUT)
@JvmOverloads
constructor(
val uri: String,
readTimeout: Int = DEFAULT_READ_TIMEOUT,
connectTimeout: Int = DEFAULT_CONNECT_TIMEOUT,
) : AutoCloseable {
private val mapper =
jacksonObjectMapper()
.setDefaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.AS_EMPTY))
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
.enable(SerializationFeature.INDENT_OUTPUT)

internal val client: Client by lazy {
val config =
ClientConfig().apply {
// Redirect ALL logs to SLF4J using logging.properties
register(LoggingFeature(logger.apply { level = Level.ALL }, Short.MAX_VALUE.toInt()))
register(JacksonJaxbJsonProvider(mapper, arrayOf(Annotations.JACKSON)))
property(ClientProperties.READ_TIMEOUT, readTimeout)
property(ClientProperties.CONNECT_TIMEOUT, connectTimeout)
}
ClientBuilder.newClient(config)
}
internal val client: Client by lazy {
val config =
ClientConfig().apply {
// Redirect ALL logs to SLF4J using logging.properties
register(LoggingFeature(logger.apply { level = Level.ALL }, Short.MAX_VALUE.toInt()))
register(JacksonJaxbJsonProvider(mapper, arrayOf(Annotations.JACKSON)))
property(ClientProperties.READ_TIMEOUT, readTimeout)
property(ClientProperties.CONNECT_TIMEOUT, connectTimeout)
}
ClientBuilder.newClient(config)
}

override fun close() = client.close()
override fun close() = client.close()

companion object {
const val DEFAULT_READ_TIMEOUT: Int = 60000
const val DEFAULT_CONNECT_TIMEOUT: Int = 60000
companion object {
const val DEFAULT_READ_TIMEOUT: Int = 60000
const val DEFAULT_CONNECT_TIMEOUT: Int = 60000

init {
SLF4JBridgeHandler.removeHandlersForRootLogger()
SLF4JBridgeHandler.install()
}
init {
SLF4JBridgeHandler.removeHandlersForRootLogger()
SLF4JBridgeHandler.install()
}

private val logger = Logger.getLogger(ClientService::class.java.canonicalName)!!
private val logger = Logger.getLogger(ClientService::class.java.canonicalName)!!
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,28 @@ import java.io.File
import java.nio.file.Paths

class GenerationTest {

@TempDir
lateinit var tempFolder: File

@Test
fun `generate project Gradle tasks`() {
val contractsFolder = Paths.get(
"src",
"test",
"resources",
"contracts",
).toFile()
val contractsFolder =
Paths
.get(
"src",
"test",
"resources",
"contracts",
).toFile()

val generatorConfiguration = GeneratorConfiguration(
projectName = "testProject",
packageName = "com.test",
outputDir = tempFolder.canonicalPath,
contracts = loadContractConfigurations(listOf(contractsFolder)),
contextPath = "test",
)
val generatorConfiguration =
GeneratorConfiguration(
projectName = "testProject",
packageName = "com.test",
outputDir = tempFolder.canonicalPath,
contracts = loadContractConfigurations(listOf(contractsFolder)),
contextPath = "test",
)
assertDoesNotThrow {
OpenApiGenerator(generatorConfiguration).generate()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@
*/
package org.web3j.openapi.codegen.common

data class Import(val import: String)
data class Import(
val import: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ data class ContractDetails(
var abiDefinitions: List<AbiDefinition>,
) {
init {
abiDefinitions.filter { it.isPayable }
abiDefinitions
.filter { it.isPayable }
.forEach { it.inputs.add(AbiDefinition.NamedType("weiValue", "uint")) }
abiDefinitions = handleDuplicateNames(handleDuplicateNames(abiDefinitions, "event"), "function")
.apply { forEach { abiDefinition -> abiDefinition.inputs = handleDuplicateInputNames(abiDefinition.inputs) } }
abiDefinitions =
handleDuplicateNames(handleDuplicateNames(abiDefinitions, "event"), "function")
.apply { forEach { abiDefinition -> abiDefinition.inputs = handleDuplicateInputNames(abiDefinition.inputs) } }
}

val lowerCaseContractName: String
Expand All @@ -37,10 +39,11 @@ data class ContractDetails(
get() = contractName.decapitalize()

val deployParameters: String
get() = abiDefinitions
.filter { it.type == "constructor" }
.firstOrNull { it.inputs.isNotEmpty() }
?.run {
"(parameters: ${capitalizedContractName}DeployParameters)"
} ?: "()"
get() =
abiDefinitions
.filter { it.type == "constructor" }
.firstOrNull { it.inputs.isNotEmpty() }
?.run {
"(parameters: ${capitalizedContractName}DeployParameters)"
} ?: "()"
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,22 @@ package org.web3j.openapi.codegen.config
import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName
import org.web3j.abi.datatypes.Address

data class GeneratorConfiguration @JvmOverloads constructor(
val projectName: String,
var packageName: String,
val outputDir: String,
val contracts: List<ContractConfiguration>,
val addressLength: Int = Address.DEFAULT_LENGTH / java.lang.Byte.SIZE,
val contextPath: String,
val version: String = VersionProvider.versionName,
val sanitizedProjectName: String = sanitizeName(projectName),
val withImplementations: Boolean = true,
) {
val rootProjectName = sanitizedProjectName.lowercase().replace(' ', '-')
data class GeneratorConfiguration
@JvmOverloads
constructor(
val projectName: String,
var packageName: String,
val outputDir: String,
val contracts: List<ContractConfiguration>,
val addressLength: Int = Address.DEFAULT_LENGTH / java.lang.Byte.SIZE,
val contextPath: String,
val version: String = VersionProvider.versionName,
val sanitizedProjectName: String = sanitizeName(projectName),
val withImplementations: Boolean = true,
) {
val rootProjectName = sanitizedProjectName.lowercase().replace(' ', '-')

init {
packageName = packageName.lowercase()
init {
packageName = packageName.lowercase()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,28 @@ import java.time.format.DateTimeFormatter
import java.util.Properties

object VersionProvider {

val versionName: String
val buildTimestamp: OffsetDateTime

private val timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS O")

init {
val url = javaClass.classLoader.getResource("openapi-version.properties")
?: throw IllegalStateException("No openapi-version.properties file found in the classpath.")
val url =
javaClass.classLoader.getResource("openapi-version.properties")
?: throw IllegalStateException("No openapi-version.properties file found in the classpath.")

val properties = Properties().apply { load(url.openStream()) }

versionName = properties.getProperty("version")
buildTimestamp = properties.getProperty("timestamp").toLong().let {
Instant.ofEpochMilli(it).atOffset(ZoneOffset.UTC)
}
buildTimestamp =
properties.getProperty("timestamp").toLong().let {
Instant.ofEpochMilli(it).atOffset(ZoneOffset.UTC)
}
}

fun getVersion(): Array<String> {
return arrayOf(
fun getVersion(): Array<String> =
arrayOf(
"Version: $versionName",
"Build timestamp: ${buildTimestamp.let { timeFormatter.format(it) }}",
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import java.nio.file.Paths
class CoreGenerator(
configuration: GeneratorConfiguration,
) : AbstractGenerator(
configuration,
) {
configuration,
) {
init {
context["contractsConfiguration"] = configuration.contracts
context["apiImports"] = getApiImports()
Expand All @@ -48,10 +48,12 @@ class CoreGenerator(
logger.debug("Generating ${it.contractDetails.capitalizedContractName} Open API folders and files")
CoreApiGenerator(
configuration.packageName,
folderPath = Paths.get(
folderPath,
it.contractDetails.lowerCaseContractName,
).toString(),
folderPath =
Paths
.get(
folderPath,
it.contractDetails.lowerCaseContractName,
).toString(),
contractDetails = it.contractDetails,
).generate()
}
Expand All @@ -78,11 +80,12 @@ class CoreGenerator(
}
}

private fun getApiImports(): List<Import> {
return configuration.contracts.map {
Import("import ${configuration.packageName}.core.${it.contractDetails.lowerCaseContractName}.${it.contractDetails.capitalizedContractName}")
private fun getApiImports(): List<Import> =
configuration.contracts.map {
Import(
"import ${configuration.packageName}.core.${it.contractDetails.lowerCaseContractName}.${it.contractDetails.capitalizedContractName}",
)
}
}

private fun copySources(folderPath: String) {
generateFromTemplate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ internal class CoreApiGenerator(
}
}

private fun modelImports(): List<Import> {
return contractDetails.abiDefinitions
private fun modelImports(): List<Import> =
contractDetails.abiDefinitions
.filter { it.type == "function" && it.inputs.isNotEmpty() || it.type == "event" }
.map {
if (it.type == "function") {
Expand All @@ -84,10 +84,9 @@ internal class CoreApiGenerator(
)
}
}
}

private fun eventImports(): List<Import> {
return contractDetails.abiDefinitions
private fun eventImports(): List<Import> =
contractDetails.abiDefinitions
.filter { it.type == "event" }
.map {
Import(
Expand All @@ -96,7 +95,6 @@ internal class CoreApiGenerator(
}EventResource",
)
}
}

private fun contractResources(): ContractResources {
val functionResources = mutableListOf<FunctionResource>()
Expand All @@ -123,8 +121,10 @@ internal class CoreApiGenerator(
functionName = sanitizedAbiDefinitionName,
resource = "fun $sanitizedAbiDefinitionName($parameters)",
method = if (it.inputs.isEmpty()) "@GET" else "@POST",
returnType = it.getReturnType(packageName, contractDetails.lowerCaseContractName)
.toString(),
returnType =
it
.getReturnType(packageName, contractDetails.lowerCaseContractName)
.toString(),
operationTag = operationTag,
mediaType = "@Produces(MediaType.APPLICATION_JSON)",
path = "@Path(\"$sanitizedAbiDefinitionName\")",
Expand Down Expand Up @@ -203,12 +203,14 @@ internal class CoreApiGenerator(
name = "${contractDetails.capitalizedContractName}Events.kt",
)

val eventsFolder = File(
Paths.get(
folderPath,
"events",
).toString(),
)
val eventsFolder =
File(
Paths
.get(
folderPath,
"events",
).toString(),
)

contractDetails.abiDefinitions
.filter { it.type == "event" }
Expand Down
Loading