/** * Copyright (C) 2015 Orange * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.francetelecom.clara.cloud.presentation.environments; import com.francetelecom.clara.cloud.commons.BusinessException; import com.francetelecom.clara.cloud.core.service.ManageApplication; import com.francetelecom.clara.cloud.core.service.ManageApplicationRelease; import com.francetelecom.clara.cloud.core.service.ManageEnvironment; import com.francetelecom.clara.cloud.core.service.exception.ApplicationNotFoundException; import com.francetelecom.clara.cloud.core.service.exception.InvalidConfigOverrideException; import com.francetelecom.clara.cloud.core.service.exception.ObjectNotFoundException; import com.francetelecom.clara.cloud.coremodel.ApplicationRelease; import com.francetelecom.clara.cloud.coremodel.PaasUser; import com.francetelecom.clara.cloud.logicalmodel.InvalidConfigServiceException; import com.francetelecom.clara.cloud.logicalmodel.LogicalConfigService; import com.francetelecom.clara.cloud.logicalmodel.LogicalConfigServiceUtils; import com.francetelecom.clara.cloud.logicalmodel.LogicalConfigServiceUtils.ConfigEntry; import com.francetelecom.clara.cloud.logicalmodel.LogicalConfigServiceUtils.StructuredLogicalConfigServiceContent; import com.francetelecom.clara.cloud.presentation.common.WicketUtils; import com.francetelecom.clara.cloud.presentation.designer.pages.DesignerHelperPage; import com.francetelecom.clara.cloud.presentation.designer.panels.DesignerArchitectureMatrixPanel; import com.francetelecom.clara.cloud.presentation.releases.SelectedReleasePage; import com.francetelecom.clara.cloud.presentation.resource.CacheActivatedImage; import com.francetelecom.clara.cloud.presentation.tools.*; import com.francetelecom.clara.cloud.services.dto.ConfigOverrideDTO; import com.francetelecom.clara.cloud.services.dto.EnvironmentDto; import org.apache.wicket.Component; import org.apache.wicket.Session; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.attributes.AjaxRequestAttributes; import org.apache.wicket.ajax.form.OnChangeAjaxBehavior; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox; import org.apache.wicket.bean.validation.PropertyValidator; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.FormComponent; import org.apache.wicket.markup.html.form.RequiredTextField; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.StringResourceModel; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.util.visit.IVisit; import org.apache.wicket.util.visit.IVisitor; import org.apache.wicket.validation.IValidatable; import org.apache.wicket.validation.validator.AbstractValidator; import org.slf4j.LoggerFactory; import javax.validation.constraints.NotNull; import java.io.Serializable; import java.util.*; /** * EnvironmentCreatePanel * Environment creation page * * Updated : $LastChangedDate$ * @author : $Author$ * @version : $Revision$ */ public class EnvironmentCreatePanel extends Panel{ private static final long serialVersionUID = -5260113851920407357L; private static final transient org.slf4j.Logger logger = LoggerFactory.getLogger(EnvironmentCreatePanel.class); private ManageEnvironment manageEnvironment; private ManageApplicationRelease manageApplicationRelease; private ManageApplication manageApplication; private ApplicationRelease release; private PaasUser paasUser = WicketSession.get().getPaasUser(); private Form<MyFormEnvironmentDto> envForm; private WebMarkupContainer container; private DesignerArchitectureMatrixPanel envArchitecturePanel; private AjaxCheckBox overridePropsCheckbox; private Map<String, LogicalConfigService> configOverrides = new HashMap<>(); public EnvironmentCreatePanel(String id, ApplicationRelease release, ManageApplicationRelease manageApplicationRelease, ManageEnvironment manageEnvironment, ManageApplication manageApplication) { super(id); this.manageApplication = manageApplication; this.manageApplicationRelease = manageApplicationRelease; this.manageEnvironment = manageEnvironment; this.release = release; } private void initComponents() { createEnvironmentForm(); setOutputMarkupId(true); } private void createEnvironmentForm() { MyFormEnvironmentDto envDto = new MyFormEnvironmentDto(); List<ApplicationRelease> releaseList = null; if (release != null) { envDto.setRelease(release); releaseList = new ArrayList<ApplicationRelease>(); releaseList.add(release); } else { releaseList = manageApplicationRelease.findMyApplicationReleases(); } envForm = new Form<>("envForm", new CompoundPropertyModel<>(envDto)); // ChoiceRenderer<ApplicationRelease> choiceRenderer = new ChoiceRenderer<ApplicationRelease>("releaseVersion", "name"); CompoundChoiceRenderer<ApplicationRelease> compoundChoiceRenderer = new CompoundChoiceRenderer<ApplicationRelease>(new String[]{"application.label", "releaseVersion"}, "uid", " - "); final DropDownChoice<ApplicationRelease> envDtoDropDownChoice = new DropDownChoice<ApplicationRelease>("release", releaseList, compoundChoiceRenderer); envDtoDropDownChoice.add(new OnChangeAjaxBehavior() { private static final long serialVersionUID = -8967171434567279367L; @Override protected void onUpdate(AjaxRequestTarget target) { try { ((DesignerHelperPage) getPage()).getLogicalDeploymentPersisted(envDtoDropDownChoice.getModelObject().getUID()); } catch (ObjectNotFoundException e) { return; } envArchitecturePanel.updateTable(); configOverrides.clear(); target.add(container); } }); if (release != null) { envDtoDropDownChoice.setEnabled(false); } // release required envDtoDropDownChoice.add(new PropertyValidator<>()); envForm.add(envDtoDropDownChoice); envForm.add(new CacheActivatedImage("imageHelp.releaseField", getString("image.help"))); final RequiredTextField<String> label = new RequiredTextField<>("label"); label.setLabel(new StringResourceModel("portal.environment.name.label",null)); label.add(new PropertyValidator<>()); label.add(new AbstractValidator<String>() { private static final long serialVersionUID = 5714188138333004292L; @Override protected void onValidate(IValidatable<String> iValidatable) { boolean isUnique = false; try { String releaseUID; if (release != null) { releaseUID = release.getUID(); } else { releaseUID = envDtoDropDownChoice.getRawInput(); } isUnique = manageEnvironment.isEnvironmentLabelUniqueForRelease(paasUser.getSsoId().getValue(), iValidatable.getValue(), releaseUID); } catch (BusinessException e) { error(iValidatable); logger.error(e.getMessage(), e); } if(!isUnique) { error(iValidatable); } } @Override protected String resourceKey() { return "portal.environment.label.non.unique"; } @Override protected Map<String, Object> variablesMap(IValidatable<String> stringIValidatable) { Map<String, Object> map = super.variablesMap(stringIValidatable); map.put("label", stringIValidatable.getValue()); return map; } }); DropDownChoice<EnvironmentDto.EnvironmentTypeEnum> envType = new DropDownChoice<EnvironmentDto.EnvironmentTypeEnum>("type", Arrays.asList(EnvironmentDto.EnvironmentTypeEnum.values())); envType.setLabel(new StringResourceModel("portal.environment.type.label",null)); envType.add(new PropertyValidator<>()); container = new WebMarkupContainer("propertiesContainer"); container.setOutputMarkupPlaceholderTag(true); container.setVisible(false); envArchitecturePanel = new DesignerArchitectureMatrixPanel("env-design", (DesignerHelperPage)getPage(), true, true); container.add(envArchitecturePanel); overridePropsCheckbox = new AjaxCheckBox("overridePropertiesCheckbox", new Model<Boolean>()) { private static final long serialVersionUID = 7096578812745292001L; @Override protected void onUpdate(AjaxRequestTarget target) { container.setVisible(getModelObject()); target.add(container); } }; overridePropsCheckbox.setLabel(WicketUtils.getStringResourceModel(this, "portal.environment.properties.override.label")); add(overridePropsCheckbox); createFormButtons(envForm); add(envForm); envForm.add(label); envForm.add(envType); envForm.add(container); envForm.add(overridePropsCheckbox); } private void createFormButtons(Form<MyFormEnvironmentDto> envform) { AjaxButton addButton = new AjaxButton("addEnvButton") { private static final long serialVersionUID = 2435430716213738894L; @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { addEnvCreation((Form<MyFormEnvironmentDto>) form, target); } @Override protected void onError(AjaxRequestTarget target, Form<?> form) { target.add(form); } @Override protected void updateAjaxAttributes(AjaxRequestAttributes attributes) { attributes.getAjaxCallListeners().add(new BlockUIDecorator(getString("portal.info.env.create"))); } }; envform.add(addButton); // Cancel release add / update button AjaxButton cancelButton = new AjaxButton("cancelEnvButton") { private static final long serialVersionUID = -4353787741035247426L; @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { if (getPage() instanceof SelectedReleasePage) { ((SelectedReleasePage)getPage()).cancelEnvironmentCreation(target); } else { ((EnvironmentsPage)getPage()).cancelEnvironmentCreation(target); } } @Override protected void onError(AjaxRequestTarget target, Form<?> form) { target.add(form); } }; cancelButton.setDefaultFormProcessing(false); envform.add(cancelButton); } public void addEnvCreation(Form<MyFormEnvironmentDto> form, AjaxRequestTarget target) { PageParameters params = new PageParameters(); MyFormEnvironmentDto env = form.getModelObject(); params.set("appUid", env.getRelease().getApplication().getUID()); params.set("releaseUid", env.getRelease().getUID()); try { String configRoleUID = createConfigRole(env.getRelease().getApplication().getUID(), env.getLabel()); String envUid; if (configRoleUID != null) { envUid = manageEnvironment.createEnvironment(env.release.getUID(), env.type, paasUser.getSsoId().getValue() , env.label, Arrays.asList(configRoleUID)); } else { envUid = manageEnvironment.createEnvironment(env.release.getUID(), env.type, paasUser.getSsoId().getValue() , env.label); } params.set("envUid", envUid); } catch (BusinessException e) { FeedbackPanel globalFeedback = ((DesignerHelperPage) this.findPage()).getFeedbackPanel(); BusinessExceptionHandler handler = new BusinessExceptionHandler(globalFeedback); handler.error(e); target.add(globalFeedback); return; } String successMsg = getString("portal.environment.creation.successful", new Model<Object[]>(new Object[]{env.getLabel(), env.getRelease().getApplication().getLabel()+" - "+env.getRelease().getReleaseVersion()})); Session.get().info(successMsg); setResponsePage(SelectedEnvironmentPage.class, params); } @Override protected void onInitialize() { super.onInitialize(); initComponents(); envForm.visitChildren(FormComponent.class, new IVisitor<Component, Void>() { @Override public void component(Component object, IVisit<Void> visit) { object.add(new FieldFeedbackDecorator()); visit.dontGoDeeper(); } }); } class MyFormEnvironmentDto implements Serializable { private static final long serialVersionUID = 5874638410811831883L; @NotNull private ApplicationRelease release; @NotNull private String label; @NotNull private EnvironmentDto.EnvironmentTypeEnum type; MyFormEnvironmentDto() { } public ApplicationRelease getRelease() { return release; } public void setRelease(ApplicationRelease release) { this.release = release; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public EnvironmentDto.EnvironmentTypeEnum getType() { return type; } public void setType(EnvironmentDto.EnvironmentTypeEnum type) { this.type = type; } } public void addEnvironmentConfigOverride(LogicalConfigService logicalConfigOverride) { configOverrides.put(logicalConfigOverride.getLabel(), logicalConfigOverride); } public LogicalConfigService getEnvironmentConfigOverride(String label) { return configOverrides.get(label); } private String createConfigRole(String applicationUID, String envName) throws InvalidConfigServiceException, ApplicationNotFoundException, InvalidConfigOverrideException { if (logger.isDebugEnabled()) { logger.debug("create config role for env " + envName); } if (configOverrides.size() == 0) { return null; } if (overridePropsCheckbox.getModelObject().equals(Boolean.FALSE)) { return null; } LogicalConfigServiceUtils util = new LogicalConfigServiceUtils(); List<ConfigOverrideDTO> configOverrideDTOs = new ArrayList<>(); for (LogicalConfigService configService : configOverrides.values()) { StructuredLogicalConfigServiceContent content = util.parseConfigContent(configService.getConfigSetContent()); for (ConfigEntry configEntry : content.getConfigEntries()) { ConfigOverrideDTO configOverrideDTO = new ConfigOverrideDTO(); configOverrideDTO.setComment(configEntry.getComment()); configOverrideDTO.setConfigSet(configService.getLabel()); configOverrideDTO.setKey(configEntry.getKey()); configOverrideDTO.setValue(configEntry.getValue()); configOverrideDTOs.add(configOverrideDTO); } } if (logger.isDebugEnabled()) { logger.debug("create config role with overriden values " + configOverrideDTOs); } return manageApplication.createConfigRole(applicationUID, "implicit role for env " + envName, configOverrideDTOs); } }