API utilizada para exemplificar fluxo de projeto com Corda do desafio FIAP
para cenário de câmbio
O projeto utiliza o fluxo de versionamento GitHub flow.
Instruções
Apesar de o Java já estar em uma versão a frente, o Corda possui uma limitação sendo necessário utilizar a versão 8 para a execução do CorDapp
Corda requires at least version 8u171, but do not currently support Java 9
or higher for this version of Corda.Corda has been tested against the following Java builds:
- Amazon Corretto
- Oracle JDK
- Red Hat’s OpenJDK
- Zulu’s OpenJDK
OpenJDK builds often exclude JavaFX, which is required by the Corda GUI
tools. Corda supports only Java 8.
O Java 8 pode tanto ser instalado através da JDK contida no site da Oracle ou no site do OpenJDK
Como alternativa é possível utilizar o SDKMan e instalar o Java através do comando:
foo@bar:~$ sdk install java <version>
Para listagem de todas as versões do Java disponíveis, execute o comando:
foo@bar:~$ sdk list java
Instruções
O projeto foi concebido para que a instalação do Gradle fosse opcional, para tanto, é possível rodar as configurações do projeto após instalação do Java pelos arquivos gradle.bat em sistemas Windows e gradlew em sistemas Unix, que interagem com o arquivo gradle-wrapper.jar contido na pasta gradle/wrapper na raiz do projeto.
Caso mesmo assim se deseje rodar o projeto pelo Gradle na máquina, o mesmo pode ser instalado através do site.
Como alternativa é possível utilizar o SDKMan e instalar o Maven através do comando:
foo@bar:~$ sdk install gradle
Para listagem de todas as versões do Gradle disponíveis, execute o comando:
foo@bar:~$ sdk list gradle
Projeto principal
.
├── application
│ ├── cordapp-contracts-states
│ ├── cordapp-flows
│ └── rest-api
├── build
│ ├── dokka
│ ├── nodes
│ │ ├── Banco
│ │ ├── Banco_node.conf
│ │ ├── Corretora
│ │ ├── Corretora_node.conf
│ │ ├── Notary
│ │ ├── Notary_node.conf
│ │ ├── runnodes
│ │ ├── runnodes.bat
│ │ └── runnodes.jar
│ └── reports
│ ├── dependencyCheck
│ ├── docs
│ │ └── dependencyUpdates
│ ├── markdownlint
│ ├── ossindex
│ └── project
│ └── dependencies
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── plugins
│ ├── configs
│ │ └── detekt
│ │ └── config.yml
│ ├── docs.gradle
│ ├── ides.gradle
│ ├── jacoco.gradle
│ ├── kotlin.gradle
│ ├── lint.gradle
│ ├── security.gradle
│ └── sonarqube.gradle
├── README.md
└── settings.gradle
application/cordapp-contracts-states
.
├── build
│ ├── dokka
│ └── reports
│ ├── detekt
│ ├── docs
│ │ └── dependencyUpdates
│ └── project
│ └── dependencies
├── build.gradle
└── src
└── main
└── kotlin
└── br
└── com
└── fiap
└── mba
└── corda
├── contracts
└── states
application/cordapp-flows
.
├── build
│ ├── dokka
│ └── reports
│ ├── detekt
│ ├── docs
│ │ └── dependencyUpdates
│ └── project
├── build.gradle
└── src
└── main
└── kotlin
└── br
└── com
└── fiap
└── mba
└── corda
└── flows
application/rest-api
.
├── build
│ ├── dokka
│ ├── generated
│ │ └── openapi-code-server
│ │ └── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── openapi
│ │ └── cambio
│ │ └── server
│ │ ├── api
│ │ └── model
│ └── reports
│ ├── detekt
│ ├── docs
│ │ └── dependencyUpdates
│ └── project
│ └── dependencies
├── build.gradle
├── plugins
│ ├── mapstruct.gradle
│ └── openapi.gradle
└── src
└── main
├── kotlin
│ └── br
│ └── com
│ └── fiap
│ └── mba
│ └── mscambio
│ ├── configs
│ ├── converters
│ ├── dtos
│ ├── exceptions
│ ├── factories
│ ├── gateways
│ ├── MsCambioApplication.kt
│ ├── resources
│ │ └── impl
│ └── services
│ └── impl
└── resources
├── application-dev.yaml
├── application.yaml
├── i18n
│ └── messages_pt.properties
└── openapi
└── cambio-api.yaml
foo@bar:~$ git clone https://github.com/arthurfnsc/ms-cambio.git
foo@bar:~$ cd ms-cambio
O projeto pode ser executado em ambiente Linux ou Windows, sendo os comandos diferenciando por duas opções Linux e Windows respectivamente
Primeiramente é preciso gerar os nodes do Corda e subí-los. Essas
configurações se encontram no arquivo build.gradle
dentro da task deployNodes
foo@bar:ms-cambio$ [./gradlew | gradlew.bat] clean deployNodes
foo@bar:ms-cambio$ [./build/nodes/runnodes | .\build\nodes\runnodes.bat]
Em seguida é preciso subir os servidores com a aplicação Web para teste
para isso, basta executar as seguintes tasks também presentes no
arquivo build.gradle
foo@bar:ms-cambio$ [./gradlew | gradlew.bat] application:rest-api:runBancoServer
foo@bar:ms-cambio$ [./gradlew | gradlew.bat] application:rest-api:runCorretoraServer
Como o propósito do desafio foi realizar uma Prova de Conceito,
alguns conteúdos mais avançados de segurança não foram explorados,
para tanto, serão executadas as soluções como se estivessem em servidores
Web distintos, porém, as duas apontam para o mesmo ambiente Corda:
Em localhost:50001 estará a solução apontando para o usuário do Banco e em localhost:50002 a solução apontando para para o usuário da Corretora
foo@bar:ms-cambio$ [./gradlew | gradlew.bat] dependencyUpdates
foo@bar:ms-cambio$ [./gradlew | gradlew.bat] dokka
foo@bar:ms-cambio$ [./gradlew | gradlew.bat] projectReport
foo@bar:ms-cambio$ [./gradlew | gradlew.bat] audit
foo@bar:ms-cambio$ [./gradlew | gradlew.bat] dependencyCheckAggregate
foo@bar:ms-cambio$ [./gradlew | gradlew.bat] test
A task de test está associada à task jacocoTestReport (para mais informações plugins/jacoco.gradle)
Porém, por se tratar de um projeto com sub-estruturas de pastas
.
└── application
├── cordapp-contracts-states
├── cordapp-flows
└── rest-api
É necessário executar uma task caso se deseje agrupar os reports a fim de enviá-los para o SonarQube ou caso se deseje ver esses dados agrupados.
foo@bar:ms-cambio$ [./gradlew | gradlew.bat] jacocoRootReport
A task depende da task de test de cada projeto, executando estes primeiramente.
Os Testes de Mutantes são bem úteis para se descobrir comportamentos inesperados no nosso código que não estão cobertos.
Para executá-los no projeto utilize a task:
foo@bar:ms-cambio$ [./gradlew | gradlew.bat] pitest
O SonarQube é uma ferramenta de análise estática de código. Nesse projeto colocamos um arquivo com o docker-compose na pasta config/sonarqube/sonarqube-h2.yml caso se deseje executar a análise em ambiente local. Para tanto, execute os seguintes comandos:
foo@bar:ms-cambio$ docker-compose -f config/sonarqube/sonarqube-h2.yml up
O SonarQube estará disponível na porta 9000. Para o usuário defaut o login é admin e a senha é admin.
Com o SonarQube em execução rode o comando:
foo@bar:ms-cambio$ [./gradlew | gradlew.bat] sonarqube
É comum ao importar o projeto em uma IDE que classes contidas nos pacotes org.openapi.cambio.server apresentem erros de compilação.
Isso ocorre porque ao utilizar a estratégia de API First é necessário a geração das classes para que o projeto possa compilar.
A geração das classes se encontra atrelada ao goal compileKotlin no
ciclo de vida do Gradle, e pode ser melhor detalhado em
"plugins/openapi.gradle na raiz do projeto.
compileKotlin.dependsOn(
generateCambioApiServer
)
sourceSets.main.java.srcDir "$cambioApiServerOutput/src/main/java"
Uma das formas de resolver o problema é a execução da task compileKotlin
foo@bar:ms-cambio$ [./gradlew | gradlew.bat] compileKotlin
Ou a execução de outras tasks que tenham relação direta com o compileKotlin, como build ou bootRun.
As classes geradas se encontrarão no diretório org.openapi.cambio.server dentro do projeto application/rest-api
.
└── build
└── generated
└── openapi-code-server
├── pom.xml
├── README.md
└── src
└── main
└── java
└── org
└── openapi
└── cambio
└── server
├── api
└── model
Mesmo após a geração de classes, é comum algumas IDEs ainda não sincronizarem
as novas classes no projeto aberto, para tanto, lembre-se de sincronizar o
projeto para que as novas classes entrem no classpath do projeto, e com isso,
possam ser importadas por outras classes.
Caso se deseje rodar os testes pelo terminal ou IDE lembre-se de possuir a JDK 8 instalada em uma das versões com suporte
- Amazon Corretto
- Oracle JDK
- Red Hat’s OpenJDK
- Zulu’s OpenJDK
Em um cenário em que eu estava testando no IntelliJ ocorreu um erro referente a java.lang.NoSuchFieldException: target.
No meu caso, a exemplo da pessoa que fez a pergunta, e estava usando uma variação OpenJ9 do JDK
Alterando para uma versão como o Open JDK Zulu resolvi o problema