Corda intellij Plugin (#3)

* First cut for corda intellij Plugin
This commit is contained in:
Patrick Kuo 2017-06-19 16:41:28 +01:00 committed by GitHub
parent d0daac8dd6
commit 21e1c86155
21 changed files with 782 additions and 0 deletions

21
.idea/runConfigurations/CordaPlugin.xml generated Normal file
View File

@ -0,0 +1,21 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="CordaPlugin" type="GradleRunConfiguration" factoryName="Gradle" singleton="true">
<log_file path="$PROJECT_DIR$/experimental/intellij-plugin/build/idea-sandbox/system/log/idea.log" checked="true" skipped="true" show_all="false" alias="idea.log" />
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runIde" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<method />
</configuration>
</component>

View File

@ -0,0 +1,41 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id "org.jetbrains.intellij" version "0.2.11"
}
apply plugin: 'kotlin'
intellij {
version 'IU-2017.1'
//IntelliJ IDEA 2016.3 dependency; for a full list of IntelliJ IDEA releases please see https://www.jetbrains.com/intellij-repository/releases
plugins = ['Kotlin', 'devkit', 'gradle'] //Bundled plugin dependencies
pluginName "$project.name"
updateSinceUntilBuild = false
sameSinceUntilBuild = false
buildDir = "$projectDir/build"
}
group 'net.corda'
version '0.1.0' // Plugin version
repositories {
mavenCentral()
}
sourceSets {
main{
java.srcDirs += 'src/main/kotlin'
resources.srcDirs += 'src/main/resources'
}
}

View File

@ -0,0 +1 @@
kotlin_version=1.1.2-2

View File

@ -0,0 +1,25 @@
# Corda Intellij Plugin
Corda Intellij Plugin is a plugin for Intellij Idea IDE which aid Corda application development.
## Features
* Setup CorDapp project in a few clicks.
* Support Java and Kotlin project.
* User can choose to include different Corda module templates.
## Getting started
This project uses gradle to manage dependencies, Intellij's Plugin runner DOES NOT work in this project.
###Running the project
You can run or debug the project using provided Intellij Run Configuration `CordaPlugin` or by using the gradle command
`./gradlew runIde` IDE's log file is located in `build/idea-sandbox/system/log/idea.log`
## TODOs
* Create a higher quality Corda icon.
* Create a more compact kotlin CorDapp template.
* Add Java Templates.
* Figure out how to import gradle setting in the plugin, to avoid having to manual import after project creation.
* Support other build tools? (Maven, SBT etc...)
* Custom run configuration for running and debugging CorDapp in Intellij.
* Add Python option?
* Flow visualiser?

View File

@ -0,0 +1 @@
rootProject.name = "CordaPlugin"

View File

