blob: d73fdd23a25c4d5a1c730e853609e7fa75961271 [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.brooklyn.entity.nosql.mongodb;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBRouter;
import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBRouterCluster;
import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardedDeployment;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.math.MathPredicates;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicates;
public class MongoDBClientSshDriver extends AbstractMongoDBSshDriver implements MongoDBClientDriver {
private static final Logger LOG = LoggerFactory.getLogger(MongoDBClientSshDriver.class);
private boolean isRunning = false;
public MongoDBClientSshDriver(EntityLocal entity, SshMachineLocation machine) {
super(entity, machine);
}
@Override
public void customize() {
String command = String.format("mkdir -p %s", getUserScriptDir());
newScript(CUSTOMIZING)
.updateTaskAndFailOnNonZeroResultCode()
.body.append(command).execute();
Map<String, String> scripts = entity.getConfig(MongoDBClient.JS_SCRIPTS);
for (String scriptName : scripts.keySet()) {
copyResource(scripts.get(scriptName), getUserScriptDir() + scriptName + ".js");
}
}
@Override
public void launch() {
AbstractMongoDBServer server = getServer();
// The scripts are going to be run on the machine via SSH so it shouldn't matter
// that the accessible host and port might be different.
String host = server.getAttribute(AbstractMongoDBServer.HOSTNAME);
Integer port = server.getAttribute(AbstractMongoDBServer.PORT);
List<String> scripts = entity.getConfig(MongoDBClient.STARTUP_JS_SCRIPTS);
if (scripts!=null) {
for (String scriptName : scripts) {
try {
LOG.debug("Running MongoDB script "+scriptName+" at "+getEntity());
runScript("", scriptName, host, port);
} catch (Exception e) {
LOG.warn("Error running MongoDB script "+scriptName+" at "+getEntity()+", throwing: "+e);
isRunning = false;
Exceptions.propagateIfFatal(e);
throw new IllegalStateException("Error running MongoDB script "+scriptName+" at "+entity+": "+e, e);
}
}
}
isRunning = true;
}
@Override
public boolean isRunning() {
// TODO better would be to get some confirmation
return isRunning;
}
@Override
public void stop() {
try {
super.stop();
} finally {
isRunning = false;
}
}
private String getUserScriptDir() {
return getRunDir() + "/userScripts/" ;
}
@Override
public void runScript(String preStart, String scriptName) {
AbstractMongoDBServer server = getServer();
String host = server.getAttribute(AbstractMongoDBServer.HOSTNAME);
Integer port = server.getAttribute(AbstractMongoDBServer.PORT);
runScript(preStart, scriptName, host, port);
}
private void runScript(String preStart, String scriptName, String host, Integer port) {
// TODO: escape preStart to prevent injection attack
String command = String.format("%s/bin/mongo %s:%s --eval \"%s\" %s/%s > out.log 2> err.log < /dev/null", getExpandedInstallDir(),
host, port, preStart, getUserScriptDir(), scriptName + ".js");
newScript(LAUNCHING)
.updateTaskAndFailOnNonZeroResultCode()
.body.append(command).execute();
}
private AbstractMongoDBServer getServer() {
AbstractMongoDBServer server = entity.getConfig(MongoDBClient.SERVER);
MongoDBShardedDeployment deployment = entity.getConfig(MongoDBClient.SHARDED_DEPLOYMENT);
if (server == null) {
Preconditions.checkNotNull(deployment, "Either server or shardedDeployment must be specified for %s", this);
server = DependentConfiguration.builder()
.attributeWhenReady(deployment.getRouterCluster(), MongoDBRouterCluster.ANY_ROUTER)
.blockingDetails("any available router")
.runNow();
DependentConfiguration.builder()
.attributeWhenReady(server, MongoDBRouter.SHARD_COUNT)
.readiness(MathPredicates.<Integer>greaterThan(0))
.runNow();
} else {
if (deployment != null) {
log.warn("Server and ShardedDeployment defined for {}; using server ({} instead of {})",
new Object[] {this, server, deployment});
}
DependentConfiguration.builder()
.attributeWhenReady(server, Startable.SERVICE_UP)
.readiness(Predicates.equalTo(true))
.runNow();
}
return server;
}
}