/* * 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.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import jp.primecloud.auto.common.constant.PCCConstant; 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.InstanceDto; import jp.primecloud.auto.service.dto.PlatformDto; import jp.primecloud.auto.ui.DialogConfirm.Buttons; import jp.primecloud.auto.ui.DialogConfirm.Result; 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.Validator; import com.vaadin.data.validator.RegexpValidator; import com.vaadin.data.validator.StringLengthValidator; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.ComboBox; import com.vaadin.ui.Form; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; 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 WinServerAddSimple extends Window { private final String COLUMN_HEIGHT = "28px"; private final int MAX_ADD_SERVER = 10; private ComponentType componentType; private ServerAddForm serverAddForm; private List<PlatformDto> platforms; public WinServerAddSimple(ComponentType componentType) { this.componentType = componentType; } @Override public void attach() { // モーダルウインドウ setIcon(Icons.ADD.resource()); setCaption(ViewProperties.getCaption("window.winServerAddSimple")); setModal(true); setWidth("450px"); setResizable(false); VerticalLayout layout = (VerticalLayout) getContent(); layout.setMargin(true, true, false, true); layout.setSpacing(false); // フォーム serverAddForm = new ServerAddForm(); layout.addComponent(serverAddForm); // 下部のバー 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.add")); addButton.addListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { addButtonClick(event); } }); 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(); serverAddForm.show(platforms, componentType); } private class ServerAddForm extends Form { private TextField prefixField; private SelectCloudTable cloudTable; private ComboBox serverNumber; @Override public void attach() { // サーバ名(Prefix) prefixField = new TextField(ViewProperties.getCaption("field.serverNamePrefix")); getLayout().addComponent(prefixField); // プラットフォーム cloudTable = new SelectCloudTable(); getLayout().addComponent(cloudTable); // サーバ台数 serverNumber = new ComboBox(ViewProperties.getCaption("field.serverNumber")); serverNumber.setWidth("110px"); serverNumber.setMultiSelect(false); for (int i = 1; i <= MAX_ADD_SERVER; i++) { serverNumber.addItem(i); } serverNumber.setNullSelectionAllowed(false); serverNumber.setValue(1); // 初期値は1 getLayout().addComponent(serverNumber); initValidation(); } private void initValidation() { String message = ViewMessages.getMessage("IUI-000025"); prefixField.setRequired(true); prefixField.setRequiredError(message); prefixField.addValidator(new StringLengthValidator(message, 1, 10, false)); prefixField.addValidator(new RegexpValidator("^[a-z]|[a-z][0-9a-z-]*[0-9a-z]$", true, message)); Validator serverNumberValidator = new Validator() { @Override public boolean isValid(Object value) { if (value == null || !(value instanceof Integer)) { return false; } else { return ((Integer) value >= 1 && (Integer) value <= MAX_ADD_SERVER); } } @Override public void validate(Object value) throws InvalidValueException { String message = ViewMessages.getMessage("IUI-000026"); if (!isValid(value)) { throw new InvalidValueException(message); } } }; serverNumber.setRequired(true); serverNumber.addValidator(serverNumberValidator); } public void show(List<PlatformDto> platforms, ComponentType componentType) { // サーバ名(Prefix) String prefix = componentType.getLayer(); if (prefix.indexOf('_') != -1) { prefix = prefix.substring(0, prefix.indexOf('_')); } prefixField.setValue(prefix); // プラットフォーム cloudTable.show(platforms, componentType); cloudTable.selectFirst(); } } private class SelectCloudTable extends Table { @Override public void attach() { // テーブル基本設定 setCaption(ViewProperties.getCaption("table.selectCloud")); setWidth("260px"); 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-cloud"); //カラム設定 addContainerProperty("No", Integer.class, null); addContainerProperty("Cloud", Label.class, new Label()); setColumnExpandRatio("Cloud", 100); setCellStyleGenerator(new StandardCellStyleGenerator()); } public void show(List<PlatformDto> platforms, ComponentType componentType) { removeAllItems(); if (platforms == null) { return; } Long componentTypeNo = componentType.getComponentTypeNo(); int index = 1; for (PlatformDto platform : platforms) { // サービス種別を利用可能かチェック boolean available = false; for (ImageDto tmpImage : platform.getImages()) { for (ComponentType tmpComponentType : tmpImage.getComponentTypes()) { if (componentTypeNo.equals(tmpComponentType.getComponentTypeNo())) { available = true; break; } } if (available) { break; } } if (!available) { continue; } // プラットフォーム名 Icons icon = IconUtils.getPlatformIcon(platform); String description = platform.getPlatform().getPlatformNameDisp(); Label label = new Label(IconUtils.createImageTag(getApplication(), icon, description), Label.CONTENT_XHTML); label.setHeight(COLUMN_HEIGHT); addItem(new Object[] { index, label }, platform.getPlatform().getPlatformNo()); index++; } } @Override public Long getValue() { return (Long) super.getValue(); } public void selectFirst() { if (size() > 0) { select(firstItemId()); } } } 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); } } } 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); } } } } } private PlatformDto findPlatform(Long platformNo) { for (PlatformDto platform : platforms) { if (platformNo.equals(platform.getPlatform().getPlatformNo())) { return platform; } } return null; } private void addButtonClick(ClickEvent event) { // 入力値を取得 String prefix = (String) serverAddForm.prefixField.getValue(); String serverNumber = String.valueOf(serverAddForm.serverNumber.getValue()); final Long platformNo = serverAddForm.cloudTable.getValue(); // 入力チェック serverAddForm.prefixField.validate(); serverAddForm.serverNumber.validate(); if (platformNo == null) { throw new AutoApplicationException("IUI-000023"); } if (prefix.startsWith("lb-")) { throw new AutoApplicationException("IUI-000083", prefix); } // 作成するサーバ名 final List<String> serverNames = createServerNames(prefix, Integer.parseInt(serverNumber)); // 確認ダイアログの表示 String message; if (serverNames.size() > 1) { message = ViewMessages.getMessage("IUI-000043", serverNames.get(0), serverNames.get(serverNames.size() - 1), serverNames.size()); } else { message = ViewMessages.getMessage("IUI-000042", serverNames.get(0), serverNames.size()); } DialogConfirm dialog = new DialogConfirm(ViewProperties.getCaption("dialog.confirm"), message, Buttons.OKCancel); dialog.setCallback(new DialogConfirm.Callback() { @Override public void onDialogResult(Result result) { if (result != Result.OK) { return; } else { addOkClick(platformNo, serverNames); } } }); getApplication().getMainWindow().addWindow(dialog); } private List<String> createServerNames(String prefix, int serverNumber) { // サーバ情報を取得 InstanceService instanceService = BeanContext.getBean(InstanceService.class); List<InstanceDto> instances = instanceService.getInstances(ViewContext.getFarmNo()); // prefixと数字から成るサーバ名のうち、最大の数字を取得 int max = 0; for (InstanceDto instance : instances) { String instanceName = instance.getInstance().getInstanceName(); if (instanceName.startsWith(prefix)) { try { int number = Integer.parseInt(instanceName.substring(prefix.length())); if (number > max) { max = number; } } catch (NumberFormatException ignore) { } } } // 最大の数字より大きい数字のサーバ名を作成 List<String> serverNames = new ArrayList<String>(); for (int i = 1; i <= serverNumber; i++) { serverNames.add(prefix + (max + i)); } return serverNames; } private void addOkClick(Long platformNo, List<String> serverNames) { // 選択されたプラットフォームの中で、サービス種類を利用可能なイメージを取得 ImageDto image = null; Long componentTypeNo = componentType.getComponentTypeNo(); PlatformDto platform = findPlatform(platformNo); for (ImageDto tmpImage : platform.getImages()) { for (ComponentType tmpComponentType : tmpImage.getComponentTypes()) { if (componentTypeNo.equals(tmpComponentType.getComponentTypeNo())) { image = tmpImage; break; } } if (image != null) { break; } } // サーバを作成 InstanceService instanceService = BeanContext.getBean(InstanceService.class); Long farmNo = ViewContext.getFarmNo(); String comment = ""; for (String serverName : serverNames) { // AWSサーバを作成 if (PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatform().getPlatformType())) { String[] instanceTypes = image.getImageAws().getInstanceTypes().split(","); instanceService.createIaasInstance(farmNo, serverName, platformNo, comment, image.getImage() .getImageNo(), instanceTypes[0].trim()); } // VMwareサーバを作成 else if (PCCConstant.PLATFORM_TYPE_VMWARE.equals(platform.getPlatform().getPlatformType())) { String[] instanceTypes = image.getImageVmware().getInstanceTypes().split(","); instanceService.createVmwareInstance(farmNo, serverName, platformNo, comment, image.getImage() .getImageNo(), instanceTypes[0].trim()); } // Niftyサーバを作成 else if (PCCConstant.PLATFORM_TYPE_NIFTY.equals(platform.getPlatform().getPlatformType())) { String[] instanceTypes = image.getImageNifty().getInstanceTypes().split(","); instanceService.createNiftyInstance(farmNo, serverName, platformNo, comment, image.getImage() .getImageNo(), instanceTypes[0].trim()); } // CloudStackサーバを作成 else if (PCCConstant.PLATFORM_TYPE_CLOUDSTACK.equals(platform.getPlatform().getPlatformType())) { String[] instanceTypes = image.getImageCloudstack().getInstanceTypes().split(","); instanceService.createIaasInstance(farmNo, serverName, platformNo, comment, image.getImage() .getImageNo(), instanceTypes[0].trim()); } // VCloudサーバを作成 else if (PCCConstant.PLATFORM_TYPE_VCLOUD.equals(platform.getPlatform().getPlatformType())) { String[] instanceTypes = image.getImageVcloud().getInstanceTypes().split(","); instanceService.createIaasInstance(farmNo, serverName, platformNo, comment, image.getImage() .getImageNo(), instanceTypes[0].trim()); } // Azureサーバを作成 else if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatform().getPlatformType())) { String[] instanceTypes = image.getImageAzure().getInstanceTypes().split(","); instanceService.createIaasInstance(farmNo, serverName, platformNo, comment, image.getImage() .getImageNo(), instanceTypes[0].trim()); } // OpenStackサーバを作成 else if (PCCConstant.PLATFORM_TYPE_OPENSTACK.equals(platform.getPlatform().getPlatformType())) { String[] instanceTypes = image.getImageOpenstack().getInstanceTypes().split(","); instanceService.createIaasInstance(farmNo, serverName, platformNo, comment, image.getImage() .getImageNo(), instanceTypes[0].trim()); } } // オペレーションログ String prefix = (String) serverAddForm.prefixField.getValue(); String serverNumber = String.valueOf(serverAddForm.serverNumber.getValue()); OperationLogger.write("SIMPLE_SERVER", "Make Server Simple", prefix + ":" + serverNumber); // 作成したサーバ名をセッションに格納 ContextUtils.setAttribute("serverNames", serverNames); // 画面を閉じる close(); } }