@ -0,0 +1,104 @@
package net.corda.ideaPlugin.module
import com.intellij.ide.fileTemplates.FileTemplateManager
import com.intellij.ide.projectWizard.ProjectSettingsStep
import com.intellij.ide.util.projectWizard.*
import com.intellij.openapi.Disposable
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleType
import com.intellij.openapi.options.ConfigurationException
import com.intellij.openapi.util.Version
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.plugins.gradle.service.project.wizard.GradleModuleBuilder.appendToFile
import org.jetbrains.plugins.gradle.service.project.wizard.GradleModuleBuilder.setupGradleSettingsFile
import java.io.File
import java.io.IOException
class CordaModuleBuilder : JavaModuleBuilder(), ModuleBuilderListener {
private val config = CordaModuleConfiguration()
init {
addListener(this)
}
override fun getBuilderId() = "corda"
override fun moduleCreated(module: Module) {
val contentEntryPath = contentEntryPath
if (contentEntryPath.isNullOrEmpty()) return
val contentRootDir = File(contentEntryPath)
FileUtilRt.createDirectory(contentRootDir)
val fileSystem = LocalFileSystem.getInstance()
val modelContentRootDir = fileSystem.refreshAndFindFileByIoFile(contentRootDir) ?: return
val packagePath = "src/main/kotlin/${config.packageName.replace(".", "/")}"
setupGradleSettingsFile(modelContentRootDir.path, modelContentRootDir, module.project.name, module.name, true)
setupFile(modelContentRootDir, "", "build.gradle", "build.gradle")
config.selectedTemplate.flatMap { CordaTemplateProvider.getTemplateFiles(it, config.language) }.forEach {
setupFile(modelContentRootDir, "$packagePath/${it.targetPath}", "${if (it.appendProjectName) config.appName else ""}${it.fileName}", it.fileName)
}
}
override fun getCustomOptionsStep(context: WizardContext, parentDisposable: Disposable?) = CordaModuleWizardStep(config)
override fun modifySettingsStep(settingsStep: SettingsStep): ModuleWizardStep? {
if (settingsStep is ProjectSettingsStep) {
val projectSettingsStep = settingsStep
val moduleNameField = settingsStep.moduleNameField
moduleNameField.text = config.appName
projectSettingsStep.setModuleName(config.packageName)
projectSettingsStep.bindModuleSettings()
}
return super.modifySettingsStep(settingsStep)
}
override fun getPresentableName() = "CorDapp"
override fun getGroupName() = "Corda"
override fun getModuleType(): ModuleType<*> = CordaModuleType.instance
private fun setupFile(modelContentRootDir: VirtualFile, path: String, fileName: String, templateName: String): VirtualFile? {
val file = getOrCreateExternalProjectConfigFile("${modelContentRootDir.path}/$path", fileName) ?: return null
saveFile(file, templateName, config.toMap())
return file
}
private fun getOrCreateExternalProjectConfigFile(parent: String, fileName: String): VirtualFile? {
val file = File(parent, fileName)
FileUtilRt.createIfNotExists(file)
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file)
}
private fun saveFile(file: VirtualFile, templateName: String, templateAttributes: Map<String, String?>?) {
val manager = FileTemplateManager.getDefaultInstance()
val template = manager.getInternalTemplate(templateName)
try {
appendToFile(file, if (templateAttributes != null) template.getText(templateAttributes) else template.text)
} catch (e: IOException) {
throw ConfigurationException(e.message, e.stackTrace.toString())
}
}
}
data class CordaModuleConfiguration(var cordaSdkVersion: Version? = null,
var group: String = "",
var appName: String = "",
var packageName: String = "",
var version: String = "",
var language: Language = Language.KOTLIN,
var selectedTemplate: List<CordaTemplate> = emptyList()) {
fun toMap(): Map<String, String> {
return mapOf("CORDA_SDK_VERSION" to cordaSdkVersion.toString(),
"PROJECT_NAME" to appName,
"PROJECT_NAME_DECAPITALIZE" to appName.decapitalize(),
"PACKAGE_NAME" to packageName,
"VERSION" to version,
"GROUP" to group,
"LANGUAGE" to language.displayName)
}
}

View File

@ -0,0 +1,19 @@
package net.corda.ideaPlugin.module
import com.intellij.openapi.module.ModuleType
import com.intellij.openapi.util.IconLoader
class CordaModuleType : ModuleType<CordaModuleBuilder>(ID) {
companion object {
val ID = "CORDA_MODULE"
val CORDA_ICON = IconLoader.getIcon("/images/corda-icon.png")
val instance = CordaModuleType()
}
override fun createModuleBuilder() = CordaModuleBuilder()
override fun getNodeIcon(p0: Boolean) = CORDA_ICON
override fun getBigIcon() = CORDA_ICON
override fun getName() = "CorDapp"
override fun getDescription() = "Corda DLT Platform Application"
}

View File

