import java.time.Instant import java.time.ZoneId import java.time.format.DateTimeFormatter import java.time.temporal.ChronoUnit buildscript { repositories { mavenLocal() mavenCentral() } dependencies { classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.30' classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.12' } } plugins { id 'java' id 'groovy' id 'idea' id 'application' id 'jacoco' id 'org.jetbrains.kotlin.jvm' version '1.3.70' id 'com.google.cloud.tools.jib' version "2.5.0" id 'org.springframework.boot' version '2.3.5.RELEASE' id 'io.spring.dependency-management' version '1.0.6.RELEASE' id 'com.palantir.git-version' version '0.12.2' id "com.google.protobuf" version "0.8.12" } group = 'io.emeraldpay.dshackle' // Version schema: // x.x.x for production, following SemVer model // x.x-SNAPSHOT for development version = '0.11.0-SNAPSHOT' java { sourceCompatibility = JavaVersion.VERSION_13 targetCompatibility = JavaVersion.VERSION_13 } repositories { mavenLocal() mavenCentral() jcenter() maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/milestone" } maven { url "https://maven.emrld.io" } } configurations { compile.exclude group: "commons-logging" compile.exclude group: "ch.qos.logback" compile.exclude group: "org.slf4j", module: "slf4j-jdk14" compile.exclude group: "org.slf4j", module: "log4j-over-slf4j" // should be used only for generation of the stubs, the lib contains grpc classes compile.exclude group: "com.salesforce.servicelibs", module: "reactor-grpc" } dependencies { implementation "io.emeraldpay:emerald-api:0.10.0-SNAPSHOT" implementation "io.grpc:grpc-protobuf:${grpcVersion}" implementation "io.grpc:grpc-stub:${grpcVersion}" implementation "io.grpc:grpc-netty:${grpcVersion}" implementation "io.netty:netty-transport:$nettyVersion" implementation "io.netty:netty-common:$nettyVersion" implementation "io.netty:netty-handler:$nettyVersion" implementation "io.netty:netty-handler-proxy:$nettyVersion" implementation "io.netty:netty-resolver:$nettyVersion" implementation "io.netty:netty-resolver-dns:$nettyVersion" implementation "io.netty:netty-codec:$nettyVersion" implementation "io.netty:netty-codec-http2:$nettyVersion" implementation "io.netty:netty-codec-http:$nettyVersion" implementation "io.netty:netty-buffer:$nettyVersion" implementation "io.netty:netty-tcnative:2.0.39.Final" implementation "io.netty:netty-tcnative-boringssl-static:2.0.39.Final" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" implementation "org.jetbrains.kotlin:kotlin-reflect" implementation("org.springframework.boot:spring-boot-starter:$springBootVersion") { exclude module: 'spring-boot-starter-logging' } implementation "org.springframework.security:spring-security-core:$springSecurtyVersion" implementation "org.springframework.security:spring-security-web:$springSecurtyVersion" implementation "org.springframework.security:spring-security-config:$springSecurtyVersion" implementation "io.projectreactor:reactor-core:$reactorVersion" implementation "io.projectreactor.netty:reactor-netty:1.0.11" implementation 'io.projectreactor.addons:reactor-extra:3.4.5' implementation 'io.projectreactor.kotlin:reactor-kotlin-extensions:1.1.4' implementation "com.salesforce.servicelibs:reactor-grpc-stub:$reactiveGrpcVersion" implementation 'io.micrometer:micrometer-registry-prometheus:1.5.6' implementation 'io.lettuce:lettuce-core:5.2.2.RELEASE' implementation "io.emeraldpay.etherjar:etherjar-domain:$etherjarVersion" implementation "io.emeraldpay.etherjar:etherjar-hex:$etherjarVersion" implementation "io.emeraldpay.etherjar:etherjar-rpc-api:$etherjarVersion" implementation "io.emeraldpay.etherjar:etherjar-rpc-http:$etherjarVersion" implementation "io.emeraldpay.etherjar:etherjar-rpc-ws:$etherjarVersion" implementation "io.emeraldpay.etherjar:etherjar-tx:$etherjarVersion" implementation "io.emeraldpay.etherjar:etherjar-contract:$etherjarVersion" implementation "io.emeraldpay.etherjar:etherjar-erc20:$etherjarVersion" implementation 'org.bitcoinj:bitcoinj-core:0.15.8' implementation 'org.yaml:snakeyaml:1.24' implementation 'org.apache.httpcomponents:httpmime:4.5.8' implementation 'org.apache.httpcomponents:httpclient:4.5.8' implementation "com.fasterxml.jackson.core:jackson-core:$jacksonVersion" implementation "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:$jacksonVersion" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jacksonVersion" implementation "com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion" implementation 'commons-io:commons-io:2.6' implementation 'org.apache.commons:commons-lang3:3.9' implementation 'org.apache.commons:commons-collections4:4.3' implementation 'javax.annotation:javax.annotation-api:1.3.2' implementation 'org.bouncycastle:bcprov-jdk15on:1.61' implementation 'com.github.ben-manes.caffeine:caffeine:2.8.5' implementation "org.slf4j:slf4j-api:$slf4jVersion" implementation "org.apache.logging.log4j:log4j-slf4j-impl:2.11.1" implementation "org.slf4j:jul-to-slf4j:$slf4jVersion" implementation "org.slf4j:jcl-over-slf4j:$slf4jVersion" testImplementation 'cglib:cglib-nodep:3.3.0' testImplementation "org.spockframework:spock-core:$spockVersion" testImplementation "io.grpc:grpc-testing:${grpcVersion}" testImplementation "io.projectreactor:reactor-test:$reactorVersion" testImplementation 'org.objenesis:objenesis:3.1' testImplementation 'org.mock-server:mockserver-netty:5.11.2' testImplementation "org.java-websocket:Java-WebSocket:1.5.1" testImplementation "nl.jqno.equalsverifier:equalsverifier:3.3" testImplementation "org.codehaus.groovy:groovy:${groovyVersion}" } compileKotlin { kotlinOptions { jvmTarget = "13" } } compileTestKotlin { kotlinOptions { jvmTarget = "13" } } test { jvmArgs '-ea' testLogging.showStandardStreams = false testLogging.exceptionFormat = 'full' finalizedBy jacocoTestReport // getting on CI: // java.security.KeyStoreException: Key protection algorithm not found: java.security.UnrecoverableKeyException: Encrypt Private Key failed: unrecognized algorithm name: PBEWithSHA1AndDESede // at java.base/sun.security.pkcs12.PKCS12KeyStore.setKeyEntry(PKCS12KeyStore.java:700) // at java.base/sun.security.pkcs12.PKCS12KeyStore.engineSetKeyEntry(PKCS12KeyStore.java:597) // at java.base/sun.security.util.KeyStoreDelegator.engineSetKeyEntry(KeyStoreDelegator.java:111) // at java.base/java.security.KeyStore.setKeyEntry(KeyStore.java:1167) // at io.netty.handler.ssl.SslContext.buildKeyStore(SslContext.java:1102) // at io.netty.handler.ssl.ReferenceCountedOpenSslServerContext.newSessionContext(ReferenceCountedOpenSslServerContext.java:123) // ---- // see // https://github.com/bcgit/bc-java/issues/941 // https://bugs.openjdk.java.net/browse/JDK-8266279 // systemProperty "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithHmacSHA256AndAES_256" } application { mainClassName = 'io.emeraldpay.dshackle.StarterKt' } jib { from { image = 'openjdk:13' } to { // by default publish as: // dshackle:shapshot, // dshackle:t, // dshackle: and // dshackle: // dshackle:latest only when publishing first version with zero patch (ex. 1.2.0) image = [ project.hasProperty('docker') ? project.property('docker') : 'emeraldpay', '/dshackle:', 'snapshot' ].join('') tags = [project.version].with (true) { add "t"+ DateTimeFormatter.ofPattern("yyyyMMddHHmm").withZone(ZoneId.of('UTC')).format(Instant.now()) add project.version.toString().replaceAll('(\\d+\\.\\d+).+', '$1') } auth { username = 'splix' password = System.getenv('DOCKER_KEY') } } container { jvmFlags = [ '-Xms1024m', ] mainClass = 'io.emeraldpay.dshackle.StarterKt' args = [] ports = ['2448', '2449', '8545'] } } jar { enabled=true } afterEvaluate { distZip.dependsOn(jar) compileKotlin.dependsOn(generateVersion) jar.dependsOn(generateVersion) } protobuf { protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" } plugins { } generateProtoTasks { } } sourceSets { main { resources.srcDirs += project.buildDir.absolutePath + "/generated/version" } } task generateVersion() { group = 'Build' description = 'Generate project version' doLast { def version = versionDetails() def resourcesDir = new File(project.buildDir.absolutePath + "/generated/version") resourcesDir.mkdirs() new File(resourcesDir, "version.properties").text = [ "# AUTOMATICALLY GENERATED", "version.app=$project.version", "version.commit=${version.gitHash}", "version.tag=${version.lastTag}", "version.date=${DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.of('UTC')).format(Instant.now().truncatedTo(ChronoUnit.SECONDS))} UTC" ].join("\n") } } // Show the list of failed tests and output only for them, helpful for CI ext.failedTests = [] tasks.withType(Test) { def stdout = new LinkedList() beforeTest { TestDescriptor td -> stdout.clear() } onOutput { TestDescriptor td, TestOutputEvent toe -> stdout.addAll(toe.getMessage().split('(?m)$')) while (stdout.size() > 100) { stdout.remove() } } afterTest { TestDescriptor descriptor, TestResult result -> if(result.resultType == org.gradle.api.tasks.testing.TestResult.ResultType.FAILURE){ failedTests << "${descriptor.className} > ${descriptor.name}" if (!stdout.isEmpty()) { println("-------- ${descriptor.className} > ${descriptor.name} OUTPUT ".padRight(120, "-")) stdout.each { print(it) } println("================".padRight(120, "=")) } } } } gradle.buildFinished { if(!failedTests.empty){ println "Failed tests for ${project.name}:" failedTests.each { failedTest -> println failedTest } println "" } } jacocoTestReport { dependsOn test reports { xml.enabled true html.enabled true } afterEvaluate { classDirectories.setFrom(files(classDirectories.files.collect { fileTree(dir: it, exclude: 'io/emeraldpay/dshackle/proto/**') })) } } jacoco { toolVersion = "0.8.7" }