/*
* 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.service.impl;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import jp.primecloud.auto.common.constant.PCCConstant;
import jp.primecloud.auto.common.status.InstanceStatus;
import jp.primecloud.auto.entity.crud.AwsInstance;
import jp.primecloud.auto.entity.crud.AzureInstance;
import jp.primecloud.auto.entity.crud.ComponentInstance;
import jp.primecloud.auto.entity.crud.ComponentLoadBalancer;
import jp.primecloud.auto.entity.crud.Farm;
import jp.primecloud.auto.entity.crud.Instance;
import jp.primecloud.auto.entity.crud.LoadBalancer;
import jp.primecloud.auto.entity.crud.LoadBalancerListener;
import jp.primecloud.auto.entity.crud.Platform;
import jp.primecloud.auto.entity.crud.PlatformAws;
import jp.primecloud.auto.service.ProcessService;
import jp.primecloud.auto.service.ServiceSupport;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
/**
* <p>
* TODO: クラスコメントを記述
* </p>
*
*/
public class ProcessServiceImpl extends ServiceSupport implements ProcessService {
/**
* {@inheritDoc}
*/
@Override
public void startInstances(Long farmNo, List<Long> instanceNos) {
this.startInstances(farmNo, instanceNos, false);
}
/**
* {@inheritDoc}
*/
@Override
public void startInstances(Long farmNo, List<Long> instanceNos, boolean startComponent) {
// インスタンスを有効にする
List<Instance> instances = instanceDao.readInInstanceNos(instanceNos);
boolean skipServer = false;
for (Instance instance : instances) {
Platform platform = platformDao.read(instance.getPlatformNo());
if (PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatformType())) {
PlatformAws platformAws = platformAwsDao.read(instance.getPlatformNo());
AwsInstance awsInstance = awsInstanceDao.read(instance.getInstanceNo());
if (platformAws.getVpc() && StringUtils.isEmpty(awsInstance.getSubnetId())) {
//EC2+VPCでサブネットが設定されていないサーバは起動不可
instanceNos.remove(instance.getInstanceNo());
continue;
}
}
if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatformType())) {
AzureInstance azureInstance = azureInstanceDao.read(instance.getInstanceNo());
if (StringUtils.isEmpty(azureInstance.getSubnetId())) {
//サブネットが設定されていないサーバは起動不可
instanceNos.remove(instance.getInstanceNo());
continue;
}
// インスタンスが未作成のものは、2件目以降は起動不可
if (StringUtils.isEmpty(azureInstance.getInstanceName()) && skipServer == true) {
instanceNos.remove(instance.getInstanceNo());
continue;
}
// インスタンスが未作成のものは、1件目のみ起動
if (StringUtils.isEmpty(azureInstance.getInstanceName()) && skipServer == false) {
skipServer = true;
}
}
if (BooleanUtils.isNotTrue(instance.getEnabled())) {
instance.setEnabled(true);
instanceDao.update(instance);
}
}
if (startComponent) {
// コンポーネントとの関連付けを有効にする
List<ComponentInstance> componentInstances = componentInstanceDao.readInInstanceNos(instanceNos);
for (ComponentInstance componentInstance : componentInstances) {
if (BooleanUtils.isNotTrue(componentInstance.getAssociate())) {
// 関連付けが無効なコンポーネントは無効にする
if (BooleanUtils.isTrue(componentInstance.getEnabled())
|| BooleanUtils.isNotTrue(componentInstance.getConfigure())) {
componentInstance.setEnabled(false);
componentInstance.setConfigure(true);
componentInstanceDao.update(componentInstance);
}
continue;
}
if (BooleanUtils.isNotTrue(componentInstance.getEnabled())
|| BooleanUtils.isNotTrue(componentInstance.getConfigure())) {
componentInstance.setEnabled(true);
componentInstance.setConfigure(true);
componentInstanceDao.update(componentInstance);
}
}
}
// ファームを更新処理対象として登録
scheduleFarm(farmNo);
}
/**
* {@inheritDoc}
*/
@Override
public void stopInstances(Long farmNo, List<Long> instanceNos) {
// インスタンスを無効にする
List<Instance> instances = instanceDao.readInInstanceNos(instanceNos);
for (Instance instance : instances) {
if (BooleanUtils.isTrue(instance.getEnabled())) {
instance.setEnabled(false);
instanceDao.update(instance);
}
}
// コンポーネントとの関連付けを無効にする
List<ComponentInstance> componentInstances = componentInstanceDao.readInInstanceNos(instanceNos);
for (ComponentInstance componentInstance : componentInstances) {
if (BooleanUtils.isTrue(componentInstance.getEnabled())
|| BooleanUtils.isNotTrue(componentInstance.getConfigure())) {
componentInstance.setEnabled(false);
componentInstance.setConfigure(true);
componentInstanceDao.update(componentInstance);
}
}
// ファームを更新処理対象として登録
scheduleFarm(farmNo);
}
/**
* {@inheritDoc}
*/
@Override
public void startComponents(Long farmNo, List<Long> componentNos) {
// コンポーネントを有効にする
List<ComponentInstance> componentInstances = componentInstanceDao.readInComponentNos(componentNos);
boolean skipServer = false;
Long skipInstanceNo = null;
for (ComponentInstance componentInstance : componentInstances) {
if (BooleanUtils.isNotTrue(componentInstance.getAssociate())) {
// 関連付けが無効なコンポーネントは無効にする
if (BooleanUtils.isTrue(componentInstance.getEnabled())
|| BooleanUtils.isNotTrue(componentInstance.getConfigure())) {
componentInstance.setEnabled(false);
componentInstance.setConfigure(true);
componentInstanceDao.update(componentInstance);
}
continue;
}
Instance instance = instanceDao.read(componentInstance.getInstanceNo());
Platform platform = platformDao.read(instance.getPlatformNo());
if (PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatformType())) {
PlatformAws platformAws = platformAwsDao.read(instance.getPlatformNo());
AwsInstance awsInstance = awsInstanceDao.read(instance.getInstanceNo());
if (platformAws.getVpc() && StringUtils.isEmpty(awsInstance.getSubnetId())) {
//EC2+VPCでサブネットが設定されていないサーバは起動不可
continue;
}
}
if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatformType())) {
AzureInstance azureInstance = azureInstanceDao.read(instance.getInstanceNo());
if (StringUtils.isEmpty(azureInstance.getSubnetId())) {
//サブネットが設定されていないサーバは起動不可
continue;
}
// インスタンスが未作成のものは、2件目以降は起動不可
// 同一インスタンスNoは、除外する
if (StringUtils.isEmpty(azureInstance.getInstanceName()) && skipServer == true
&& azureInstance.getInstanceNo().equals(skipInstanceNo) == false) {
continue;
}
// インスタンスが未作成のものは、1件目のみ起動
if (StringUtils.isEmpty(azureInstance.getInstanceName()) && skipServer == false) {
skipServer = true;
skipInstanceNo = azureInstance.getInstanceNo();
}
}
if (BooleanUtils.isNotTrue(componentInstance.getEnabled())
|| BooleanUtils.isNotTrue(componentInstance.getConfigure())) {
componentInstance.setEnabled(true);
componentInstance.setConfigure(true);
componentInstanceDao.update(componentInstance);
}
}
// コンポーネントに関連するインスタンスを有効にする
Set<Long> instanceNos = new LinkedHashSet<Long>();
for (ComponentInstance componentInstance : componentInstances) {
instanceNos.add(componentInstance.getInstanceNo());
}
List<Instance> instances = instanceDao.readInInstanceNos(instanceNos);
boolean skipServer2 = false;
for (Instance instance : instances) {
Platform platform = platformDao.read(instance.getPlatformNo());
if (PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatformType())) {
PlatformAws platformAws = platformAwsDao.read(instance.getPlatformNo());
AwsInstance awsInstance = awsInstanceDao.read(instance.getInstanceNo());
if (platformAws.getVpc() && StringUtils.isEmpty(awsInstance.getSubnetId())) {
//EC2+VPCでサブネットが設定されていないサーバは起動不可
continue;
}
}
if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatformType())) {
AzureInstance azureInstance = azureInstanceDao.read(instance.getInstanceNo());
if (StringUtils.isEmpty(azureInstance.getSubnetId())) {
//サブネットが設定されていないサーバは起動不可
continue;
}
// インスタンスが未作成のものは、2件目以降は起動不可
if (StringUtils.isEmpty(azureInstance.getInstanceName()) && skipServer2 == true) {
continue;
}
// インスタンスが未作成のものは、1件目のみ起動
if (StringUtils.isEmpty(azureInstance.getInstanceName()) && skipServer2 == false) {
skipServer2 = true;
}
}
if (BooleanUtils.isNotTrue(instance.getEnabled())) {
instance.setEnabled(true);
instanceDao.update(instance);
}
}
// ファームを更新処理対象として登録
scheduleFarm(farmNo);
}
/**
* {@inheritDoc}
*/
@Override
public void startComponents(Long farmNo, Long componentNo, List<Long> instanceNos) {
// コンポーネントを有効にする
List<ComponentInstance> componentInstances = componentInstanceDao.readByComponentNo(componentNo);
for (ComponentInstance componentInstance : componentInstances) {
if (!instanceNos.contains(componentInstance.getInstanceNo())) {
continue;
}
if (BooleanUtils.isNotTrue(componentInstance.getAssociate())) {
// 関連付けが無効なコンポーネントは無効にする
if (BooleanUtils.isTrue(componentInstance.getEnabled())
|| BooleanUtils.isNotTrue(componentInstance.getConfigure())) {
componentInstance.setEnabled(false);
componentInstance.setConfigure(true);
componentInstanceDao.update(componentInstance);
}
continue;
}
if (BooleanUtils.isNotTrue(componentInstance.getEnabled())
|| BooleanUtils.isNotTrue(componentInstance.getConfigure())) {
componentInstance.setEnabled(true);
componentInstance.setConfigure(true);
componentInstanceDao.update(componentInstance);
}
}
// インスタンスが起動していない場合は起動する
List<Instance> instances = instanceDao.readInInstanceNos(instanceNos);
for (Instance instance : instances) {
if (BooleanUtils.isNotTrue(instance.getEnabled())) {
instance.setEnabled(true);
instanceDao.update(instance);
}
}
// ファームを更新処理対象として登録
scheduleFarm(farmNo);
}
/**
* {@inheritDoc}
*/
@Override
public void stopComponents(Long farmNo, List<Long> componentNos) {
stopComponents(farmNo, componentNos, false);
}
/**
* {@inheritDoc}
*/
@Override
public void stopComponents(Long farmNo, List<Long> componentNos, boolean stopInstance) {
// コンポーネントを無効にする
List<ComponentInstance> componentInstances = componentInstanceDao.readInComponentNos(componentNos);
for (ComponentInstance componentInstance : componentInstances) {
if (BooleanUtils.isTrue(componentInstance.getEnabled())
|| BooleanUtils.isNotTrue(componentInstance.getConfigure())) {
componentInstance.setEnabled(false);
componentInstance.setConfigure(true);
componentInstanceDao.update(componentInstance);
}
}
// 関連する全てのコンポーネントが無効なインスタンスを無効にする
if (stopInstance) {
Set<Long> instanceNos = new LinkedHashSet<Long>();
for (ComponentInstance componentInstance : componentInstances) {
instanceNos.add(componentInstance.getInstanceNo());
}
List<Instance> instances = instanceDao.readInInstanceNos(instanceNos);
for (Instance instance : instances) {
if (BooleanUtils.isNotTrue(instance.getEnabled())) {
continue;
}
// 全てのコンポーネントが無効かどうかのチェック
boolean allDisabled = true;
List<ComponentInstance> componentInstances2 = componentInstanceDao.readByInstanceNo(instance
.getInstanceNo());
for (ComponentInstance componentInstance : componentInstances2) {
if (BooleanUtils.isTrue(componentInstance.getEnabled())) {
allDisabled = false;
break;
}
}
// 全てのコンポーネントが無効の場合
if (allDisabled) {
instance.setEnabled(false);
instanceDao.update(instance);
}
}
}
// ファームを更新処理対象として登録
scheduleFarm(farmNo);
}
/**
* {@inheritDoc}
*/
@Override
public void stopComponents(Long farmNo, Long componentNo, List<Long> instanceNos, boolean stopInstance) {
// コンポーネントを無効にする
List<ComponentInstance> componentInstances = componentInstanceDao.readByComponentNo(componentNo);
for (ComponentInstance componentInstance : componentInstances) {
if (!instanceNos.contains(componentInstance.getInstanceNo())) {
continue;
}
if (BooleanUtils.isTrue(componentInstance.getEnabled())
|| BooleanUtils.isNotTrue(componentInstance.getConfigure())) {
componentInstance.setEnabled(false);
componentInstance.setConfigure(true);
componentInstanceDao.update(componentInstance);
}
}
if (stopInstance) {
// 関連する全てのコンポーネントが無効なインスタンスを無効にする
for (ComponentInstance componentInstance : componentInstances) {
instanceNos.add(componentInstance.getInstanceNo());
}
List<Instance> instances = instanceDao.readInInstanceNos(instanceNos);
for (Instance instance : instances) {
if (BooleanUtils.isNotTrue(instance.getEnabled())) {
continue;
}
// 全てのコンポーネントが無効かどうかのチェック
boolean allDisabled = true;
List<ComponentInstance> componentInstances2 = componentInstanceDao.readByInstanceNo(instance
.getInstanceNo());
for (ComponentInstance componentInstance : componentInstances2) {
if (BooleanUtils.isTrue(componentInstance.getEnabled())) {
allDisabled = false;
break;
}
}
// 全てのコンポーネントが無効の場合
if (allDisabled) {
instance.setEnabled(false);
instanceDao.update(instance);
}
}
}
// ファームを更新処理対象として登録
scheduleFarm(farmNo);
}
/**
* {@inheritDoc}
*/
@Override
public void updateComponents(Long farmNo) {
// ファームを更新処理対象として登録
scheduleFarm(farmNo);
}
/**
* {@inheritDoc}
*/
@Override
public void startLoadBalancers(Long farmNo, List<Long> loadBalancerNos) {
// ロードバランサを有効にする
List<LoadBalancer> loadBalancers = loadBalancerDao.readInLoadBalancerNos(loadBalancerNos);
for (LoadBalancer loadBalancer : loadBalancers) {
if (BooleanUtils.isNotTrue(loadBalancer.getEnabled())
|| BooleanUtils.isNotTrue(loadBalancer.getConfigure())) {
loadBalancer.setEnabled(true);
loadBalancer.setConfigure(true);
loadBalancerDao.update(loadBalancer);
}
}
// コンポーネント型ロードバランサの場合、インスタンスやコンポーネントを有効にする
List<ComponentLoadBalancer> componentLoadBalancers = componentLoadBalancerDao
.readInLoadBalancerNos(loadBalancerNos);
if (!componentLoadBalancers.isEmpty()) {
// 振り分け対象のコンポーネント番号を取得
Set<Long> componentNos = new HashSet<Long>();
for (ComponentLoadBalancer componentLoadBalancer : componentLoadBalancers) {
componentNos.add(componentLoadBalancer.getComponentNo());
}
// コンポーネントを有効にする
List<ComponentInstance> componentInstances = componentInstanceDao.readInComponentNos(componentNos);
for (ComponentInstance componentInstance : componentInstances) {
if (BooleanUtils.isNotTrue(componentInstance.getEnabled())) {
componentInstance.setEnabled(true);
componentInstanceDao.update(componentInstance);
}
}
// インスタンスを有効にする
Set<Long> instanceNos = new HashSet<Long>();
for (ComponentInstance componentInstance : componentInstances) {
instanceNos.add(componentInstance.getInstanceNo());
}
List<Instance> instances = instanceDao.readInInstanceNos(instanceNos);
for (Instance instance : instances) {
if (BooleanUtils.isNotTrue(instance.getEnabled())) {
instance.setEnabled(true);
instanceDao.update(instance);
}
}
}
// ファームを更新処理対象として登録
scheduleFarm(farmNo);
}
/**
* {@inheritDoc}
*/
@Override
public void stopLoadBalancers(Long farmNo, List<Long> loadBalancerNos) {
// ロードバランサを無効にする
List<LoadBalancer> loadBalancers = loadBalancerDao.readInLoadBalancerNos(loadBalancerNos);
for (LoadBalancer loadBalancer : loadBalancers) {
if (BooleanUtils.isTrue(loadBalancer.getEnabled()) || BooleanUtils.isNotTrue(loadBalancer.getConfigure())) {
loadBalancer.setEnabled(false);
loadBalancer.setConfigure(true);
loadBalancerDao.update(loadBalancer);
}
}
// コンポーネント型ロードバランサの場合、インスタンスやコンポーネントを無効にする
List<ComponentLoadBalancer> componentLoadBalancers = componentLoadBalancerDao
.readInLoadBalancerNos(loadBalancerNos);
if (!componentLoadBalancers.isEmpty()) {
// 振り分け対象のコンポーネント番号を取得
Set<Long> componentNos = new HashSet<Long>();
for (ComponentLoadBalancer componentLoadBalancer : componentLoadBalancers) {
componentNos.add(componentLoadBalancer.getComponentNo());
}
// コンポーネントを無効にする
List<ComponentInstance> componentInstances = componentInstanceDao.readInComponentNos(componentNos);
for (ComponentInstance componentInstance : componentInstances) {
if (BooleanUtils.isTrue(componentInstance.getEnabled())) {
componentInstance.setEnabled(false);
componentInstanceDao.update(componentInstance);
}
}
// インスタンスを無効にする
Set<Long> instanceNos = new HashSet<Long>();
for (ComponentInstance componentInstance : componentInstances) {
instanceNos.add(componentInstance.getInstanceNo());
}
List<Instance> instances = instanceDao.readInInstanceNos(instanceNos);
for (Instance instance : instances) {
if (BooleanUtils.isTrue(instance.getEnabled())) {
instance.setEnabled(false);
instanceDao.update(instance);
}
}
}
// リスナーを無効にする
List<LoadBalancerListener> listeners = loadBalancerListenerDao.readInLoadBalancerNos(loadBalancerNos);
for (LoadBalancerListener listener : listeners) {
if (BooleanUtils.isTrue(listener.getEnabled())) {
listener.setEnabled(false);
loadBalancerListenerDao.update(listener);
}
}
// ファームを更新処理対象として登録
scheduleFarm(farmNo);
}
/**
* {@inheritDoc}
*/
@Override
public void startLoadBalancerListeners(Long farmNo, Long loadBalancerNo, List<Integer> loadBalancerPorts) {
if (loadBalancerPorts.isEmpty()) {
return;
}
// リスナーを有効にする
List<LoadBalancerListener> listeners = loadBalancerListenerDao.readByLoadBalancerNo(loadBalancerNo);
for (LoadBalancerListener listener : listeners) {
if (!loadBalancerPorts.contains(listener.getLoadBalancerPort())) {
continue;
}
if (BooleanUtils.isNotTrue(listener.getEnabled()) || BooleanUtils.isNotTrue(listener.getConfigure())) {
listener.setEnabled(true);
listener.setConfigure(true);
loadBalancerListenerDao.update(listener);
}
}
// ロードバランサを有効にする
startLoadBalancers(farmNo, Arrays.asList(loadBalancerNo));
}
/**
* {@inheritDoc}
*/
@Override
public void stopLoadBalancerListeners(Long farmNo, Long loadBalancerNo, List<Integer> loadBalancerPorts) {
if (loadBalancerPorts.isEmpty()) {
return;
}
// リスナーを無効にする
List<LoadBalancerListener> listeners = loadBalancerListenerDao.readByLoadBalancerNo(loadBalancerNo);
for (LoadBalancerListener listener : listeners) {
if (!loadBalancerPorts.contains(listener.getLoadBalancerPort())) {
continue;
}
if (BooleanUtils.isTrue(listener.getEnabled()) || BooleanUtils.isNotTrue(listener.getConfigure())) {
listener.setEnabled(false);
listener.setConfigure(true);
loadBalancerListenerDao.update(listener);
}
}
// ロードバランサを設定対象にする
LoadBalancer loadBalancer = loadBalancerDao.read(loadBalancerNo);
if (BooleanUtils.isNotTrue(loadBalancer.getConfigure())) {
loadBalancer.setConfigure(true);
loadBalancerDao.update(loadBalancer);
}
// ファームを更新処理対象として登録
scheduleFarm(farmNo);
}
/**
* {@inheritDoc}
*/
@Override
public boolean checkSubnet(String platformType, Boolean vpc, String subnetId) {
if (PCCConstant.PLATFORM_TYPE_AWS.equals(platformType) && vpc && StringUtils.isEmpty(subnetId)
|| (PCCConstant.PLATFORM_TYPE_AZURE.equals(platformType) && StringUtils.isEmpty(subnetId))) {
//EC2+VPCまたは、Azureの場合、サブネットを設定しないと起動不可
return true;
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public HashMap<String, Boolean> checkStartupAll(String platformType, String instanceName, boolean skipServer) {
HashMap<String, Boolean> flgMap = new HashMap<String, Boolean>();
if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platformType)) {
// インスタンスが未作成のものがあった場合(同時起動)
// インスタンスが未作成のものは、2件目以降は起動不可
if (StringUtils.isEmpty(instanceName) && skipServer == true) {
// インスタンス作成中のものがあった場合は、起動不可
flgMap.put("skipServer", skipServer);
flgMap.put("startupAllErrFlg", true);
return flgMap;
}
// インスタンスが未作成のものは、1件目のみ起動
if (StringUtils.isEmpty(instanceName) && skipServer == false) {
skipServer = true;
}
}
flgMap.put("skipServer", skipServer);
flgMap.put("startupAllErrFlg", false);
return flgMap;
}
/**
* {@inheritDoc}
*/
@Override
public boolean checkStartup(String platformType, String instanceName, Long instanceNo) {
if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platformType)) {
// インスタンスが未作成のものがあった場合(個別起動)
if (StringUtils.isEmpty(instanceName)) {
List<AzureInstance> azureInstances = azureInstanceDao.readAll();
// 全Azureサーバーにインスタンス作成中のものがあるかのチェック
for (AzureInstance azureInstance : azureInstances) {
Instance instance = instanceDao.read(azureInstance.getInstanceNo());
if (instanceNo.equals(instance.getInstanceNo()) == false
&& (instance.getStatus().equals(InstanceStatus.STARTING.toString()) || instance.getStatus()
.equals(InstanceStatus.CONFIGURING.toString()))
&& StringUtils.isEmpty(azureInstance.getInstanceName())) {
// インスタンス作成中のものがあった場合は、起動不可
// 同一インスタンスNoは、除外する
return true;
}
}
}
}
return false;
}
protected void scheduleFarm(Long farmNo) {
Farm farm = farmDao.read(farmNo);
if (BooleanUtils.isNotTrue(farm.getScheduled())) {
farm.setScheduled(true);
farmDao.update(farm);
}
}
}