@ -0,0 +1,88 @@
package net.corda.ideaPlugin.module
import com.intellij.ide.util.projectWizard.ModuleWizardStep
import com.intellij.openapi.options.ConfigurationException
import com.intellij.openapi.util.Version
import com.intellij.ui.CheckBoxList
import com.intellij.ui.components.JBScrollPane
import com.intellij.ui.components.JBTextField
import com.intellij.ui.layout.CCFlags
import com.intellij.ui.layout.panel
import java.awt.BorderLayout
import javax.swing.*
class CordaModuleWizardStep(private val config: CordaModuleConfiguration) : ModuleWizardStep() {
private val sdkPanel = CordaModuleWizardPanel()
override fun getComponent() = sdkPanel
override fun updateDataModel() {
config.cordaSdkVersion = sdkPanel.cordaSdkVersion
config.language = sdkPanel.language!!
config.appName = sdkPanel.appName
config.packageName = "${sdkPanel.domain}.${sdkPanel.appName.decapitalize()}"
config.group = sdkPanel.domain
config.version = sdkPanel.version
config.selectedTemplate = sdkPanel.templates
}
@Throws(ConfigurationException::class)
override fun validate(): Boolean {
sdkPanel.cordaSdkVersion ?: throw ConfigurationException("Specify Corda SDK Version")
return super.validate()
}
}
class CordaModuleWizardPanel : JPanel(BorderLayout()) {
val cordaSdkVersion: Version? get() = cordaSdkVersionComboBox.getSelectedCordaSdkVersion()
val language: Language? get() = languageComboBox.selectedItem as? Language
val appName: String get() = appNameTextField.text
val domain: String get() = domainTextField.text
val version: String get() = versionTextField.text
val templates: List<CordaTemplate> get() = CordaTemplate.values().filter { templateList.isItemSelected(it) }
private val cordaSdkVersionComboBox = CordaSdkVersionComboBox(Version(0, 12, 1), Version(0, 11, 1))
private val languageComboBox = JComboBox(DefaultComboBoxModel(Language.values()))
private val appNameTextField = JBTextField("MyCorDapp")
private val domainTextField = JBTextField("com.myCompany")
private val versionTextField = JBTextField("1.0.0")
private val templateList = CheckBoxList<CordaTemplate>().apply {
CordaTemplate.values().forEach {
addItem(it, it.displayName, it == CordaTemplate.CORDAPP)
}
setCheckBoxListListener { i, _ ->
val template = getItemAt(i) as? CordaTemplate
template?.let { if (!it.optional) setItemSelected(it, true) }
}
}
init {
val myRoot = panel {
border = BorderFactory.createEmptyBorder(4, 5, 0, 5)
//row("Project SDK:") { projectSdkComboBox(CCFlags.growX, CCFlags.pushX) }
row("Corda SDK Version:") { cordaSdkVersionComboBox(CCFlags.growX, CCFlags.pushX) }
row("Language:") { languageComboBox(CCFlags.growX, CCFlags.pushX) }
row(JLabel("CorDapp Name:"), separated = true) { appNameTextField(CCFlags.growX, CCFlags.pushX) }
row("Company Domain:") { domainTextField(CCFlags.growX, CCFlags.pushX) }
//TODO: row("Package Name:") { packageName(CCFlags.growX, CCFlags.pushX) }
row("Version:") { versionTextField(CCFlags.growX, CCFlags.pushX) }
}
val template = panel {
row(separated = true) { (JLabel("Templates and Examples:"))(CCFlags.growX, CCFlags.pushX) }
row { (JBScrollPane(templateList))(CCFlags.grow, CCFlags.push) }
}
add(myRoot, BorderLayout.NORTH)
add(template, BorderLayout.CENTER)
languageComboBox.selectedItem = Language.KOTLIN
}
}
enum class Language(val displayName: String) {
JAVA("Java"),
KOTLIN("Kotlin");
override fun toString(): String {
return displayName
}
}

View File

