Skip to content

Commit

Permalink
build(connector-corda): fix various Unresolved reference kotlin compi…
Browse files Browse the repository at this point in the history
…ler errors

1. Started overriding a specific template (dataClass.mustache) in the
main-server sub-package of the corda connector because of issues that
are further explained here [1] and here [2].
2. Also had to update generator configuration to specifically exclude
spring-doc generation because it seems to be broken within the template
as well: it does not provide updated dependencies for the grandle and
maven manifests and so the `io.swagger.core.v3:swagger-annotations` package
was missing and failing the build in a second way.
3. The example value for the return array of `ListFlowsV1Response` in
the openapi.json spec file of the corda connector was containing dollar
signs ($) which ended up being appended to the kotlin code's annotations
as documentation, but the dollar signs have a special meaning in kotlin
and lead to syntax errors. Updating the examples to not have dollar signs
in the openapi.json specification document resulted in fixing this issue.
4. Also updated the artifact version in the openapi generator configuration
file. This is just a temporary fix, what we really need is scripts bumping
this up as part of the automated release process.

[1] OpenAPITools/openapi-generator#8366 (comment)
[2] OpenAPITools/openapi-generator#17008

Fixes #2662

Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
  • Loading branch information
petermetz committed Nov 14, 2023
1 parent 9a07913 commit 74f3292
Show file tree
Hide file tree
Showing 47 changed files with 68 additions and 333 deletions.
2 changes: 1 addition & 1 deletion packages/cactus-plugin-ledger-connector-corda/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"generate-sdk": "run-p 'generate-sdk:*'",
"generate-sdk:kotlin": "openapi-generator-cli generate -i ./src/main/json/openapi.json -g kotlin -o ./src/main/kotlin/generated/openapi/kotlin-client/ --reserved-words-mappings protected=protected",
"generate-sdk:typescript-axios": "openapi-generator-cli generate -i ./src/main/json/openapi.json -g typescript-axios -o ./src/main/typescript/generated/openapi/typescript-axios/",
"generate-server": "openapi-generator-cli generate -i ./src/main/json/openapi.json -g kotlin-spring -o ./src/main-server/kotlin/gen/kotlin-spring/ -c ./src/main-server/openapi-generator-config.yaml",
"generate-server": "yarn run --top-level openapi-generator-cli generate -i ./src/main/json/openapi.json -g kotlin-spring -o ./src/main-server/kotlin/gen/kotlin-spring/ -c ./src/main-server/openapi-generator-config.yaml",
"watch": "npm-watch",
"webpack": "npm-run-all webpack:dev",
"webpack:dev": "npm-run-all webpack:dev:node webpack:dev:web",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
README.md
pom.xml
settings.gradle
src/main/kotlin/org/hyperledger/cactus/plugin/ledger/connector/corda/server/HomeController.kt
src/main/kotlin/org/hyperledger/cactus/plugin/ledger/connector/corda/server/SpringDocConfiguration.kt
src/main/kotlin/org/hyperledger/cactus/plugin/ledger/connector/corda/server/api/ApiPluginLedgerConnectorCordaController.kt
src/main/kotlin/org/hyperledger/cactus/plugin/ledger/connector/corda/server/api/ApiPluginLedgerConnectorCordaService.kt
src/main/kotlin/org/hyperledger/cactus/plugin/ledger/connector/corda/server/api/ApiUtil.kt
Expand Down Expand Up @@ -42,4 +40,3 @@ src/main/kotlin/org/hyperledger/cactus/plugin/ledger/connector/corda/server/mode
src/main/kotlin/org/hyperledger/cactus/plugin/ledger/connector/corda/server/model/StopMonitorV1Response.kt
src/main/kotlin/org/hyperledger/cactus/plugin/ledger/connector/corda/server/model/X500Principal.kt
src/main/resources/application.yaml
src/main/resources/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ By default a [`pom.xml`](pom.xml) file will be generated. If you specified `grad

To build the project using maven, run:
```bash
mvn package && java -jar target/cactus-connector-corda-server-0.3.0.jar
mvn package && java -jar target/cactus-connector-corda-server-2.0.0-alpha.2.jar
```

To build the project using gradle, run:
```bash
gradle build && java -jar build/libs/cactus-connector-corda-server-0.3.0.jar
gradle build && java -jar build/libs/cactus-connector-corda-server-2.0.0-alpha.2.jar
```

If all builds successfully, the server should run on [http://localhost:8080/](http://localhost:8080/)
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
<artifactId>cactus-connector-corda-server</artifactId>
<packaging>jar</packaging>
<name>cactus-connector-corda-server</name>
<version>0.3.0</version>
<version>2.0.0-alpha.2</version>
<properties>
<springdoc-openapi.version>1.6.8</springdoc-openapi.version>
<findbugs-jsr305.version>3.0.2</findbugs-jsr305.version>
<jakarta-annotation.version>2.1.0</jakarta-annotation.version>
<kotlin-test-junit5.version>1.6.21</kotlin-test-junit5.version>
Expand Down Expand Up @@ -86,12 +85,7 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!--SpringDoc dependencies -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>${springdoc-openapi.version}</version>
</dependency>


<!-- @Nullable annotation -->
<dependency>
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ import org.hyperledger.cactus.plugin.ledger.connector.corda.server.model.StartMo
import org.hyperledger.cactus.plugin.ledger.connector.corda.server.model.StartMonitorV1Response
import org.hyperledger.cactus.plugin.ledger.connector.corda.server.model.StopMonitorV1Request
import org.hyperledger.cactus.plugin.ledger.connector.corda.server.model.StopMonitorV1Response
import io.swagger.v3.oas.annotations.*
import io.swagger.v3.oas.annotations.enums.*
import io.swagger.v3.oas.annotations.media.*
import io.swagger.v3.oas.annotations.responses.*
import io.swagger.v3.oas.annotations.security.*
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
Expand Down Expand Up @@ -50,82 +45,51 @@ import kotlin.collections.Map
@RequestMapping("\${api.base-path:}")
class ApiPluginLedgerConnectorCordaController(@Autowired(required = true) val service: ApiPluginLedgerConnectorCordaService) {

@Operation(
summary = "Clear transactions from internal store so they'll not be available by GetMonitorTransactionsV1 anymore.",
operationId = "clearMonitorTransactionsV1",
description = """""",
responses = [
ApiResponse(responseCode = "200", description = "OK", content = [Content(schema = Schema(implementation = ClearMonitorTransactionsV1Response::class))]) ]
)

@RequestMapping(
method = [RequestMethod.DELETE],
value = ["/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-corda/clear-monitor-transactions"],
produces = ["application/json"],
consumes = ["application/json"]
)
fun clearMonitorTransactionsV1(@Parameter(description = "") @Valid @RequestBody(required = false) clearMonitorTransactionsV1Request: ClearMonitorTransactionsV1Request?): ResponseEntity<ClearMonitorTransactionsV1Response> {
fun clearMonitorTransactionsV1( @Valid @RequestBody(required = false) clearMonitorTransactionsV1Request: ClearMonitorTransactionsV1Request?): ResponseEntity<ClearMonitorTransactionsV1Response> {
return ResponseEntity(service.clearMonitorTransactionsV1(clearMonitorTransactionsV1Request), HttpStatus.valueOf(200))
}

@Operation(
summary = "Deploys a set of jar files (Cordapps, e.g. the contracts in Corda speak).",
operationId = "deployContractJarsV1",
description = """""",
responses = [
ApiResponse(responseCode = "200", description = "OK", content = [Content(schema = Schema(implementation = DeployContractJarsSuccessV1Response::class))]),
ApiResponse(responseCode = "400", description = "Bad Request", content = [Content(schema = Schema(implementation = DeployContractJarsBadRequestV1Response::class))]) ]
)

@RequestMapping(
method = [RequestMethod.POST],
value = ["/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-corda/deploy-contract-jars"],
produces = ["application/json"],
consumes = ["application/json"]
)
fun deployContractJarsV1(@Parameter(description = "") @Valid @RequestBody(required = false) deployContractJarsV1Request: DeployContractJarsV1Request?): ResponseEntity<DeployContractJarsSuccessV1Response> {
fun deployContractJarsV1( @Valid @RequestBody(required = false) deployContractJarsV1Request: DeployContractJarsV1Request?): ResponseEntity<DeployContractJarsSuccessV1Response> {
return ResponseEntity(service.deployContractJarsV1(deployContractJarsV1Request), HttpStatus.valueOf(200))
}

@Operation(
summary = "",
operationId = "diagnoseNodeV1",
description = """Responds with diagnostic information about the Corda node""",
responses = [
ApiResponse(responseCode = "200", description = "OK", content = [Content(schema = Schema(implementation = DiagnoseNodeV1Response::class))]) ]
)

@RequestMapping(
method = [RequestMethod.POST],
value = ["/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-corda/diagnose-node"],
produces = ["application/json"],
consumes = ["application/json"]
)
fun diagnoseNodeV1(@Parameter(description = "") @Valid @RequestBody(required = false) diagnoseNodeV1Request: DiagnoseNodeV1Request?): ResponseEntity<DiagnoseNodeV1Response> {
fun diagnoseNodeV1( @Valid @RequestBody(required = false) diagnoseNodeV1Request: DiagnoseNodeV1Request?): ResponseEntity<DiagnoseNodeV1Response> {
return ResponseEntity(service.diagnoseNodeV1(diagnoseNodeV1Request), HttpStatus.valueOf(200))
}

@Operation(
summary = "Get transactions for monitored state classes.",
operationId = "getMonitorTransactionsV1",
description = """""",
responses = [
ApiResponse(responseCode = "200", description = "OK", content = [Content(schema = Schema(implementation = GetMonitorTransactionsV1Response::class))]) ]
)

@RequestMapping(
method = [RequestMethod.GET],
value = ["/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-corda/get-monitor-transactions"],
produces = ["application/json"],
consumes = ["application/json"]
)
fun getMonitorTransactionsV1(@Parameter(description = "") @Valid @RequestBody(required = false) getMonitorTransactionsV1Request: GetMonitorTransactionsV1Request?): ResponseEntity<GetMonitorTransactionsV1Response> {
fun getMonitorTransactionsV1( @Valid @RequestBody(required = false) getMonitorTransactionsV1Request: GetMonitorTransactionsV1Request?): ResponseEntity<GetMonitorTransactionsV1Response> {
return ResponseEntity(service.getMonitorTransactionsV1(getMonitorTransactionsV1Request), HttpStatus.valueOf(200))
}

@Operation(
summary = "Get the Prometheus Metrics",
operationId = "getPrometheusMetricsV1",
description = """""",
responses = [
ApiResponse(responseCode = "200", description = "OK", content = [Content(schema = Schema(implementation = kotlin.String::class))]) ]
)

@RequestMapping(
method = [RequestMethod.GET],
value = ["/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-corda/get-prometheus-exporter-metrics"],
Expand All @@ -135,88 +99,58 @@ class ApiPluginLedgerConnectorCordaController(@Autowired(required = true) val se
return ResponseEntity(service.getPrometheusMetricsV1(), HttpStatus.valueOf(200))
}

@Operation(
summary = "Invokes a contract on a Corda ledger (e.g. a flow)",
operationId = "invokeContractV1",
description = """""",
responses = [
ApiResponse(responseCode = "200", description = "OK", content = [Content(schema = Schema(implementation = InvokeContractV1Response::class))]) ]
)

@RequestMapping(
method = [RequestMethod.POST],
value = ["/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-corda/invoke-contract"],
produces = ["application/json"],
consumes = ["application/json"]
)
fun invokeContractV1(@Parameter(description = "") @Valid @RequestBody(required = false) invokeContractV1Request: InvokeContractV1Request?): ResponseEntity<InvokeContractV1Response> {
fun invokeContractV1( @Valid @RequestBody(required = false) invokeContractV1Request: InvokeContractV1Request?): ResponseEntity<InvokeContractV1Response> {
return ResponseEntity(service.invokeContractV1(invokeContractV1Request), HttpStatus.valueOf(200))
}

@Operation(
summary = "",
operationId = "listFlowsV1",
description = """Responds with a list of the flows on the Corda node.""",
responses = [
ApiResponse(responseCode = "200", description = "OK", content = [Content(schema = Schema(implementation = ListFlowsV1Response::class))]) ]
)

@RequestMapping(
method = [RequestMethod.POST],
value = ["/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-corda/list-flows"],
produces = ["application/json"],
consumes = ["application/json"]
)
fun listFlowsV1(@Parameter(description = "") @Valid @RequestBody(required = false) listFlowsV1Request: ListFlowsV1Request?): ResponseEntity<ListFlowsV1Response> {
fun listFlowsV1( @Valid @RequestBody(required = false) listFlowsV1Request: ListFlowsV1Request?): ResponseEntity<ListFlowsV1Response> {
return ResponseEntity(service.listFlowsV1(listFlowsV1Request), HttpStatus.valueOf(200))
}

@Operation(
summary = "",
operationId = "networkMapV1",
description = """Responds with a snapshot of the network map as provided by the Corda RPC call: net.corda.core.messaging.CordaRPCOps public abstract fun networkMapSnapshot(): List<NodeInfo>""",
responses = [
ApiResponse(responseCode = "200", description = "OK", content = [Content(schema = Schema(implementation = NodeInfo::class))]) ]
)

@RequestMapping(
method = [RequestMethod.POST],
value = ["/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-corda/network-map"],
produces = ["application/json"],
consumes = ["application/json"]
)
fun networkMapV1(@Parameter(description = "") @Valid @RequestBody(required = false) body: kotlin.Any?): ResponseEntity<List<NodeInfo>> {
fun networkMapV1( @Valid @RequestBody(required = false) body: kotlin.Any?): ResponseEntity<List<NodeInfo>> {
return ResponseEntity(service.networkMapV1(body), HttpStatus.valueOf(200))
}

@Operation(
summary = "Start monitoring corda changes (transactions) of given state class",
operationId = "startMonitorV1",
description = """""",
responses = [
ApiResponse(responseCode = "200", description = "OK", content = [Content(schema = Schema(implementation = StartMonitorV1Response::class))]) ]
)

@RequestMapping(
method = [RequestMethod.POST],
value = ["/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-corda/start-monitor"],
produces = ["application/json"],
consumes = ["application/json"]
)
fun startMonitorV1(@Parameter(description = "") @Valid @RequestBody(required = false) startMonitorV1Request: StartMonitorV1Request?): ResponseEntity<StartMonitorV1Response> {
fun startMonitorV1( @Valid @RequestBody(required = false) startMonitorV1Request: StartMonitorV1Request?): ResponseEntity<StartMonitorV1Response> {
return ResponseEntity(service.startMonitorV1(startMonitorV1Request), HttpStatus.valueOf(200))
}

@Operation(
summary = "Stop monitoring corda changes (transactions) of given state class",
operationId = "stopMonitorV1",
description = """""",
responses = [
ApiResponse(responseCode = "200", description = "OK", content = [Content(schema = Schema(implementation = StopMonitorV1Response::class))]) ]
)

@RequestMapping(
method = [RequestMethod.DELETE],
value = ["/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-corda/stop-monitor"],
produces = ["application/json"],
consumes = ["application/json"]
)
fun stopMonitorV1(@Parameter(description = "") @Valid @RequestBody(required = false) stopMonitorV1Request: StopMonitorV1Request?): ResponseEntity<StopMonitorV1Response> {
fun stopMonitorV1( @Valid @RequestBody(required = false) stopMonitorV1Request: StopMonitorV1Request?): ResponseEntity<StopMonitorV1Response> {
return ResponseEntity(service.stopMonitorV1(stopMonitorV1Request), HttpStatus.valueOf(200))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import net.corda.core.node.services.vault.DEFAULT_PAGE_NUM
import net.corda.core.node.services.vault.PageSpecification
import net.corda.core.node.services.vault.QueryCriteria
import net.corda.core.utilities.loggerFor
import org.hyperledger.cactus.plugin.ledger.connector.corda.server.model.GetMonitorTransactionsV1ResponseTx
import org.hyperledger.cactus.plugin.ledger.connector.corda.server.model.GetMonitorTransactionsV1ResponseTxInner
import rx.Subscription
import java.math.BigInteger
import java.time.LocalDateTime
Expand All @@ -26,7 +26,7 @@ class StateMonitorClientSession(private val rpc: NodeRPCConnection, private val
* Simple data class for monitor reactive `subscription`, and queue of `stateChanges` received from corda
*/
private data class StateMonitor(
val stateChanges: MutableSet<GetMonitorTransactionsV1ResponseTx>,
val stateChanges: MutableSet<GetMonitorTransactionsV1ResponseTxInner>,
val subscription: Subscription
)

Expand Down Expand Up @@ -57,10 +57,10 @@ class StateMonitorClientSession(private val rpc: NodeRPCConnection, private val
val stateUpdates = this.rpc.proxy.vaultTrackByWithPagingSpec(cordaState, criteria, pagingSpec).updates

var indexCounter = BigInteger.valueOf(0)
val stateChanges = mutableSetOf<GetMonitorTransactionsV1ResponseTx>()
val stateChanges = mutableSetOf<GetMonitorTransactionsV1ResponseTxInner>()
val monitorSub = stateUpdates.subscribe { update ->
update.produced.forEach { change ->
val txResponse = GetMonitorTransactionsV1ResponseTx(indexCounter.toString(), change.toString())
val txResponse = GetMonitorTransactionsV1ResponseTxInner(indexCounter.toString(), change.toString())
indexCounter = indexCounter.add(BigInteger.valueOf(1))
logger.debug("Pushing new transaction for state '{}', index {}", stateName, indexCounter)
stateChanges.add(txResponse)
Expand All @@ -78,7 +78,7 @@ class StateMonitorClientSession(private val rpc: NodeRPCConnection, private val
* @param stateName String representation of corda state to monitor.
* @return Set of corda state changes
*/
fun getTransactions(stateName: String): MutableSet<GetMonitorTransactionsV1ResponseTx> {
fun getTransactions(stateName: String): MutableSet<GetMonitorTransactionsV1ResponseTxInner> {
if (!monitors.containsKey(stateName)) {
throw Exception("No monitor running for corda state $stateName on requested client")
}
Expand Down
Loading

0 comments on commit 74f3292

Please sign in to comment.