/* * 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.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import jp.primecloud.auto.exception.AutoApplicationException; import jp.primecloud.auto.service.ComponentService; import jp.primecloud.auto.service.InstanceService; import jp.primecloud.auto.service.dto.ComponentTypeDto; import jp.primecloud.auto.service.dto.InstanceDto; 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.AbsoluteLayout; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; 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.TwinColSelect; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; /** * <p> * サービスの新規作成画面を生成します。 * </p> * */ @SuppressWarnings("serial") public class WinServiceAdd extends Window { private final String COLUMN_HEIGHT = "30px"; private BasicForm basicForm; private List<ComponentTypeDto> componentTypes; private List<InstanceDto> instances; @Override public void attach() { // モーダルウインドウ setIcon(Icons.ADD.resource()); setCaption(ViewProperties.getCaption("window.winServiceAdd")); setModal(true); setWidth("630px"); //setHeight("500px"); VerticalLayout layout = (VerticalLayout) getContent(); layout.setMargin(false, 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.addService")); 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.serviceTable.show(componentTypes); basicForm.serviceTable.selectFirst(); } private class BasicForm extends Form { private TextField serviceNameField; private TextField commentField; private SelectServiceTable serviceTable; private TextField diskSizeField; private ServerSelect serverSelect; @Override public void attach() { setStyleName("win-service-add-form"); // サービス名 serviceNameField = new TextField(ViewProperties.getCaption("field.serviceName")); getLayout().addComponent(serviceNameField); // コメント commentField = new TextField(ViewProperties.getCaption("field.comment")); commentField.setWidth("90%"); getLayout().addComponent(commentField); // サービス種類情報テーブル serviceTable = new SelectServiceTable(); getLayout().addComponent(serviceTable); serviceTable.addListener(new Property.ValueChangeListener() { @Override public void valueChange(Property.ValueChangeEvent event) { serviceTableSelect(event); } }); // ディスクサイズ diskSizeField = new TextField(ViewProperties.getCaption("field.diskSize")); getLayout().addComponent(diskSizeField); // サーバ選択フォーム AbsoluteLayout layout = new AbsoluteLayout(); layout.setWidth("100%"); layout.setHeight("20px"); layout.setStyleName("serverselect"); Label selectLbl = new Label(ViewProperties.getCaption("label.serverSelectable")); Label selectedLbl = new Label(ViewProperties.getCaption("label.serverSelected")); layout.addComponent(selectLbl, "left:10%"); layout.addComponent(selectedLbl, "left:65%"); getLayout().addComponent(layout); serverSelect = new ServerSelect(); serverSelect.setWidth("95%"); getLayout().addComponent(serverSelect); // 新規サーバ追加ボタン Button addServerButton = new Button(ViewProperties.getCaption("button.addServerQuick")); addServerButton.setDescription(ViewProperties.getCaption("description.addServerQuick")); addServerButton.setIcon(Icons.ADD.resource()); addServerButton.addListener(new ClickListener() { @Override public void buttonClick(ClickEvent event) { addServerButton(event); } }); HorizontalLayout layout2 = new HorizontalLayout(); Label label = new Label(ViewProperties.getCaption("label.addServerQuick")); layout2.addComponent(addServerButton); layout2.addComponent(label); layout2.setComponentAlignment(label, Alignment.MIDDLE_LEFT); getLayout().addComponent(layout2); initValidation(); } private void initValidation() { String message = ViewMessages.getMessage("IUI-000031"); serviceNameField.setRequired(true); serviceNameField.setRequiredError(message); serviceNameField.addValidator(new StringLengthValidator(message, -1, 15, false)); serviceNameField.addValidator(new RegexpValidator("^[0-9a-z]|[0-9a-z][0-9a-z-]*[0-9a-z]$", true, message)); message = ViewMessages.getMessage("IUI-000003"); commentField.addValidator(new StringLengthValidator(message, -1, 100, true)); message = ViewMessages.getMessage("IUI-000032"); diskSizeField.setRequired(true); diskSizeField.setRequiredError(message); diskSizeField.addValidator(new RegexpValidator("^[1-9]|[1-9][0-9]{1,2}|1000$", true, message)); } private void serviceTableSelect(Property.ValueChangeEvent event) { // 選択がない場合はサーバ選択をクリア if (serviceTable.getValue() == null) { serverSelect.removeAllItems(); return; } // 選択されたサービス種類で利用可能なサーバ情報を選択画面に表示 ComponentTypeDto componentType = findComponentType(serviceTable.getValue()); serverSelect.show(instances, componentType.getInstanceNos()); } } private class SelectServiceTable extends Table { @Override public void attach() { // テーブル基本設定 setCaption(ViewProperties.getCaption("table.selectService")); setWidth("440px"); setPageLength(4); setSortDisabled(true); setColumnHeaderMode(Table.COLUMN_HEADER_MODE_HIDDEN); setColumnReorderingAllowed(false); setColumnCollapsingAllowed(false); setSelectable(true); setMultiSelect(false); setNullSelectionAllowed(false); setImmediate(true); addStyleName("win-service-add-service"); // カラム設定 addContainerProperty("No", Integer.class, null); addContainerProperty("Service", Label.class, new Label()); addContainerProperty("Description", String.class, null); setColumnExpandRatio("Description", 100); setCellStyleGenerator(new StandardCellStyleGenerator()); } public void show(List<ComponentTypeDto> componentTypes) { removeAllItems(); if (componentTypes == null) { return; } for (int i = 0; i < componentTypes.size(); i++) { ComponentTypeDto componentType = componentTypes.get(i); // サービス名 String name = componentType.getComponentType().getComponentTypeNameDisp(); Icons nameIcon = Icons.fromName(componentType.getComponentType().getComponentTypeName()); Label slbl = new Label(IconUtils.createImageTag(getApplication(), nameIcon, name), Label.CONTENT_XHTML); slbl.setHeight(COLUMN_HEIGHT); // サービス説明 String description = componentType.getComponentType().getLayerDisp(); addItem(new Object[] { (i + 1), slbl, description }, componentType.getComponentType() .getComponentTypeNo()); } } @Override public Long getValue() { return (Long) super.getValue(); } public void selectFirst() { if (size() > 0) { select(firstItemId()); } } } public class ServerSelect extends TwinColSelect { @Override public void attach() { setCaption(ViewProperties.getCaption("field.selectServer")); setRows(7); setNullSelectionAllowed(true); setMultiSelect(true); setImmediate(true); setStyleName("serverselect"); } public void show(List<InstanceDto> instances, List<Long> availableInstanceNos) { removeAllItems(); if (instances == null || availableInstanceNos == null) { return; } for (Long instanceNo : availableInstanceNos) { for (InstanceDto instance : instances) { if (instanceNo.equals(instance.getInstance().getInstanceNo())) { addItem(instance.getInstance().getInstanceName()); break; } } } } @Override @SuppressWarnings("unchecked") public Collection<String> getValue() { return (Collection<String>) super.getValue(); } } private void loadData() { // サービス種類情報を取得 ComponentService componentService = BeanContext.getBean(ComponentService.class); componentTypes = componentService.getComponentTypes(ViewContext.getFarmNo()); // 有効でないサービス種類情報を除外 for (int i = componentTypes.size() - 1; i >= 0; i--) { if (BooleanUtils.isNotTrue(componentTypes.get(i).getComponentType().getSelectable())) { componentTypes.remove(i); } } // サービス種類情報をソート Collections.sort(componentTypes, new Comparator<ComponentTypeDto>() { @Override public int compare(ComponentTypeDto o1, ComponentTypeDto o2) { int order1 = (o1.getComponentType().getViewOrder() != null) ? o1.getComponentType().getViewOrder() : Integer.MAX_VALUE; int order2 = (o2.getComponentType().getViewOrder() != null) ? o2.getComponentType().getViewOrder() : Integer.MAX_VALUE; return order1 - order2; } }); // 全インスタンスを取得 InstanceService instanceService = BeanContext.getBean(InstanceService.class); instances = instanceService.getInstances(ViewContext.getFarmNo()); } private ComponentTypeDto findComponentType(Long componentTypeNo) { for (ComponentTypeDto componentType : componentTypes) { if (componentTypeNo.equals(componentType.getComponentType().getComponentTypeNo())) { return componentType; } } return null; } private void addServerButton(ClickEvent event) { // 選択されているサービス種類を取得 final Long componentTypeNo = basicForm.serviceTable.getValue(); if (componentTypeNo == null) { // サービス種類が選択されていない場合 throw new AutoApplicationException("IUI-000030"); } ComponentTypeDto componentType = findComponentType(componentTypeNo); WinServerAddSimple winServerAddSimple = new WinServerAddSimple(componentType.getComponentType()); winServerAddSimple.addListener(new CloseListener() { @Override @SuppressWarnings("unchecked") public void windowClose(CloseEvent e) { // 作成したサーバ名を取得 List<String> addedServerNames = (List<String>) ContextUtils.getAttribute("serverNames"); if (addedServerNames != null) { ContextUtils.removeAttribute("serverNames"); // 選択されているサーバ名を取得 Collection<String> selectedServerNames = basicForm.serverSelect.getValue(); // サービス種類情報を再表示 loadData(); basicForm.serviceTable.show(componentTypes); // 元のサービス種類を選択する basicForm.serviceTable.select(componentTypeNo); // 元のサーバ名と作成したサーバ名を選択する List<String> serverNames = new ArrayList<String>(selectedServerNames); serverNames.addAll(addedServerNames); basicForm.serverSelect.setValue(serverNames); } } }); getWindow().getApplication().getMainWindow().addWindow(winServerAddSimple); } private void addButtonClick(ClickEvent event) { // 入力値を取得 String serviceName = (String) basicForm.serviceNameField.getValue(); String comment = (String) basicForm.commentField.getValue(); String diskSize = (String) basicForm.diskSizeField.getValue(); Long componentTypeNo = basicForm.serviceTable.getValue(); Collection<String> serverNames = basicForm.serverSelect.getValue(); // 入力チェック basicForm.serviceNameField.validate(); basicForm.commentField.validate(); basicForm.diskSizeField.validate(); if (componentTypeNo == null) { throw new AutoApplicationException("IUI-000030"); } if ("base".equals(serviceName) || serviceName.startsWith("lb-")) { throw new AutoApplicationException("IUI-000053", serviceName); } // サービスを作成 ComponentService componentService = BeanContext.getBean(ComponentService.class); Long componentNo = componentService.createComponent(ViewContext.getFarmNo(), serviceName, componentTypeNo, comment, Integer.valueOf(diskSize)); // オペレーションログ OperationLogger.writeComponent("SERVICE", "Make Service", componentNo, null); // 選択されたサーバのinstanceNoのリスト List<Long> instanceNos = new ArrayList<Long>(); for (InstanceDto instance : instances) { if (serverNames.contains(instance.getInstance().getInstanceName())) { instanceNos.add(instance.getInstance().getInstanceNo()); } } // サービスにサーバを追加 try { componentService.associateInstances(componentNo, instanceNos); } catch (AutoApplicationException e) { // エラーの場合、作成したサービスを削除する componentService.deleteComponent(componentNo); throw e; } // 画面を閉じる close(); } }