@ -0,0 +1,30 @@
package net.corda.ideaPlugin.module
import com.intellij.openapi.util.Version
import com.intellij.ui.ColoredListCellRenderer
import com.intellij.ui.SimpleTextAttributes
import javax.swing.DefaultComboBoxModel
import javax.swing.JComboBox
import javax.swing.JList
class CordaSdkVersionComboBox(vararg val sdkVersions: Version) : JComboBox<Version>() {
init {
renderer = object : ColoredListCellRenderer<Any?>() {
override fun customizeCellRenderer(list: JList<*>, value: Any?, index: Int, selected: Boolean, hasFocus: Boolean) {
if (value is Version) {
append(value.toString())
} else {
append("Select Corda SDK Version", SimpleTextAttributes.ERROR_ATTRIBUTES)
}
}
}
updateSdkList(null, true)
}
fun updateSdkList(sdkVersionToSelect: Version?, selectAnySdk: Boolean) {
model = DefaultComboBoxModel(arrayOf(null, *sdkVersions))
selectedItem = if (selectAnySdk) sdkVersions.firstOrNull() else sdkVersionToSelect
}
fun getSelectedCordaSdkVersion() = selectedItem as? Version
}

View File

@ -0,0 +1,41 @@
package net.corda.ideaPlugin.module
object CordaTemplateProvider {
fun getTemplateFiles(cordaTemplate: CordaTemplate, language: Language): List<TemplateFile> {
return when (language) {
Language.KOTLIN -> getKotlinTemplateFiles(cordaTemplate)
Language.JAVA -> getJavaTemplateFiles(cordaTemplate)
}
}
private fun getKotlinTemplateFiles(cordaTemplate: CordaTemplate): List<TemplateFile> {
return when (cordaTemplate) {
CordaTemplate.CORDAPP -> listOf(
TemplateFile("Main.kt", "", appendProjectName = false),
TemplateFile("Flow.kt", "/flow"),
TemplateFile("Contract.kt", "/contract"),
TemplateFile("State.kt", "/state"))
CordaTemplate.WEBAPI -> listOf(
TemplateFile("Api.kt", "/api"),
TemplateFile("Plugin.kt", "/plugin"))
CordaTemplate.RPC -> listOf(TemplateFile("ClientRPC.kt", "/client"))
}
}
private fun getJavaTemplateFiles(cordaTemplate: CordaTemplate): List<TemplateFile> {
// TODO: Provide java template.
return when (cordaTemplate) {
CordaTemplate.CORDAPP -> listOf()
CordaTemplate.WEBAPI -> listOf()
CordaTemplate.RPC -> listOf()
}
}
}
enum class CordaTemplate(val displayName: String, val optional: Boolean = true) {
CORDAPP("CorDapp Template", optional = false),
WEBAPI("Web API Template"),
RPC("RPC Client Template")
}
data class TemplateFile(val fileName: String, val targetPath: String, val appendProjectName: Boolean = true)

View File

@ -0,0 +1,36 @@
<idea-plugin>
<id>net.corda</id>
<name>CorDapp Plugin</name>
<version>1.0</version>
<vendor email="support@yourcompany.com" url="http://www.yourcompany.com">YourCompany</vendor>
<description><![CDATA[
Enter short description for your plugin here.<br>
<em>most HTML tags may be used</em>
]]></description>
<change-notes><![CDATA[
Add change notes here.<br>
<em>most HTML tags may be used</em>
]]>
</change-notes>
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
<idea-version since-build="145.0"/>
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
on how to target different products -->
<depends>com.intellij.modules.lang</depends>
<depends>org.jetbrains.kotlin</depends>
<depends>DevKit</depends>
<depends>org.jetbrains.plugins.gradle</depends>
<extensions defaultExtensionNs="com.intellij">
<moduleType id="CORDA_MODULE" implementationClass="net.corda.ideaPlugin.module.CordaModuleType"/>
</extensions>
<actions>
<!-- Add your actions here -->
</actions>
</idea-plugin>

View File

