Commit 8e666886 authored by Gianluca Filippone's avatar Gianluca Filippone
Browse files

[CRV-291] Provided EE selection from console and adapted REST interface for...

[CRV-291] Provided EE selection from console and adapted REST interface for create and enact methods
parent 353a3c53
......@@ -35,16 +35,19 @@ import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.syncope.client.console.wizards.WizardMgtPanel;
import org.apache.syncope.client.console.wizards.any.AnyWrapper;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.SchemaType;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.springframework.util.ReflectionUtils;
......@@ -53,7 +56,7 @@ public class ChoreographyDirectoryPanel extends GroupDirectoryPanel {
private static final long serialVersionUID = 3727444742501082182L;
private final ChoreographyRestClient choreographyRestClient;
private final ChoreographyRestClient choreographyRestClient;
public ChoreographyDirectoryPanel(final String id, final PageReference pageRef) {
super(id, new Builder(AnyTypeKind.GROUP.name(), pageRef), false);
......@@ -61,7 +64,18 @@ public class ChoreographyDirectoryPanel extends GroupDirectoryPanel {
choreographyRestClient = new ChoreographyRestClient();
utilityModal.addSubmitButton();
utilityModal.size(Modal.Size.Small);
utilityModal.size(Modal.Size.Medium);
utilityModal.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
private static final long serialVersionUID = 8804221891699487139L;
@Override
public void onClose(final AjaxRequestTarget target) {
target.add(container);
utilityModal.show(false);
}
});
}
@Override
......@@ -122,18 +136,6 @@ public class ChoreographyDirectoryPanel extends GroupDirectoryPanel {
String chorStatus = model.getObject().getPlainAttrMap().get("status").getValues().iterator().next();
ChoreographyActionsPanel choreographyActionsPanel = new ChoreographyActionsPanel(componentId);
choreographyActionsPanel.addAction(new IndicatingAjaxLink<Void>("link") {
private static final long serialVersionUID = 3104631231085231035L;
@Override
public void onClick(final AjaxRequestTarget target) {
PageParameters param = new PageParameters();
param.add("chor", model.getObject().getKey());
setResponsePage(ChoreographyDetailPage.class, param);
}
}, ChoreographyActionsPanel.ChoreographyActionType.SHOW);
if (chorStatus.equals("PENDING CREATE") || chorStatus.equals("PENDING UPDATE")) {
choreographyActionsPanel.addAction(new IndicatingAjaxLink<Void>("link") {
......@@ -141,14 +143,27 @@ public class ChoreographyDirectoryPanel extends GroupDirectoryPanel {
@Override
public void onClick(final AjaxRequestTarget target) {
try {
choreographyRestClient.enactChoreography(model.getObject().getKey());
String eeKey = choreographyRestClient
.getChoreographyEE(model.getObject().getKey()).getKey();
choreographyRestClient.enactChoreography(model.getObject().getKey(), eeKey);
SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
target.add(container);
} catch (SyncopeClientException e) {
LOG.error("While enacting choreography {}", model.getObject().getName(), e);
SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
? e.getClass().getName() : e.getMessage());
if (e.getType().equals(ClientExceptionType.NotFound)) {
utilityModal.setContent(new SelectEEModalPanel(
utilityModal,
model.getObject(),
pageRef));
utilityModal.header(Model.of("Select Enactment Engine"));
utilityModal.show(true);
target.add(utilityModal);
} else {
LOG.error("While enacting choreography {}", model.getObject().getName(), e);
SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
? e.getClass().getName() : e.getMessage());
}
}
((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
}
......@@ -263,6 +278,17 @@ public class ChoreographyDirectoryPanel extends GroupDirectoryPanel {
if (!chorStatus.equals("PENDING DELETE")) {
choreographyActionsPanel.addAction(new IndicatingAjaxLink<Void>("link") {
private static final long serialVersionUID = 3104631231085231035L;
@Override
public void onClick(final AjaxRequestTarget target) {
PageParameters param = new PageParameters();
param.add("chor", model.getObject().getKey());
setResponsePage(ChoreographyDetailPage.class, param);
}
}, ChoreographyActionsPanel.ChoreographyActionType.SHOW);
choreographyActionsPanel.addAction(new IndicatingAjaxLink<Void>("link") {
private static final long serialVersionUID = -7978723352517770644L;
@Override
......
/*
* Copyright 2017 The CHOReVOLUTION project.
*
* 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 org.apache.syncope.client.console.panels;
import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.select.BootstrapSelect;
import java.io.Serializable;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.commons.Constants;
import org.apache.syncope.client.console.pages.BasePage;
import org.apache.syncope.client.console.rest.AnyObjectRestClient;
import org.apache.syncope.client.console.rest.ChoreographyRestClient;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.search.AnyObjectFiqlSearchConditionBuilder;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.model.IModel;
public class SelectEEModalPanel extends AbstractModalPanel<Serializable> {
private static final long serialVersionUID = -1656302837627844520L;
private final ChoreographyRestClient choreographyRestClient;
private final GroupTO choreography;
private final DropDownChoice<AnyObjectTO> enactmentEngineSelect;
public SelectEEModalPanel(
final BaseModal<Serializable> modal,
final GroupTO choreography,
final PageReference pageRef) {
super(modal, pageRef);
this.choreography = choreography;
this.choreographyRestClient = new ChoreographyRestClient();
final WebMarkupContainer container = new WebMarkupContainer("container");
container.setOutputMarkupId(true);
add(container);
final Form<String> form = new Form<>("selectEEForm");
form.setMarkupId("selectEEForm");
form.setOutputMarkupId(true);
container.add(form);
this.enactmentEngineSelect = new EnactmentEngineDropdown("eeSelect");
form.add(enactmentEngineSelect);
}
@Override
public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
try {
AnyObjectTO selectedEE = enactmentEngineSelect.getModel().getObject();
if (selectedEE != null) {
choreographyRestClient.enactChoreography(choreography.getKey(), selectedEE.getKey());
modal.close(target);
SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
} else {
SyncopeConsoleSession.get()
.error("No Enactment Engine selected for choreography " + choreography.getName());
}
} catch (SyncopeClientException e) {
LOG.error("While enacting choreography {}", choreography.getName(), e);
SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
? e.getClass().getName() : e.getMessage());
}
((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
}
private class EnactmentEngineDropdown extends BootstrapSelect<AnyObjectTO> {
private static final long serialVersionUID = -5192516768556628105L;
private AnyObjectTO enactmentEngine;
private class EnactmentEngineRenderer extends ChoiceRenderer<AnyObjectTO> {
private static final long serialVersionUID = -5883415718568173146L;
@Override
public String getDisplayValue(final AnyObjectTO object) {
return object.getName();
}
}
EnactmentEngineDropdown(final String id) {
super(id);
AnyObjectRestClient anyObjectRestClient = new AnyObjectRestClient();
List<AnyObjectTO> enactmentEngines = anyObjectRestClient.search(
SyncopeConstants.ROOT_REALM,
new AnyObjectFiqlSearchConditionBuilder("ENACTMENT ENGINE").query(),
1,
1,
new SortParam<>("name", false),
"ENACTMENT ENGINE");
setChoiceRenderer(new EnactmentEngineRenderer());
setChoices(enactmentEngines);
setModel(new IModel<AnyObjectTO>() {
private static final long serialVersionUID = 8125687269026843312L;
@Override
public AnyObjectTO getObject() {
return enactmentEngine;
}
@Override
public void setObject(final AnyObjectTO object) {
enactmentEngine = object;
}
@Override
public void detach() {
// Empty
}
});
}
}
}
......@@ -33,8 +33,8 @@ public class ChoreographyRestClient extends BaseRestClient {
getService(ChoreographyService.class).delete(choreographyKey);
}
public void enactChoreography(final String choregographyKey) {
getService(ChoreographyService.class).enact(choregographyKey);
public void enactChoreography(final String choregographyKey, final String enactmentEngineKey) {
getService(ChoreographyService.class).enact(choregographyKey, enactmentEngineKey);
}
public void startChoreography(final String choreographyKey) {
......
<!DOCTYPE html>
<!--
Copyright 2017 The CHOReVOLUTION project.
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.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
<span wicket:id="container">
<div class="form-group">
<form wicket:id="selectEEForm">
<fieldset class="form-group">
<select wicket:id="eeSelect"/>
</fieldset>
</form>
</div>
</span>
</wicket:panel>
</html>
......@@ -276,12 +276,12 @@ public class ChoreographyLogic extends AbstractLogic<AbstractBaseBean> {
}
@PreAuthorize("hasRole('" + ChorevolutionEntitlement.CHOREOGRAPHY_CREATE + "')")
public String create(final String name, final String enactmentEngineKey, final InputStream chorSpec) {
AnyObjectTO enactmentEngine = enactmentEngineExists(enactmentEngineKey);
public String create(final String name, final InputStream chorSpec) {
//AnyObjectTO enactmentEngine = enactmentEngineExists(enactmentEngineKey);
GroupTO choreography = new GroupTO();
try {
// 1. create the choreography group
// create the choreography group
choreography.setName(name);
choreography.setRealm(SyncopeConstants.ROOT_REALM);
choreography.getAuxClasses().add("Choreography");
......@@ -298,11 +298,6 @@ public class ChoreographyLogic extends AbstractLogic<AbstractBaseBean> {
choreography = groupLogic.create(choreography, false).getEntity();
// 2. set the membership with the given enactment engine
AnyObjectPatch eePatch = new AnyObjectPatch();
eePatch.setKey(enactmentEngine.getKey());
eePatch.getMemberships().add(new MembershipPatch.Builder().group(choreography.getKey()).build());
anyObjectLogic.update(eePatch, false);
} catch (Exception e) {
throw new RuntimeException("While creating " + name, e);
}
......@@ -395,10 +390,27 @@ public class ChoreographyLogic extends AbstractLogic<AbstractBaseBean> {
}
@PreAuthorize("hasRole('" + ChorevolutionEntitlement.CHOREOGRAPHY_ENACT + "')")
public void enact(final String key) {
public void enact(final String key, final String enactmentEngineKey) {
GroupTO choreography = groupLogic.read(key);
AnyObjectTO enactmentEngine = enactmentEngineForChoreography(choreography.getKey());
// Enactment Engine selection
AnyObjectTO enactmentEngine;
try {
// If already defined, select the enactment engine for the choreography
enactmentEngine = enactmentEngineForChoreography(choreography.getKey());
} catch (NotFoundException e) {
try {
// If the EE was not already selected, search for the enactment engine and set the relationship
enactmentEngine = enactmentEngineExists(enactmentEngineKey);
AnyObjectPatch eePatch = new AnyObjectPatch();
eePatch.setKey(enactmentEngine.getKey());
eePatch.getMemberships().add(new MembershipPatch.Builder().group(choreography.getKey()).build());
anyObjectLogic.update(eePatch, false);
} catch (Exception ex) {
throw new RuntimeException("While enacting choreography " + choreography.getKey(), ex);
}
}
Map<String, AttrTO> choreographyAttrs = choreography.getPlainAttrMap();
try {
InputStream chorSpec = new ByteArrayInputStream(
......
......@@ -51,13 +51,12 @@ public interface ChoreographyService extends JAXRSService {
@Path("{key}")
@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
ChoreographyTO read(@PathParam("key") String choreographyKey);
ChoreographyTO read(@NotNull @PathParam("key") String choreographyKey);
/**
* Creates a choreography.
*
* @param name choreography name
* @param enactmentEngineKey target enactment engine instance
* @param chorSpec ChorSpec XML representation
* @return Response object featuring Location header of created choreography
*/
......@@ -65,7 +64,6 @@ public interface ChoreographyService extends JAXRSService {
@Consumes({ MediaType.APPLICATION_XML })
Response create(
@NotNull @QueryParam("name") String name,
@NotNull @QueryParam("enactmentEngineKey") String enactmentEngineKey,
InputStream chorSpec);
/**
......@@ -96,10 +94,13 @@ public interface ChoreographyService extends JAXRSService {
* Request to enact the given choreography, onto the associated Enactment Engine.
*
* @param key choreography key
* @param enactmentEngineKey target enactment engine instance (ignored if it has been already specified)
*/
@POST
@Path("{key}/enact")
void enact(@NotNull @PathParam("key") String key);
void enact(
@NotNull @PathParam("key") String key,
@NotNull @QueryParam("enactmentEngineKey") String enactmentEngineKey);
/**
* This operation will used to notify that an enactment operation was completed, providing the
......
......@@ -37,8 +37,8 @@ public class ChoreographyServiceImpl extends AbstractServiceImpl implements Chor
private ChoreographyLogic logic;
@Override
public Response create(final String name, final String enactmentEngineKey, final InputStream chorSpec) {
String key = logic.create(name, enactmentEngineKey, chorSpec);
public Response create(final String name, final InputStream chorSpec) {
String key = logic.create(name, chorSpec);
return Response.
created(uriInfo.getAbsolutePathBuilder().path(key).build()).
header(RESTHeaders.RESOURCE_KEY, key).
......@@ -61,8 +61,8 @@ public class ChoreographyServiceImpl extends AbstractServiceImpl implements Chor
}
@Override
public void enact(final String key) {
logic.enact(key);
public void enact(final String key, final String enactmentEngineKey) {
logic.enact(key, enactmentEngineKey);
}
@Override
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment