/* * Copyright 2014 by SCSK Corporation. * * This file is part of PrimeCloud Controller(TM). * * PrimeCloud Controller(TM) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * PrimeCloud Controller(TM) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PrimeCloud Controller(TM). If not, see <http://www.gnu.org/licenses/>. */ package jp.primecloud.auto.process.lb; import java.util.List; import jp.primecloud.auto.common.constant.PCCConstant; import jp.primecloud.auto.common.status.LoadBalancerInstanceStatus; import jp.primecloud.auto.common.status.LoadBalancerListenerStatus; import jp.primecloud.auto.common.status.LoadBalancerStatus; import jp.primecloud.auto.entity.crud.Farm; import jp.primecloud.auto.entity.crud.LoadBalancer; import jp.primecloud.auto.entity.crud.LoadBalancerInstance; import jp.primecloud.auto.entity.crud.LoadBalancerListener; import jp.primecloud.auto.exception.AutoException; import jp.primecloud.auto.process.ProcessLogger; import jp.primecloud.auto.process.aws.AwsLoadBalancerProcess; import jp.primecloud.auto.process.aws.AwsProcessClient; import jp.primecloud.auto.process.aws.AwsProcessClientFactory; import jp.primecloud.auto.process.hook.ProcessHook; import jp.primecloud.auto.process.zabbix.ZabbixLoadBalancerProcess; import jp.primecloud.auto.service.ServiceSupport; import jp.primecloud.auto.util.MessageUtils; import org.apache.commons.lang.BooleanUtils; /** * <p> * TODO: クラスコメントを記述 * </p> * */ public class LoadBalancerProcess extends ServiceSupport { protected AwsProcessClientFactory awsProcessClientFactory; protected AwsLoadBalancerProcess awsLoadBalancerProcess; protected ComponentLoadBalancerProcess componentLoadBalancerProcess; protected IaasGatewayLoadBalancerProcess iaasGatewayLoadBalancerProcess; protected ZabbixLoadBalancerProcess zabbixLoadBalancerProcess; protected ProcessLogger processLogger; protected ProcessHook processHook; public void start(Long loadBalancerNo) { LoadBalancer loadBalancer = loadBalancerDao.read(loadBalancerNo); if (loadBalancer == null) { // ロードバランサが存在しない throw new AutoException("EPROCESS-000010", loadBalancerNo); } if (BooleanUtils.isNotTrue(loadBalancer.getEnabled())) { // 開始対象のロードバランサではない return; } LoadBalancerStatus status = LoadBalancerStatus.fromStatus(loadBalancer.getStatus()); if (status != LoadBalancerStatus.STOPPED && status != LoadBalancerStatus.RUNNING) { // 処理中のため実行できない場合 if (log.isDebugEnabled()) { log.debug(MessageUtils.format("LoadBalancer {1} status is {2}.(loadBalancerNo={0})", loadBalancerNo, loadBalancer.getLoadBalancerName(), status)); } return; } if (log.isInfoEnabled()) { log.info(MessageUtils.getMessage("IPROCESS-200001", loadBalancerNo, loadBalancer.getLoadBalancerName())); } // フック処理の実行 Farm farm = farmDao.read(loadBalancer.getFarmNo()); processHook.execute("pre-start-loadbalancer", farm.getUserNo(), farm.getFarmNo(), loadBalancerNo); // ステータスの更新 if (status == LoadBalancerStatus.RUNNING) { status = LoadBalancerStatus.CONFIGURING; } else { status = LoadBalancerStatus.STARTING; } loadBalancer.setStatus(status.toString()); loadBalancerDao.update(loadBalancer); // イベントログ出力 if (status == LoadBalancerStatus.STARTING) { processLogger.info(null, null, "LoadBalancerStart", new Object[] { loadBalancer.getLoadBalancerName() }); } else if (status == LoadBalancerStatus.CONFIGURING) { processLogger.info(null, null, "LoadBalancerReload", new Object[] { loadBalancer.getLoadBalancerName() }); } try { // ロードバランサ開始処理 startLoadBalancer(loadBalancer); // Zabbixへの監視登録 if (zabbixLoadBalancerDao.countByLoadBalancerNo(loadBalancerNo) > 0) { zabbixLoadBalancerProcess.startHost(loadBalancerNo); } } catch (RuntimeException e) { loadBalancer = loadBalancerDao.read(loadBalancerNo); status = LoadBalancerStatus.fromStatus(loadBalancer.getStatus()); // イベントログ出力 if (status == LoadBalancerStatus.STARTING) { processLogger.info(null, null, "LoadBalancerStartFail", new Object[] { loadBalancer.getLoadBalancerName() }); } else if (status == LoadBalancerStatus.CONFIGURING) { processLogger.info(null, null, "LoadBalancerReloadFail", new Object[] { loadBalancer.getLoadBalancerName() }); } // ステータスの更新 loadBalancer = loadBalancerDao.read(loadBalancerNo); loadBalancer.setStatus(LoadBalancerStatus.WARNING.toString()); loadBalancerDao.update(loadBalancer); // フック処理の実行 processHook.execute("post-start-loadbalancer", farm.getUserNo(), farm.getFarmNo(), loadBalancerNo); throw e; } loadBalancer = loadBalancerDao.read(loadBalancerNo); status = LoadBalancerStatus.fromStatus(loadBalancer.getStatus()); // イベントログ出力 if (status == LoadBalancerStatus.STARTING) { processLogger.info(null, null, "LoadBalancerStartFinish", new Object[] { loadBalancer.getLoadBalancerName() }); } else if (status == LoadBalancerStatus.CONFIGURING) { processLogger.info(null, null, "LoadBalancerReloadFinish", new Object[] { loadBalancer.getLoadBalancerName() }); } // ステータスの更新 loadBalancer = loadBalancerDao.read(loadBalancerNo); loadBalancer.setStatus(LoadBalancerStatus.RUNNING.toString()); loadBalancerDao.update(loadBalancer); // フック処理の実行 processHook.execute("post-start-loadbalancer", farm.getUserNo(), farm.getFarmNo(), loadBalancerNo); if (log.isInfoEnabled()) { log.info(MessageUtils.getMessage("IPROCESS-200002", loadBalancerNo, loadBalancer.getLoadBalancerName())); } } public void stop(Long loadBalancerNo) { LoadBalancer loadBalancer = loadBalancerDao.read(loadBalancerNo); if (loadBalancer == null) { // ロードバランサが存在しない throw new AutoException("EPROCESS-000010", loadBalancerNo); } if (BooleanUtils.isTrue(loadBalancer.getEnabled())) { // 終了対象のインスタンスではない return; } LoadBalancerStatus status = LoadBalancerStatus.fromStatus(loadBalancer.getStatus()); if (status != LoadBalancerStatus.STOPPED && status != LoadBalancerStatus.RUNNING && status != LoadBalancerStatus.WARNING) { // 処理中のため実行できない場合 if (log.isDebugEnabled()) { log.debug(MessageUtils.format("LoadBalancer {1} status is {2}.(loadBalancerNo={0})", loadBalancerNo, loadBalancer.getLoadBalancerName(), status)); } return; } if (log.isInfoEnabled()) { log.info(MessageUtils.getMessage("IPROCESS-200003", loadBalancerNo, loadBalancer.getLoadBalancerName())); } // フック処理の実行 Farm farm = farmDao.read(loadBalancer.getFarmNo()); processHook.execute("pre-stop-loadbalancer", farm.getUserNo(), farm.getFarmNo(), loadBalancerNo); // ステータスの更新 loadBalancer.setStatus(LoadBalancerStatus.STOPPING.toString()); loadBalancerDao.update(loadBalancer); // イベントログ出力 processLogger.info(null, null, "LoadBalancerStop", new Object[] { loadBalancer.getLoadBalancerName() }); try { // Zabbixの監視停止 if (zabbixLoadBalancerDao.countByLoadBalancerNo(loadBalancerNo) > 0) { zabbixLoadBalancerProcess.stopHost(loadBalancerNo); } } catch (RuntimeException e) { log.warn(e.getMessage()); } try { // ロードバランサ終了処理 stopLoadBalancer(loadBalancer); } catch (RuntimeException e) { log.warn(e.getMessage()); } // イベントログ出力 processLogger.info(null, null, "LoadBalancerStopFinish", new Object[] { loadBalancer.getLoadBalancerName() }); // ステータスの更新 loadBalancer = loadBalancerDao.read(loadBalancerNo); loadBalancer.setStatus(LoadBalancerStatus.STOPPED.toString()); loadBalancerDao.update(loadBalancer); // リスナーや振り分けインスタンスのステータスを更新 List<LoadBalancerListener> listeners = loadBalancerListenerDao.readByLoadBalancerNo(loadBalancerNo); for (LoadBalancerListener listener : listeners) { LoadBalancerListenerStatus status2 = LoadBalancerListenerStatus.fromStatus(listener.getStatus()); if (status2 != LoadBalancerListenerStatus.STOPPED) { listener.setStatus(LoadBalancerListenerStatus.STOPPED.toString()); loadBalancerListenerDao.update(listener); } } List<LoadBalancerInstance> lbInstances = loadBalancerInstanceDao.readByLoadBalancerNo(loadBalancerNo); for (LoadBalancerInstance lbInstance : lbInstances) { LoadBalancerInstanceStatus status2 = LoadBalancerInstanceStatus.fromStatus(lbInstance.getStatus()); if (status2 != LoadBalancerInstanceStatus.STOPPED) { lbInstance.setStatus(LoadBalancerInstanceStatus.STOPPED.toString()); loadBalancerInstanceDao.update(lbInstance); } } // フック処理の実行 processHook.execute("post-stop-loadbalancer", farm.getUserNo(), farm.getFarmNo(), loadBalancerNo); if (log.isInfoEnabled()) { log.info(MessageUtils.getMessage("IPROCESS-200004", loadBalancerNo, loadBalancer.getLoadBalancerName())); } } public void configure(Long loadBalancerNo) { LoadBalancer loadBalancer = loadBalancerDao.read(loadBalancerNo); if (loadBalancer == null) { // ロードバランサが存在しない throw new AutoException("EPROCESS-000010", loadBalancerNo); } if (log.isInfoEnabled()) { log.info(MessageUtils.getMessage("IPROCESS-200011", loadBalancerNo, loadBalancer.getLoadBalancerName())); } LoadBalancerStatus initStatus = LoadBalancerStatus.fromStatus(loadBalancer.getStatus()); // ステータスの更新 if (BooleanUtils.isTrue(loadBalancer.getConfigure())) { loadBalancer.setStatus(LoadBalancerStatus.CONFIGURING.toString()); loadBalancerDao.update(loadBalancer); } // イベントログ出力 if (BooleanUtils.isTrue(loadBalancer.getConfigure())) { processLogger.info(null, null, "LoadBalancerConfig", new Object[] { loadBalancer.getLoadBalancerName() }); } try { // ロードバランサ設定処理 configureLoadBalancer(loadBalancer); } catch (RuntimeException e) { // イベントログ出力 if (BooleanUtils.isTrue(loadBalancer.getConfigure())) { processLogger.info(null, null, "LoadBalancerConfigFail", new Object[] { loadBalancer.getLoadBalancerName() }); } // ステータスの更新 if (BooleanUtils.isTrue(loadBalancer.getConfigure())) { loadBalancer = loadBalancerDao.read(loadBalancerNo); loadBalancer.setStatus(initStatus.toString()); loadBalancer.setConfigure(false); loadBalancerDao.update(loadBalancer); } // ロードバランサ停止時はエラーを握り潰す if (BooleanUtils.isNotTrue(loadBalancer.getEnabled())) { log.warn(e.getMessage()); return; } throw e; } // イベントログ出力 if (BooleanUtils.isTrue(loadBalancer.getConfigure())) { processLogger.info(null, null, "LoadBalancerConfigFinish", new Object[] { loadBalancer.getLoadBalancerName() }); } // ステータスの更新 if (BooleanUtils.isTrue(loadBalancer.getConfigure())) { loadBalancer = loadBalancerDao.read(loadBalancerNo); loadBalancer.setStatus(initStatus.toString()); loadBalancer.setConfigure(false); loadBalancerDao.update(loadBalancer); } if (log.isInfoEnabled()) { log.info(MessageUtils.getMessage("IPROCESS-200012", loadBalancerNo, loadBalancer.getLoadBalancerName())); } } protected void startLoadBalancer(LoadBalancer loadBalancer) { String type = loadBalancer.getType(); // AWSプラットフォーム型ロードバランサ if (PCCConstant.LOAD_BALANCER_ELB.equals(type)) { Farm farm = farmDao.read(loadBalancer.getFarmNo()); AwsProcessClient awsProcessClient = awsProcessClientFactory.createAwsProcessClient(farm.getUserNo(), loadBalancer.getPlatformNo()); awsLoadBalancerProcess.start(awsProcessClient, loadBalancer.getLoadBalancerNo()); } // コンポーネント型ロードバランサ else if (PCCConstant.LOAD_BALANCER_ULTRAMONKEY.equals(type)) { componentLoadBalancerProcess.start(loadBalancer.getLoadBalancerNo()); } // IaaS Gateway型ロードバランサ else if (PCCConstant.LOAD_BALANCER_CLOUDSTACK.equals(type)) { iaasGatewayLoadBalancerProcess.start(loadBalancer.getLoadBalancerNo()); } } protected void stopLoadBalancer(LoadBalancer loadBalancer) { String type = loadBalancer.getType(); // AWSプラットフォーム型ロードバランサ if (PCCConstant.LOAD_BALANCER_ELB.equals(type)) { Farm farm = farmDao.read(loadBalancer.getFarmNo()); AwsProcessClient awsProcessClient = awsProcessClientFactory.createAwsProcessClient(farm.getUserNo(), loadBalancer.getPlatformNo()); awsLoadBalancerProcess.stop(awsProcessClient, loadBalancer.getLoadBalancerNo()); } // コンポーネント型ロードバランサ else if (PCCConstant.LOAD_BALANCER_ULTRAMONKEY.equals(type)) { componentLoadBalancerProcess.stop(loadBalancer.getLoadBalancerNo()); } // IaaS Gateway型ロードバランサ else if (PCCConstant.LOAD_BALANCER_CLOUDSTACK.equals(type)) { iaasGatewayLoadBalancerProcess.stop(loadBalancer.getLoadBalancerNo()); } } protected void configureLoadBalancer(LoadBalancer loadBalancer) { String type = loadBalancer.getType(); // AWSプラットフォーム型ロードバランサ if (PCCConstant.LOAD_BALANCER_ELB.equals(type)) { Farm farm = farmDao.read(loadBalancer.getFarmNo()); AwsProcessClient awsProcessClient = awsProcessClientFactory.createAwsProcessClient(farm.getUserNo(), loadBalancer.getPlatformNo()); awsLoadBalancerProcess.configure(awsProcessClient, loadBalancer.getLoadBalancerNo()); } // コンポーネント型ロードバランサ else if (PCCConstant.LOAD_BALANCER_ULTRAMONKEY.equals(type)) { componentLoadBalancerProcess.configure(loadBalancer.getLoadBalancerNo()); } // IaaS Gateway型ロードバランサ else if (PCCConstant.LOAD_BALANCER_CLOUDSTACK.equals(type)) { iaasGatewayLoadBalancerProcess.configure(loadBalancer.getLoadBalancerNo()); } } public void setAwsProcessClientFactory(AwsProcessClientFactory awsProcessClientFactory) { this.awsProcessClientFactory = awsProcessClientFactory; } public void setAwsLoadBalancerProcess(AwsLoadBalancerProcess awsLoadBalancerProcess) { this.awsLoadBalancerProcess = awsLoadBalancerProcess; } /** * componentLoadBalancerProcessを設定します。 * * @param componentLoadBalancerProcess componentLoadBalancerProcess */ public void setComponentLoadBalancerProcess(ComponentLoadBalancerProcess componentLoadBalancerProcess) { this.componentLoadBalancerProcess = componentLoadBalancerProcess; } public void setIaasGatewayLoadBalancerProcess(IaasGatewayLoadBalancerProcess iaasGatewayLoadBalancerProcess) { this.iaasGatewayLoadBalancerProcess = iaasGatewayLoadBalancerProcess; } public void setZabbixLoadBalancerProcess(ZabbixLoadBalancerProcess zabbixLoadBalancerProcess) { this.zabbixLoadBalancerProcess = zabbixLoadBalancerProcess; } /** * processLoggerを設定します。 * * @param processLogger processLogger */ public void setProcessLogger(ProcessLogger processLogger) { this.processLogger = processLogger; } /** * processHookを設定します。 * * @param processHook processHook */ public void setProcessHook(ProcessHook processHook) { this.processHook = processHook; } }