@ -0,0 +1,32 @@
package ${PACKAGE_NAME}.api
import net.corda.core.messaging.CordaRPCOps
import javax.ws.rs.GET
import javax.ws.rs.PUT
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.Response
// This API is accessible from /api/${PROJECT_NAME_DECAPITALIZE}. The endpoint paths specified below are relative to it.
@Path("${PROJECT_NAME_DECAPITALIZE}")
class ${PROJECT_NAME}Api(val services: CordaRPCOps) {
/**
* Accessible at /api/template/${PROJECT_NAME_DECAPITALIZE}GetEndpoint.
*/
@GET
@Path("${PROJECT_NAME_DECAPITALIZE}GetEndpoint")
@Produces(MediaType.APPLICATION_JSON)
fun templateGetEndpoint(): Response {
return Response.ok(mapOf("message" to "${PROJECT_NAME} GET endpoint.")).build()
}
/**
* Accessible at /api/template/${PROJECT_NAME_DECAPITALIZE}PutEndpoint.
*/
@PUT
@Path("${PROJECT_NAME_DECAPITALIZE}PutEndpoint")
fun templatePutEndpoint(payload: Any): Response {
return Response.ok("${PROJECT_NAME} PUT endpoint.").build()
}
}

View File

@ -0,0 +1,44 @@
package ${PACKAGE_NAME}.client
import com.google.common.net.HostAndPort
import ${PACKAGE_NAME}.state.${PROJECT_NAME}State
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.loggerFor
import org.slf4j.Logger
import rx.Observable
/**
* Demonstration of how to use the CordaRPCClient to connect to a Corda Node and
* stream some State data from the node.
*/
fun main(args: Array<String>) {
${PROJECT_NAME}ClientRPC().main(args)
}
private class ${PROJECT_NAME}ClientRPC {
companion object {
val logger: Logger = loggerFor<${PROJECT_NAME}ClientRPC>()
}
fun main(args: Array<String>) {
require(args.size == 1) { "Usage: ${PROJECT_NAME}ClientRPC <node address>" }
val nodeAddress = HostAndPort.fromString(args[0])
val client = CordaRPCClient(nodeAddress)
// Can be amended in the com.template.MainKt file.
val proxy = client.start("user1", "test").proxy
// Grab all signed transactions and all future signed transactions.
val (transactions: List<SignedTransaction>, futureTransactions: Observable<SignedTransaction>) =
proxy.verifiedTransactions()
// Log the existing TemplateStates and listen for new ones.
futureTransactions.startWith(transactions).toBlocking().subscribe { transaction ->
transaction.tx.outputs.forEach { output ->
val state = output.data as ${PROJECT_NAME}State
logger.info(state.toString())
}
}
}
}

View File

@ -0,0 +1,19 @@
package ${PACKAGE_NAME}.contract
import net.corda.core.contracts.Contract
import net.corda.core.contracts.TransactionForContract
import net.corda.core.crypto.SecureHash
/**
* Define your contract here.
*/
open class ${PROJECT_NAME}Contract : Contract {
/**
* The verify() function of the contract of each of the transaction's input and output states must not throw an
* exception for a transaction to be considered valid.
*/
override fun verify(tx: TransactionForContract) {}
/** A reference to the underlying legal contract template and associated parameters. */
override val legalContractReference: SecureHash = SecureHash.sha256("Prose contract.")
}

View File

@ -0,0 +1,33 @@
package ${PACKAGE_NAME}.flow
import co.paralleluniverse.fibers.Suspendable
import net.corda.core.identity.Party
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.InitiatedBy
import net.corda.core.flows.InitiatingFlow
/**
* Define your flow here.
*/
object ${PROJECT_NAME}Flow {
/**
* You can add a constructor to each FlowLogic subclass to pass objects into the flow.
*/
@InitiatingFlow
class Initiator: FlowLogic<Unit>() {
/**
* Define the initiator's flow logic here.
*/
@Suspendable
override fun call() {}
}
@InitiatedBy(Initiator::class)
class Acceptor(val counterparty: Party) : FlowLogic<Unit>() {
/**
* Define the acceptor's flow logic here.
*/
@Suspendable
override fun call() {}
}
}

