| /* |
| * 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; |
| } |
| } |