Use external pantheon-plugin-api library (#1505)

* Use the external jars to provide the plugin libraries.
* Add mavenLocal to local repositories to aid development
* Remove the :plugins project
* Move the PantheonPluginContextImpl into :pantheon
* rename a few files
Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
pull/2/head
Danno Ferrin 6 years ago committed by GitHub
parent ac9d1e4ca0
commit 16c64e64f0
  1. 8
      acceptance-tests/build.gradle
  2. 6
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java
  3. 2
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/plugins/PantheonEventsPluginTest.java
  4. 9
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/plugins/PicoCLIOptionsPluginTest.java
  5. 1
      build.gradle
  6. 2
      gradle/versions.gradle
  7. 2
      gradle/wrapper/gradle-wrapper.properties
  8. 21
      pantheon/build.gradle
  9. 2
      pantheon/src/main/java/tech/pegasys/pantheon/Pantheon.java
  10. 6
      pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java
  11. 2
      pantheon/src/main/java/tech/pegasys/pantheon/services/PantheonEventsImpl.java
  12. 6
      pantheon/src/main/java/tech/pegasys/pantheon/services/PantheonPluginContextImpl.java
  13. 2
      pantheon/src/main/java/tech/pegasys/pantheon/services/PicoCLIOptionsImpl.java
  14. 2
      pantheon/src/test/java/tech/pegasys/pantheon/cli/CommandTestAbstract.java
  15. 4
      pantheon/src/test/java/tech/pegasys/pantheon/plugins/TestPantheonEventsPlugin.java
  16. 6
      pantheon/src/test/java/tech/pegasys/pantheon/plugins/TestPicoCLIPlugin.java
  17. 4
      pantheon/src/test/java/tech/pegasys/pantheon/services/PantheonPluginContextImplTest.java
  18. 58
      plugins/build.gradle
  19. 20
      plugins/src/main/java/tech/pegasys/pantheon/plugins/PantheonContext.java
  20. 22
      plugins/src/main/java/tech/pegasys/pantheon/plugins/PantheonPlugin.java
  21. 2
      plugins/src/main/java/tech/pegasys/pantheon/plugins/internal/package-info.java
  22. 36
      plugins/src/main/java/tech/pegasys/pantheon/plugins/services/PantheonEvents.java
  23. 27
      plugins/src/main/java/tech/pegasys/pantheon/plugins/services/PicoCLIOptions.java
  24. 1
      settings.gradle

@ -31,9 +31,8 @@ dependencies {
testImplementation project(':ethereum:permissioning')
testImplementation project(':ethereum:rlp')
testImplementation project(':metrics:core')
testImplementation project(':plugins')
testImplementation project(path: ':plugins', configuration: 'testArtifacts')
testImplementation project(':pantheon')
testImplementation project(path: ':pantheon', configuration: 'testArtifacts')
testImplementation project(':services:kvstore')
testImplementation project(':testutil')
testImplementation project(':util')
@ -52,15 +51,16 @@ dependencies {
testImplementation 'org.web3j:abi'
testImplementation 'org.web3j:core'
testImplementation 'org.web3j:crypto'
testImplementation 'tech.pegasys.pantheon:plugin-api'
}
test.enabled = false
sourceSets {
test { resources { srcDirs "${rootDir}/plugins/build/libs" } }
test { resources { srcDirs "${rootDir}/pantheon/build/libs" } }
}
processTestResources.dependsOn(':plugins:testJar')
processTestResources.dependsOn(':pantheon:testJar')
task acceptanceTest(type: Test) {
dependsOn(rootProject.installDist)

@ -26,10 +26,10 @@ import tech.pegasys.pantheon.ethereum.eth.transactions.PendingTransactions;
import tech.pegasys.pantheon.ethereum.graphql.GraphQLConfiguration;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem;
import tech.pegasys.pantheon.plugins.internal.PantheonPluginContextImpl;
import tech.pegasys.pantheon.plugins.services.PantheonEvents;
import tech.pegasys.pantheon.plugins.services.PicoCLIOptions;
import tech.pegasys.pantheon.plugin.services.PantheonEvents;
import tech.pegasys.pantheon.plugin.services.PicoCLIOptions;
import tech.pegasys.pantheon.services.PantheonEventsImpl;
import tech.pegasys.pantheon.services.PantheonPluginContextImpl;
import tech.pegasys.pantheon.services.PicoCLIOptionsImpl;
import tech.pegasys.pantheon.services.kvstore.RocksDbConfiguration;
import tech.pegasys.pantheon.util.enode.EnodeURL;

@ -35,7 +35,7 @@ public class PantheonEventsPluginTest extends AcceptanceTestBase {
minerNode = pantheon.createMinerNode("minerNode");
pluginNode =
pantheon.createPluginsNode(
"node1", Collections.singletonList("testPlugin"), Collections.emptyList());
"node1", Collections.singletonList("testPlugins"), Collections.emptyList());
cluster.start(pluginNode, minerNode);
}

@ -41,14 +41,15 @@ public class PicoCLIOptionsPluginTest extends AcceptanceTestBase {
node =
pantheon.createPluginsNode(
"node1",
Collections.singletonList("testPlugin"),
Collections.singletonList("testPlugins"),
Collections.singletonList("--Xtest-option=" + MAGIC_WORDS));
cluster.start(node);
}
@Test
public void shouldRegister() throws IOException {
final Path registrationFile = node.homeDirectory().resolve("plugins/testPlugin.registered");
final Path registrationFile =
node.homeDirectory().resolve("plugins/pluginLifecycle.registered");
waitForFile(registrationFile);
// this assert is false as CLI will not be parsed at this point
@ -58,7 +59,7 @@ public class PicoCLIOptionsPluginTest extends AcceptanceTestBase {
@Test
public void shouldStart() throws IOException {
final Path registrationFile = node.homeDirectory().resolve("plugins/testPlugin.started");
final Path registrationFile = node.homeDirectory().resolve("plugins/pluginLifecycle.started");
waitForFile(registrationFile);
// this assert is true as CLI will be parsed at this point
@ -70,7 +71,7 @@ public class PicoCLIOptionsPluginTest extends AcceptanceTestBase {
@Ignore("No way to do a graceful shutdown of Pantheon at the moment.")
public void shouldStop() {
cluster.stopNode(node);
waitForFile(node.homeDirectory().resolve("plugins/testPlugin.stopped"));
waitForFile(node.homeDirectory().resolve("plugins/pluginLifecycle.stopped"));
}
private void waitForFile(final Path path) {

@ -89,6 +89,7 @@ allprojects {
} else {
jcenter()
mavenCentral()
mavenLocal()
maven { url "https://consensys.bintray.com/pegasys-repo" }
}
}

@ -84,5 +84,7 @@ dependencyManagement {
dependency 'org.web3j:crypto:4.3.0'
dependency 'org.xerial.snappy:snappy-java:1.1.7.3'
dependency "tech.pegasys.pantheon:plugin-api:${rootProject.version}"
}
}

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip

@ -41,7 +41,6 @@ dependencies {
implementation project(':ethereum:permissioning')
implementation project(':ethereum:p2p')
implementation project(':ethereum:rlp')
implementation project(':plugins')
implementation project(':metrics:core')
implementation project(':services:kvstore')
@ -53,6 +52,7 @@ dependencies {
implementation 'net.consensys.cava:cava-toml'
implementation 'org.apache.logging.log4j:log4j-api'
implementation 'org.springframework.security:spring-security-crypto'
implementation 'tech.pegasys.pantheon:plugin-api'
runtime 'org.apache.logging.log4j:log4j-core'
runtime 'org.apache.logging.log4j:log4j-slf4j-impl'
@ -61,6 +61,7 @@ dependencies {
testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts')
testImplementation 'com.squareup.okhttp3:okhttp'
testImplementation 'com.google.auto.service:auto-service'
testImplementation 'junit:junit'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.awaitility:awaitility'
@ -75,3 +76,21 @@ task writeInfoFile(type: ProjectPropertiesFile) {
}
compileJava.dependsOn(writeInfoFile)
task testJar(type: Jar) {
archiveName 'testPlugins.jar'
manifest {
attributes(
'Specification-Title': baseName,
'Specification-Version': project.version,
'Implementation-Title': baseName,
'Implementation-Version': calculateVersion()
)
}
archiveClassifier = 'tests'
from sourceSets.test.output
}
configurations { testArtifacts }
artifacts { testArtifacts testJar }

@ -18,7 +18,7 @@ import tech.pegasys.pantheon.cli.PantheonCommand;
import tech.pegasys.pantheon.controller.PantheonController;
import tech.pegasys.pantheon.ethereum.eth.EthereumWireProtocolConfiguration;
import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration;
import tech.pegasys.pantheon.plugins.internal.PantheonPluginContextImpl;
import tech.pegasys.pantheon.services.PantheonPluginContextImpl;
import tech.pegasys.pantheon.services.kvstore.RocksDbConfiguration;
import tech.pegasys.pantheon.util.BlockImporter;

@ -65,10 +65,10 @@ import tech.pegasys.pantheon.metrics.MetricsSystem;
import tech.pegasys.pantheon.metrics.prometheus.MetricsConfiguration;
import tech.pegasys.pantheon.metrics.prometheus.PrometheusMetricsSystem;
import tech.pegasys.pantheon.metrics.vertx.VertxMetricsAdapterFactory;
import tech.pegasys.pantheon.plugins.internal.PantheonPluginContextImpl;
import tech.pegasys.pantheon.plugins.services.PantheonEvents;
import tech.pegasys.pantheon.plugins.services.PicoCLIOptions;
import tech.pegasys.pantheon.plugin.services.PantheonEvents;
import tech.pegasys.pantheon.plugin.services.PicoCLIOptions;
import tech.pegasys.pantheon.services.PantheonEventsImpl;
import tech.pegasys.pantheon.services.PantheonPluginContextImpl;
import tech.pegasys.pantheon.services.PicoCLIOptionsImpl;
import tech.pegasys.pantheon.services.kvstore.RocksDbConfiguration;
import tech.pegasys.pantheon.util.BlockImporter;

@ -14,7 +14,7 @@ package tech.pegasys.pantheon.services;
import tech.pegasys.pantheon.ethereum.core.Block;
import tech.pegasys.pantheon.ethereum.eth.sync.BlockBroadcaster;
import tech.pegasys.pantheon.plugins.services.PantheonEvents;
import tech.pegasys.pantheon.plugin.services.PantheonEvents;
import com.google.common.collect.ImmutableMap;
import io.vertx.core.json.Json;

@ -10,13 +10,13 @@
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.plugins.internal;
package tech.pegasys.pantheon.services;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import tech.pegasys.pantheon.plugins.PantheonContext;
import tech.pegasys.pantheon.plugins.PantheonPlugin;
import tech.pegasys.pantheon.plugin.PantheonContext;
import tech.pegasys.pantheon.plugin.PantheonPlugin;
import java.io.IOException;
import java.net.MalformedURLException;

@ -12,7 +12,7 @@
*/
package tech.pegasys.pantheon.services;
import tech.pegasys.pantheon.plugins.services.PicoCLIOptions;
import tech.pegasys.pantheon.plugin.services.PicoCLIOptions;
import picocli.CommandLine;

@ -34,7 +34,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration;
import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.metrics.prometheus.MetricsConfiguration;
import tech.pegasys.pantheon.plugins.internal.PantheonPluginContextImpl;
import tech.pegasys.pantheon.services.PantheonPluginContextImpl;
import tech.pegasys.pantheon.services.kvstore.RocksDbConfiguration;
import tech.pegasys.pantheon.util.BlockImporter;
import tech.pegasys.pantheon.util.bytes.BytesValue;

@ -12,7 +12,9 @@
*/
package tech.pegasys.pantheon.plugins;
import tech.pegasys.pantheon.plugins.services.PantheonEvents;
import tech.pegasys.pantheon.plugin.PantheonContext;
import tech.pegasys.pantheon.plugin.PantheonPlugin;
import tech.pegasys.pantheon.plugin.services.PantheonEvents;
import java.io.File;
import java.io.IOException;

@ -12,7 +12,9 @@
*/
package tech.pegasys.pantheon.plugins;
import tech.pegasys.pantheon.plugins.services.PicoCLIOptions;
import tech.pegasys.pantheon.plugin.PantheonContext;
import tech.pegasys.pantheon.plugin.PantheonPlugin;
import tech.pegasys.pantheon.plugin.services.PicoCLIOptions;
import java.io.File;
import java.io.IOException;
@ -91,7 +93,7 @@ public class TestPicoCLIPlugin implements PantheonPlugin {
/** This is used to signal to the acceptance test that certain tasks were completed. */
private void writeSignal(final String signal) {
try {
final File callbackFile = new File(callbackDir, "testPlugin." + signal);
final File callbackFile = new File(callbackDir, "pluginLifecycle." + signal);
if (!callbackFile.getParentFile().exists()) {
callbackFile.getParentFile().mkdirs();
callbackFile.getParentFile().deleteOnExit();

@ -10,12 +10,12 @@
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.plugins.internal;
package tech.pegasys.pantheon.services;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import tech.pegasys.pantheon.plugins.PantheonPlugin;
import tech.pegasys.pantheon.plugin.PantheonPlugin;
import tech.pegasys.pantheon.plugins.TestPicoCLIPlugin;
import java.io.File;

@ -1,58 +0,0 @@
/*
* Copyright 2018 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
apply plugin: 'java-library'
jar {
baseName 'pantheon-plugins'
manifest {
attributes(
'Specification-Title': baseName,
'Specification-Version': project.version,
'Implementation-Title': baseName,
'Implementation-Version': calculateVersion()
)
}
}
dependencies {
implementation 'com.google.guava:guava'
implementation 'org.apache.logging.log4j:log4j-api'
testAnnotationProcessor 'com.google.auto.service:auto-service'
testImplementation 'com.google.auto.service:auto-service'
testImplementation 'info.picocli:picocli'
testImplementation 'junit:junit'
testImplementation 'org.apache.logging.log4j:log4j-api'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.mockito:mockito-core'
}
task testJar(type: Jar) {
archiveName 'testPlugin.jar'
manifest {
attributes(
'Specification-Title': baseName,
'Specification-Version': project.version,
'Implementation-Title': baseName,
'Implementation-Version': calculateVersion()
)
}
archiveClassifier = 'tests'
from sourceSets.test.output
}
configurations { testArtifacts }
artifacts { testArtifacts testJar }

@ -1,20 +0,0 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.plugins;
import java.util.Optional;
public interface PantheonContext {
<T> Optional<T> getService(Class<T> serviceType);
}

@ -1,22 +0,0 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.plugins;
public interface PantheonPlugin {
void register(PantheonContext context);
void start();
void stop();
}

@ -1,2 +0,0 @@
/** This package will be hidden from external users once Pantheon migrates to Java 11. */
package tech.pegasys.pantheon.plugins.internal;

@ -1,36 +0,0 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.plugins.services;
public interface PantheonEvents {
/**
* Returns the raw RLP of a block that Pantheon has received and that has passed basic validation
* checks.
*
* @param blockJSONListener The listener that will accept a JSON string as the event.
* @return an object to be used as an identifier when de-registering the event.
*/
Object addNewBlockPropagatedListener(NewBlockPropagatedListener blockJSONListener);
/**
* Remove the blockAdded listener from pantheon notifications.
*
* @param listenerIdentifier The instance that was returned from addBlockAddedListener;
*/
void removeNewBlockPropagatedListener(Object listenerIdentifier);
interface NewBlockPropagatedListener {
void newBlockPropagated(String jsonBlock);
}
}

@ -1,27 +0,0 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.plugins.services;
/** This service will be available during the registration callbacks. */
public interface PicoCLIOptions {
/**
* During the registration callback plugins can register CLI options that should be added to
* Pantheon's CLI startup.
*
* @param namespace A namespace prefix. All registered options must start with this prefix
* @param optionObject The instance of the object to be inspected. PicoCLI will reflect the fields
* of this object to extract the CLI options.
*/
void addPicoCLIOptions(String namespace, Object optionObject);
}

@ -35,7 +35,6 @@ include 'ethereum:trie'
include 'metrics:core'
include 'metrics:rocksdb'
include 'pantheon'
include 'plugins'
include 'services:kvstore'
include 'services:pipeline'
include 'services:tasks'

Loading…
Cancel
Save