View File

@ -0,0 +1,40 @@
package ${PACKAGE_NAME}
import com.google.common.util.concurrent.Futures
import net.corda.core.crypto.X509Utilities.getX509Name
import net.corda.core.getOrThrow
import net.corda.core.node.services.ServiceInfo
import net.corda.node.driver.driver
import net.corda.nodeapi.User
import net.corda.node.services.transactions.ValidatingNotaryService
/**
* This file is exclusively for being able to run your nodes through an IDE (as opposed to running deployNodes)
* Do not use in a production environment.
*
* To debug your CorDapp:
*
* 1. Run the "Run ${PROJECT_NAME} CorDapp" run configuration.
* 2. Wait for all the nodes to start.
* 3. Note the debug ports for each node, which should be output to the console. The "Debug CorDapp" configuration runs
* with port 5007, which should be "NodeA". In any case, double-check the console output to be sure.
* 4. Set your breakpoints in your CorDapp code.
* 5. Run the "Debug CorDapp" remote debug run configuration.
*/
fun main(args: Array<String>) {
// No permissions required as we are not invoking flows.
val user = User("user1", "test", permissions = setOf())
driver(isDebug = true) {
startNode(getX509Name("Controller", "London", "root@city.uk.example"), setOf(ServiceInfo(ValidatingNotaryService.type)))
val (nodeA, nodeB, nodeC) = Futures.allAsList(
startNode(getX509Name("NodeA", "Paris", "root@city.fr.example"), rpcUsers = listOf(user)),
startNode(getX509Name("NodeB", "Rome", "root@city.it.example"), rpcUsers = listOf(user)),
startNode(getX509Name("NodeC", "New York", "root@city.us.example"), rpcUsers = listOf(user))).getOrThrow()
startWebserver(nodeA)
startWebserver(nodeB)
startWebserver(nodeC)
waitForAllNodesToFinish()
}
}

View File

@ -0,0 +1,30 @@
package ${PACKAGE_NAME}.plugin
import ${PACKAGE_NAME}.api.${PROJECT_NAME}Api
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.node.CordaPluginRegistry
import net.corda.core.serialization.SerializationCustomization
import java.util.function.Function
class ${PROJECT_NAME}Plugin : CordaPluginRegistry() {
/**
* A list of classes that expose web APIs.
*/
override val webApis: List<Function<CordaRPCOps, out Any>> = listOf(Function(::${PROJECT_NAME}Api))
/**
* A list of directories in the resources directory that will be served by Jetty under /web.
* The template's web frontend is accessible at /web/template.
*/
override val staticServeDirs: Map<String, String> = mapOf(
// This will serve the ${PROJECT_NAME_DECAPITALIZE}Web directory in resources to /web/${PROJECT_NAME_DECAPITALIZE}
"${PROJECT_NAME_DECAPITALIZE}" to javaClass.classLoader.getResource("${PROJECT_NAME_DECAPITALIZE}Web").toExternalForm()
)
/**
* Whitelisting the required types for serialisation by the Corda node.
*/
override fun customizeSerialization(custom: SerializationCustomization): Boolean {
return true
}
}

View File

@ -0,0 +1,14 @@
package ${PACKAGE_NAME}.state
import ${PACKAGE_NAME}.contract.${PROJECT_NAME}Contract
import net.corda.core.contracts.ContractState
import net.corda.core.identity.AbstractParty
/**
* Define your state object here.
*/
class ${PROJECT_NAME}State(override val contract: ${PROJECT_NAME}Contract): ContractState {
/** The public keys of the involved parties. */
override val participants: List<AbstractParty>
get() = listOf()
}

View File

