by geek & poke
public class MyPlugin extends AbstractPlugin {
private final Settings settings;
public MyPlugin(Settings settings) {
this.settings = settings;
}
@Override
public String name() {
return "MyPlugin";
}
@Override
public String description() {
return "This is the description for my plugin";
}
}
public class MyPlugin extends AbstractPlugin {
...
//Define own modules
@Override
public Collection<Class<? extends Module>> modules() {
return ImmutableList.of(MyModule.class);
}
//Define own services
@Override
public Collection<Class<? extends LifecycleComponent>> services() {
return ImmutableList.of(MyService.class);
}
}
public class MyPlugin extends AbstractPlugin {
...
//Define own modules
@Override
public void processModule(Module module) {
if ((module instanceof RestModule)) {
((RestModule)module).addRestAction(MyRestAction.class);
}
if ((module instanceof ???)) {
((???)module).doModuleSpecificStuffHere();
}
}
}
plugin=org.company.es.plugins.MyPlugin
Main artefact
Your code
Dependecies
by geek & poke
public class AuditService extends AbstractLifecycleComponent<AuditService>{
...
@Inject
public AuditService(Settings settings,
IndicesService indicesService,
Client client,
ClusterService clusterService,
TransportFlushAction tfa) {
super(settings);
this.indicesService = indicesService;
this.clusterService = clusterService;
...
}
@Override
protected void doStart() throws ElasticsearchException {
...
this.indicesService.indicesLifecycle().addListener(auditIndicesLsListener);
}
Dependency Injection by guice
IndicesLifecycle.Listener auditIndicesLsListener =
new IndicesLifecycle.Listener() {
@Override
public void afterIndexShardStarted(final IndexShard indexShard) {
if (indexShard.routingEntry().primary()
&& !indexShard.indexService().index().name().equals(auditIndexName)) {
AuditIndexOpListener auditListener =
new AuditIndexOpListener(indexShard);
indexShard.indexingService().addListener(auditListener);
}
}
class AuditIndexOpListener extends IndexingOperationListener {
private final IndexShard indexShard;
public AuditIndexOpListener(IndexShard indexShard) {
this.indexShard = indexShard;
}
@Override
public void postIndex(Index index) {
String nodeName = indexShard.nodeName();
String indexName = indexShard.indexService().index().name();
Change change = new Change(nodeName, indexName, ...);
//store it in elasticsearch (or anywhere else)
IndexRequest ir = new IndexRequest().source(change.sourceAsMap());
addToBulkIndex(ir);
}
}
public class AuditModule extends AbstractModule {
@Override
protected void configure() {
//nothing to bind here
}
@Override
public void processModule(Module module) {
if ((module instanceof ActionModule)) {
((ActionModule)module).registerAction(FlushAction.INSTANCE,
TransportFlushAction.class);
}
if ((module instanceof RestModule)) {
((RestModule)module).addRestAction(AuditRestAction.class);
}
}
}
public class AuditPlugin extends AbstractPlugin {
...
public String name() {
return "AuditPlugin";
}
public String description() {
return "This is the description for the AuditPlugin";
}
@Override
public Collection<Class<? extends Module>> modules() {
return ImmutableList.of(AuditModule.class);
}
@Override
public Collection<Class<? extends LifecycleComponent>> services() {
return ImmutableList.of(AuditService.class);
}
}
plugin=de.saly.es.example.audit.plugin.AuditPlugin
public class SSLNettyTransport extends NettyTransport {
@Override
public ChannelPipelineFactory configureServerChannelPipelineFactory(String name,
Settings settings) {
return new SSLServerChannelPipelineFactory(this, name, settings, this.settings);
}
protected class SSLServerChannelPipelineFactory extends SecureServerChannelPipelineFactory {
public SSLServerChannelPipelineFactory(NettyTransport nettyTransport, String name,
Settings sslsettings, Settings essettings) {
super(nettyTransport, name, sslsettings);
}
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = super.getPipeline();
SSLEngine engine = ...
SslHandler sslHandler = new SslHandler(engine);
pipeline.addFirst("ssl_server", sslHandler);
return pipeline;
}
}
}
public class TSslPlugin extends AbstractPlugin {
...
public void onModule(TransportModule transportModule) {
transportModule.setTransport(SSLNettyTransport.class, name());
}
public void onModule(RestModule restModule) {
restModule.addRestAction(TSslRestAction.class);
}
}
public class TSslRestAction extends BaseRestHandler{
@Inject
public TSslRestAction(Settings settings, Client client,
RestController controller) {
super(settings, controller, client);
controller.registerHandler(Method.GET, "/_tssl/state", this);
controller.registerHandler(Method.POST, "/_tssl/state", this);
}
@Override
protected void handleRequest(RestRequest request, RestChannel channel,
Client client) throws Exception {
XContentBuilder builder = JsonXContent.contentBuilder();
builder.startObject();
builder.field("enabled_protocols", SecurityUtil.ENABLED_SSL_PROTOCOLS);
builder.field("enabled_chipers", SecurityUtil.ENABLED_SSL_CIPHERS);
builder.endObject();
channel.sendResponse(new BytesRestResponse(RestStatus.OK, builder));
}
}
plugin=de.saly.es.example.tssl.plugin.TSslPlugin
version=${project.version}
Always test with multiple nodes (cluster scenario)
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-test-framework</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
# Install from maven central
bin/plugin --install de.saly/elasticsearch-sample-plugin-tssl/1.1
# Install from a .zip file
bin/plugin --url file:///Users/.../elasticsearch-sample-plugin-tssl-1.1.zip \
--install elasticsearch-sample-plugin-tssl
<?xml version="1.0"?>
<assembly>
<id>plugin</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<useTransitiveFiltering>true</useTransitiveFiltering>
<excludes>
<exclude>org.elasticsearch:elasticsearch</exclude>
</excludes>
</dependencySet>
</dependencySets>
</assembly>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<outputDirectory>${project.build.directory}/releases/</outputDirectory>
<descriptors>
<descriptor>${basedir}/src/main/assemblies/plugin.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
# Load this plugin from the classpath
# (does only makes sense if plugins.load_classpath_plugins is false)
# Order is respected
plugin.types: org.company.MyPlugin,com.guhgle.FantasticPlugin
# If a plugin listed here is not installed for current node, the node will not start.
plugin.mandatory: mapper-attachments,lang-groovy
# If its true (which is the default) load all plugins which are in the classpath
# No order guarantee
plugins.load_classpath_plugins: true
today
by geek & poke
System.exit(0);