parent
774622abfb
commit
cfd8bddde4
|
@ -23,9 +23,6 @@ import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.logging.Loggers;
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.jmx.ManagedGroupName;
|
|
||||||
|
|
||||||
import static org.elasticsearch.index.IndexServiceManagement.buildIndexGroupName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -77,9 +74,4 @@ public abstract class AbstractIndexComponent implements IndexComponent {
|
||||||
public String nodeName() {
|
public String nodeName() {
|
||||||
return indexSettings.get("name", "");
|
return indexSettings.get("name", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ManagedGroupName
|
|
||||||
private String managementGroupName() {
|
|
||||||
return buildIndexGroupName(index);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -23,7 +23,6 @@ import org.elasticsearch.common.inject.AbstractModule;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.service.IndexService;
|
import org.elasticsearch.index.service.IndexService;
|
||||||
import org.elasticsearch.index.service.InternalIndexService;
|
import org.elasticsearch.index.service.InternalIndexService;
|
||||||
import org.elasticsearch.jmx.JmxService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -39,8 +38,5 @@ public class IndexModule extends AbstractModule {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(IndexService.class).to(InternalIndexService.class).asEagerSingleton();
|
bind(IndexService.class).to(InternalIndexService.class).asEagerSingleton();
|
||||||
if (JmxService.shouldExport(settings)) {
|
|
||||||
bind(IndexServiceManagement.class).asEagerSingleton();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.index;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.component.CloseableComponent;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.index.service.IndexService;
|
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
|
||||||
import org.elasticsearch.jmx.JmxService;
|
|
||||||
import org.elasticsearch.jmx.MBean;
|
|
||||||
import org.elasticsearch.jmx.ManagedAttribute;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@MBean(objectName = "", description = "")
|
|
||||||
public class IndexServiceManagement extends AbstractIndexComponent implements CloseableComponent {
|
|
||||||
|
|
||||||
public static String buildIndexGroupName(Index index) {
|
|
||||||
return "service=indices,index=" + index.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final JmxService jmxService;
|
|
||||||
|
|
||||||
private final IndexService indexService;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public IndexServiceManagement(Index index, @IndexSettings Settings indexSettings, JmxService jmxService, IndexService indexService) {
|
|
||||||
super(index, indexSettings);
|
|
||||||
this.jmxService = jmxService;
|
|
||||||
this.indexService = indexService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() {
|
|
||||||
jmxService.unregisterGroup(buildIndexGroupName(indexService.index()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Index Name")
|
|
||||||
public String getIndex() {
|
|
||||||
return indexService.index().name();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -55,7 +55,6 @@ import org.elasticsearch.index.search.stats.ShardSearchModule;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.index.settings.IndexSettingsService;
|
import org.elasticsearch.index.settings.IndexSettingsService;
|
||||||
import org.elasticsearch.index.shard.IndexShardCreationException;
|
import org.elasticsearch.index.shard.IndexShardCreationException;
|
||||||
import org.elasticsearch.index.shard.IndexShardManagement;
|
|
||||||
import org.elasticsearch.index.shard.IndexShardModule;
|
import org.elasticsearch.index.shard.IndexShardModule;
|
||||||
import org.elasticsearch.index.shard.ShardId;
|
import org.elasticsearch.index.shard.ShardId;
|
||||||
import org.elasticsearch.index.shard.service.IndexShard;
|
import org.elasticsearch.index.shard.service.IndexShard;
|
||||||
|
@ -398,11 +397,6 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
// close shard actions
|
|
||||||
if (indexShard != null) {
|
|
||||||
shardInjector.getInstance(IndexShardManagement.class).close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// this logic is tricky, we want to close the engine so we rollback the changes done to it
|
// this logic is tricky, we want to close the engine so we rollback the changes done to it
|
||||||
// and close the shard so no operations are allowed to it
|
// and close the shard so no operations are allowed to it
|
||||||
if (indexShard != null) {
|
if (indexShard != null) {
|
||||||
|
|
|
@ -23,9 +23,6 @@ import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.logging.Loggers;
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.jmx.ManagedGroupName;
|
|
||||||
|
|
||||||
import static org.elasticsearch.index.shard.IndexShardManagement.buildShardGroupName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -69,9 +66,4 @@ public abstract class AbstractIndexShardComponent implements IndexShardComponent
|
||||||
public String nodeName() {
|
public String nodeName() {
|
||||||
return indexSettings.get("name", "");
|
return indexSettings.get("name", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ManagedGroupName
|
|
||||||
public String managementGroupName() {
|
|
||||||
return buildShardGroupName(shardId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,139 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.index.shard;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.component.CloseableComponent;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.unit.ByteSizeValue;
|
|
||||||
import org.elasticsearch.index.engine.Engine;
|
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
|
||||||
import org.elasticsearch.index.shard.service.IndexShard;
|
|
||||||
import org.elasticsearch.index.store.Store;
|
|
||||||
import org.elasticsearch.index.translog.Translog;
|
|
||||||
import org.elasticsearch.jmx.JmxService;
|
|
||||||
import org.elasticsearch.jmx.MBean;
|
|
||||||
import org.elasticsearch.jmx.ManagedAttribute;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import static org.elasticsearch.index.IndexServiceManagement.buildIndexGroupName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@MBean(objectName = "", description = "")
|
|
||||||
public class IndexShardManagement extends AbstractIndexShardComponent implements CloseableComponent {
|
|
||||||
|
|
||||||
public static String buildShardGroupName(ShardId shardId) {
|
|
||||||
return buildIndexGroupName(shardId.index()) + ",subService=shards,shard=" + shardId.id();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final JmxService jmxService;
|
|
||||||
|
|
||||||
private final IndexShard indexShard;
|
|
||||||
|
|
||||||
private final Store store;
|
|
||||||
|
|
||||||
private final Translog translog;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public IndexShardManagement(ShardId shardId, @IndexSettings Settings indexSettings, JmxService jmxService, IndexShard indexShard,
|
|
||||||
Store store, Translog translog) {
|
|
||||||
super(shardId, indexSettings);
|
|
||||||
this.jmxService = jmxService;
|
|
||||||
this.indexShard = indexShard;
|
|
||||||
this.store = store;
|
|
||||||
this.translog = translog;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() {
|
|
||||||
jmxService.unregisterGroup(buildShardGroupName(indexShard.shardId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Index Name")
|
|
||||||
public String getIndex() {
|
|
||||||
return indexShard.shardId().index().name();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Shard Id")
|
|
||||||
public int getShardId() {
|
|
||||||
return indexShard.shardId().id();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Storage Size")
|
|
||||||
public String getStoreSize() {
|
|
||||||
try {
|
|
||||||
return store.estimateSize().toString();
|
|
||||||
} catch (IOException e) {
|
|
||||||
return "NA";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "The current transaction log id")
|
|
||||||
public long getTranslogId() {
|
|
||||||
return translog.currentId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Number of transaction log operations")
|
|
||||||
public long getTranslogNumberOfOperations() {
|
|
||||||
return translog.estimatedNumberOfOperations();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Estimated size in memory the transaction log takes")
|
|
||||||
public String getTranslogSize() {
|
|
||||||
return new ByteSizeValue(translog.memorySizeInBytes()).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "The state of the shard")
|
|
||||||
public String getState() {
|
|
||||||
return indexShard.state().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Primary")
|
|
||||||
public boolean isPrimary() {
|
|
||||||
return indexShard.routingEntry().primary();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "The state of the shard as perceived by the cluster")
|
|
||||||
public String getRoutingState() {
|
|
||||||
return indexShard.routingEntry().state().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "The number of documents in the index")
|
|
||||||
public int getNumDocs() {
|
|
||||||
Engine.Searcher searcher = indexShard.searcher();
|
|
||||||
try {
|
|
||||||
return searcher.reader().numDocs();
|
|
||||||
} finally {
|
|
||||||
searcher.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "The total number of documents in the index (including deleted ones)")
|
|
||||||
public int getMaxDoc() {
|
|
||||||
Engine.Searcher searcher = indexShard.searcher();
|
|
||||||
try {
|
|
||||||
return searcher.reader().maxDoc();
|
|
||||||
} finally {
|
|
||||||
searcher.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,7 +24,6 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.shard.service.IndexShard;
|
import org.elasticsearch.index.shard.service.IndexShard;
|
||||||
import org.elasticsearch.index.shard.service.InternalIndexShard;
|
import org.elasticsearch.index.shard.service.InternalIndexShard;
|
||||||
import org.elasticsearch.index.warmer.ShardIndexWarmerService;
|
import org.elasticsearch.index.warmer.ShardIndexWarmerService;
|
||||||
import org.elasticsearch.jmx.JmxService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -44,9 +43,6 @@ public class IndexShardModule extends AbstractModule {
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(ShardId.class).toInstance(shardId);
|
bind(ShardId.class).toInstance(shardId);
|
||||||
bind(IndexShard.class).to(InternalIndexShard.class).asEagerSingleton();
|
bind(IndexShard.class).to(InternalIndexShard.class).asEagerSingleton();
|
||||||
if (JmxService.shouldExport(settings)) {
|
|
||||||
bind(IndexShardManagement.class).asEagerSingleton();
|
|
||||||
}
|
|
||||||
bind(ShardIndexWarmerService.class).asEagerSingleton();
|
bind(ShardIndexWarmerService.class).asEagerSingleton();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.index.store;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.index.shard.AbstractIndexShardComponent;
|
|
||||||
import org.elasticsearch.jmx.MBean;
|
|
||||||
import org.elasticsearch.jmx.ManagedAttribute;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@MBean(objectName = "shardType=store", description = "The storage of the index shard")
|
|
||||||
public class StoreManagement extends AbstractIndexShardComponent {
|
|
||||||
|
|
||||||
private final Store store;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public StoreManagement(Store store) {
|
|
||||||
super(store.shardId(), store.indexSettings());
|
|
||||||
this.store = store;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Size in bytes")
|
|
||||||
public long getSizeInBytes() {
|
|
||||||
try {
|
|
||||||
return store.estimateSize().bytes();
|
|
||||||
} catch (IOException e) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Size")
|
|
||||||
public String getSize() {
|
|
||||||
try {
|
|
||||||
return store.estimateSize().toString();
|
|
||||||
} catch (IOException e) {
|
|
||||||
return "NA";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,7 +24,6 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.store.distributor.Distributor;
|
import org.elasticsearch.index.store.distributor.Distributor;
|
||||||
import org.elasticsearch.index.store.distributor.LeastUsedDistributor;
|
import org.elasticsearch.index.store.distributor.LeastUsedDistributor;
|
||||||
import org.elasticsearch.index.store.distributor.RandomWeightedDistributor;
|
import org.elasticsearch.index.store.distributor.RandomWeightedDistributor;
|
||||||
import org.elasticsearch.jmx.JmxService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -50,9 +49,6 @@ public class StoreModule extends AbstractModule {
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(DirectoryService.class).to(indexStore.shardDirectory()).asEagerSingleton();
|
bind(DirectoryService.class).to(indexStore.shardDirectory()).asEagerSingleton();
|
||||||
bind(Store.class).asEagerSingleton();
|
bind(Store.class).asEagerSingleton();
|
||||||
if (JmxService.shouldExport(settings)) {
|
|
||||||
bind(StoreManagement.class).asEagerSingleton();
|
|
||||||
}
|
|
||||||
if (distributor == null) {
|
if (distributor == null) {
|
||||||
distributor = loadDistributor(settings);
|
distributor = loadDistributor(settings);
|
||||||
}
|
}
|
||||||
|
|
|
@ -353,7 +353,6 @@ public class InternalIndicesService extends AbstractLifecycleComponent<IndicesSe
|
||||||
indexInjector.getInstance(IndexFieldDataService.class).clear();
|
indexInjector.getInstance(IndexFieldDataService.class).clear();
|
||||||
indexInjector.getInstance(AnalysisService.class).close();
|
indexInjector.getInstance(AnalysisService.class).close();
|
||||||
indexInjector.getInstance(IndexEngine.class).close();
|
indexInjector.getInstance(IndexEngine.class).close();
|
||||||
indexInjector.getInstance(IndexServiceManagement.class).close();
|
|
||||||
|
|
||||||
indexInjector.getInstance(IndexGateway.class).close(delete);
|
indexInjector.getInstance(IndexGateway.class).close(delete);
|
||||||
indexInjector.getInstance(MapperService.class).close();
|
indexInjector.getInstance(MapperService.class).close();
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.jmx;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple based class for JMX related services with {@link #doConfigure()} only being called if
|
|
||||||
* jmx is enabled.
|
|
||||||
*/
|
|
||||||
public abstract class AbstractJmxModule extends AbstractModule {
|
|
||||||
|
|
||||||
private final Settings settings;
|
|
||||||
|
|
||||||
protected AbstractJmxModule(Settings settings) {
|
|
||||||
this.settings = settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure() {
|
|
||||||
if (JmxService.shouldExport(settings)) {
|
|
||||||
doConfigure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void doConfigure();
|
|
||||||
}
|
|
|
@ -1,119 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.jmx;
|
|
||||||
|
|
||||||
import org.elasticsearch.cluster.ClusterChangedEvent;
|
|
||||||
import org.elasticsearch.cluster.ClusterService;
|
|
||||||
import org.elasticsearch.cluster.ClusterStateListener;
|
|
||||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.jmx.action.GetJmxServiceUrlAction;
|
|
||||||
|
|
||||||
import javax.management.MBeanServerConnection;
|
|
||||||
import javax.management.remote.JMXConnector;
|
|
||||||
import javax.management.remote.JMXConnectorFactory;
|
|
||||||
import javax.management.remote.JMXServiceURL;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
|
|
||||||
import static java.util.concurrent.Executors.newSingleThreadExecutor;
|
|
||||||
import static org.elasticsearch.common.util.concurrent.EsExecutors.daemonThreadFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
// TODO Disabled for now. Can be used to mbean proxy other nodes in the cluster from within the same console. Need the jmxruntime_optional jars though..,
|
|
||||||
public class JmxClusterService extends AbstractComponent {
|
|
||||||
|
|
||||||
private final ClusterService clusterService;
|
|
||||||
|
|
||||||
private final JmxService jmxService;
|
|
||||||
|
|
||||||
private final GetJmxServiceUrlAction getJmxServiceUrlAction;
|
|
||||||
|
|
||||||
private final ExecutorService clusterNodesJmxUpdater;
|
|
||||||
|
|
||||||
public JmxClusterService(Settings settings, ClusterService clusterService, JmxService jmxService, final GetJmxServiceUrlAction getJmxServiceUrlAction) {
|
|
||||||
super(settings);
|
|
||||||
this.clusterService = clusterService;
|
|
||||||
this.jmxService = jmxService;
|
|
||||||
this.getJmxServiceUrlAction = getJmxServiceUrlAction;
|
|
||||||
|
|
||||||
this.clusterNodesJmxUpdater = newSingleThreadExecutor(daemonThreadFactory(settings, "jmxService#updateTask"));
|
|
||||||
|
|
||||||
if (jmxService.publishUrl() != null) {
|
|
||||||
clusterService.add(new JmxClusterEventListener());
|
|
||||||
for (final DiscoveryNode node : clusterService.state().nodes()) {
|
|
||||||
clusterNodesJmxUpdater.execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
String nodeServiceUrl = getJmxServiceUrlAction.obtainPublishUrl(node);
|
|
||||||
registerNode(node, nodeServiceUrl);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() {
|
|
||||||
if (clusterNodesJmxUpdater != null) {
|
|
||||||
clusterNodesJmxUpdater.shutdownNow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerNode(DiscoveryNode node, String nodeServiceUrl) {
|
|
||||||
try {
|
|
||||||
JMXServiceURL jmxServiceURL = new JMXServiceURL(nodeServiceUrl);
|
|
||||||
JMXConnector jmxConnector = JMXConnectorFactory.connect(jmxServiceURL, null);
|
|
||||||
|
|
||||||
MBeanServerConnection connection = jmxConnector.getMBeanServerConnection();
|
|
||||||
|
|
||||||
// for (ObjectName objectName : connection.queryNames(null, null)) {
|
|
||||||
// try {
|
|
||||||
// MBeanProxy mBeanProxy = new MBeanProxy(remoteName, connection);
|
|
||||||
// } catch (InstanceAlreadyExistsException e) {
|
|
||||||
// // ignore
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// logger.warn("Failed to register proxy mbean", e);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.warn("Failed to register node [" + node + "] with serviceUrl [" + nodeServiceUrl + "]", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class JmxClusterEventListener implements ClusterStateListener {
|
|
||||||
@Override
|
|
||||||
public void clusterChanged(ClusterChangedEvent event) {
|
|
||||||
if (!event.nodesChanged()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (final DiscoveryNode node : event.nodesDelta().addedNodes()) {
|
|
||||||
clusterNodesJmxUpdater.execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
String nodeServiceUrl = getJmxServiceUrlAction.obtainPublishUrl(node);
|
|
||||||
registerNode(node, nodeServiceUrl);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.jmx;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class JmxConnectorCreationException extends JmxException {
|
|
||||||
|
|
||||||
public JmxConnectorCreationException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JmxConnectorCreationException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.jmx;
|
|
||||||
|
|
||||||
import org.elasticsearch.ElasticSearchException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class JmxException extends ElasticSearchException {
|
|
||||||
|
|
||||||
public JmxException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JmxException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,83 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.jmx;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
|
||||||
import org.elasticsearch.common.inject.TypeLiteral;
|
|
||||||
import org.elasticsearch.common.inject.matcher.Matchers;
|
|
||||||
import org.elasticsearch.common.inject.spi.InjectionListener;
|
|
||||||
import org.elasticsearch.common.inject.spi.TypeEncounter;
|
|
||||||
import org.elasticsearch.common.inject.spi.TypeListener;
|
|
||||||
import org.elasticsearch.common.logging.Loggers;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.jmx.action.GetJmxServiceUrlAction;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class JmxModule extends AbstractModule {
|
|
||||||
|
|
||||||
private final Settings settings;
|
|
||||||
|
|
||||||
public JmxModule(Settings settings) {
|
|
||||||
this.settings = settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure() {
|
|
||||||
JmxService jmxService = new JmxService(Loggers.getLogger(JmxService.class, settings.get("name")), settings);
|
|
||||||
bind(JmxService.class).toInstance(jmxService);
|
|
||||||
bind(GetJmxServiceUrlAction.class).asEagerSingleton();
|
|
||||||
if (JmxService.shouldExport(settings)) {
|
|
||||||
bindListener(Matchers.any(), new JmxExporterTypeListener(jmxService));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class JmxExporterTypeListener implements TypeListener {
|
|
||||||
|
|
||||||
private final JmxService jmxService;
|
|
||||||
|
|
||||||
private JmxExporterTypeListener(JmxService jmxService) {
|
|
||||||
this.jmxService = jmxService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <I> void hear(TypeLiteral<I> typeLiteral, TypeEncounter<I> typeEncounter) {
|
|
||||||
Class<? super I> type = typeLiteral.getRawType();
|
|
||||||
if (type.isAnnotationPresent(MBean.class)) {
|
|
||||||
typeEncounter.register(new JmxExporterInjectionListener<I>(jmxService));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class JmxExporterInjectionListener<I> implements InjectionListener<I> {
|
|
||||||
|
|
||||||
private final JmxService jmxService;
|
|
||||||
|
|
||||||
private JmxExporterInjectionListener(JmxService jmxService) {
|
|
||||||
this.jmxService = jmxService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterInjection(I instance) {
|
|
||||||
jmxService.registerMBean(instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.jmx;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class JmxRegistrationException extends JmxException {
|
|
||||||
|
|
||||||
public JmxRegistrationException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JmxRegistrationException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,248 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.jmx;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
|
||||||
import org.elasticsearch.common.network.NetworkService;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.transport.PortsRange;
|
|
||||||
|
|
||||||
import javax.management.InstanceAlreadyExistsException;
|
|
||||||
import javax.management.MBeanServer;
|
|
||||||
import javax.management.ObjectName;
|
|
||||||
import javax.management.remote.JMXConnectorServer;
|
|
||||||
import javax.management.remote.JMXConnectorServerFactory;
|
|
||||||
import javax.management.remote.JMXServiceURL;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.management.ManagementFactory;
|
|
||||||
import java.rmi.registry.LocateRegistry;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class JmxService {
|
|
||||||
|
|
||||||
public static class SettingsConstants {
|
|
||||||
|
|
||||||
public static final String EXPORT = "jmx.export";
|
|
||||||
public static final String CREATE_CONNECTOR = "jmx.create_connector";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean shouldExport(Settings settings) {
|
|
||||||
return settings.getAsBoolean(SettingsConstants.CREATE_CONNECTOR, false) || settings.getAsBoolean(SettingsConstants.EXPORT, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we use {jmx.port} without prefix of $ since we don't want it to be resolved as a setting property
|
|
||||||
|
|
||||||
public static final String JMXRMI_URI_PATTERN = "service:jmx:rmi:///jndi/rmi://:{jmx.port}/jmxrmi";
|
|
||||||
|
|
||||||
public static final String JMXRMI_PUBLISH_URI_PATTERN = "service:jmx:rmi:///jndi/rmi://{jmx.host}:{jmx.port}/jmxrmi";
|
|
||||||
|
|
||||||
private final ESLogger logger;
|
|
||||||
|
|
||||||
private final Settings settings;
|
|
||||||
|
|
||||||
private final String jmxDomain;
|
|
||||||
|
|
||||||
private String serviceUrl;
|
|
||||||
|
|
||||||
private String publishUrl;
|
|
||||||
|
|
||||||
private final MBeanServer mBeanServer;
|
|
||||||
|
|
||||||
private JMXConnectorServer connectorServer;
|
|
||||||
|
|
||||||
private final CopyOnWriteArrayList<ResourceDMBean> constructionMBeans = new CopyOnWriteArrayList<ResourceDMBean>();
|
|
||||||
|
|
||||||
private final CopyOnWriteArrayList<ResourceDMBean> registeredMBeans = new CopyOnWriteArrayList<ResourceDMBean>();
|
|
||||||
|
|
||||||
private String nodeDescription;
|
|
||||||
|
|
||||||
private volatile boolean started = false;
|
|
||||||
|
|
||||||
public JmxService(ESLogger logger, final Settings settings) {
|
|
||||||
this.logger = logger;
|
|
||||||
this.settings = settings;
|
|
||||||
|
|
||||||
this.jmxDomain = settings.get("jmx.domain", "org.elasticsearch");
|
|
||||||
|
|
||||||
this.mBeanServer = ManagementFactory.getPlatformMBeanServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String serviceUrl() {
|
|
||||||
return this.serviceUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String publishUrl() {
|
|
||||||
return this.publishUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void connectAndRegister(String nodeDescription, final NetworkService networkService) {
|
|
||||||
if (started) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
started = true;
|
|
||||||
this.nodeDescription = nodeDescription;
|
|
||||||
if (settings.getAsBoolean(SettingsConstants.CREATE_CONNECTOR, false)) {
|
|
||||||
// we are going to create the connector, set the GC interval to a large value
|
|
||||||
try {
|
|
||||||
if (System.getProperty("sun.rmi.dgc.client.gcInterval") == null)
|
|
||||||
System.setProperty("sun.rmi.dgc.client.gcInterval", "36000000");
|
|
||||||
if (System.getProperty("sun.rmi.dgc.server.gcInterval") == null)
|
|
||||||
System.setProperty("sun.rmi.dgc.server.gcInterval", "36000000");
|
|
||||||
} catch (Exception secExc) {
|
|
||||||
logger.warn("Failed to set sun.rmi.dgc.xxx system properties", secExc);
|
|
||||||
}
|
|
||||||
|
|
||||||
final String port = settings.get("jmx.port", "9400-9500");
|
|
||||||
|
|
||||||
PortsRange portsRange = new PortsRange(port);
|
|
||||||
final AtomicReference<Exception> lastException = new AtomicReference<Exception>();
|
|
||||||
boolean success = portsRange.iterate(new PortsRange.PortCallback() {
|
|
||||||
@Override
|
|
||||||
public boolean onPortNumber(int portNumber) {
|
|
||||||
try {
|
|
||||||
LocateRegistry.createRegistry(portNumber);
|
|
||||||
serviceUrl = settings.get("jmx.service_url", JMXRMI_URI_PATTERN).replace("{jmx.port}", Integer.toString(portNumber));
|
|
||||||
// Create the JMX service URL.
|
|
||||||
JMXServiceURL url = new JMXServiceURL(serviceUrl);
|
|
||||||
// Create the connector server now.
|
|
||||||
connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, settings.getAsMap(), mBeanServer);
|
|
||||||
connectorServer.start();
|
|
||||||
|
|
||||||
// create the publish url
|
|
||||||
String publishHost = networkService.resolvePublishHostAddress(settings.get("jmx.publish_host")).getHostAddress();
|
|
||||||
publishUrl = settings.get("jmx.publish_url", JMXRMI_PUBLISH_URI_PATTERN).replace("{jmx.port}", Integer.toString(portNumber)).replace("{jmx.host}", publishHost);
|
|
||||||
} catch (Exception e) {
|
|
||||||
lastException.set(e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (!success) {
|
|
||||||
throw new JmxConnectorCreationException("Failed to bind to [" + port + "]", lastException.get());
|
|
||||||
}
|
|
||||||
logger.info("bound_address {{}}, publish_address {{}}", serviceUrl, publishUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ResourceDMBean resource : constructionMBeans) {
|
|
||||||
register(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerMBean(Object instance) {
|
|
||||||
ResourceDMBean resourceDMBean = new ResourceDMBean(instance, logger);
|
|
||||||
if (!resourceDMBean.isManagedResource()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!started) {
|
|
||||||
constructionMBeans.add(resourceDMBean);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
register(resourceDMBean);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unregisterGroup(String groupName) {
|
|
||||||
for (ResourceDMBean resource : registeredMBeans) {
|
|
||||||
if (!groupName.equals(resource.getGroupName())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
registeredMBeans.remove(resource);
|
|
||||||
|
|
||||||
String resourceName = resource.getFullObjectName();
|
|
||||||
try {
|
|
||||||
ObjectName objectName = new ObjectName(getObjectName(resourceName));
|
|
||||||
if (mBeanServer.isRegistered(objectName)) {
|
|
||||||
mBeanServer.unregisterMBean(objectName);
|
|
||||||
if (logger.isTraceEnabled()) {
|
|
||||||
logger.trace("Unregistered " + objectName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.warn("Failed to unregister " + resource.getFullObjectName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void close() {
|
|
||||||
if (!started) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
started = false;
|
|
||||||
// unregister mbeans
|
|
||||||
for (ResourceDMBean resource : registeredMBeans) {
|
|
||||||
String resourceName = resource.getFullObjectName();
|
|
||||||
try {
|
|
||||||
ObjectName objectName = new ObjectName(getObjectName(resourceName));
|
|
||||||
if (mBeanServer.isRegistered(objectName)) {
|
|
||||||
mBeanServer.unregisterMBean(objectName);
|
|
||||||
if (logger.isTraceEnabled()) {
|
|
||||||
logger.trace("Unregistered " + objectName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.warn("Failed to unregister " + resource.getFullObjectName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (connectorServer != null) {
|
|
||||||
try {
|
|
||||||
connectorServer.stop();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.debug("Failed to close connector", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void register(ResourceDMBean resourceDMBean) throws JmxRegistrationException {
|
|
||||||
try {
|
|
||||||
String resourceName = resourceDMBean.getFullObjectName();
|
|
||||||
ObjectName objectName = new ObjectName(getObjectName(resourceName));
|
|
||||||
if (!mBeanServer.isRegistered(objectName)) {
|
|
||||||
try {
|
|
||||||
mBeanServer.registerMBean(resourceDMBean, objectName);
|
|
||||||
registeredMBeans.add(resourceDMBean);
|
|
||||||
if (logger.isTraceEnabled()) {
|
|
||||||
logger.trace("Registered " + resourceDMBean + " under " + objectName);
|
|
||||||
}
|
|
||||||
} catch (InstanceAlreadyExistsException e) {
|
|
||||||
//this might happen if multiple instances are trying to concurrently register same objectName
|
|
||||||
logger.debug("Could not register object with name:" + objectName + "(" + e.getMessage() + ")");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.debug("Could not register object with name: " + objectName + ", already registered");
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.warn("Could not register object with name: " + resourceDMBean.getFullObjectName() + "(" + e.getMessage() + ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getObjectName(String resourceName) {
|
|
||||||
return getObjectName(jmxDomain, resourceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getObjectName(String jmxDomain, String resourceName) {
|
|
||||||
return jmxDomain + ":" + resourceName;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.jmx;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target({ElementType.TYPE})
|
|
||||||
@Inherited
|
|
||||||
public @interface MBean {
|
|
||||||
String description() default "";
|
|
||||||
|
|
||||||
String objectName() default "";
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.jmx;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target({ElementType.METHOD, ElementType.FIELD})
|
|
||||||
public @interface ManagedAttribute {
|
|
||||||
String description() default "";
|
|
||||||
|
|
||||||
boolean writable() default false;
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.jmx;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target({ElementType.METHOD})
|
|
||||||
public @interface ManagedGroupName {
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.jmx;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target({ElementType.METHOD})
|
|
||||||
public @interface ManagedOperation {
|
|
||||||
String description() default "";
|
|
||||||
}
|
|
|
@ -1,570 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.jmx;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import org.elasticsearch.common.Classes;
|
|
||||||
import org.elasticsearch.common.Preconditions;
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.collect.MapBuilder;
|
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
|
||||||
|
|
||||||
import javax.management.*;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import static org.elasticsearch.common.collect.MapBuilder.newMapBuilder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ResourceDMBean implements DynamicMBean {
|
|
||||||
private static final Class<?>[] primitives = {int.class, byte.class, short.class, long.class,
|
|
||||||
float.class, double.class, boolean.class, char.class};
|
|
||||||
|
|
||||||
private final ESLogger logger;
|
|
||||||
|
|
||||||
private final Object obj;
|
|
||||||
|
|
||||||
private final String objectName;
|
|
||||||
|
|
||||||
private final String groupName;
|
|
||||||
|
|
||||||
private final String fullObjectName;
|
|
||||||
|
|
||||||
private final String description;
|
|
||||||
|
|
||||||
private final MBeanAttributeInfo[] attributesInfo;
|
|
||||||
|
|
||||||
private final MBeanOperationInfo[] operationsInfo;
|
|
||||||
|
|
||||||
private final MBeanInfo mBeanInfo;
|
|
||||||
|
|
||||||
private final ImmutableMap<String, AttributeEntry> attributes;
|
|
||||||
|
|
||||||
private final ImmutableList<MBeanOperationInfo> operations;
|
|
||||||
|
|
||||||
public ResourceDMBean(Object instance, ESLogger logger) {
|
|
||||||
Preconditions.checkNotNull(instance, "Cannot make an MBean wrapper for null instance");
|
|
||||||
this.obj = instance;
|
|
||||||
this.logger = logger;
|
|
||||||
|
|
||||||
MapBuilder<String, AttributeEntry> attributesBuilder = newMapBuilder();
|
|
||||||
List<MBeanOperationInfo> operationsBuilder = new ArrayList<MBeanOperationInfo>();
|
|
||||||
|
|
||||||
MBean mBean = obj.getClass().getAnnotation(MBean.class);
|
|
||||||
|
|
||||||
this.groupName = findGroupName();
|
|
||||||
|
|
||||||
if (mBean != null && Strings.hasLength(mBean.objectName())) {
|
|
||||||
objectName = mBean.objectName();
|
|
||||||
} else {
|
|
||||||
if (Strings.hasLength(groupName)) {
|
|
||||||
// we have something in the group object name, don't put anything in the object name
|
|
||||||
objectName = "";
|
|
||||||
} else {
|
|
||||||
objectName = obj.getClass().getSimpleName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder(groupName);
|
|
||||||
if (Strings.hasLength(groupName) && Strings.hasLength(objectName)) {
|
|
||||||
sb.append(",");
|
|
||||||
}
|
|
||||||
sb.append(objectName);
|
|
||||||
this.fullObjectName = sb.toString();
|
|
||||||
|
|
||||||
this.description = findDescription();
|
|
||||||
findFields(attributesBuilder);
|
|
||||||
findMethods(attributesBuilder, operationsBuilder);
|
|
||||||
|
|
||||||
this.attributes = attributesBuilder.immutableMap();
|
|
||||||
this.operations = ImmutableList.copyOf(operationsBuilder);
|
|
||||||
|
|
||||||
attributesInfo = new MBeanAttributeInfo[attributes.size()];
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
MBeanAttributeInfo info;
|
|
||||||
for (AttributeEntry entry : attributes.values()) {
|
|
||||||
info = entry.getInfo();
|
|
||||||
attributesInfo[i++] = info;
|
|
||||||
if (logger.isInfoEnabled()) {
|
|
||||||
logger.trace("Attribute " + info.getName() + "[r=" + info.isReadable() + ",w="
|
|
||||||
+ info.isWritable() + ",is=" + info.isIs() + ",type=" + info.getType() + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
operationsInfo = new MBeanOperationInfo[operations.size()];
|
|
||||||
operations.toArray(operationsInfo);
|
|
||||||
|
|
||||||
if (logger.isTraceEnabled()) {
|
|
||||||
if (operations.size() > 0)
|
|
||||||
logger.trace("Operations are:");
|
|
||||||
for (MBeanOperationInfo op : operationsInfo) {
|
|
||||||
logger.trace("Operation " + op.getReturnType() + " " + op.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.mBeanInfo = new MBeanInfo(getObject().getClass().getCanonicalName(), description, attributesInfo, null, operationsInfo, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MBeanInfo getMBeanInfo() {
|
|
||||||
return mBeanInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized Object getAttribute(String name) throws AttributeNotFoundException {
|
|
||||||
if (name == null || name.length() == 0)
|
|
||||||
throw new NullPointerException("Invalid attribute requested " + name);
|
|
||||||
|
|
||||||
Attribute attr = getNamedAttribute(name);
|
|
||||||
if (attr == null) {
|
|
||||||
throw new AttributeNotFoundException("Unknown attribute '" + name
|
|
||||||
+ "'. Known attributes names are: " + attributes.keySet());
|
|
||||||
}
|
|
||||||
return attr.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void setAttribute(Attribute attribute) {
|
|
||||||
if (attribute == null || attribute.getName() == null)
|
|
||||||
throw new NullPointerException("Invalid attribute requested " + attribute);
|
|
||||||
|
|
||||||
setNamedAttribute(attribute);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized AttributeList getAttributes(String[] names) {
|
|
||||||
AttributeList al = new AttributeList();
|
|
||||||
for (String name : names) {
|
|
||||||
Attribute attr = getNamedAttribute(name);
|
|
||||||
if (attr != null) {
|
|
||||||
al.add(attr);
|
|
||||||
} else {
|
|
||||||
logger.warn("Did not find attribute " + name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return al;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized AttributeList setAttributes(AttributeList list) {
|
|
||||||
AttributeList results = new AttributeList();
|
|
||||||
for (Object aList : list) {
|
|
||||||
Attribute attr = (Attribute) aList;
|
|
||||||
|
|
||||||
if (setNamedAttribute(attr)) {
|
|
||||||
results.add(attr);
|
|
||||||
} else {
|
|
||||||
if (logger.isWarnEnabled()) {
|
|
||||||
logger.warn("Failed to update attribute name " + attr.getName() + " with value "
|
|
||||||
+ attr.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object invoke(String name, Object[] args, String[] sig) throws MBeanException,
|
|
||||||
ReflectionException {
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("Invoke method called on " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
MBeanOperationInfo opInfo = null;
|
|
||||||
for (MBeanOperationInfo op : operationsInfo) {
|
|
||||||
if (op.getName().equals(name)) {
|
|
||||||
opInfo = op;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opInfo == null) {
|
|
||||||
final String msg = "Operation " + name + " not in ModelMBeanInfo";
|
|
||||||
throw new MBeanException(new ServiceNotFoundException(msg), msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Class<?>[] classes = new Class[sig.length];
|
|
||||||
for (int i = 0; i < classes.length; i++) {
|
|
||||||
classes[i] = getClassForName(sig[i]);
|
|
||||||
}
|
|
||||||
Method method = getObject().getClass().getMethod(name, classes);
|
|
||||||
return method.invoke(getObject(), args);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new MBeanException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Object getObject() {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Class<?> getClassForName(String name) throws ClassNotFoundException {
|
|
||||||
try {
|
|
||||||
return Classes.getDefaultClassLoader().loadClass(name);
|
|
||||||
} catch (ClassNotFoundException cnfe) {
|
|
||||||
// Could be a primitive - let's check
|
|
||||||
for (Class<?> primitive : primitives) {
|
|
||||||
if (name.equals(primitive.getName())) {
|
|
||||||
return primitive;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new ClassNotFoundException("Class " + name + " cannot be found");
|
|
||||||
}
|
|
||||||
|
|
||||||
private String findGroupName() {
|
|
||||||
Class objClass = getObject().getClass();
|
|
||||||
while (objClass != Object.class) {
|
|
||||||
Method[] methods = objClass.getDeclaredMethods();
|
|
||||||
for (Method method : methods) {
|
|
||||||
if (method.isAnnotationPresent(ManagedGroupName.class)) {
|
|
||||||
try {
|
|
||||||
method.setAccessible(true);
|
|
||||||
return (String) method.invoke(getObject());
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.warn("Failed to get group name for [" + getObject() + "]", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
objClass = objClass.getSuperclass();
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private String findDescription() {
|
|
||||||
MBean mbean = getObject().getClass().getAnnotation(MBean.class);
|
|
||||||
if (mbean != null && mbean.description() != null && mbean.description().trim().length() > 0) {
|
|
||||||
return mbean.description();
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private void findMethods(MapBuilder<String, AttributeEntry> attributesBuilder, List<MBeanOperationInfo> ops) {
|
|
||||||
// find all methods but don't include methods from Object class
|
|
||||||
List<Method> methods = new ArrayList<Method>(Arrays.asList(getObject().getClass().getMethods()));
|
|
||||||
List<Method> objectMethods = new ArrayList<Method>(Arrays.asList(Object.class.getMethods()));
|
|
||||||
methods.removeAll(objectMethods);
|
|
||||||
|
|
||||||
for (Method method : methods) {
|
|
||||||
// does method have @ManagedAttribute annotation?
|
|
||||||
ManagedAttribute attr = method.getAnnotation(ManagedAttribute.class);
|
|
||||||
if (attr != null) {
|
|
||||||
String methodName = method.getName();
|
|
||||||
if (!methodName.startsWith("get") && !methodName.startsWith("set") && !methodName.startsWith("is")) {
|
|
||||||
if (logger.isWarnEnabled())
|
|
||||||
logger.warn("method name " + methodName
|
|
||||||
+ " doesn't start with \"get\", \"set\", or \"is\""
|
|
||||||
+ ", but is annotated with @ManagedAttribute: will be ignored");
|
|
||||||
} else {
|
|
||||||
MBeanAttributeInfo info;
|
|
||||||
String attributeName = null;
|
|
||||||
boolean writeAttribute = false;
|
|
||||||
if (isSetMethod(method)) { // setter
|
|
||||||
attributeName = methodName.substring(3);
|
|
||||||
info = new MBeanAttributeInfo(attributeName, method.getParameterTypes()[0]
|
|
||||||
.getCanonicalName(), attr.description(), true, true, false);
|
|
||||||
writeAttribute = true;
|
|
||||||
} else { // getter
|
|
||||||
if (method.getParameterTypes().length == 0
|
|
||||||
&& method.getReturnType() != java.lang.Void.TYPE) {
|
|
||||||
boolean hasSetter = attributesBuilder.containsKey(attributeName);
|
|
||||||
// we found is method
|
|
||||||
if (methodName.startsWith("is")) {
|
|
||||||
attributeName = methodName.substring(2);
|
|
||||||
info = new MBeanAttributeInfo(attributeName, method.getReturnType()
|
|
||||||
.getCanonicalName(), attr.description(), true, hasSetter, true);
|
|
||||||
} else {
|
|
||||||
// this has to be get
|
|
||||||
attributeName = methodName.substring(3);
|
|
||||||
info = new MBeanAttributeInfo(attributeName, method.getReturnType()
|
|
||||||
.getCanonicalName(), attr.description(), true, hasSetter, false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (logger.isWarnEnabled()) {
|
|
||||||
logger.warn("Method " + method.getName()
|
|
||||||
+ " must have a valid return type and zero parameters");
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AttributeEntry ae = attributesBuilder.get(attributeName);
|
|
||||||
// is it a read method?
|
|
||||||
if (!writeAttribute) {
|
|
||||||
// we already have annotated field as read
|
|
||||||
if (ae instanceof FieldAttributeEntry && ae.getInfo().isReadable()) {
|
|
||||||
logger.warn("not adding annotated method " + method
|
|
||||||
+ " since we already have read attribute");
|
|
||||||
}
|
|
||||||
// we already have annotated set method
|
|
||||||
else if (ae instanceof MethodAttributeEntry) {
|
|
||||||
MethodAttributeEntry mae = (MethodAttributeEntry) ae;
|
|
||||||
if (mae.hasSetMethod()) {
|
|
||||||
attributesBuilder.put(attributeName, new MethodAttributeEntry(mae.getInfo(), mae
|
|
||||||
.getSetMethod(), method));
|
|
||||||
}
|
|
||||||
} // we don't have such entry
|
|
||||||
else {
|
|
||||||
attributesBuilder.put(attributeName, new MethodAttributeEntry(info, null, method));
|
|
||||||
}
|
|
||||||
}// is it a set method?
|
|
||||||
else {
|
|
||||||
if (ae instanceof FieldAttributeEntry) {
|
|
||||||
// we already have annotated field as write
|
|
||||||
if (ae.getInfo().isWritable()) {
|
|
||||||
logger.warn("Not adding annotated method " + methodName
|
|
||||||
+ " since we already have writable attribute");
|
|
||||||
} else {
|
|
||||||
// we already have annotated field as read
|
|
||||||
// lets make the field writable
|
|
||||||
Field f = ((FieldAttributeEntry) ae).getField();
|
|
||||||
MBeanAttributeInfo i = new MBeanAttributeInfo(ae.getInfo().getName(),
|
|
||||||
f.getType().getCanonicalName(), attr.description(), true,
|
|
||||||
!Modifier.isFinal(f.getModifiers()), false);
|
|
||||||
attributesBuilder.put(attributeName, new FieldAttributeEntry(i, f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// we already have annotated getOrIs method
|
|
||||||
else if (ae instanceof MethodAttributeEntry) {
|
|
||||||
MethodAttributeEntry mae = (MethodAttributeEntry) ae;
|
|
||||||
if (mae.hasIsOrGetMethod()) {
|
|
||||||
attributesBuilder.put(attributeName, new MethodAttributeEntry(info, method, mae
|
|
||||||
.getIsOrGetMethod()));
|
|
||||||
}
|
|
||||||
} // we don't have such entry
|
|
||||||
else {
|
|
||||||
attributesBuilder.put(attributeName, new MethodAttributeEntry(info, method, null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (method.isAnnotationPresent(ManagedOperation.class)) {
|
|
||||||
ManagedOperation op = method.getAnnotation(ManagedOperation.class);
|
|
||||||
String attName = method.getName();
|
|
||||||
if (isSetMethod(method) || isGetMethod(method)) {
|
|
||||||
attName = attName.substring(3);
|
|
||||||
} else if (isIsMethod(method)) {
|
|
||||||
attName = attName.substring(2);
|
|
||||||
}
|
|
||||||
// expose unless we already exposed matching attribute field
|
|
||||||
boolean isAlreadyExposed = attributesBuilder.containsKey(attName);
|
|
||||||
if (!isAlreadyExposed) {
|
|
||||||
ops.add(new MBeanOperationInfo(op != null ? op.description() : "", method));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isSetMethod(Method method) {
|
|
||||||
return (method.getName().startsWith("set") && method.getParameterTypes().length == 1 && method.getReturnType() == java.lang.Void.TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isGetMethod(Method method) {
|
|
||||||
return (method.getParameterTypes().length == 0 && method.getReturnType() != java.lang.Void.TYPE && method.getName().startsWith("get"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isIsMethod(Method method) {
|
|
||||||
return (method.getParameterTypes().length == 0 && (method.getReturnType() == boolean.class || method.getReturnType() == Boolean.class) && method.getName().startsWith("is"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void findFields(MapBuilder<String, AttributeEntry> attributesBuilder) {
|
|
||||||
// traverse class hierarchy and find all annotated fields
|
|
||||||
for (Class<?> clazz = getObject().getClass(); clazz != null; clazz = clazz.getSuperclass()) {
|
|
||||||
Field[] fields = clazz.getDeclaredFields();
|
|
||||||
for (Field field : fields) {
|
|
||||||
ManagedAttribute attr = field.getAnnotation(ManagedAttribute.class);
|
|
||||||
if (attr != null) {
|
|
||||||
String fieldName = renameToJavaCodingConvention(field.getName());
|
|
||||||
MBeanAttributeInfo info = new MBeanAttributeInfo(fieldName, field.getType().getCanonicalName(),
|
|
||||||
attr.description(), true, !Modifier.isFinal(field.getModifiers()) && attr.writable(), false);
|
|
||||||
attributesBuilder.put(fieldName, new FieldAttributeEntry(info, field));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Attribute getNamedAttribute(String name) {
|
|
||||||
Attribute result = null;
|
|
||||||
AttributeEntry entry = attributes.get(name);
|
|
||||||
if (entry != null) {
|
|
||||||
MBeanAttributeInfo i = entry.getInfo();
|
|
||||||
try {
|
|
||||||
result = new Attribute(name, entry.invoke(null));
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Attribute " + name + " has r=" + i.isReadable() + ",w="
|
|
||||||
+ i.isWritable() + ",is=" + i.isIs() + " and value "
|
|
||||||
+ result.getValue());
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.debug("Exception while reading value of attribute " + name, e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.warn("Did not find queried attribute with name " + name);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean setNamedAttribute(Attribute attribute) {
|
|
||||||
boolean result = false;
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Invoking set on attribute " + attribute.getName() + " with value " + attribute.getValue());
|
|
||||||
|
|
||||||
AttributeEntry entry = attributes.get(attribute.getName());
|
|
||||||
if (entry != null) {
|
|
||||||
try {
|
|
||||||
entry.invoke(attribute);
|
|
||||||
result = true;
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.warn("Exception while writing value for attribute " + attribute.getName(), e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.warn("Could not invoke set on attribute " + attribute.getName() + " with value "
|
|
||||||
+ attribute.getValue());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String renameToJavaCodingConvention(String fieldName) {
|
|
||||||
if (fieldName.contains("_")) {
|
|
||||||
Pattern p = Pattern.compile("_.");
|
|
||||||
Matcher m = p.matcher(fieldName);
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
while (m.find()) {
|
|
||||||
m.appendReplacement(sb, fieldName.substring(m.end() - 1, m.end()).toUpperCase());
|
|
||||||
}
|
|
||||||
m.appendTail(sb);
|
|
||||||
char first = sb.charAt(0);
|
|
||||||
if (Character.isLowerCase(first)) {
|
|
||||||
sb.setCharAt(0, Character.toUpperCase(first));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
} else {
|
|
||||||
if (Character.isLowerCase(fieldName.charAt(0))) {
|
|
||||||
return fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
|
|
||||||
} else {
|
|
||||||
return fieldName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MethodAttributeEntry implements AttributeEntry {
|
|
||||||
|
|
||||||
final MBeanAttributeInfo info;
|
|
||||||
|
|
||||||
final Method isOrGetmethod;
|
|
||||||
|
|
||||||
final Method setMethod;
|
|
||||||
|
|
||||||
public MethodAttributeEntry(final MBeanAttributeInfo info, final Method setMethod,
|
|
||||||
final Method isOrGetMethod) {
|
|
||||||
super();
|
|
||||||
this.info = info;
|
|
||||||
this.setMethod = setMethod;
|
|
||||||
this.isOrGetmethod = isOrGetMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object invoke(Attribute a) throws Exception {
|
|
||||||
if (a == null && isOrGetmethod != null)
|
|
||||||
return isOrGetmethod.invoke(getObject());
|
|
||||||
else if (a != null && setMethod != null)
|
|
||||||
return setMethod.invoke(getObject(), a.getValue());
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MBeanAttributeInfo getInfo() {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasIsOrGetMethod() {
|
|
||||||
return isOrGetmethod != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasSetMethod() {
|
|
||||||
return setMethod != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Method getIsOrGetMethod() {
|
|
||||||
return isOrGetmethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Method getSetMethod() {
|
|
||||||
return setMethod;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class FieldAttributeEntry implements AttributeEntry {
|
|
||||||
|
|
||||||
private final MBeanAttributeInfo info;
|
|
||||||
|
|
||||||
private final Field field;
|
|
||||||
|
|
||||||
public FieldAttributeEntry(final MBeanAttributeInfo info, final Field field) {
|
|
||||||
super();
|
|
||||||
this.info = info;
|
|
||||||
this.field = field;
|
|
||||||
if (!field.isAccessible()) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Field getField() {
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object invoke(Attribute a) throws Exception {
|
|
||||||
if (a == null) {
|
|
||||||
return field.get(getObject());
|
|
||||||
} else {
|
|
||||||
field.set(getObject(), a.getValue());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MBeanAttributeInfo getInfo() {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private interface AttributeEntry {
|
|
||||||
public Object invoke(Attribute a) throws Exception;
|
|
||||||
|
|
||||||
public MBeanAttributeInfo getInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isManagedResource() {
|
|
||||||
return !attributes.isEmpty() || !operations.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFullObjectName() {
|
|
||||||
return this.fullObjectName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getObjectName() {
|
|
||||||
return this.objectName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGroupName() {
|
|
||||||
return this.groupName;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,118 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.jmx.action;
|
|
||||||
|
|
||||||
import org.elasticsearch.ElasticSearchException;
|
|
||||||
import org.elasticsearch.cluster.ClusterService;
|
|
||||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.jmx.JmxService;
|
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
|
||||||
import org.elasticsearch.transport.*;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class GetJmxServiceUrlAction extends AbstractComponent {
|
|
||||||
|
|
||||||
private final JmxService jmxService;
|
|
||||||
|
|
||||||
private final TransportService transportService;
|
|
||||||
|
|
||||||
private final ClusterService clusterService;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public GetJmxServiceUrlAction(Settings settings, JmxService jmxService,
|
|
||||||
TransportService transportService, ClusterService clusterService) {
|
|
||||||
super(settings);
|
|
||||||
this.jmxService = jmxService;
|
|
||||||
this.transportService = transportService;
|
|
||||||
this.clusterService = clusterService;
|
|
||||||
|
|
||||||
transportService.registerHandler(GetJmxServiceUrlTransportHandler.ACTION, new GetJmxServiceUrlTransportHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String obtainPublishUrl(final DiscoveryNode node) throws ElasticSearchException {
|
|
||||||
if (clusterService.state().nodes().localNodeId().equals(node.id())) {
|
|
||||||
return jmxService.publishUrl();
|
|
||||||
} else {
|
|
||||||
return transportService.submitRequest(node, GetJmxServiceUrlTransportHandler.ACTION, TransportRequest.Empty.INSTANCE, new FutureTransportResponseHandler<GetJmxServiceUrlResponse>() {
|
|
||||||
@Override
|
|
||||||
public GetJmxServiceUrlResponse newInstance() {
|
|
||||||
return new GetJmxServiceUrlResponse();
|
|
||||||
}
|
|
||||||
}).txGet().url();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class GetJmxServiceUrlTransportHandler extends BaseTransportRequestHandler<TransportRequest.Empty> {
|
|
||||||
|
|
||||||
static final String ACTION = "jmx/publishUrl";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TransportRequest.Empty newInstance() {
|
|
||||||
return TransportRequest.Empty.INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String executor() {
|
|
||||||
return ThreadPool.Names.SAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void messageReceived(TransportRequest.Empty request, TransportChannel channel) throws Exception {
|
|
||||||
channel.sendResponse(new GetJmxServiceUrlResponse(jmxService.publishUrl()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class GetJmxServiceUrlResponse extends TransportResponse {
|
|
||||||
|
|
||||||
private String url;
|
|
||||||
|
|
||||||
GetJmxServiceUrlResponse() {
|
|
||||||
}
|
|
||||||
|
|
||||||
GetJmxServiceUrlResponse(String url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String url() {
|
|
||||||
return this.url;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
|
||||||
super.readFrom(in);
|
|
||||||
url = in.readString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
|
||||||
super.writeTo(out);
|
|
||||||
out.writeString(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -46,7 +46,6 @@ import org.elasticsearch.common.io.CachedStreams;
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.logging.Loggers;
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
import org.elasticsearch.common.network.NetworkModule;
|
import org.elasticsearch.common.network.NetworkModule;
|
||||||
import org.elasticsearch.common.network.NetworkService;
|
|
||||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.settings.SettingsModule;
|
import org.elasticsearch.common.settings.SettingsModule;
|
||||||
|
@ -70,8 +69,6 @@ import org.elasticsearch.indices.cluster.IndicesClusterStateService;
|
||||||
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
|
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
|
||||||
import org.elasticsearch.indices.memory.IndexingMemoryController;
|
import org.elasticsearch.indices.memory.IndexingMemoryController;
|
||||||
import org.elasticsearch.indices.ttl.IndicesTTLService;
|
import org.elasticsearch.indices.ttl.IndicesTTLService;
|
||||||
import org.elasticsearch.jmx.JmxModule;
|
|
||||||
import org.elasticsearch.jmx.JmxService;
|
|
||||||
import org.elasticsearch.monitor.MonitorModule;
|
import org.elasticsearch.monitor.MonitorModule;
|
||||||
import org.elasticsearch.monitor.MonitorService;
|
import org.elasticsearch.monitor.MonitorService;
|
||||||
import org.elasticsearch.monitor.jvm.JvmInfo;
|
import org.elasticsearch.monitor.jvm.JvmInfo;
|
||||||
|
@ -143,7 +140,6 @@ public final class InternalNode implements Node {
|
||||||
modules.add(new NetworkModule());
|
modules.add(new NetworkModule());
|
||||||
modules.add(new NodeCacheModule(settings));
|
modules.add(new NodeCacheModule(settings));
|
||||||
modules.add(new ScriptModule(settings));
|
modules.add(new ScriptModule(settings));
|
||||||
modules.add(new JmxModule(settings));
|
|
||||||
modules.add(new EnvironmentModule(environment));
|
modules.add(new EnvironmentModule(environment));
|
||||||
modules.add(new NodeEnvironmentModule(nodeEnvironment));
|
modules.add(new NodeEnvironmentModule(nodeEnvironment));
|
||||||
modules.add(new ClusterNameModule(settings));
|
modules.add(new ClusterNameModule(settings));
|
||||||
|
@ -217,7 +213,6 @@ public final class InternalNode implements Node {
|
||||||
injector.getInstance(HttpServer.class).start();
|
injector.getInstance(HttpServer.class).start();
|
||||||
}
|
}
|
||||||
injector.getInstance(BulkUdpService.class).start();
|
injector.getInstance(BulkUdpService.class).start();
|
||||||
injector.getInstance(JmxService.class).connectAndRegister(discoService.nodeDescription(), injector.getInstance(NetworkService.class));
|
|
||||||
|
|
||||||
logger.info("{{}}[{}]: started", Version.CURRENT, JvmInfo.jvmInfo().pid());
|
logger.info("{{}}[{}]: started", Version.CURRENT, JvmInfo.jvmInfo().pid());
|
||||||
|
|
||||||
|
@ -259,7 +254,6 @@ public final class InternalNode implements Node {
|
||||||
injector.getInstance(SearchService.class).stop();
|
injector.getInstance(SearchService.class).stop();
|
||||||
injector.getInstance(RestController.class).stop();
|
injector.getInstance(RestController.class).stop();
|
||||||
injector.getInstance(TransportService.class).stop();
|
injector.getInstance(TransportService.class).stop();
|
||||||
injector.getInstance(JmxService.class).close();
|
|
||||||
|
|
||||||
for (Class<? extends LifecycleComponent> plugin : pluginsService.services()) {
|
for (Class<? extends LifecycleComponent> plugin : pluginsService.services()) {
|
||||||
injector.getInstance(plugin).stop();
|
injector.getInstance(plugin).stop();
|
||||||
|
|
|
@ -25,7 +25,6 @@ import org.elasticsearch.common.inject.Module;
|
||||||
import org.elasticsearch.common.inject.Modules;
|
import org.elasticsearch.common.inject.Modules;
|
||||||
import org.elasticsearch.common.inject.SpawnModules;
|
import org.elasticsearch.common.inject.SpawnModules;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.jmx.JmxService;
|
|
||||||
import org.elasticsearch.transport.local.LocalTransportModule;
|
import org.elasticsearch.transport.local.LocalTransportModule;
|
||||||
import org.elasticsearch.transport.netty.NettyTransportModule;
|
import org.elasticsearch.transport.netty.NettyTransportModule;
|
||||||
|
|
||||||
|
@ -54,8 +53,5 @@ public class TransportModule extends AbstractModule implements SpawnModules {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(TransportService.class).asEagerSingleton();
|
bind(TransportService.class).asEagerSingleton();
|
||||||
if (JmxService.shouldExport(settings)) {
|
|
||||||
bind(TransportServiceManagement.class).asEagerSingleton();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.transport;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.jmx.MBean;
|
|
||||||
import org.elasticsearch.jmx.ManagedAttribute;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@MBean(objectName = "service=transport", description = "Transport")
|
|
||||||
public class TransportServiceManagement {
|
|
||||||
|
|
||||||
private final TransportService transportService;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public TransportServiceManagement(TransportService transportService) {
|
|
||||||
this.transportService = transportService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Transport address published to other nodes")
|
|
||||||
public String getPublishAddress() {
|
|
||||||
return transportService.boundAddress().publishAddress().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Transport address bounded on")
|
|
||||||
public String getBoundAddress() {
|
|
||||||
return transportService.boundAddress().boundAddress().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Total number of transport requests sent")
|
|
||||||
public long getTotalNumberOfRequests() {
|
|
||||||
return transportService.requestIds.get();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.transport.local;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.jmx.MBean;
|
|
||||||
import org.elasticsearch.transport.Transport;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@MBean(objectName = "service=transport,transportType=local", description = "Local Transport")
|
|
||||||
public class LocalTransportManagement {
|
|
||||||
|
|
||||||
private final LocalTransport transport;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public LocalTransportManagement(Transport transport) {
|
|
||||||
this.transport = (LocalTransport) transport;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.transport.local;
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.jmx.JmxService;
|
|
||||||
import org.elasticsearch.transport.Transport;
|
import org.elasticsearch.transport.Transport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,8 +38,5 @@ public class LocalTransportModule extends AbstractModule {
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(LocalTransport.class).asEagerSingleton();
|
bind(LocalTransport.class).asEagerSingleton();
|
||||||
bind(Transport.class).to(LocalTransport.class).asEagerSingleton();
|
bind(Transport.class).to(LocalTransport.class).asEagerSingleton();
|
||||||
if (JmxService.shouldExport(settings)) {
|
|
||||||
bind(LocalTransportManagement.class).asEagerSingleton();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,100 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to ElasticSearch and Shay Banon under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. ElasticSearch licenses this
|
|
||||||
* file to you 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 org.elasticsearch.transport.netty;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.jmx.MBean;
|
|
||||||
import org.elasticsearch.jmx.ManagedAttribute;
|
|
||||||
import org.elasticsearch.transport.Transport;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@MBean(objectName = "service=transport,transportType=netty", description = "Netty Transport")
|
|
||||||
public class NettyTransportManagement {
|
|
||||||
|
|
||||||
private final NettyTransport transport;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public NettyTransportManagement(Transport transport) {
|
|
||||||
this.transport = (NettyTransport) transport;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Number of connections this node has to other nodes")
|
|
||||||
public long getNumberOfOutboundConnections() {
|
|
||||||
return transport.connectedNodes.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Number if IO worker threads")
|
|
||||||
public int getWorkerCount() {
|
|
||||||
return transport.workerCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Port(s) netty was configured to bind on")
|
|
||||||
public String getPort() {
|
|
||||||
return transport.port;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Host to bind to")
|
|
||||||
public String getBindHost() {
|
|
||||||
return transport.bindHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Host to publish")
|
|
||||||
public String getPublishHost() {
|
|
||||||
return transport.publishHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "Connect timeout")
|
|
||||||
public String getConnectTimeout() {
|
|
||||||
return transport.connectTimeout.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "TcpNoDelay")
|
|
||||||
public Boolean getTcpNoDelay() {
|
|
||||||
return transport.tcpNoDelay;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "TcpKeepAlive")
|
|
||||||
public Boolean getTcpKeepAlive() {
|
|
||||||
return transport.tcpKeepAlive;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "ReuseAddress")
|
|
||||||
public Boolean getReuseAddress() {
|
|
||||||
return transport.reuseAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "TcpSendBufferSize")
|
|
||||||
public String getTcpSendBufferSize() {
|
|
||||||
if (transport.tcpSendBufferSize == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return transport.tcpSendBufferSize.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ManagedAttribute(description = "TcpReceiveBufferSize")
|
|
||||||
public String getTcpReceiveBufferSize() {
|
|
||||||
if (transport.tcpReceiveBufferSize == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return transport.tcpReceiveBufferSize.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.transport.netty;
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.jmx.JmxService;
|
|
||||||
import org.elasticsearch.transport.Transport;
|
import org.elasticsearch.transport.Transport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,8 +38,5 @@ public class NettyTransportModule extends AbstractModule {
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(NettyTransport.class).asEagerSingleton();
|
bind(NettyTransport.class).asEagerSingleton();
|
||||||
bind(Transport.class).to(NettyTransport.class).asEagerSingleton();
|
bind(Transport.class).to(NettyTransport.class).asEagerSingleton();
|
||||||
if (JmxService.shouldExport(settings)) {
|
|
||||||
bind(NettyTransportManagement.class).asEagerSingleton();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue