package org.xbib.elasticsearch.gatherer.state; import java.io.IOException; import java.lang.management.ManagementFactory; import java.util.List; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.ClusterChangedEvent; import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.cluster.ClusterStateListener; import org.elasticsearch.common.collect.ImmutableList; import org.elasticsearch.common.collect.ImmutableList.Builder; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.monitor.jvm.JvmInfo; import org.elasticsearch.transport.Transport; import org.elasticsearch.transport.TransportInfo; import org.xbib.elasticsearch.gatherer.job.JobEvent; import static org.elasticsearch.common.xcontent.ToXContent.EMPTY_PARAMS; import static org.elasticsearch.common.xcontent.XContentFactory.xContent; import static org.elasticsearch.common.xcontent.XContentParser.Token.END_ARRAY; import static org.elasticsearch.common.xcontent.XContentType.JSON; public class GathererState extends AbstractComponent implements ClusterStateListener { public static final String PLUGIN_GATHERER_STATE = "plugin.gatherer.state"; private final Client client; private final ClusterService clusterService; private final String gathererId; @Inject public GathererState(Settings settings, Client client, ClusterService clusterService, Transport transport) { super(settings); this.client = client; this.clusterService = clusterService; this.gathererId = transport.boundAddress() != null ? "gatherer-" + transport.boundAddress().toString() : "gatherer-" + clusterService.localNode().getId(); } public String getId() { return gathererId; } public List<JobEvent> get() throws IOException { return get(PLUGIN_GATHERER_STATE); } public void add(JobEvent status) throws IOException { add(PLUGIN_GATHERER_STATE, get(), status); } public void remove(JobEvent status) throws IOException { remove(PLUGIN_GATHERER_STATE, get(), status); } public void update(JobEvent status) throws IOException { update(PLUGIN_GATHERER_STATE, get(), status); } private List<JobEvent> get(String name) throws IOException { return parseSetting(getSetting(name)); } private void add(String name, List<JobEvent> values, JobEvent status) throws IOException { String value = generateSetting(ImmutableList.<JobEvent>builder() .addAll(values) .add(status) .build()); updateSetting(name, value); } private void remove(String name, List<JobEvent> values, JobEvent status) throws IOException { Builder<JobEvent> updatedValues = ImmutableList.builder(); for (JobEvent value : values) { if (!value.equals(status)) { updatedValues.add(value); } } String value = generateSetting(updatedValues.build()); updateSetting(name, value); } private void update(String name, List<JobEvent> values, JobEvent status) throws IOException { Builder<JobEvent> updatedValues = ImmutableList.builder(); for (JobEvent value : values) { if (value.equals(status)) { updatedValues.add(status); } else { updatedValues.add(value); } } String value = generateSetting(updatedValues.build()); updateSetting(name, value); } private Settings getSettings() { return clusterService.state().getMetaData().persistentSettings(); } private String getSetting(String name) { return getSettings().get(name, "[]"); } private void updateSetting(String name, String value) { client.admin().cluster().prepareUpdateSettings() .setPersistentSettings(ImmutableSettings.builder() .put(getSettings()) .put(name, value) .build()) .execute() .actionGet(); } private List<JobEvent> parseSetting(String value) throws IOException { XContentParser parser = xContent(JSON).createParser(value); Builder<JobEvent> builder = ImmutableList.builder(); parser.nextToken(); while (parser.nextToken() != END_ARRAY) { JobEvent status = new JobEvent(); builder.add(status.fromXContent(parser)); } return builder.build(); } private String generateSetting(List<JobEvent> values) throws IOException { XContentBuilder builder = XContentFactory.jsonBuilder(); builder.startArray(); for (JobEvent value : values) { value.toXContent(builder, EMPTY_PARAMS); } builder.endArray(); return builder.string(); } @Override public void clusterChanged(ClusterChangedEvent event) { logger.info("cluster changed {}", event.state().prettyPrint()); } }