diff --git a/.gitignore b/.gitignore index c81757e..b9a99ba 100644 --- a/.gitignore +++ b/.gitignore @@ -86,3 +86,6 @@ workspace/** #*.pfx #CPIFileStatus*.json #GroupPolicy.json + +# Ignore temporary data files +*.dat \ No newline at end of file diff --git a/build.gradle b/build.gradle index 1475791..ab9ec21 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { id 'org.jetbrains.kotlin.plugin.jpa' id 'java' id 'maven-publish' - id 'csde' + id 'net.corda.plugins.csde' } allprojects { @@ -15,6 +15,23 @@ allprojects { def javaVersion = VERSION_11 + // Configure the CSDE + csde { + cordaClusterURL = "https://localhost:8888" + networkConfigFile = "config/static-network-config.json" + corDappCpiName = "MyCorDapp" + notaryCpiName = "NotaryServer" + cordaRpcUser = "admin" + cordaRpcPasswd ="admin" + csdeWorkspaceDir = "workspace" + notaryVersion = cordaNotaryPluginsVersion + combinedWorkerVersion = "5.0.0.0-Gecko1.0" + postgresJdbcVersion = "42.4.3" + cordaDbContainerName = "CSDEpostgresql" + cordaBinDir = "${System.getProperty("user.home")}/.corda/corda5" + cordaCliBinDir = "${System.getProperty("user.home")}/.corda/cli" + } + // Declare the set of Java compiler options we need to build a CorDapp. tasks.withType(JavaCompile) { // -parameters - Needed for reflection and serialization to work correctly. @@ -25,9 +42,23 @@ allprojects { repositories { // All dependencies are held in Maven Central + mavenLocal() mavenCentral() + + // R3 Internal repositories for dev + // Repository provides Corda 5 binaries that implement Corda-API. + // These will be made publicly available. + // Final location to be decided. + // Repository subject to change maven { - url = "$artifactoryContextUrl/" + url = "$artifactoryContextUrl/corda-os-maven" + authentication { + basic(BasicAuthentication) + } + credentials { + username = findProperty('cordaArtifactoryUsername') ?: System.getenv('CORDA_ARTIFACTORY_USERNAME') + password = findProperty('cordaArtifactoryPassword') ?: System.getenv('CORDA_ARTIFACTORY_PASSWORD') + } } } diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle deleted file mode 100644 index 97750bf..0000000 --- a/buildSrc/build.gradle +++ /dev/null @@ -1,29 +0,0 @@ - -plugins { - id 'groovy-gradle-plugin' - id 'java' -} - -def constants = new Properties() -file("$rootDir/../gradle.properties").withInputStream { InputStream input -> constants.load(input) } -def artifactoryContextUrl = constants.getProperty('artifactoryContextUrl') - -repositories { - mavenCentral() - mavenLocal() - maven { - url = "$artifactoryContextUrl/" - } -} - -dependencies { - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' - - implementation "com.konghq:unirest-java:$unirestVersion" - implementation "com.konghq:unirest-objectmapper-jackson:$unirestVersion" - implementation "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion" - implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$jacksonVersion" - - implementation "net.corda:corda-base:$cordaApiVersion" -} diff --git a/buildSrc/gradle.properties b/buildSrc/gradle.properties deleted file mode 100644 index 7ab643a..0000000 --- a/buildSrc/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -jacksonVersion = 2.13.4 -unirestVersion=3.13.10 - -cordaApiVersion=5.0.0.665-Gecko1.0 diff --git a/buildSrc/settings.gradle b/buildSrc/settings.gradle deleted file mode 100644 index 86ac012..0000000 --- a/buildSrc/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -// File intentionally left blank diff --git a/buildSrc/src/main/groovy/csde.gradle b/buildSrc/src/main/groovy/csde.gradle deleted file mode 100644 index f9e32e5..0000000 --- a/buildSrc/src/main/groovy/csde.gradle +++ /dev/null @@ -1,259 +0,0 @@ -// Note, IntelliJ does not recognise the imported Java Classes, hence they are -// highlighted in Red. However, they are recognised in the gradle compilation. - - -// todo: look at the declaration of the script variables, can they be combined with the declaration of the Project Context -// todo: investigate adding corda-cli to the class path then executing it directly - might not work as gradle has to set up the jar file, so its not their when you start. -// Todo: write a test flow runner helper function?? -// todo: rename deployCPIsHelper -// todo: add proper logging, rather than reading Stdout -// todo: add test corda running/live task -// todo: add a test to check docker is running and display error if not + halt start corda -// todo: add a clean corda task. -// todo: fix logging level and make it configurable. - - -import com.r3.csde.CordaLifeCycleHelper -import com.r3.csde.ProjectContext -import com.r3.csde.DeployCPIsHelper -import com.r3.csde.BuildCPIsHelper -import com.r3.csde.ProjectUtils -import com.r3.csde.CordaStatusQueries -import com.r3.csde.VNodesHelper -import com.r3.csde.NetworkConfig - -plugins { - id 'java-library' - id 'groovy' - id 'java' -} - - -configurations { - combinedWorker{ - canBeConsumed = false - canBeResolved= true - } - - myPostgresJDBC { - canBeConsumed = false - canBeResolved = true - } - - notaryServerCPB { - canBeConsumed = false - canBeResolved = true - } -} - -// Dependencies for supporting tools -dependencies { - combinedWorker "net.corda:corda-combined-worker:$combinedWorkerVersion" - myPostgresJDBC "org.postgresql:postgresql:$postgresqlVersion" - notaryServerCPB("com.r3.corda.notary.plugin.nonvalidating:notary-plugin-non-validating-server:$cordaNotaryPluginsVersion") { - artifact { - classifier = 'package' - extension = 'cpb' - } - } -} - -// task groupings -def cordaGroup = 'csde-corda' // corda lifecycle tasks -def cordappGroup = 'csde-cordapp' // tasks to build and deploy corDapps -def queriesGroup = 'csde-queries' // tasks which query corda status -def supportingGroup = 'supporting' // tasks which should be hidden from the csde user - - -def cordaBinDir = System.getenv("CSDE_CORDA_BIN") ?: System.getProperty('user.home') + "/.corda/corda5" -def cordaCliBinDir = System.getenv("CSDE_CORDA_CLI") ?:System.getProperty('user.home') + "/.corda/cli" -def cordaJDBCDir = cordaBinDir + "/jdbcDrivers" -def cordaNotaryServerDir = cordaBinDir + "/notaryserver" -def signingCertAlias="gradle-plugin-default-key" -// Get error if this is not a autotyped object -// def signingCertFName = "$rootDir/config/gradle-plugin-default-key.pem" -def signingCertFName = rootDir.toString() + "/config/gradle-plugin-default-key.pem" -def keystoreAlias = "my-signing-key" -def keystoreFName = devEnvWorkspace + "/signingkeys.pfx" -def keystoreCertFName = devEnvWorkspace + "/signingkey1.pem" -def combiWorkerPidCacheFile = devEnvWorkspace + "/CordaPID.dat" -// todo: can we rely on the build directory always being /workflow/build? aslo, is the -// workflow directory the correct place to build the cpb to. shoudl it be the main build directory. -def workflowBuildDir = rootDir.toString() + "/workflows/build" - - -// todo: Need to read things from cordapp plugin - the cordapp names will be changed by the user -def appCpiName = 'cpi name' // !!! this must match with the cpi name in /config/static-network-config.json -def notaryCpiName = 'CSDE Notary Server CPI' - - -// todo: there should be a better way to set up these project context variables. -def projectContext = new ProjectContext(project, - cordaClusterURL.toString(), - cordaRpcUser, - cordaRpcPasswd, - devEnvWorkspace, - // todo: why is this not obtained in the groovy def's abouve - its inconsistent. - new String("${System.getProperty("java.home")}/bin"), - dbContainerName, - cordaJDBCDir, - combiWorkerPidCacheFile, - signingCertAlias, - signingCertFName, - keystoreAlias, - keystoreFName, - keystoreCertFName, - appCpiName, - notaryCpiName, - devEnvWorkspace, - cordaCliBinDir, - cordaNotaryServerDir, - workflowBuildDir, - cordaNotaryPluginsVersion -) - -def networkConfig = new NetworkConfig("config/static-network-config.json") - -def utils = new ProjectUtils() - -// Initiate workspace folder - -tasks.register('projInit') { - group = supportingGroup - doLast { - mkdir devEnvWorkspace - } -} - - -// CordaLifeCycle tasks - -def cordaLifeCycle = new CordaLifeCycleHelper(projectContext) - -tasks.register("startCorda") { - group = cordaGroup - dependsOn('getDevCordaLite', 'getPostgresJDBC') - doLast { - mkdir devEnvWorkspace - cordaLifeCycle.startCorda() - } -} - -tasks.register("stopCorda") { - group = cordaGroup - doLast { - cordaLifeCycle.stopCorda() - } -} - -tasks.register("stopAndCleanCorda") { - group = cordaGroup - dependsOn('clean') - doLast { - try { - cordaLifeCycle.stopCorda() - } catch (Exception ignore) { - println("ignoring exception: ${ignore.toString()}") - } - delete devEnvWorkspace - } -} - -tasks.register("getPostgresJDBC") { - group = supportingGroup - doLast { - copy { - from configurations.myPostgresJDBC - into "$cordaJDBCDir" - } - } -} - -tasks.register("getDevCordaLite", Copy) { - group = supportingGroup - from configurations.combinedWorker - into cordaBinDir -} - - -// Corda status queries - -def cordaStatusQueries = new CordaStatusQueries(projectContext) - - -tasks.register('listVNodes') { - group = queriesGroup - doLast { - cordaStatusQueries.listVNodes() - } -} - -tasks.register('listCPIs') { - group = queriesGroup - doLast { - cordaStatusQueries.listCPIs() - } -} - -// Build CPI tasks - -def buildCPIsHelper = new BuildCPIsHelper(projectContext, networkConfig) - -tasks.register("1-createGroupPolicy") { - group = cordappGroup - dependsOn('projInit') - doLast { - buildCPIsHelper.createGroupPolicy() - } -} - -tasks.register("getNotaryServerCPB", Copy) { - group = supportingGroup - from configurations.notaryServerCPB - into cordaNotaryServerDir -} - -tasks.register('2-createKeystore') { - group = cordappGroup - dependsOn('projInit') - doLast { - buildCPIsHelper.createKeyStore() - } -} - -tasks.register('3-buildCPIs') { - group = cordappGroup - def dependsOnTasks = subprojects.collect {it.tasks.findByName("build") } - dependsOnTasks.add('1-createGroupPolicy') - dependsOnTasks.add('2-createKeystore') - dependsOnTasks.add('getNotaryServerCPB') - dependsOn dependsOnTasks - doLast{ - buildCPIsHelper.buildCPIs() - } -} - - -// deploy CPI tasks - -def deployCPIsHelper = new DeployCPIsHelper(projectContext) - -tasks.register('4-deployCPIs') { - group = cordappGroup - dependsOn('3-buildCPIs') - doLast { - deployCPIsHelper.deployCPIs() - } -} - -// Setup VNodes tasks - -def vNodesHelper = new VNodesHelper(projectContext, networkConfig ) - -tasks.register('5-vNodeSetup') { - group = cordappGroup - dependsOn('4-deployCPIs') - doLast { - vNodesHelper.vNodesSetup() - } -} diff --git a/buildSrc/src/main/java/com/r3/csde/BuildCPIsHelper.java b/buildSrc/src/main/java/com/r3/csde/BuildCPIsHelper.java deleted file mode 100644 index c160870..0000000 --- a/buildSrc/src/main/java/com/r3/csde/BuildCPIsHelper.java +++ /dev/null @@ -1,270 +0,0 @@ -package com.r3.csde; - -import java.io.*; -import java.util.LinkedList; -import java.util.List; - -// todo: This class needs refactoring, see https://r3-cev.atlassian.net/browse/CORE-11624 -public class BuildCPIsHelper { - - public ProjectContext pc; - public ProjectUtils utils; - - public NetworkConfig config; - public BuildCPIsHelper(ProjectContext _pc, NetworkConfig _config) { - pc = _pc; - utils = new ProjectUtils(pc); - config = _config; - } - - public void createGroupPolicy() throws IOException { - - File groupPolicyFile = new File(String.format("%s/GroupPolicy.json", pc.devEnvWorkspace)); - File devnetFile = new File(pc.project.getRootDir() + "/" + config.getConfigFilePath()); - - - if (!groupPolicyFile.exists() || groupPolicyFile.lastModified() < devnetFile.lastModified()) { - - pc.out.println("createGroupPolicy: Creating a GroupPolicy"); - - List configX500Ids = config.getX500Names(); - LinkedList commandList = new LinkedList<>(); - - commandList.add(String.format("%s/java", pc.javaBinDir)); - commandList.add(String.format("-Dpf4j.pluginsDir=%s/plugins/", pc.cordaCliBinDir)); - commandList.add("-jar"); - commandList.add(String.format("%s/corda-cli.jar", pc.cordaCliBinDir)); - commandList.add("mgm"); - commandList.add("groupPolicy"); - for (String id : configX500Ids) { - commandList.add("--name"); - commandList.add(id); - } - commandList.add("--endpoint-protocol=1"); - commandList.add("--endpoint=http://localhost:1080"); - - ProcessBuilder pb = new ProcessBuilder(commandList); - pb.redirectErrorStream(true); - Process proc = pb.start(); - BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream())); - - // todo add exception catching - FileWriter fileWriter = new FileWriter(groupPolicyFile); - String line; - while (( line = reader.readLine()) != null){ - fileWriter.write(line + "\n"); - } - fileWriter.close(); - - } else { - pc.out.println("createPolicyTask: everything up to date; nothing to do."); - } - - } - - public void createKeyStore() throws IOException, InterruptedException { - - File keystoreFile = new File(pc.keystoreFName); - if(!keystoreFile.exists()) { - pc.out.println("createKeystore: Create a keystore"); - - generateKeyPair(); - addDefaultSigningKey(); - exportCert(); - - } else { - pc.out.println("createKeystore: keystore already created; nothing to do."); - } - - } - - private void generateKeyPair() throws IOException, InterruptedException { - - LinkedList cmdArray = new LinkedList<>(); - - cmdArray.add(pc.javaBinDir + "/keytool"); - cmdArray.add("-genkeypair"); - cmdArray.add("-alias"); - cmdArray.add(pc.keystoreAlias); - cmdArray.add("-keystore"); - cmdArray.add(pc.keystoreFName); - cmdArray.add("-storepass"); - cmdArray.add("keystore password"); - cmdArray.add("-dname"); - cmdArray.add("CN=CPI Example - My Signing Key, O=CorpOrgCorp, L=London, C=GB"); - cmdArray.add("-keyalg"); - cmdArray.add("RSA"); - cmdArray.add("-storetype"); - cmdArray.add("pkcs12"); - cmdArray.add("-validity"); - cmdArray.add("4000"); - - ProcessBuilder pb = new ProcessBuilder(cmdArray); - pb.redirectErrorStream(true); - Process proc = pb.start(); - proc.waitFor(); - - } - - private void addDefaultSigningKey() throws IOException, InterruptedException { - - LinkedList cmdArray = new LinkedList<>(); - - cmdArray.add(pc.javaBinDir + "/keytool"); - cmdArray.add("-importcert"); - cmdArray.add("-keystore"); - cmdArray.add(pc.keystoreFName); - cmdArray.add("-storepass"); - cmdArray.add("keystore password"); - cmdArray.add("-noprompt"); - cmdArray.add("-alias"); - cmdArray.add(pc.signingCertAlias); - cmdArray.add("-file"); - cmdArray.add(pc.signingCertFName); - - ProcessBuilder pb = new ProcessBuilder(cmdArray); - pb.redirectErrorStream(true); - Process proc = pb.start(); - proc.waitFor(); - } - - private void exportCert() throws IOException, InterruptedException { - - LinkedList cmdArray = new LinkedList<>(); - - cmdArray.add(pc.javaBinDir + "/keytool"); - cmdArray.add("-exportcert"); - cmdArray.add("-rfc"); - cmdArray.add("-alias"); - cmdArray.add(pc.keystoreAlias); - cmdArray.add("-keystore"); - cmdArray.add(pc.keystoreFName); - cmdArray.add("-storepass"); - cmdArray.add("keystore password"); - cmdArray.add("-file"); - cmdArray.add(pc.keystoreCertFName); - - ProcessBuilder pb = new ProcessBuilder(cmdArray); - pb.redirectErrorStream(true); - Process proc = pb.start(); - proc.waitFor(); - - } - - public void buildCPIs() throws IOException, InterruptedException, CsdeException { - createCorDappCPI(); - createNotaryCPI(); - } - - private void createCorDappCPI() throws IOException, InterruptedException, CsdeException { - - String appCPIFilePath = pc.workflowBuildDir + "/" + - pc.project.getRootProject().getName() + "-" + - pc.project.getVersion() + ".cpi"; - - File appCPIFile = new File(appCPIFilePath); - appCPIFile.delete(); - - File srcDir = new File(pc.workflowBuildDir + "/libs"); - File[] appCPBs = srcDir.listFiles(( x , name ) -> name.endsWith(".cpb")); - if (appCPBs == null) throw new CsdeException("Expecting exactly one CPB but no CPB found."); - if (appCPBs.length != 1) throw new CsdeException("Expecting exactly one CPB but more than one found."); - - pc.out.println("appCpbs:"); - pc.out.println(appCPBs[0].getAbsolutePath()); - - LinkedList commandList = new LinkedList<>(); - - commandList.add(String.format("%s/java", pc.javaBinDir)); - commandList.add(String.format("-Dpf4j.pluginsDir=%s/plugins/", pc.cordaCliBinDir)); - commandList.add("-jar"); - commandList.add(String.format("%s/corda-cli.jar", pc.cordaCliBinDir)); - commandList.add("package"); - commandList.add("create-cpi"); - commandList.add("--cpb"); - commandList.add(appCPBs[0].getAbsolutePath()); - commandList.add("--group-policy"); - commandList.add(pc.devEnvWorkspace + "/GroupPolicy.json"); - commandList.add("--cpi-name"); - commandList.add(pc.appCPIName); - commandList.add("--cpi-version"); - commandList.add(pc.project.getVersion().toString()); - commandList.add("--file"); - commandList.add(appCPIFilePath); - commandList.add("--keystore"); - commandList.add(pc.devEnvWorkspace + "/signingkeys.pfx"); - commandList.add("--storepass"); - commandList.add("keystore password"); - commandList.add("--key"); - commandList.add("my-signing-key"); // todo: should be passed as context property - - - - ProcessBuilder pb = new ProcessBuilder(commandList); - pb.redirectErrorStream(true); - Process proc = pb.start(); - proc.waitFor(); - - //Get CPI packaging errors - if (proc.getErrorStream().available() > 0) { - proc.getErrorStream().transferTo(pc.out); - } - } - - private void createNotaryCPI() throws CsdeException, IOException, InterruptedException { - - String notaryCPIFilePath = pc.workflowBuildDir + "/" + - pc.notaryCPIName.replace(' ', '-').toLowerCase() + "-" + - pc.project.getVersion() + ".cpi"; - - File notaryCPIFile = new File(notaryCPIFilePath); - notaryCPIFile.delete(); - - File srcDir = new File(pc.cordaNotaryServiceDir); - File[] notaryCPBs = srcDir.listFiles(( x , name ) -> name.endsWith(".cpb") && name.contains(pc.cordaNotaryPluginsVersion)); - if (notaryCPBs == null) throw new CsdeException("Expecting exactly one notary CPB but no CPB found."); - if (notaryCPBs.length != 1) throw new CsdeException("Expecting exactly one notary CPB but more than one found."); - - pc.out.println("notaryCpbs:"); - pc.out.println(notaryCPBs[0]); - - LinkedList commandList = new LinkedList<>(); - - commandList.add(String.format("%s/java", pc.javaBinDir)); - commandList.add(String.format("-Dpf4j.pluginsDir=%s/plugins/", pc.cordaCliBinDir)); - commandList.add("-jar"); - commandList.add(String.format("%s/corda-cli.jar", pc.cordaCliBinDir)); - commandList.add("package"); - commandList.add("create-cpi"); - commandList.add("--cpb"); - commandList.add(notaryCPBs[0].getAbsolutePath()); - commandList.add("--group-policy"); - commandList.add(pc.devEnvWorkspace + "/GroupPolicy.json"); - commandList.add("--cpi-name"); - commandList.add(pc.notaryCPIName); - commandList.add("--cpi-version"); - commandList.add(pc.project.getVersion().toString()); - commandList.add("--file"); - commandList.add(notaryCPIFilePath); - commandList.add("--keystore"); - commandList.add(pc.devEnvWorkspace + "/signingkeys.pfx"); - commandList.add("--storepass"); - commandList.add("keystore password"); - commandList.add("--key"); - commandList.add("my-signing-key"); - - ProcessBuilder pb = new ProcessBuilder(commandList); - pb.redirectErrorStream(true); - Process proc = pb.start(); - proc.waitFor(); - - } - - // todo: this might be needed for improved logging - private void printCmdArray(LinkedList cmdArray) { - for (int i = 0; i < cmdArray.size(); i++) { - pc.out.print(cmdArray.get(i) + " "); - } - } - -} diff --git a/buildSrc/src/main/java/com/r3/csde/CordaLifeCycleHelper.java b/buildSrc/src/main/java/com/r3/csde/CordaLifeCycleHelper.java deleted file mode 100644 index c76382f..0000000 --- a/buildSrc/src/main/java/com/r3/csde/CordaLifeCycleHelper.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.r3.csde; - -import kong.unirest.Unirest; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.util.Scanner; - -/** - * Manages Bringing corda up, testing for liveness and taking corda down - */ -// todo: This class needs refactoring, see https://r3-cev.atlassian.net/browse/CORE-11624 -public class CordaLifeCycleHelper { - - ProjectContext pc; - ProjectUtils utils; - - public CordaLifeCycleHelper(ProjectContext _pc) { - pc = _pc; - utils = new ProjectUtils(pc); - Unirest.config().verifySsl(false); - } - - public void startCorda() throws IOException, CsdeException { - File cordaPIDFile = new File(pc.cordaPidCache); - if (cordaPIDFile.exists()) { - throw new CsdeException("Cannot start the Combined worker. Cached process ID file " + cordaPIDFile + " existing. Was the combined worker already started?"); - } - PrintStream pidStore = new PrintStream(new FileOutputStream(cordaPIDFile)); - File combinedWorkerJar = pc.project.getConfigurations().getByName("combinedWorker").getSingleFile(); - - // Manual version of the command to start postgres (for reference): - // docker run -d --rm -p5432:5432 --name CSDEpostgresql -e POSTGRES_DB=cordacluster -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=password postgres:latest - - new ProcessBuilder( - "docker", - "run", "-d", "--rm", - "-p", "5432:5432", - "--name", pc.dbContainerName, - "-e", "POSTGRES_DB=cordacluster", - "-e", "POSTGRES_USER=postgres", - "-e", "POSTGRES_PASSWORD=password", - "postgres:latest").start(); - - // todo: we should poll for readiness not wait 10 seconds, see https://r3-cev.atlassian.net/browse/CORE-11626 - utils.rpcWait(10000); - - ProcessBuilder procBuild = new ProcessBuilder(pc.javaBinDir + "/java", - "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005", - "-DsecurityMangerEnabled=false", - "-Dlog4j.configurationFile=" + pc.project.getRootDir() + "/config/log4j2.xml", - "-Dco.paralleluniverse.fibers.verifyInstrumentation=true", - "-jar", - combinedWorkerJar.toString(), - "--instance-id=0", - "-mbus.busType=DATABASE", - "-spassphrase=password", - "-ssalt=salt", - "-ddatabase.user=user", - "-ddatabase.pass=password", - "-ddatabase.jdbc.url=jdbc:postgresql://localhost:5432/cordacluster", - "-ddatabase.jdbc.directory="+pc.JDBCDir); - - procBuild.redirectErrorStream(true); - Process proc = procBuild.start(); - pidStore.print(proc.pid()); - pc.out.println("Corda Process-id="+proc.pid()); - proc.getInputStream().transferTo(pc.out); - - // todo: we should poll for readiness before completing the startCorda task, see https://r3-cev.atlassian.net/browse/CORE-11625 - } - - - public void stopCorda() throws IOException, CsdeException { - File cordaPIDFile = new File(pc.cordaPidCache); - if(cordaPIDFile.exists()) { - Scanner sc = new Scanner(cordaPIDFile); - long pid = sc.nextLong(); - pc.out.println("pid to kill=" + pid); - - if (System.getProperty("os.name").toLowerCase().contains("windows")) { - new ProcessBuilder("Powershell", "-Command", "Stop-Process", "-Id", Long.toString(pid), "-PassThru").start(); - } else { - new ProcessBuilder("kill", "-9", Long.toString(pid)).start(); - } - - Process proc = new ProcessBuilder("docker", "stop", pc.dbContainerName).start(); - - cordaPIDFile.delete(); - } - else { - throw new CsdeException("Cannot stop the Combined worker. Cached process ID file " + pc.cordaPidCache + " missing. Was the combined worker not started?"); - } - } -} diff --git a/buildSrc/src/main/java/com/r3/csde/CordaStatusQueries.java b/buildSrc/src/main/java/com/r3/csde/CordaStatusQueries.java deleted file mode 100644 index 38bf834..0000000 --- a/buildSrc/src/main/java/com/r3/csde/CordaStatusQueries.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.r3.csde; - -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.Unirest; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -// todo: This class needs refactoring, see https://r3-cev.atlassian.net/browse/CORE-11624 -public class CordaStatusQueries { - - ProjectContext pc; - - public CordaStatusQueries(ProjectContext _pc) { - pc = _pc; - } - - public HttpResponse getCpiInfo() { - Unirest.config().verifySsl(false); - return Unirest.get(pc.baseURL + "/api/v1/cpi/") - .basicAuth(pc.rpcUser, pc.rpcPasswd) - .asJson(); - } - - public HttpResponse getVNodeInfo() { - Unirest.config().verifySsl(false); - return Unirest.get(pc.baseURL + "/api/v1/virtualnode/") - .basicAuth(pc.rpcUser, pc.rpcPasswd) - .asJson(); - } - - // cpiName, cpiVersion - public void listCPIs() { - HttpResponse cpiResponse = getCpiInfo(); - - JSONArray cpisJson = (JSONArray) cpiResponse.getBody().getObject().get("cpis"); - - List> lines = new LinkedList<>(); - for (Object o : cpisJson) { - if (o instanceof JSONObject) { - JSONObject idObj = ((JSONObject) o).getJSONObject("id"); - String cpiName = idObj.get("cpiName").toString(); - String cpiVersion = idObj.get("cpiVersion").toString(); - - lines.add(Arrays.asList(cpiName, cpiVersion)); - } - } - List title = Arrays.asList("CPI Name", "CPI Version"); - List titleSizes = Arrays.asList(40, 20); - printTable(titleSizes, title, lines); - } - - public void listVNodesVerbose() { - HttpResponse vnodeResponse = getVNodeInfo(); - pc.out.println("VNodes:\n" + vnodeResponse.getBody().toPrettyString()); - } - - // x500Name, shortHash, cpiName - public void listVNodes() { - HttpResponse vnodeResponse = getVNodeInfo(); - - JSONArray virtualNodesJson = (JSONArray) vnodeResponse.getBody().getObject().get("virtualNodes"); - - List> lines = new LinkedList<>(); - for (Object o : virtualNodesJson) { - if (o instanceof JSONObject) { - JSONObject idObj = ((JSONObject) o).getJSONObject("holdingIdentity"); - String x500Name = idObj.get("x500Name").toString(); - String shortHash = idObj.get("shortHash").toString(); - - JSONObject cpiObj = ((JSONObject) o).getJSONObject("cpiIdentifier"); - String cpiName = cpiObj.get("cpiName").toString(); - - lines.add(Arrays.asList(x500Name, shortHash, cpiName)); - } - } - List title = Arrays.asList("X500 Name", "Holding identity short hash", "CPI Name"); - List titleSizes = Arrays.asList(60, 30, 40); - printTable(titleSizes, title, lines); - } - - public void printTable(List titleSizes, List title, List> lines) { - int width = titleSizes.stream().reduce(0, Integer::sum); - String separator = "-".repeat(width + 1); - pc.out.println(separator); - pc.out.println(formatLine(titleSizes, title)); - pc.out.println(separator); - for (List line : lines) { - pc.out.println(formatLine(titleSizes, line)); - } - pc.out.println(separator); - } - - public String formatLine(List titleSizes, List line) { - StringBuilder sb = new StringBuilder(); - int delta = 0; - for (int i = 0; i < titleSizes.size(); i++) { - String s = line.get(i); - sb.append("| ").append(s); - delta += titleSizes.get(i) - (2 + s.length()); - - if (delta > 0) { - sb.append(" ".repeat(delta)); - delta = 0; - } else { - sb.append(" "); - delta -= 1; - } - } - sb.append("|"); - return sb.toString(); - } -} diff --git a/buildSrc/src/main/java/com/r3/csde/CsdeException.java b/buildSrc/src/main/java/com/r3/csde/CsdeException.java deleted file mode 100644 index 72f8fea..0000000 --- a/buildSrc/src/main/java/com/r3/csde/CsdeException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.r3.csde; - -public class CsdeException extends Exception { - public CsdeException(String message, Throwable cause) { - super(message, cause); - } - public CsdeException(String message){ - super(message); - } -} \ No newline at end of file diff --git a/buildSrc/src/main/java/com/r3/csde/DeployCPIsHelper.java b/buildSrc/src/main/java/com/r3/csde/DeployCPIsHelper.java deleted file mode 100644 index fe1362b..0000000 --- a/buildSrc/src/main/java/com/r3/csde/DeployCPIsHelper.java +++ /dev/null @@ -1,187 +0,0 @@ -package com.r3.csde; - -import kong.unirest.JsonNode; -import kong.unirest.Unirest; -import kong.unirest.json.JSONArray; -import kong.unirest.json.JSONObject; -import kong.unirest.HttpResponse; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.PrintStream; -import static java.net.HttpURLConnection.HTTP_BAD_REQUEST; -import static java.net.HttpURLConnection.HTTP_OK; - -// todo: This class needs refactoring, see https://r3-cev.atlassian.net/browse/CORE-11624 -public class DeployCPIsHelper { - - public DeployCPIsHelper() { - } - ProjectContext pc; - CordaStatusQueries queries; - ProjectUtils utils; - - public DeployCPIsHelper(ProjectContext _pc) { - pc = _pc; - queries = new CordaStatusQueries(pc); - utils = new ProjectUtils(pc); - } - - public void deployCPIs() throws FileNotFoundException, CsdeException{ - - uploadCertificate(pc.signingCertAlias, pc.signingCertFName); - uploadCertificate(pc.keystoreAlias, pc.keystoreCertFName); - - // todo: make consistent with other string building code - remove String.format - String appCPILocation = String.format("%s/%s-%s.cpi", - pc.workflowBuildDir, - pc.project.getName(), - pc.project.getVersion()); - deployCPI(appCPILocation, pc.appCPIName,pc.project.getVersion().toString()); - - String notaryCPILocation = String.format("%s/%s-%s.cpi", - pc.workflowBuildDir, - pc.notaryCPIName.replace(' ','-').toLowerCase(), - pc.project.getVersion()); - deployCPI(notaryCPILocation, - pc.notaryCPIName, - pc.project.getVersion().toString(), - "-NotaryServer" ); - - } - - public void uploadCertificate(String certAlias, String certFName) { - Unirest.config().verifySsl(false); - HttpResponse uploadResponse = Unirest.put(pc.baseURL + "/api/v1/certificates/cluster/code-signer") - .field("alias", certAlias) - .field("certificate", new File(certFName)) - .basicAuth(pc.rpcUser, pc.rpcPasswd) - .asJson(); - pc.out.println("Certificate/key upload, alias "+certAlias+" certificate/key file "+certFName); - pc.out.println(uploadResponse.getBody().toPrettyString()); - } - - public void forceuploadCPI(String cpiFName) throws FileNotFoundException, CsdeException { - forceuploadCPI(cpiFName, ""); - } - - public void forceuploadCPI(String cpiFName, String uploadStatusQualifier) throws FileNotFoundException, CsdeException { - Unirest.config().verifySsl(false); - HttpResponse jsonResponse = Unirest.post(pc.baseURL + "/api/v1/maintenance/virtualnode/forcecpiupload/") - .field("upload", new File(cpiFName)) - .basicAuth(pc.rpcUser, pc.rpcPasswd) - .asJson(); - - if(jsonResponse.getStatus() == HTTP_OK) { - String id = (String) jsonResponse.getBody().getObject().get("id"); - pc.out.println("get id:\n" +id); - HttpResponse statusResponse = uploadStatus(id); - - if (statusResponse.getStatus() == HTTP_OK) { - PrintStream cpiUploadStatus = new PrintStream(new FileOutputStream( - pc.CPIUploadStatusFName.replace(".json", uploadStatusQualifier + ".json" ))); - cpiUploadStatus.print(statusResponse.getBody()); - pc.out.println("Caching CPI file upload status:\n" + statusResponse.getBody()); - } else { - utils.reportError(statusResponse); - } - } - else { - utils.reportError(jsonResponse); - } - } - - private boolean uploadStatusRetry(HttpResponse response) { - int status = response.getStatus(); - JsonNode body = response.getBody(); - // Do not retry on success // todo: need to think through the possible outcomes here - what if the bodyTitle is null, it won't retry - if(status == HTTP_OK) { - // Keep retrying until we get "OK" may move through "Validating upload", "Persisting CPI" - return !(body.getObject().get("status").equals("OK")); - } - else if (status == HTTP_BAD_REQUEST){ - String bodyTitle = response.getBody().getObject().getString("title"); - return bodyTitle != null && bodyTitle.matches("No such requestId=[-0-9a-f]+"); - } - return false; - } - - public HttpResponse uploadStatus(String requestId) { - HttpResponse statusResponse = null; - do { - utils.rpcWait(1000); - statusResponse = Unirest - .get(pc.baseURL + "/api/v1/cpi/status/" + requestId + "/") - .basicAuth(pc.rpcUser, pc.rpcPasswd) - .asJson(); - pc.out.println("Upload status="+statusResponse.getStatus()+", status query response:\n"+statusResponse.getBody().toPrettyString()); - } - while(uploadStatusRetry(statusResponse)); - - return statusResponse; - } - - public void deployCPI(String cpiFName, String cpiName, String cpiVersion) throws FileNotFoundException, CsdeException { - deployCPI(cpiFName, cpiName, cpiVersion, ""); - } - - public void deployCPI(String cpiFName, - String cpiName, - String cpiVersion, - String uploadStatusQualifier) throws FileNotFoundException, CsdeException { - // todo: where is the primary instance declared? - Unirest.config().verifySsl(false); - - HttpResponse cpiResponse = queries.getCpiInfo(); - JSONArray jArray = (JSONArray) cpiResponse.getBody().getObject().get("cpis"); - - int matches = 0; - for(Object o: jArray.toList() ) { - if(o instanceof JSONObject) { - JSONObject idObj = ((JSONObject) o).getJSONObject("id"); - if((idObj.get("cpiName").toString().equals(cpiName) - && idObj.get("cpiVersion").toString().equals(cpiVersion))) { - matches++; - } - } - } - pc.out.println("Matching CPIS="+matches); - - if(matches == 0) { - HttpResponse uploadResponse = Unirest.post(pc.baseURL + "/api/v1/cpi/") - .field("upload", new File(cpiFName)) - .basicAuth(pc.rpcUser, pc.rpcPasswd) - .asJson(); - - JsonNode body = uploadResponse.getBody(); - - int status = uploadResponse.getStatus(); - - pc.out.println("Upload Status:" + status); - pc.out.println("Pretty print the body\n" + body.toPrettyString()); - - // We expect the id field to be a string. - if (status == HTTP_OK) { - String id = (String) body.getObject().get("id"); - pc.out.println("get id:\n" + id); - - HttpResponse statusResponse = uploadStatus(id); - if (statusResponse.getStatus() == HTTP_OK) { - PrintStream cpiUploadStatus = new PrintStream(new FileOutputStream( - pc.CPIUploadStatusFName.replace(".json", uploadStatusQualifier + ".json" ))); - cpiUploadStatus.print(statusResponse.getBody()); - pc.out.println("Caching CPI file upload status:\n" + statusResponse.getBody()); - } else { - utils.reportError(statusResponse); - } - } else { - utils.reportError(uploadResponse); - } - } - else { - pc.out.println("CPI already uploaded doing a 'force' upload."); - forceuploadCPI(cpiFName, uploadStatusQualifier); - } - } - -} diff --git a/buildSrc/src/main/java/com/r3/csde/NetworkConfig.java b/buildSrc/src/main/java/com/r3/csde/NetworkConfig.java deleted file mode 100644 index 9b3f0ca..0000000 --- a/buildSrc/src/main/java/com/r3/csde/NetworkConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.r3.csde; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; - -import java.io.FileInputStream; -import java.util.List; -import java.util.stream.Collectors; - - -/** - * This class reads the network config from the json file and makes it available as a list of VNodes. - */ -public class NetworkConfig { - - private List vNodes; - private String configFilePath; - - public NetworkConfig(String _configFilePath) throws CsdeException { - configFilePath = _configFilePath; - - ObjectMapper mapper = new ObjectMapper(); - try { - FileInputStream in = new FileInputStream(configFilePath); - vNodes = mapper.readValue(in, new TypeReference>() { - }); - } catch (Exception e) { - throw new CsdeException("Failed to read static network configuration file, with exception: " + e); - } - } - - String getConfigFilePath() { return configFilePath; } - - List getVNodes() { return vNodes; } - - List getX500Names() { - return vNodes.stream().map(vn -> vn.getX500Name()).collect(Collectors.toList()); - } - -} diff --git a/buildSrc/src/main/java/com/r3/csde/ProjectContext.java b/buildSrc/src/main/java/com/r3/csde/ProjectContext.java deleted file mode 100644 index 0e84567..0000000 --- a/buildSrc/src/main/java/com/r3/csde/ProjectContext.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.r3.csde; - -import org.gradle.api.Project; -import java.io.PrintStream; -import java.util.Map; - -public class ProjectContext { - Project project; - String baseURL = "https://localhost:8888"; - String rpcUser = "admin"; - String rpcPasswd = "admin"; - String workspaceDir = "workspace"; - int retryWaitMs = 1000; - PrintStream out = System.out; - String CPIUploadStatusBaseName = "CPIFileStatus.json"; - String NotaryCPIUploadBaseName = "CPIFileStatus-NotaryServer.json"; - String CPIUploadStatusFName; - String NotaryCPIUploadStatusFName; - String javaBinDir; - String cordaPidCache = "CordaPIDCache.dat"; - String dbContainerName; - String JDBCDir; - String combinedWorkerBinRe; - Map notaryRepresentatives = null; - String signingCertAlias; - String signingCertFName; - String keystoreAlias; - String keystoreFName; - String keystoreCertFName; - String appCPIName; - String notaryCPIName; - String devEnvWorkspace; - String cordaCliBinDir; - String cordaNotaryServiceDir; - String workflowBuildDir; - String cordaNotaryPluginsVersion; - - public ProjectContext (Project inProject, - String inBaseUrl, - String inRpcUser, - String inRpcPasswd, - String inWorkspaceDir, - String inJavaBinDir, - String inDbContainerName, - String inJDBCDir, - String inCordaPidCache, - String inSigningCertAlias, - String inSigningCertFName, - String inKeystoreAlias, - String inKeystoreFName, - String inKeystoreCertFName, - String inAppCPIName, - String inNotaryCPIName, - String inDevEnvWorkspace, - String inCordaCLiBinDir, - String inCordaNotaryServiceDir, - String inWorkflowBuildDir, - String inCordaNotaryPluginsVersion - ) { - project = inProject; - baseURL = inBaseUrl; - rpcUser = inRpcUser; - rpcPasswd = inRpcPasswd; - workspaceDir = inWorkspaceDir; - javaBinDir = inJavaBinDir; - cordaPidCache = inCordaPidCache; - dbContainerName = inDbContainerName; - JDBCDir = inJDBCDir; - CPIUploadStatusFName = workspaceDir + "/" + CPIUploadStatusBaseName; - NotaryCPIUploadStatusFName = workspaceDir + "/" + NotaryCPIUploadBaseName; - signingCertAlias = inSigningCertAlias; - signingCertFName = inSigningCertFName; - keystoreAlias = inKeystoreAlias; - keystoreFName = inKeystoreFName; - keystoreCertFName = inKeystoreCertFName; - appCPIName = inAppCPIName; - notaryCPIName = inNotaryCPIName; - devEnvWorkspace = inDevEnvWorkspace; - cordaCliBinDir = inCordaCLiBinDir; - cordaNotaryServiceDir = inCordaNotaryServiceDir; - workflowBuildDir = inWorkflowBuildDir; - cordaNotaryPluginsVersion = inCordaNotaryPluginsVersion; - } -} diff --git a/buildSrc/src/main/java/com/r3/csde/ProjectUtils.java b/buildSrc/src/main/java/com/r3/csde/ProjectUtils.java deleted file mode 100644 index dbc3dd8..0000000 --- a/buildSrc/src/main/java/com/r3/csde/ProjectUtils.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.r3.csde; - -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; - -import static java.lang.Thread.sleep; - -// todo: This class needs refactoring, see https://r3-cev.atlassian.net/browse/CORE-11624 -public class ProjectUtils { - - ProjectContext pc; - - ProjectUtils(ProjectContext _pc) { - pc = _pc; - } - - void rpcWait(int millis) { - try { - sleep(millis); - } - catch(InterruptedException e) { - throw new UnsupportedOperationException("Interrupts not supported.", e); - } - } - - public void reportError(HttpResponse response) throws CsdeException { - - pc.out.println("*** *** ***"); - pc.out.println("Unexpected response from Corda"); - pc.out.println("Status="+ response.getStatus()); - pc.out.println("*** Headers ***\n"+ response.getHeaders()); - pc.out.println("*** Body ***\n"+ response.getBody()); - pc.out.println("*** *** ***"); - throw new CsdeException("Error: unexpected response from Corda."); - } -} diff --git a/buildSrc/src/main/java/com/r3/csde/VNode.java b/buildSrc/src/main/java/com/r3/csde/VNode.java deleted file mode 100644 index d77d85c..0000000 --- a/buildSrc/src/main/java/com/r3/csde/VNode.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.r3.csde; - - -/** - * This class is a representation of a Vnode used to express the vNodes required on the network. - */ - -public class VNode { - private String x500Name; - private String cpi; - - private String serviceX500Name; - - public VNode() { } - - public String getX500Name(){ return x500Name; } - public void setX500Name(String _x500Name) { x500Name = _x500Name; } - - public String getCpi() { return cpi; } - public void setCpi(String _cpi) { cpi = _cpi; } - - public String getServiceX500Name() { return serviceX500Name; } - public void setServiceX500Name(String _name) { serviceX500Name = _name; } - -} diff --git a/buildSrc/src/main/java/com/r3/csde/VNodesHelper.java b/buildSrc/src/main/java/com/r3/csde/VNodesHelper.java deleted file mode 100644 index bafdc75..0000000 --- a/buildSrc/src/main/java/com/r3/csde/VNodesHelper.java +++ /dev/null @@ -1,288 +0,0 @@ -package com.r3.csde; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.r3.csde.dtos.*; -import kong.unirest.HttpResponse; -import kong.unirest.JsonNode; -import kong.unirest.Unirest; -import java.io.FileInputStream; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import static java.net.HttpURLConnection.HTTP_OK; - -/** - * The VNodesHelper class is used to create and register the Vnodes specified in the static-network-config.json file. - */ - -public class VNodesHelper { - private ProjectContext pc; - private ProjectUtils utils; - private NetworkConfig config; - private ObjectMapper mapper; - - public VNodesHelper(ProjectContext _pc, NetworkConfig _config) { - pc = _pc; - utils = new ProjectUtils(pc); - config = _config; - Unirest.config().verifySsl(false); - mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - } - - /** - * Entry point for setting up vnodes, called from the 5-vNodeSetup task in csde.gradle - */ - public void vNodesSetup() throws CsdeException { - List requiredNodes = config.getVNodes(); - createVNodes(requiredNodes); - registerVNodes(requiredNodes); - } - - /** - * Creates vnodes specified in the config if they don't already exist. - * @param requiredNodes represents the list of VNodes as specified in the network Config json file (static-network-config.json) - */ - private void createVNodes(List requiredNodes) throws CsdeException { - - // Get existing Nodes. - List existingVNodes = getExistingNodes(); - - // Check if each required vnode already exist, if not create it. - for (VNode vn : requiredNodes) { - // Match on x500 and cpi name - List matches = existingVNodes - .stream() - .filter(existing -> - existing.getHoldingIdentity().getX500Name().equals( vn.getX500Name()) && - existing.getCpiIdentifier().getCpiName().equals(vn.getCpi())) - .collect(Collectors.toList()); - - if (matches.size() == 0) { - createVNode(vn); - } - } - } - - /** - * Gets a list of the virtual nodes which have already been created. - * @return a list of the virtual nodes which have already been created. - */ - private List getExistingNodes () throws CsdeException { - - HttpResponse response = Unirest.get(pc.baseURL + "/api/v1/virtualnode") - .basicAuth(pc.rpcUser, pc.rpcPasswd) - .asJson(); - - if (response.getStatus() != HTTP_OK) { - throw new CsdeException("Failed to get Existing vNodes, response status: "+ response.getStatus()); - } - - try { - return mapper.readValue(response.getBody().toString(), VirtualNodesDTO.class).getVirtualNodes(); - } catch (Exception e){ - throw new CsdeException("Failed to get Existing vNodes with exception: " + e); - } - } - - /** - * Creates a vnode on the Corda cluster from the VNode info. - * @param vNode represents a virtual node using VNode Class. - */ - private void createVNode(VNode vNode) throws CsdeException { - - pc.out.println("Creating virtual node for "+ vNode.getX500Name()); - - // Reads the current CPIFileChecksum value and checks it has been uploaded. - String cpiCheckSum = getCpiCheckSum(vNode); - if (!checkCpiUploaded(cpiCheckSum)) throw new CsdeException("Cpi " + cpiCheckSum + " not uploaded."); - - // Creates the vnode on Cluster - HttpResponse response = Unirest.post(pc.baseURL + "/api/v1/virtualnode") - .body("{ \"request\" : { \"cpiFileChecksum\": \"" + cpiCheckSum + "\", \"x500Name\": \"" + vNode.getX500Name() + "\" } }") - .basicAuth(pc.rpcUser, pc.rpcPasswd) - .asJson(); - - if (response.getStatus() != HTTP_OK) { - throw new CsdeException("Creation of virtual node failed with response status: " + response.getStatus()); - } - } - - /** - * Reads the latest CPI checksums from file. - * @param vNode represents a virtual node using VNode Class. - */ - private String getCpiCheckSum(VNode vNode) throws CsdeException { - - try { - String file = (vNode.getServiceX500Name() == null) ? pc.CPIUploadStatusFName : pc.NotaryCPIUploadStatusFName; - FileInputStream in = new FileInputStream(file); - CPIFileStatusDTO statusDTO = mapper.readValue(in, CPIFileStatusDTO.class); - return statusDTO.getCpiFileChecksum().toString(); - } catch (Exception e) { - throw new CsdeException("Failed to read CPI checksum from file, with error: " + e); - } - } - - private boolean checkCpiUploaded(String cpiCheckSum) throws CsdeException { - - HttpResponse response = Unirest.get(pc.baseURL + "/api/v1/cpi") - .basicAuth(pc.rpcUser, pc.rpcPasswd) - .asJson(); - - if (response.getStatus() != HTTP_OK) { - throw new CsdeException("Failed to check cpis, response status: " + response.getStatus()); - } - - try { - GetCPIsResponseDTO cpisResponse = mapper.readValue( - response.getBody().toString(), GetCPIsResponseDTO.class); - - for (CpiMetadataDTO cpi: cpisResponse.getCpis()) { - if (Objects.equals(cpi.getCpiFileChecksum(), cpiCheckSum)) { - return true; - } - } - // Returns false if no cpis were returned or the cpiCheckSum didnt' match ay results. - return false; - } catch (Exception e) { - throw new CsdeException("Failed to check cpis with exception: " + e); - } - } - - /** - * Checks if the required virtual nodes have been registered and if not registers them. - * @param requiredNodes represents the list of VNodes as specified in the network Config json file (static-network-config.json) - */ - private void registerVNodes(List requiredNodes) throws CsdeException { - - // There appears to be a delay between the successful post /virtualnodes synchronous call and the - // vnodes being returned in the GET /virtualnodes call. Putting a thread wait here as a quick fix - // as this will move to async mechanism post beta2. - utils.rpcWait(2000); - List existingVNodes = getExistingNodes(); - - for (VNode vn: requiredNodes) { - // Match on x500 and cpi name - List matches = existingVNodes - .stream() - .filter(existing -> - existing.getHoldingIdentity().getX500Name().equals( vn.getX500Name()) && - existing.getCpiIdentifier().getCpiName().equals(vn.getCpi())) - .collect(Collectors.toList()); - - if (matches.size() == 0) { - throw new CsdeException("Registration failed because virtual node for '" + vn.getX500Name() + "' not found."); - } else if (matches.size() >1 ) { - throw new CsdeException(("Registration failed because more than virtual node for '" + vn.getX500Name() + "'")); - } - - String shortHash = matches.get(0).getHoldingIdentity().getShortHash(); - - if (!checkVNodeIsRegistered(shortHash)) { - registerVnode(vn, shortHash); - } - } - } - - /** - * Registers a virtual node. - * @param vnode represents the vnode to be registered. - * @param shortHash the shortHash of the virtual node to register. - */ - private void registerVnode(VNode vnode, String shortHash) throws CsdeException { - - pc.out.println("Registering vNode: " + vnode.getX500Name() + " with shortHash: " + shortHash); - - // Configure the registration body (notary vs non notary) - String registrationBody; - if (vnode.getServiceX500Name() == null) { - registrationBody = - "{ \"action\" : \"requestJoin\"," + - " \"context\" : {" + - " \"corda.key.scheme\" : \"CORDA.ECDSA.SECP256R1\" } }"; - } else { - registrationBody = - "{ \"action\" : \"requestJoin\"," + - " \"context\" : {" + - " \"corda.key.scheme\" : \"CORDA.ECDSA.SECP256R1\", " + - " \"corda.roles.0\" : \"notary\", " + - " \"corda.notary.service.name\" : \"" + vnode.getServiceX500Name() + "\", " + - " \"corda.notary.service.plugin\" : \"net.corda.notary.NonValidatingNotary\" } }"; - } - - HttpResponse response = Unirest.post(pc.baseURL + "/api/v1/membership/" + shortHash) - .body(registrationBody) - .basicAuth(pc.rpcUser, pc.rpcPasswd) - .asJson(); - - if (response.getStatus() == HTTP_OK) { - pc.out.println("Membership requested for node " + shortHash); - } else { - throw new CsdeException("Failed to register virtual node " + shortHash + ", response status: " + response.getStatus() ); - } - - // wait until Vnode registered - pollForRegistration(shortHash, 30000, 1000); - - } - - /** - * Checks if a virtual node with given shortHash has been registered - * @param shortHash shortHash of the node which is being checked. - * @return returns true if the vnode is registered - */ - private boolean checkVNodeIsRegistered(String shortHash) throws CsdeException { - - // Queries registration status for vnode. - HttpResponse response = Unirest.get(pc.baseURL + "/api/v1/membership/" + shortHash) - .basicAuth(pc.rpcUser, pc.rpcPasswd) - .asJson(); - - if (response.getStatus() != HTTP_OK) - throw new CsdeException("Failed to check registration status for virtual node '" + shortHash + - "' response status: " + response.getStatus()); - - try { - // If the response body is not empty check all previous requests for an "APPROVED" - if (!response.getBody().getArray().isEmpty()) { - List requests = mapper.readValue( - response.getBody().toString(), new TypeReference<>() { - }); - for (RegistrationRequestProgressDTO request : requests) { - if (Objects.equals(request.getRegistrationStatus(), "APPROVED")) { - return true; - } - } - } - // Returns false if array was empty or "APPROVED" wasn't found - return false; - - } catch (Exception e) { - throw new CsdeException("Failed to check registration status for " + shortHash + - " with exception " + e); - } - } - - /** - * Polls for registration of a vnode - * @param shortHash short hash of the node which is being poled for - * @param duration the number of milliseconds before the pollign times out - * @param cooldown the number of milliseconds in between poll attempts. - */ - private void pollForRegistration(String shortHash, int duration, int cooldown) throws CsdeException { - - int timer = 0; - while (timer < duration ) { - if (checkVNodeIsRegistered(shortHash)){ - pc.out.println("Vnode " + shortHash +" registered."); - return; - } - utils.rpcWait(cooldown); - timer += cooldown; - } - throw new CsdeException("Vnode " + shortHash + " failed to register in " + duration + " milliseconds"); - } -} diff --git a/buildSrc/src/main/java/com/r3/csde/dtos/CPIFileStatusDTO.java b/buildSrc/src/main/java/com/r3/csde/dtos/CPIFileStatusDTO.java deleted file mode 100644 index 1c6e118..0000000 --- a/buildSrc/src/main/java/com/r3/csde/dtos/CPIFileStatusDTO.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.r3.csde.dtos; - -public class CPIFileStatusDTO { - private String status; - private String cpiFileChecksum; - - public CPIFileStatusDTO() {} - - public String getStatus() { return status; } - - public void setStatus(String status) { this.status = status; } - - public String getCpiFileChecksum() { return cpiFileChecksum; } - - public void setCpiFileChecksum(String cpiFileChecksum) { this.cpiFileChecksum = cpiFileChecksum; } -} diff --git a/buildSrc/src/main/java/com/r3/csde/dtos/CpiIdentifierDTO.java b/buildSrc/src/main/java/com/r3/csde/dtos/CpiIdentifierDTO.java deleted file mode 100644 index e5d5dde..0000000 --- a/buildSrc/src/main/java/com/r3/csde/dtos/CpiIdentifierDTO.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.r3.csde.dtos; - -public class CpiIdentifierDTO { - - // Note, these DTOs don't cover all returned values, just the ones required for CSDE - private String cpiName; - private String cpiVersion; - private String signerSummaryHash; - - public CpiIdentifierDTO() { } - - public String getCpiName() { return cpiName; } - - public void setCpiName(String cpiName) { this.cpiName = cpiName; } - - public String getCpiVersion() { return cpiVersion; } - - public void setCpiVersion(String cpiVersion) { this.cpiVersion = cpiVersion; } - - public String getSignerSummaryHash() { return signerSummaryHash; } - - public void setSignerSummaryHash(String signerSummaryHash) { this.signerSummaryHash = signerSummaryHash; } -} diff --git a/buildSrc/src/main/java/com/r3/csde/dtos/CpiMetadataDTO.java b/buildSrc/src/main/java/com/r3/csde/dtos/CpiMetadataDTO.java deleted file mode 100644 index ef89c7d..0000000 --- a/buildSrc/src/main/java/com/r3/csde/dtos/CpiMetadataDTO.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.r3.csde.dtos; - -public class CpiMetadataDTO { - // Note, these DTOs don't cover all returned values, just the ones required for CSDE. - private String cpiFileChecksum; - private CpiIdentifierDTO id; - - public CpiMetadataDTO() {} - - public String getCpiFileChecksum() { return cpiFileChecksum; } - - public void setCpiFileChecksum(String cpiFileChecksum) { this.cpiFileChecksum = cpiFileChecksum; } - - public CpiIdentifierDTO getId() { return id; } - - public void setId(CpiIdentifierDTO id) { this.id = id; } -} diff --git a/buildSrc/src/main/java/com/r3/csde/dtos/GetCPIsResponseDTO.java b/buildSrc/src/main/java/com/r3/csde/dtos/GetCPIsResponseDTO.java deleted file mode 100644 index a16e9a1..0000000 --- a/buildSrc/src/main/java/com/r3/csde/dtos/GetCPIsResponseDTO.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.r3.csde.dtos; - -import java.util.List; - -public class GetCPIsResponseDTO { - - private List cpis; - - public GetCPIsResponseDTO() {} - - public List getCpis() { return cpis; } - - public void setCpis(List cpis) { this.cpis = cpis; } -} diff --git a/buildSrc/src/main/java/com/r3/csde/dtos/HoldingIdentityDTO.java b/buildSrc/src/main/java/com/r3/csde/dtos/HoldingIdentityDTO.java deleted file mode 100644 index 48c12c0..0000000 --- a/buildSrc/src/main/java/com/r3/csde/dtos/HoldingIdentityDTO.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.r3.csde.dtos; - -public class HoldingIdentityDTO { - // Note, these DTOs don't cover all returned values, just the ones required for CSDE. - private String fullHash; - private String groupId; - private String shortHash; - private String x500Name; - - public HoldingIdentityDTO() {} - - public String getFullHash() { return fullHash; } - - public void setFullHash(String fullHash) { this.fullHash = fullHash; } - - public String getGroupId() { return groupId; } - - public void setGroupID(String groupID) { this.groupId = groupId; } - - public String getShortHash() { return shortHash; } - - public void setShortHash(String shortHash) { this.shortHash = shortHash; } - - public String getX500Name() { return x500Name; } - - public void setX500Name(String x500Name) { this.x500Name = x500Name; } -} diff --git a/buildSrc/src/main/java/com/r3/csde/dtos/RegistrationRequestProgressDTO.java b/buildSrc/src/main/java/com/r3/csde/dtos/RegistrationRequestProgressDTO.java deleted file mode 100644 index b3e63b0..0000000 --- a/buildSrc/src/main/java/com/r3/csde/dtos/RegistrationRequestProgressDTO.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.r3.csde.dtos; - -public class RegistrationRequestProgressDTO { - // Note, these DTOs don't cover all returned values, just the ones required for CSDE. - private String registrationStatus; - private String reason; - - public RegistrationRequestProgressDTO() {} - - public String getRegistrationStatus() { return registrationStatus; } - - public void setRegistrationStatus(String registrationStatus) { this.registrationStatus = registrationStatus; } - - public String getReason() { return reason; } - - public void setReason(String reason) { this.reason = reason; } -} diff --git a/buildSrc/src/main/java/com/r3/csde/dtos/VirtualNodeInfoDTO.java b/buildSrc/src/main/java/com/r3/csde/dtos/VirtualNodeInfoDTO.java deleted file mode 100644 index 152cf3e..0000000 --- a/buildSrc/src/main/java/com/r3/csde/dtos/VirtualNodeInfoDTO.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.r3.csde.dtos; - -public class VirtualNodeInfoDTO { - // Note, these DTOs don't cover all returned values, just the ones required for CSDE. - private HoldingIdentityDTO holdingIdentity; - private CpiIdentifierDTO cpiIdentifier; - - public VirtualNodeInfoDTO() {} - - public HoldingIdentityDTO getHoldingIdentity() { return holdingIdentity; } - - public void setHoldingIdentity(HoldingIdentityDTO holdingIdentity) { this.holdingIdentity = holdingIdentity; } - - public CpiIdentifierDTO getCpiIdentifier() { return cpiIdentifier; } - - public void setCpiIdentifier(CpiIdentifierDTO cpiIdentifier) { this.cpiIdentifier = cpiIdentifier; } -} diff --git a/buildSrc/src/main/java/com/r3/csde/dtos/VirtualNodesDTO.java b/buildSrc/src/main/java/com/r3/csde/dtos/VirtualNodesDTO.java deleted file mode 100644 index 86966b7..0000000 --- a/buildSrc/src/main/java/com/r3/csde/dtos/VirtualNodesDTO.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.r3.csde.dtos; - -import java.util.List; - -public class VirtualNodesDTO { - - private List virtualNodes; - - public VirtualNodesDTO() {} - - public List getVirtualNodes() { return virtualNodes; } - - public void setVirtualNodes(List virtualNodes) { this.virtualNodes = virtualNodes; } -} diff --git a/config/static-network-config.json b/config/static-network-config.json index 9adde9b..b0f2519 100644 --- a/config/static-network-config.json +++ b/config/static-network-config.json @@ -1,23 +1,23 @@ [ { "x500Name" : "CN=Alice, OU=Test Dept, O=R3, L=London, C=GB", - "cpi" : "cpi name" + "cpi" : "MyCorDapp" }, { "x500Name" : "CN=Bob, OU=Test Dept, O=R3, L=London, C=GB", - "cpi" : "cpi name" + "cpi" : "MyCorDapp" }, { "x500Name" : "CN=Charlie, OU=Test Dept, O=R3, L=London, C=GB", - "cpi" : "cpi name" + "cpi" : "MyCorDapp" }, { "x500Name" : "CN=Dave, OU=Test Dept, O=R3, L=London, C=GB", - "cpi" : "cpi name" + "cpi" : "MyCorDapp" }, { "x500Name" : "CN=NotaryRep1, OU=Test Dept, O=R3, L=London, C=GB", - "cpi" : "CSDE Notary Server CPI", + "cpi" : "NotaryServer", "serviceX500Name": "CN=NotaryService, OU=Test Dept, O=R3, L=London, C=GB" } ] diff --git a/gradle.properties b/gradle.properties index c2b0246..4ec3ac0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,10 +4,6 @@ kotlin.code.style=official # This needs to match the version supported by the Corda Cluster the CorDapp will run on. cordaApiVersion=5.0.0.665-Gecko1.0 -# Settings For Development Utilities -combinedWorkerVersion=5.0.0.0-Gecko1.0 -simulatorVersion=5.0.0.0-Gecko1.0 - # Specify the version of the notary plugins to use. # Currently packaged as part of corda-runtime-os, so should be set to a corda-runtime-os version. cordaNotaryPluginsVersion=5.0.0.0-Gecko1.0 @@ -15,6 +11,9 @@ cordaNotaryPluginsVersion=5.0.0.0-Gecko1.0 # Specify the version of the cordapp-cpb and cordapp-cpk plugins cordaPluginsVersion=7.0.1 +# Specify the version of the CSDE gradle plugin to use +csdePluginVersion=1.0.+ + # For the time being this just needs to be set to a dummy value. platformVersion = 999 @@ -31,15 +30,7 @@ mockitoKotlinVersion=4.0.0 mockitoVersion=4.6.1 hamcrestVersion=2.2 -postgresqlVersion=42.4.3 - -cordaClusterURL=https://localhost:8888 -cordaRpcUser=admin -cordaRpcPasswd=admin -devEnvWorkspace=workspace -dbContainerName=CSDEpostgresql # R3 internal repository -#S3 version for HC and RC versions published by CD/CD team -artifactoryContextUrl=https://staging.download.corda.net/maven/20ede3c6-29c0-11ed-966d-b7c36748b9f6-Gecko-RC03/ -#artifactoryContextUrl=https://staging.download.corda.net/maven/20ede3c6-29c0-11ed-966d-b7c36748b9f6-Gecko-RC02/ \ No newline at end of file +# Use this version when pointing to artefacts in artifactory that have not been published to S3 +artifactoryContextUrl=https://software.r3.com/artifactory \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 585a354..d343d5f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,8 +3,16 @@ pluginManagement { repositories { gradlePluginPortal() mavenCentral() + mavenLocal() maven { - url = "$artifactoryContextUrl/" + url = "$artifactoryContextUrl/corda-os-maven" + authentication { + basic(BasicAuthentication) + } + credentials { + username = settings.ext.find('cordaArtifactoryUsername') ?: System.getenv('CORDA_ARTIFACTORY_USERNAME') + password = settings.ext.find('cordaArtifactoryPassword') ?: System.getenv('CORDA_ARTIFACTORY_PASSWORD') + } } } @@ -14,6 +22,7 @@ pluginManagement { id 'net.corda.plugins.cordapp-cpk2' version cordaPluginsVersion id 'net.corda.plugins.cordapp-cpb2' version cordaPluginsVersion id 'net.corda.cordapp.cordapp-configuration' version cordaApiVersion + id 'net.corda.plugins.csde' version csdePluginVersion id 'org.jetbrains.kotlin.jvm' version kotlinVersion id 'org.jetbrains.kotlin.plugin.jpa' version kotlinVersion id 'org.jetbrains.kotlin.plugin.allopen' version kotlinVersion