/*
* 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.ui;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import jp.primecloud.auto.common.constant.PCCConstant;
import jp.primecloud.auto.config.Config;
import jp.primecloud.auto.entity.crud.ComponentType;
import jp.primecloud.auto.exception.AutoApplicationException;
import jp.primecloud.auto.service.InstanceService;
import jp.primecloud.auto.service.dto.ImageDto;
import jp.primecloud.auto.service.dto.PlatformDto;
import jp.primecloud.auto.ui.util.BeanContext;
import jp.primecloud.auto.ui.util.ContextUtils;
import jp.primecloud.auto.ui.util.IconUtils;
import jp.primecloud.auto.ui.util.Icons;
import jp.primecloud.auto.ui.util.OperationLogger;
import jp.primecloud.auto.ui.util.ViewContext;
import jp.primecloud.auto.ui.util.ViewMessages;
import jp.primecloud.auto.ui.util.ViewProperties;
import org.apache.commons.lang.BooleanUtils;
import com.vaadin.data.Property;
import com.vaadin.data.validator.RegexpValidator;
import com.vaadin.data.validator.StringLengthValidator;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
/**
* <p>
* サーバの新規作成画面を生成します。
* </p>
*
*/
@SuppressWarnings("serial")
public class WinServerAdd extends Window {
private final String COLUMN_HEIGHT = "28px";
private BasicForm basicForm;
private List<PlatformDto> platforms;
@Override
public void attach() {
//モーダルウインドウ
setIcon(Icons.ADD.resource());
setCaption(ViewProperties.getCaption("window.winServerAdd"));
setModal(true);
setWidth("620px");
//setHeight("600px");
VerticalLayout layout = (VerticalLayout) getContent();
layout.setMargin(true, true, false, true);
layout.setSpacing(false);
// フォーム
basicForm = new BasicForm();
layout.addComponent(basicForm);
// 下部のバー
HorizontalLayout bottomLayout = new HorizontalLayout();
bottomLayout.setSpacing(true);
bottomLayout.setMargin(false, false, true, false);
layout.addComponent(bottomLayout);
layout.setComponentAlignment(bottomLayout, Alignment.BOTTOM_RIGHT);
// Addボタン
Button addButton = new Button(ViewProperties.getCaption("button.add"));
addButton.setDescription(ViewProperties.getCaption("description.addServer"));
addButton.addListener(new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
addButtonClick(event);
}
});
addButton.setClickShortcut(KeyCode.ENTER); // [Enter]でaddButtonクリック
addButton.focus();
bottomLayout.addComponent(addButton);
// Cancelボタン
Button cancelButton = new Button(ViewProperties.getCaption("button.cancel"));
cancelButton.setDescription(ViewProperties.getCaption("description.cancel"));
cancelButton.addListener(new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
close();
}
});
bottomLayout.addComponent(cancelButton);
// プラットフォーム情報の表示
loadData();
basicForm.cloudTable.show(platforms);
basicForm.cloudTable.selectFirst();
}
private class BasicForm extends Form {
private TextField serverNameField;
private TextField commentField;
private SelectCloudTable cloudTable;
private SelectImageTable imageTable;
private AvailableServiceTable serviceTable;
private Button attachButton;
private List<Long> selectedComponentNos;
@Override
public void attach() {
// サーバ名
serverNameField = new TextField(ViewProperties.getCaption("field.serverName"));
getLayout().addComponent(serverNameField);
// コメント
commentField = new TextField(ViewProperties.getCaption("field.comment"));
commentField.setWidth("95%");
getLayout().addComponent(commentField);
// プラットフォーム情報テーブル
cloudTable = new SelectCloudTable();
getLayout().addComponent(cloudTable);
cloudTable.addListener(new Property.ValueChangeListener() {
@Override
public void valueChange(Property.ValueChangeEvent event) {
cloudTableSelect(event);
}
});
// サービスを有効にするかどうか
String enableServiceConf = Config.getProperty("ui.enableService");
boolean enableService = (enableServiceConf == null) || (BooleanUtils.toBoolean(enableServiceConf));
// サーバ種別情報テーブル
imageTable = new SelectImageTable(enableService);
getLayout().addComponent(imageTable);
imageTable.addListener(new Property.ValueChangeListener() {
@Override
public void valueChange(Property.ValueChangeEvent event) {
imageTableSelect(event);
}
});
if (enableService) {
// サービス情報テーブル
serviceTable = new AvailableServiceTable();
Panel panel = new Panel();
panel.setSizeFull();
panel.setWidth("470px");
CssLayout lay = new CssLayout();
panel.setContent(lay);
lay.setSizeFull();
lay.addStyleName("win-server-add-panel");
panel.addComponent(serviceTable);
getLayout().addComponent(panel);
// サービス選択ボタン
attachButton = new Button(ViewProperties.getCaption("button.serverAttachService"));
attachButton.setDescription(ViewProperties.getCaption("description.serverAttachService"));
attachButton.setIcon(Icons.SERVICETAB.resource());
attachButton.addListener(new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
attachButtonClick(event);
}
});
HorizontalLayout attachLayout = new HorizontalLayout();
attachLayout.setSpacing(true);
Label attachLabel = new Label(ViewProperties.getCaption("label.serverAttachService"));
attachLayout.addComponent(attachButton);
attachLayout.addComponent(attachLabel);
attachLayout.setComponentAlignment(attachLabel, Alignment.MIDDLE_LEFT);
getLayout().addComponent(attachLayout);
}
initValidation();
}
private void initValidation() {
String message = ViewMessages.getMessage("IUI-000022");
serverNameField.setRequired(true);
serverNameField.setRequiredError(message);
serverNameField.addValidator(new StringLengthValidator(message, -1, 15, false));
serverNameField.addValidator(new RegexpValidator("^[a-z]|[a-z][0-9a-z-]*[0-9a-z]$", true, message));
message = ViewMessages.getMessage("IUI-000003");
commentField.addValidator(new StringLengthValidator(message, -1, 100, true));
}
private void cloudTableSelect(Property.ValueChangeEvent event) {
// 選択がない場合はサーバ種別情報をクリア
if (cloudTable.getValue() == null) {
imageTable.removeAllItems();
return;
}
// サーバ種別情報を表示
PlatformDto platform = findPlatform(cloudTable.getValue());
imageTable.show(platform.getImages());
imageTable.selectFirst();
}
private void imageTableSelect(Property.ValueChangeEvent event) {
// 選択したサービスをクリア
selectedComponentNos = null;
if (serviceTable == null) {
return;
}
// 選択がない場合はサービス情報をクリア
if (cloudTable.getValue() == null || imageTable.getValue() == null) {
serviceTable.removeAllItems();
serviceTable.setCaption("");
attachButton.setEnabled(false);
return;
}
// サービス情報を表示
ImageDto image = findImage(cloudTable.getValue(), imageTable.getValue());
serviceTable.show(image.getComponentTypes());
// サービス情報テーブルのキャプションを変更
String caption = "「" + image.getImage().getImageNameDisp() + "」で利用できるサービス";
serviceTable.setCaption(caption);
// サービス選択ボタンを状態を変更
if (image.getComponentTypes().size() > 0) {
attachButton.setEnabled(true);
} else {
attachButton.setEnabled(false);
}
}
@SuppressWarnings("unchecked")
private void attachButtonClick(ClickEvent event) {
if (cloudTable.getValue() == null || imageTable.getValue() == null) {
return;
}
ImageDto image = findImage(cloudTable.getValue(), imageTable.getValue());
WinServerAttachService winServerAttachService = new WinServerAttachService(null, image,
selectedComponentNos);
winServerAttachService.addListener(new Window.CloseListener() {
@Override
public void windowClose(Window.CloseEvent e) {
List<Long> componentNos = (List<Long>) ContextUtils.getAttribute("componentNos");
if (componentNos != null) {
ContextUtils.removeAttribute("componentNos");
selectedComponentNos = componentNos;
}
}
});
getWindow().getApplication().getMainWindow().addWindow(winServerAttachService);
}
}
private class SelectCloudTable extends Table {
@Override
public void attach() {
// テーブル基本設定
setCaption(ViewProperties.getCaption("table.selectCloud"));
setWidth("470px");
setPageLength(4);
setColumnHeaderMode(Table.COLUMN_HEADER_MODE_HIDDEN);
setSortDisabled(true);
setColumnReorderingAllowed(false);
setColumnCollapsingAllowed(false);
setSelectable(true);
setMultiSelect(false);
setNullSelectionAllowed(false);
setImmediate(true);
addStyleName("win-server-add-cloud");
// カラム設定
addContainerProperty("No", Integer.class, null);
addContainerProperty("Cloud", Label.class, new Label());
setColumnExpandRatio("Cloud", 100);
setCellStyleGenerator(new StandardCellStyleGenerator());
}
public void show(List<PlatformDto> platforms) {
removeAllItems();
if (platforms == null) {
return;
}
for (int i = 0; i < platforms.size(); i++) {
PlatformDto platform = platforms.get(i);
// プラットフォーム名
Icons icon = IconUtils.getPlatformIcon(platform);
String description = platform.getPlatform().getPlatformNameDisp();
Label slbl = new Label(IconUtils.createImageTag(getApplication(), icon, description),
Label.CONTENT_XHTML);
slbl.setHeight(COLUMN_HEIGHT);
addItem(new Object[] { (i + 1), slbl }, platform.getPlatform().getPlatformNo());
}
}
@Override
public Long getValue() {
return (Long) super.getValue();
}
public void selectFirst() {
if (size() > 0) {
select(firstItemId());
}
}
}
private class SelectImageTable extends Table {
private boolean enableService;
public SelectImageTable(boolean enableService) {
this.enableService = enableService;
}
@Override
public void attach() {
// テーブル基本設定
setCaption(ViewProperties.getCaption("table.selectImage"));
setWidth("470px");
if (enableService) {
setPageLength(3);
} else {
setPageLength(6);
}
setColumnHeaderMode(Table.COLUMN_HEADER_MODE_HIDDEN);
setSortDisabled(true);
setColumnReorderingAllowed(false);
setColumnCollapsingAllowed(false);
setSelectable(true);
setMultiSelect(false);
setNullSelectionAllowed(false);
setImmediate(true);
addStyleName("win-server-add-os");
// カラム設定
addContainerProperty("No", Integer.class, null);
addContainerProperty("Image", Label.class, new Label());
setColumnExpandRatio("Image", 100);
setCellStyleGenerator(new StandardCellStyleGenerator());
}
public void show(List<ImageDto> images) {
removeAllItems();
if (images == null) {
return;
}
for (int i = 0; i < images.size(); i++) {
ImageDto image = images.get(i);
// サーバ種別名
String name = image.getImage().getImageNameDisp();
Icons nameIcon = IconUtils.getImageIcon(image);
Label nlbl = new Label(IconUtils.createImageTag(getApplication(), nameIcon, name), Label.CONTENT_XHTML);
nlbl.setHeight(COLUMN_HEIGHT);
addItem(new Object[] { (i + 1), nlbl }, image.getImage().getImageNo());
}
}
@Override
public Long getValue() {
return (Long) super.getValue();
}
public void selectFirst() {
if (size() > 0) {
select(firstItemId());
}
}
}
private class AvailableServiceTable extends Table {
@Override
public void attach() {
// テーブル基本設定
setCaption(ViewProperties.getCaption("table.availableService"));
setWidth("100%");
setHeight("100px");
setPageLength(3);
setColumnHeaderMode(Table.COLUMN_HEADER_MODE_HIDDEN);
setSortDisabled(true);
setColumnReorderingAllowed(false);
setColumnCollapsingAllowed(false);
setSelectable(false);
setMultiSelect(false);
setImmediate(true);
addStyleName("win-server-add-service");
//カラム設定
addContainerProperty("Service", Label.class, new Label());
addContainerProperty("Description", String.class, null);
setColumnExpandRatio("Service", 100);
setCellStyleGenerator(new StandardCellStyleGenerator());
}
public void show(List<ComponentType> componentTypes) {
removeAllItems();
if (componentTypes == null) {
return;
}
for (ComponentType componentType : componentTypes) {
// サービス名
String name = componentType.getComponentTypeNameDisp();
Icons nameIcon = Icons.fromName(componentType.getComponentTypeName());
Label slbl = new Label(IconUtils.createImageTag(getApplication(), nameIcon, name), Label.CONTENT_XHTML);
slbl.setHeight("26px");
// サービス説明
String description = componentType.getLayerDisp();
addItem(new Object[] { slbl, description }, componentType.getComponentTypeNo());
}
}
@Override
public Long getValue() {
return (Long) super.getValue();
}
}
private void loadData() {
// プラットフォーム情報を取得
InstanceService instanceService = BeanContext.getBean(InstanceService.class);
platforms = instanceService.getPlatforms(ViewContext.getUserNo());
// 有効でないプラットフォーム情報を除外
for (int i = platforms.size() - 1; i >= 0; i--) {
if (BooleanUtils.isNotTrue(platforms.get(i).getPlatform().getSelectable())) {
platforms.remove(i);
}
}
// プラットフォーム情報をソート
Collections.sort(platforms, new Comparator<PlatformDto>() {
@Override
public int compare(PlatformDto o1, PlatformDto o2) {
int order1 = (o1.getPlatform().getViewOrder() != null) ? o1.getPlatform().getViewOrder()
: Integer.MAX_VALUE;
int order2 = (o2.getPlatform().getViewOrder() != null) ? o2.getPlatform().getViewOrder()
: Integer.MAX_VALUE;
return order1 - order2;
}
});
for (PlatformDto platform : platforms) {
List<ImageDto> images = platform.getImages();
// 有効でないサーバ種別情報を除外
for (int i = images.size() - 1; i >= 0; i--) {
if (BooleanUtils.isNotTrue(images.get(i).getImage().getSelectable())) {
images.remove(i);
}
}
// サーバ種別情報をソート
Collections.sort(images, new Comparator<ImageDto>() {
@Override
public int compare(ImageDto o1, ImageDto o2) {
int order1 = (o1.getImage().getViewOrder() != null) ? o1.getImage().getViewOrder()
: Integer.MAX_VALUE;
int order2 = (o2.getImage().getViewOrder() != null) ? o2.getImage().getViewOrder()
: Integer.MAX_VALUE;
return order1 - order2;
}
});
}
for (PlatformDto platform : platforms) {
for (ImageDto image : platform.getImages()) {
List<ComponentType> componentTypes = image.getComponentTypes();
// 有効でないサービス情報情報を除外
for (int i = componentTypes.size() - 1; i >= 0; i--) {
if (BooleanUtils.isNotTrue(componentTypes.get(i).getSelectable())) {
componentTypes.remove(i);
}
}
// 利用可能なサービス情報をソート
Collections.sort(componentTypes, new Comparator<ComponentType>() {
@Override
public int compare(ComponentType o1, ComponentType o2) {
int order1 = (o1.getViewOrder() != null) ? o1.getViewOrder() : Integer.MAX_VALUE;
int order2 = (o2.getViewOrder() != null) ? o2.getViewOrder() : Integer.MAX_VALUE;
return order1 - order2;
}
});
}
}
}
private PlatformDto findPlatform(Long platformNo) {
for (PlatformDto platform : platforms) {
if (platformNo.equals(platform.getPlatform().getPlatformNo())) {
return platform;
}
}
return null;
}
private ImageDto findImage(Long platformNo, Long imageNo) {
PlatformDto platform = findPlatform(platformNo);
for (ImageDto image : platform.getImages()) {
if (imageNo.equals(image.getImage().getImageNo())) {
return image;
}
}
return null;
}
private void addButtonClick(ClickEvent event) {
// 入力値を取得
String serverName = (String) basicForm.serverNameField.getValue();
String comment = (String) basicForm.commentField.getValue();
Long platformNo = basicForm.cloudTable.getValue();
Long imageNo = basicForm.imageTable.getValue();
// 入力チェック
basicForm.serverNameField.validate();
basicForm.commentField.validate();
if (platformNo == null) {
throw new AutoApplicationException("IUI-000023");
}
if (imageNo == null) {
throw new AutoApplicationException("IUI-000024");
}
if (serverName.startsWith("lb-")) {
throw new AutoApplicationException("IUI-000083", serverName);
}
// 選択されたイメージを取得
PlatformDto platform = findPlatform(platformNo);
ImageDto image = findImage(platformNo, imageNo);
// サーバを作成
InstanceService instanceService = BeanContext.getBean(InstanceService.class);
Long farmNo = ViewContext.getFarmNo();
Long instanceNo = null;
// AWSサーバを作成
if (PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatform().getPlatformType())) {
String[] instanceTypes = image.getImageAws().getInstanceTypes().split(",");
instanceNo = instanceService.createIaasInstance(farmNo, serverName, platformNo, comment, imageNo,
instanceTypes[0].trim());
}
// VMwareサーバを作成
else if (PCCConstant.PLATFORM_TYPE_VMWARE.equals(platform.getPlatform().getPlatformType())) {
String[] instanceTypes = image.getImageVmware().getInstanceTypes().split(",");
instanceNo = instanceService.createVmwareInstance(farmNo, serverName, platformNo, comment, imageNo,
instanceTypes[0].trim());
}
// Niftyサーバを作成
else if (PCCConstant.PLATFORM_TYPE_NIFTY.equals(platform.getPlatform().getPlatformType())) {
String[] instanceTypes = image.getImageNifty().getInstanceTypes().split(",");
instanceNo = instanceService.createNiftyInstance(farmNo, serverName, platformNo, comment, imageNo,
instanceTypes[0].trim());
}
// CloudStackサーバを作成
else if (PCCConstant.PLATFORM_TYPE_CLOUDSTACK.equals(platform.getPlatform().getPlatformType())) {
String[] instanceTypes = image.getImageCloudstack().getInstanceTypes().split(",");
instanceNo = instanceService.createIaasInstance(farmNo, serverName, platformNo, comment, imageNo,
instanceTypes[0].trim());
}
// vCloudサーバを作成
else if (PCCConstant.PLATFORM_TYPE_VCLOUD.equals(platform.getPlatform().getPlatformType())) {
String[] instanceTypes = image.getImageVcloud().getInstanceTypes().split(",");
instanceNo = instanceService.createIaasInstance(farmNo, serverName, platformNo, comment, imageNo,
instanceTypes[0].trim());
}
// Azureサーバを作成
else if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatform().getPlatformType())) {
String[] instanceTypes = image.getImageAzure().getInstanceTypes().split(",");
instanceNo = instanceService.createIaasInstance(farmNo, serverName, platformNo, comment, imageNo,
instanceTypes[0].trim());
}
// OpenStackサーバを作成
else if (PCCConstant.PLATFORM_TYPE_OPENSTACK.equals(platform.getPlatform().getPlatformType())) {
String[] instanceTypes = image.getImageOpenstack().getInstanceTypes().split(",");
instanceNo = instanceService.createIaasInstance(farmNo, serverName, platformNo, comment, imageNo,
instanceTypes[0].trim());
}
// オペレーションログ
OperationLogger.writeInstance("SERVER", "Make Server", instanceNo, null);
// サーバにサービスを関連付ける
if (basicForm.selectedComponentNos != null && basicForm.selectedComponentNos.size() > 0) {
instanceService.associateComponents(instanceNo, basicForm.selectedComponentNos);
}
// 画面を閉じる
close();
}
}