/* * Copyright 2014-2016 CyberVision, Inc. * * 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.kaaproject.kaa.server.control.service.zk; import org.apache.curator.framework.CuratorFramework; import org.apache.thrift.TException; import org.kaaproject.kaa.server.common.thrift.KaaThriftService; import org.kaaproject.kaa.server.common.thrift.gen.operations.Notification; import org.kaaproject.kaa.server.common.thrift.gen.operations.OperationsThriftService; import org.kaaproject.kaa.server.common.thrift.gen.operations.OperationsThriftService.Client; import org.kaaproject.kaa.server.common.thrift.util.ThriftActivity; import org.kaaproject.kaa.server.common.thrift.util.ThriftClient; import org.kaaproject.kaa.server.common.thrift.util.ThriftExecutor; import org.kaaproject.kaa.server.common.zk.control.ControlNode; import org.kaaproject.kaa.server.common.zk.gen.BootstrapNodeInfo; import org.kaaproject.kaa.server.common.zk.gen.ConnectionInfo; import org.kaaproject.kaa.server.common.zk.gen.ControlNodeInfo; import org.kaaproject.kaa.server.common.zk.gen.OperationsNodeInfo; import org.kaaproject.kaa.server.node.service.config.KaaNodeServerConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.List; /** * The Class ControlZkService. */ @Service public class ControlZkService { private static final Logger LOG = LoggerFactory.getLogger(ControlZkService.class); @Autowired private KaaNodeServerConfig kaaNodeServerConfig; @Autowired private CuratorFramework zkClient; private ControlNode controlZkNode; /** * KaaNodeServerConfig getter. * * @return KaaNodeServerConfig */ private KaaNodeServerConfig getNodeConfig() { return kaaNodeServerConfig; } /** * Start Zookeeper service. */ public void start() { if (getNodeConfig().isZkEnabled()) { LOG.info("Control service starting ZooKepper connection to {}", getNodeConfig().getZkHostPortList()); ControlNodeInfo nodeInfo = new ControlNodeInfo(); ConnectionInfo connectionInfo = new ConnectionInfo( getNodeConfig().getThriftHost(), getNodeConfig().getThriftPort(), null); nodeInfo.setConnectionInfo(connectionInfo); controlZkNode = new ControlNode(nodeInfo, zkClient); try { controlZkNode.start(); } catch (Exception ex) { if (getNodeConfig().isZkIgnoreErrors()) { LOG.info("Failed to register control in ZooKeeper", ex); } else { LOG.error("Failed to register control in ZooKeeper", ex); throw new RuntimeException(ex); // NOSONAR } } } } /** * Stop Zookeeper Service. */ public void stop() { if (getNodeConfig().isZkEnabled()) { try { controlZkNode.close(); } catch (IOException ex) { LOG.warn("Error closing ZK node", ex); } } } /** * Send endpoint notification. * * @param thriftNotification the thrift notification */ public void sendEndpointNotification(final Notification thriftNotification) { if (getNodeConfig().isZkEnabled()) { List<OperationsNodeInfo> endpoints = controlZkNode.getCurrentOperationServerNodes(); for (OperationsNodeInfo endpoint : endpoints) { String host = endpoint.getConnectionInfo().getThriftHost().toString(); int port = endpoint.getConnectionInfo().getThriftPort(); try { ThriftClient<OperationsThriftService.Client> thriftClient = new ThriftClient<>(host, port, KaaThriftService.OPERATIONS_SERVICE, OperationsThriftService.Client.class); thriftClient.setThriftActivity(new ThriftActivity<OperationsThriftService.Client>() { @Override public void isSuccess(boolean activitySuccess) { if (!activitySuccess) { LOG.error("Sending notification to endpoint server failed."); } } @Override public void doInTemplate(Client template) { try { // NOSONAR template.onNotification(thriftNotification); } catch (TException ex) { LOG.error("Unexpected error occurred while send notification to endpoint server", ex); } } }); ThriftExecutor.execute(thriftClient); } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { LOG.error("Unexpected error occurred while creating thrift connection" + " to send notification to endpoint server", ex); } } } } /** * Gets the control zk node. * * @return the control zk node */ public ControlNode getControlZkNode() { return controlZkNode; } /** * Gets the current bootstrap nodes. * * @return the current bootstrap nodes */ public List<BootstrapNodeInfo> getCurrentBootstrapNodes() { if (getNodeConfig().isZkEnabled()) { return controlZkNode.getCurrentBootstrapNodes(); } else { return null; // NOSONAR } } }