/*
* Copyright 2014 Alexey Plotnik
*
* Licensed 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.stem.service;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.stem.api.ClusterManagerClient;
import org.stem.api.REST;
import org.stem.api.request.JoinRequest;
import org.stem.api.response.ClusterResponse;
import org.stem.coordination.ZooException;
import org.stem.coordination.ZookeeperClient;
import org.stem.coordination.ZookeeperFactoryCached;
import org.stem.db.Layout;
import org.stem.db.MountPoint;
import org.stem.db.StorageNodeDescriptor;
import org.stem.utils.Utils;
import java.net.InetAddress;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ClusterService {
public static ClusterService instance; // TODO: make private
// static {
// instance = new ClusterService();
// }
private static ClusterManagerClient client = ClusterManagerClient.create(StorageNodeDescriptor.getClusterManagerEndpoint());
ListeningExecutorService executor;
public final ZookeeperClient zookeeperClient;
public DataClusterNotificator notificator;
public ClusterService() {
String endpoint = StorageNodeDescriptor.cluster().getZookeeperEndpoint();
try {
zookeeperClient = ZookeeperFactoryCached.newClient(endpoint);
} catch (ZooException e) {
throw new RuntimeException("Fail to initialize cluster service", e);
}
}
public ClusterService(REST.Cluster cluster) {
String endpoint = cluster.getZookeeperEndpoint();
try {
zookeeperClient = ZookeeperFactoryCached.newClient(endpoint);
executor = newExecutor(4, "Periodic-Tasks-%d");
} catch (ZooException e) {
throw new RuntimeException("Fail to initialize cluster service", e);
}
}
public void join() {
client.join(prepareJoinRequest(), zookeeperClient);
}
private static JoinRequest prepareJoinRequest() {
List<InetAddress> ipAddresses = Utils.getIpAddresses();
Map<UUID, MountPoint> mountPoints = Layout.getInstance().getMountPoints();
JoinRequest req = new JoinRequest();
REST.StorageNode node = req.getNode();
node.setId(StorageNodeDescriptor.id);
node.setHostname(Utils.getMachineHostname());
node.setListen(StorageNodeDescriptor.getNodeListenAddress() + ':' + StorageNodeDescriptor.getNodeListenPort());
for (InetAddress ipAddress : ipAddresses) {
node.getIpAddresses().add(ipAddress.toString());
}
long capacity = 0;
for (MountPoint mp : mountPoints.values()) {
REST.Disk disk = new REST.Disk(
mp.getId(),
mp.getPath(),
mp.getTotalSizeInBytes(),
mp.getAllocatedSizeInBytes());
node.getDisks().add(disk);
capacity += disk.getTotal();
}
node.setCapacity(capacity);
return req;
}
public static REST.Cluster describeAndInit() {
ClusterResponse resp = client.describeCluster();
instance = new ClusterService(resp.getCluster());
return resp.getCluster();
}
// public ClusterResponse.Cluster describeCluster() {
// ClusterResponse resp = client.describeCluster();
// return resp.getCluster();
// }
public void startDataNotificator() throws Exception {
notificator = new DataClusterNotificator();
executor.submit(notificator);
}
public void stop() {
notificator.stop();
executor.shutdown();
}
private static ListeningExecutorService newExecutor(int threads, String name) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(threads,
threads,
30,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory(name));
executor.allowCoreThreadTimeOut(true);
return MoreExecutors.listeningDecorator(executor);
}
private static ThreadFactory threadFactory(String nameFormat) {
return new ThreadFactoryBuilder().setNameFormat(nameFormat).build();
}
}