@ -0,0 +1,162 @@
buildscript {
ext.corda_release_version = '${CORDA_SDK_VERSION}'
ext.corda_gradle_plugins_version = '0.11.2'
ext.kotlin_version = '1.1.2'
ext.junit_version = '4.12'
ext.quasar_version = '0.7.6'
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "net.corda.plugins:publish-utils:$corda_gradle_plugins_version"
classpath "net.corda.plugins:cordformation:$corda_gradle_plugins_version"
classpath "net.corda.plugins:quasar-utils:$corda_gradle_plugins_version"
}
}
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'net.corda.plugins.publish-utils'
apply plugin: 'net.corda.plugins.cordformation'
apply plugin: 'net.corda.plugins.quasar-utils'
apply plugin: 'maven-publish'
group '${GROUP}'
version '${VERSION}'
repositories {
mavenLocal()
mavenCentral()
jcenter()
maven { url 'https://dl.bintray.com/kotlin/exposed' }
maven { url 'https://jitpack.io' }
}
sourceSets {
main {
resources {
srcDir "config/dev"
}
}
test {
resources {
srcDir "config/test"
}
}
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testCompile "junit:junit:$junit_version"
// Corda integration dependencies
compile "net.corda:core:$corda_release_version"
compile "net.corda:finance:$corda_release_version"
compile "net.corda:jackson:$corda_release_version"
compile "net.corda:node:$corda_release_version"
compile "net.corda:rpc:$corda_release_version"
compile "net.corda:webserver:$corda_release_version"
runtime "net.corda:corda:$corda_release_version"
runtime "net.corda:webserver:$corda_release_version"
testCompile "net.corda:test-utils:$corda_release_version"
// GraphStream: For visualisation (required by TemplateClientRPC app)
compile "org.graphstream:gs-core:1.3"
compile("org.graphstream:gs-ui:1.3") {
exclude group: "bouncycastle"
}
// CorDapp dependencies
// Specify your cordapp's dependencies below, including dependent cordapps
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
languageVersion = "1.1"
apiVersion = "1.1"
jvmTarget = "1.8"
javaParameters = true // Useful for reflection.
}
}
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
directory "./build/nodes"
networkMap "CN=Controller,O=R3,OU=corda,L=London,C=UK"
node {
name "CN=Controller,O=R3,OU=corda,L=London,C=UK"
advertisedServices = ["corda.notary.validating"]
p2pPort 10002
rpcPort 10003
cordapps = []
}
node {
name "CN=NodeA,O=NodeA,L=London,C=UK"
advertisedServices = []
p2pPort 10005
rpcPort 10006
webPort 10007
cordapps = []
rpcUsers = [[user: "user1", "password": "test", "permissions": []]]
}
node {
name "CN=NodeB,O=NodeB,L=New York,C=US"
advertisedServices = []
p2pPort 10008
rpcPort 10009
webPort 10010
cordapps = []
rpcUsers = [[user: "user1", "password": "test", "permissions": []]]
}
node {
name "CN=NodeC,O=NodeC,L=Paris,C=FR"
advertisedServices = []
p2pPort 10011
rpcPort 10012
webPort 10013
cordapps = []
rpcUsers = [[user: "user1", "password": "test", "permissions": []]]
}
}
// TODO: Make into gradle plugin without any references to Jython
task installJythonDeps(dependsOn: ['build']) {
project.copy {
from project.configurations.runtime
into "build/jythonDeps"
}
}
installJythonDeps.shouldRunAfter build
idea {
module {
downloadJavadoc = true // defaults to false
downloadSources = true
}
}
publishing {
publications {
jarAndSources(MavenPublication) {
from components.java
artifactId 'cordapp-name-goes-here'
artifact sourceJar
artifact javadocJar
}
}
}
task runTemplateClientRPC(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'com.template.client.TemplateClientRPCKt'
args 'localhost:10006'
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -18,6 +18,7 @@ include 'webserver:webcapsule'
include 'experimental'
include 'experimental:sandbox'
include 'experimental:quasar-hook'
include 'experimental:intellij-plugin'
include 'verifier'
include 'test-utils'
include 'tools:explorer'