blob: d600e69dbdbdf700161cbd1651a3aa400054f870 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF 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.apache.geode.admin.internal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import org.apache.logging.log4j.Logger;
import org.apache.geode.admin.AdminDistributedSystem;
import org.apache.geode.admin.DistributionLocator;
import org.apache.geode.admin.DistributionLocatorConfig;
import org.apache.geode.admin.ManagedEntityConfig;
import org.apache.geode.annotations.internal.MakeNotStatic;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.distributed.internal.DistributionManager;
import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
import org.apache.geode.internal.admin.remote.DistributionLocatorId;
import org.apache.geode.internal.logging.LogService;
/**
* Default administrative implementation of a DistributionLocator.
*
* @since GemFire 3.5
*/
public class DistributionLocatorImpl implements DistributionLocator, InternalManagedEntity {
private static final Logger logger = LogService.getLogger();
/**
* How many new <code>DistributionLocator</code>s have been created?
*/
@MakeNotStatic
private static int newLocators = 0;
//////////////////// Instance Fields ////////////////////
/**
* The configuration object for this locator
*/
private final DistributionLocatorConfigImpl config;
/**
* The id of this distribution locator
*/
private final String id;
/**
* Used to control the actual DistributionLocator service
*/
private ManagedEntityController controller;
/**
* The system that this locator is a part of
*/
private AdminDistributedSystemImpl system;
// -------------------------------------------------------------------------
// constructor(s)...
// -------------------------------------------------------------------------
/**
* Constructs new instance of <code>DistributionLocatorImpl</code> that is a member of the given
* distributed system.
*/
public DistributionLocatorImpl(DistributionLocatorConfig config,
AdminDistributedSystemImpl system) {
this.config = (DistributionLocatorConfigImpl) config;
this.config.validate();
this.config.setManagedEntity(this);
this.id = getNewId();
this.controller = system.getEntityController();
this.system = system;
}
// -------------------------------------------------------------------------
// Attribute accessors/mutators...
// -------------------------------------------------------------------------
@Override
public String getId() {
return this.id;
}
@Override
public String getNewId() {
synchronized (DistributionLocatorImpl.class) {
return "Locator" + (++newLocators);
}
}
/**
* Returns the configuration object for this locator.
*
* @since GemFire 4.0
*/
@Override
public DistributionLocatorConfig getConfig() {
return this.config;
}
@Override
public AdminDistributedSystem getDistributedSystem() {
return this.system;
}
/**
* Unfortunately, it doesn't make much sense to maintain the state of a locator. The admin API
* does not receive notification when the locator actually starts and stops. If we try to guess,
* we'll just end up with race conditions galore. So, we can't fix bug 32455 for locators.
*/
@Override
public int setState(int state) {
throw new UnsupportedOperationException(
"Can not set the state of a locator.");
}
// -------------------------------------------------------------------------
// Operations...
// -------------------------------------------------------------------------
/**
* Polls to determine whether or not this managed entity has started.
*/
@Override
public boolean waitToStart(long timeout) throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < timeout) {
if (this.isRunning()) {
return true;
} else {
Thread.sleep(100);
}
}
logger.info("Done waiting for locator");
return this.isRunning();
}
/**
* Polls to determine whether or not this managed entity has stopped.
*/
@Override
public boolean waitToStop(long timeout) throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < timeout) {
if (!this.isRunning()) {
return true;
} else {
Thread.sleep(100);
}
}
return !this.isRunning();
}
@Override
public boolean isRunning() {
DistributionManager dm =
((AdminDistributedSystemImpl) getDistributedSystem()).getDistributionManager();
if (dm == null) {
try {
return this.controller.isRunning(this);
} catch (IllegalStateException e) {
return false;
}
}
String host = getConfig().getHost();
int port = getConfig().getPort();
String bindAddress = getConfig().getBindAddress();
boolean found = false;
Map<InternalDistributedMember, Collection<String>> hostedLocators = dm.getAllHostedLocators();
for (Iterator<InternalDistributedMember> memberIter =
hostedLocators.keySet().iterator(); memberIter.hasNext();) {
for (Iterator<String> locatorIter =
hostedLocators.get(memberIter.next()).iterator(); locatorIter.hasNext();) {
DistributionLocatorId locator = new DistributionLocatorId(locatorIter.next());
found = found || locator.getHostName().equals(host);
if (!found && !host.contains(".")) {
try {
InetAddress inetAddr = InetAddress.getByName(host);
found = locator.getHost().getHostName().equals(inetAddr.getHostName());
if (!found) {
found =
locator.getHost().getAddress().getHostAddress().equals(inetAddr.getHostAddress());
}
} catch (UnknownHostException e) {
// try config host as if it is an IP address instead of host name
}
}
if (locator.getBindAddress() != null && !locator.getBindAddress().isEmpty()
&& bindAddress != null && !bindAddress.isEmpty()) {
found = found && locator.getBindAddress().equals(bindAddress);
}
found = found && locator.getPort() == port;
if (found) {
return true;
}
}
}
return found;
}
@Override
public void start() {
this.config.validate();
this.controller.start(this);
this.config.setLocator(this);
this.system.updateLocatorsString();
}
@Override
public void stop() {
this.controller.stop(this);
this.config.setLocator(null);
}
@Override
public String getLog() {
return this.controller.getLog(this);
}
/**
* Returns a string representation of the object.
*
* @return a string representation of the object
*/
@Override
public String toString() {
return "DistributionLocator " + getId();
}
//////////////////////// Command execution ////////////////////////
@Override
public ManagedEntityConfig getEntityConfig() {
return this.getConfig();
}
@Override
public String getEntityType() {
return "Locator";
}
@Override
public String getStartCommand() {
StringBuffer sb = new StringBuffer();
sb.append(this.controller.getProductExecutable(this, "gemfire"));
sb.append(" start-locator -q -dir=");
sb.append(this.getConfig().getWorkingDirectory());
sb.append(" -port=");
sb.append(this.getConfig().getPort());
Properties props = config.getDistributedSystemProperties();
Enumeration en = props.propertyNames();
while (en.hasMoreElements()) {
String pn = (String) en.nextElement();
sb.append(" -D" + DistributionConfig.GEMFIRE_PREFIX + "" + pn + "=" + props.getProperty(pn));
}
String bindAddress = this.getConfig().getBindAddress();
if (bindAddress != null && bindAddress.length() > 0) {
sb.append(" -address=");
sb.append(this.getConfig().getBindAddress());
}
sb.append(" ");
String sslArgs = this.controller.buildSSLArguments(this.system.getConfig());
if (sslArgs != null) {
sb.append(sslArgs);
}
return sb.toString().trim();
}
@Override
public String getStopCommand() {
StringBuffer sb = new StringBuffer();
sb.append(this.controller.getProductExecutable(this, "gemfire"));
sb.append(" stop-locator -q -dir=");
sb.append(this.getConfig().getWorkingDirectory());
sb.append(" -port=");
sb.append(this.getConfig().getPort());
String bindAddress = this.getConfig().getBindAddress();
if (bindAddress != null && bindAddress.length() > 0) {
sb.append(" -address=");
sb.append(this.getConfig().getBindAddress());
}
sb.append(" ");
String sslArgs = this.controller.buildSSLArguments(this.system.getConfig());
if (sslArgs != null) {
sb.append(sslArgs);
}
return sb.toString().trim();
}
@Override
public String getIsRunningCommand() {
StringBuffer sb = new StringBuffer();
sb.append(this.controller.getProductExecutable(this, "gemfire"));
sb.append(" status-locator -dir=");
sb.append(this.getConfig().getWorkingDirectory());
return sb.toString().trim();
}
public String getLogCommand() {
StringBuffer sb = new StringBuffer();
sb.append(this.controller.getProductExecutable(this, "gemfire"));
sb.append(" tail-locator-log -dir=");
sb.append(this.getConfig().getWorkingDirectory());
return sb.toString().trim();
}
}