/**
*
* 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.airavata.common.utils;
import org.apache.airavata.common.exception.ApplicationSettingsException;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.server.ServerCnxnFactory;
import org.apache.zookeeper.server.ServerConfig;
import org.apache.zookeeper.server.ZooKeeperServer;
import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
public class AiravataZKUtils implements Watcher {
private final static Logger logger = LoggerFactory.getLogger(AiravataZKUtils.class);
public static final String ZK_EXPERIMENT_STATE_NODE = "state";
public static final String DELIVERY_TAG_POSTFIX = "-deliveryTag";
public static final String CANCEL_DELIVERY_TAG_POSTFIX = "-cancel-deliveryTag";
@Override
public void process(WatchedEvent event) {
}
public static String getExpZnodePath(String experimentId) throws ApplicationSettingsException {
return "/experiments" + File.separator + ServerSettings.getGFacServerName() + File.separator + experimentId;
}
public static String getExpZnodeHandlerPath(String experimentId, String className) throws ApplicationSettingsException {
return "/experiments" + File.separator + ServerSettings.getGFacServerName() + File.separator + experimentId +
File.separator + className;
}
public static String getZKhostPort() throws ApplicationSettingsException {
return ServerSettings.getZookeeperConnection();
}
public static int getZKTimeout()throws ApplicationSettingsException {
return ServerSettings.getZookeeperTimeout();
}
public static String getExpStatePath(String experimentId) throws ApplicationSettingsException {
return AiravataZKUtils.getExpZnodePath(experimentId) +
File.separator +
"state";
}
public static String getExpState(CuratorFramework curatorClient, String expId) throws Exception {
Stat exists = curatorClient.checkExists().forPath(getExpStatePath(expId));
if (exists != null) {
return new String(curatorClient.getData().storingStatIn(exists).forPath(getExpStatePath(expId)));
}
return null;
}
public static void runZKFromConfig(ServerConfig config,ServerCnxnFactory cnxnFactory) throws IOException {
AiravataZKUtils.logger.info("Starting Zookeeper server...");
FileTxnSnapLog txnLog = null;
try {
// Note that this thread isn't going to be doing anything else,
// so rather than spawning another thread, we will just call
// run() in this thread.
// create a file logger url from the command line args
ZooKeeperServer zkServer = new ZooKeeperServer();
txnLog = new FileTxnSnapLog(new File(config.getDataDir()), new File(
config.getDataDir()));
zkServer.setTxnLogFactory(txnLog);
zkServer.setTickTime(config.getTickTime());
zkServer.setMinSessionTimeout(config.getMinSessionTimeout());
zkServer.setMaxSessionTimeout(config.getMaxSessionTimeout());
cnxnFactory = ServerCnxnFactory.createFactory();
cnxnFactory.configure(config.getClientPortAddress(),
config.getMaxClientCnxns());
cnxnFactory.startup(zkServer);
cnxnFactory.join();
if (zkServer.isRunning()) {
zkServer.shutdown();
}
} catch (InterruptedException e) {
// warn, but generally this is ok
AiravataZKUtils.logger.warn("Server interrupted", e);
System.exit(1);
} finally {
if (txnLog != null) {
txnLog.close();
}
}
}
public static void startEmbeddedZK(ServerCnxnFactory cnxnFactory) {
if (ServerSettings.isEmbeddedZK()) {
ServerConfig serverConfig = new ServerConfig();
URL resource = ApplicationSettings.loadFile("zoo.cfg");
try {
if (resource == null) {
logger.error("There is no zoo.cfg file in the classpath... Failed to start Zookeeper Server");
System.exit(1);
}
serverConfig.parse(resource.getPath());
} catch (QuorumPeerConfig.ConfigException e) {
logger.error("Error while starting embedded Zookeeper", e);
System.exit(2);
}
final ServerConfig fServerConfig = serverConfig;
final ServerCnxnFactory fserverCnxnFactory = cnxnFactory;
(new Thread() {
public void run() {
try {
AiravataZKUtils.runZKFromConfig(fServerConfig,fserverCnxnFactory);
} catch (IOException e) {
logger.error("Error while starting embedded Zookeeper", e);
System.exit(3);
}
}
}).start();
}else{
logger.info("Skipping Zookeeper embedded startup ...");
}
}
public static byte[] toByteArray(double value) {
byte[] bytes = new byte[8];
ByteBuffer.wrap(bytes).putDouble(value);
return bytes;
}
public static long getDeliveryTag(String experimentID, CuratorFramework curatorClient, String experimentNode,
String pickedChild) throws Exception {
String deliveryTagPath = experimentNode + File.separator + pickedChild + File.separator + experimentID
+ DELIVERY_TAG_POSTFIX;
Stat exists = curatorClient.checkExists().forPath(deliveryTagPath);
if(exists==null) {
logger.error("Cannot find delivery Tag in path:" + deliveryTagPath + " for this experiment");
return -1;
}
return bytesToLong(curatorClient.getData().storingStatIn(exists).forPath(deliveryTagPath));
}
public static byte[] longToBytes(long x) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(x);
return buffer.array();
}
public static long bytesToLong(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.put(bytes);
buffer.flip();//need flip
return buffer.getLong();
}
public static double toDouble(byte[] bytes) {
return ByteBuffer.wrap(bytes).getDouble();
}
public static long getCancelDeliveryTagIfExist(String experimentId, CuratorFramework curatorClient,
String experimentNode, String pickedChild) throws Exception {
String cancelDeliveryTagPath = experimentNode + File.separator + pickedChild + File.separator + experimentId +
AiravataZKUtils.CANCEL_DELIVERY_TAG_POSTFIX;
Stat exists = curatorClient.checkExists().forPath(cancelDeliveryTagPath);
if (exists == null) {
return -1; // no cancel deliverytag found
} else {
return bytesToLong(curatorClient.getData().storingStatIn(exists).forPath(cancelDeliveryTagPath));
}
}
}