You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2020/01/09 10:46:21 UTC
[syncope] 02/03: [SYNCOPE-1531] Improvements: Swagger docs +
propagation actions for CSV export + result page in Admin Console for CSV
import
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
commit 18d84af51dee57f4636ddca65dcdf33b4b7e29f5
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Wed Jan 8 17:17:38 2020 +0100
[SYNCOPE-1531] Improvements: Swagger docs + propagation actions for CSV export + result page in Admin Console for CSV import
---
...AnyDirectoryPanelAdditionalActionsProvider.java | 42 +++++--
.../client/console/panels/CSVConfPanel.java | 7 +-
.../console/rest/ReconciliationRestClient.java | 8 +-
.../console/wizards/CSVPullWizardBuilder.java | 21 ++--
.../console/wizards/CSVPushWizardBuilder.java | 28 ++++-
.../wizards/any/LinkedAccountPlainAttrsPanel.java | 3 +-
.../wizards/any/ProvisioningReportsPanel.java | 95 +++++++++++++++
.../wizards/CSVPullWizardBuilder$PullTask.html | 2 +-
.../CSVPullWizardBuilder$PullTask.properties | 2 +-
.../CSVPullWizardBuilder$PullTask_fr_CA.properties | 2 +-
.../CSVPullWizardBuilder$PullTask_it.properties | 2 +-
.../CSVPullWizardBuilder$PullTask_ja.properties | 2 +-
.../CSVPullWizardBuilder$PullTask_pt_BR.properties | 2 +-
.../CSVPullWizardBuilder$PullTask_ru.properties | 2 +-
.../wizards/CSVPushWizardBuilder$PushTask.html | 3 +-
.../CSVPushWizardBuilder$PushTask.properties | 3 +-
.../CSVPushWizardBuilder$PushTask_fr_CA.properties | 3 +-
.../CSVPushWizardBuilder$PushTask_it.properties | 3 +-
.../CSVPushWizardBuilder$PushTask_ja.properties | 3 +-
.../CSVPushWizardBuilder$PushTask_pt_BR.properties | 3 +-
.../CSVPushWizardBuilder$PushTask_ru.properties | 3 +-
.../ProvisioningReportsPanel.html} | 11 +-
.../ProvisioningReportsPanel.properties} | 8 +-
.../ProvisioningReportsPanel_fr_CA.properties} | 8 +-
.../ProvisioningReportsPanel_it.properties} | 8 +-
.../ProvisioningReportsPanel_ja.properties} | 8 +-
.../ProvisioningReportsPanel_pt_BR.properties} | 8 +-
.../ProvisioningReportsPanel_ru.properties} | 8 +-
.../syncope/client/ui/commons/BaseLogin.java | 3 +-
.../console/audit/AuditHistoryDirectoryPanel.java | 3 +-
.../client/console/panels/AnyDirectoryPanel.java | 3 +-
.../client/console/panels/ConsoleLogPanel.java | 6 +-
.../markup/html/form/AjaxCharacterFieldPanel.java | 3 +-
.../wizards/any/AbstractAttrsWizardStep.java | 5 +-
.../syncope/common/lib/to/ProvisioningReport.java | 15 ++-
.../common/rest/api/beans/AbstractCSVSpec.java | 70 ++++++++---
.../syncope/common/rest/api/beans/CSVPushSpec.java | 16 +++
.../syncope/common/rest/api/beans/ReconQuery.java | 3 +-
.../syncope/common/rest/api/beans/ExecQuery.java | 1 -
.../common/rest/api/beans/ExecuteQuery.java | 1 -
.../common/rest/api/service/JAXRSService.java | 2 +
.../syncope/core/logic/ReconciliationLogic.java | 69 +++++------
.../core/logic/ReconciliationLogicTest.java | 12 +-
.../api/jexl/SyncopeJexlFunctions.java | 1 -
.../pushpull/stream/SyncopeStreamPullExecutor.java | 3 +-
.../pushpull/stream/SyncopeStreamPushExecutor.java | 4 +-
.../provisioning/api/IntAttrNameParserTest.java | 7 +-
core/provisioning-java/pom.xml | 5 +
.../java/pushpull/OutboundMatcher.java | 5 +-
.../java/pushpull/stream/CSVStreamConnector.java} | 132 +++++++++++++++------
.../pushpull/stream/StreamPullJobDelegate.java | 4 +-
.../pushpull/stream/StreamPushJobDelegate.java | 30 +++--
.../core/provisioning/java/utils/MappingUtils.java | 3 +-
.../java/pushpull/LDAPPasswordPullActionsTest.java | 33 +++---
.../pushpull/stream/StreamPullJobDelegateTest.java | 58 +++++----
.../pushpull/stream/StreamPushJobDelegateTest.java | 36 +++---
core/spring/pom.xml | 9 +-
.../client/console/rest/BpmnProcessRestClient.java | 5 +-
.../syncope/core/logic/saml2/SAML2UserManager.java | 3 +-
.../org/apache/syncope/fit/console/LogsITCase.java | 5 +-
.../syncope/fit/core/ReconciliationITCase.java | 13 +-
61 files changed, 567 insertions(+), 299 deletions(-)
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionsProvider.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionsProvider.java
index c6abd9d..b091655 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionsProvider.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionsProvider.java
@@ -18,6 +18,8 @@
*/
package org.apache.syncope.client.console.commons;
+import java.io.Serializable;
+import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.syncope.client.console.PreferenceManager;
@@ -29,8 +31,11 @@ import org.apache.syncope.client.console.wicket.ajax.form.AjaxDownloadBehavior;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wizards.CSVPullWizardBuilder;
import org.apache.syncope.client.console.wizards.CSVPushWizardBuilder;
+import org.apache.syncope.client.console.wizards.any.ProvisioningReportsPanel;
+import org.apache.syncope.client.console.wizards.any.ResultPage;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
+import org.apache.syncope.common.lib.to.ProvisioningReport;
import org.apache.syncope.common.rest.api.beans.AnyQuery;
import org.apache.syncope.common.rest.api.beans.CSVPullSpec;
import org.apache.syncope.common.rest.api.beans.CSVPushSpec;
@@ -39,6 +44,7 @@ import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.StringResourceModel;
@@ -70,17 +76,39 @@ public class IdMAnyDirectoryPanelAdditionalActionsProvider implements AnyDirecto
modal.close(target);
} else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
AjaxWizard.NewItemFinishEvent<?> payload = (AjaxWizard.NewItemFinishEvent) event.getPayload();
- if (Constants.OPERATION_SUCCEEDED.equals(payload.getResult())) {
- AjaxRequestTarget target = payload.getTarget();
+ AjaxRequestTarget target = payload.getTarget();
+ SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+
+ target.add(container);
+
+ if (payload.getResult() instanceof ArrayList) {
+ modal.setContent(new ResultPage<Serializable>(
+ null,
+ payload.getResult()) {
+
+ private static final long serialVersionUID = -2630573849050255233L;
+
+ @Override
+ protected void closeAction(final AjaxRequestTarget target) {
+ modal.close(target);
+ }
+
+ @Override
+ protected Panel customResultBody(
+ final String id, final Serializable item, final Serializable result) {
+
+ @SuppressWarnings("unchecked")
+ ArrayList<ProvisioningReport> reports = (ArrayList<ProvisioningReport>) result;
+ return new ProvisioningReportsPanel(id, reports, pageRef);
+ }
+ });
+ target.add(modal.getForm());
+ } else if (Constants.OPERATION_SUCCEEDED.equals(payload.getResult())) {
if (csvDownloadBehavior.hasResponse()) {
csvDownloadBehavior.initiate(target);
}
-
- SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
- ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-
- target.add(container);
modal.close(target);
}
}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/CSVConfPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/CSVConfPanel.java
index a5e4f0c..4867673 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/CSVConfPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/CSVConfPanel.java
@@ -18,7 +18,6 @@
*/
package org.apache.syncope.client.console.panels;
-import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -43,21 +42,21 @@ public class CSVConfPanel extends Panel {
AjaxCharacterFieldPanel columnSeparator = new AjaxCharacterFieldPanel(
"columnSeparator", "columnSeparator", new PropertyModel<>(spec, "columnSeparator"));
- columnSeparator.setChoices(Arrays.asList(',', ';', ' '));
+ columnSeparator.setChoices(List.of(',', ';', ' '));
columnSeparator.setRequired(true);
add(columnSeparator);
AjaxTextFieldPanel arrayElementSeparator = new AjaxTextFieldPanel(
"arrayElementSeparator", "arrayElementSeparator",
new PropertyModel<>(spec, "arrayElementSeparator"));
- arrayElementSeparator.setChoices(Arrays.asList(";"));
+ arrayElementSeparator.setChoices(List.of(";"));
arrayElementSeparator.setRequired(true);
arrayElementSeparator.addValidator(new StringValidator(1, 1));
add(arrayElementSeparator);
AjaxCharacterFieldPanel quoteChar = new AjaxCharacterFieldPanel(
"quoteChar", "quoteChar", new PropertyModel<>(spec, "quoteChar"));
- quoteChar.setChoices(Arrays.asList('"'));
+ quoteChar.setChoices(List.of('"'));
quoteChar.setRequired(true);
add(quoteChar);
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ReconciliationRestClient.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ReconciliationRestClient.java
index 3855eb7..a341569 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ReconciliationRestClient.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ReconciliationRestClient.java
@@ -19,7 +19,8 @@
package org.apache.syncope.client.console.rest;
import java.io.InputStream;
-import java.util.List;
+import java.util.ArrayList;
+import java.util.stream.Collectors;
import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.client.Client;
import org.apache.cxf.jaxrs.client.WebClient;
@@ -63,12 +64,13 @@ public class ReconciliationRestClient extends BaseRestClient {
return response;
}
- public static List<ProvisioningReport> pull(final CSVPullSpec spec, final InputStream csv) {
+ public static ArrayList<ProvisioningReport> pull(final CSVPullSpec spec, final InputStream csv) {
ReconciliationService service = getService(ReconciliationService.class);
Client client = WebClient.client(service);
client.type(RESTHeaders.TEXT_CSV);
- List<ProvisioningReport> result = service.pull(spec, csv);
+ ArrayList<ProvisioningReport> result = service.pull(spec, csv).stream().
+ collect(Collectors.toCollection(ArrayList::new));
SyncopeConsoleSession.get().resetClient(ReconciliationService.class);
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder.java
index 1c3a2a2..99fb6b1 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder.java
@@ -21,9 +21,7 @@ package org.apache.syncope.client.console.wizards;
import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.fileinput.BootstrapFileInputField;
import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.fileinput.FileInputConfig;
import java.io.ByteArrayInputStream;
-import java.io.Serializable;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -36,6 +34,7 @@ import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPalettePanel;
import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.common.lib.to.ProvisioningReport;
import org.apache.syncope.common.lib.types.ConflictResolutionAction;
import org.apache.syncope.common.lib.types.IdMImplementationType;
import org.apache.syncope.common.lib.types.MatchingRule;
@@ -102,9 +101,8 @@ public class CSVPullWizardBuilder extends BaseAjaxWizardBuilder<CSVPullSpec> {
}
@Override
- protected Serializable onApplyInternal(final CSVPullSpec modelObject) {
- ReconciliationRestClient.pull(modelObject, new ByteArrayInputStream(csv.getObject()));
- return Constants.OPERATION_SUCCEEDED;
+ protected ArrayList<ProvisioningReport> onApplyInternal(final CSVPullSpec modelObject) {
+ return ReconciliationRestClient.pull(modelObject, new ByteArrayInputStream(csv.getObject()));
}
@Override
@@ -243,23 +241,24 @@ public class CSVPullWizardBuilder extends BaseAjaxWizardBuilder<CSVPullSpec> {
AjaxDropDownChoicePanel<MatchingRule> matchingRule = new AjaxDropDownChoicePanel<>(
"matchingRule", "matchingRule", new PropertyModel<>(spec, "matchingRule"), false);
- matchingRule.setChoices(Arrays.asList(MatchingRule.values()));
+ matchingRule.setChoices(List.of(MatchingRule.values()));
add(matchingRule);
AjaxDropDownChoicePanel<UnmatchingRule> unmatchingRule = new AjaxDropDownChoicePanel<>(
"unmatchingRule", "unmatchingRule", new PropertyModel<>(spec, "unmatchingRule"),
false);
- unmatchingRule.setChoices(Arrays.asList(UnmatchingRule.values()));
+ unmatchingRule.setChoices(List.of(UnmatchingRule.values()));
add(unmatchingRule);
- AjaxPalettePanel<String> actions = new AjaxPalettePanel.Builder<String>().
- build("actions", new PropertyModel<>(spec, "actions"), new ListModel<>(pullActions.getObject()));
- add(actions);
+ AjaxPalettePanel<String> provisioningActions =
+ new AjaxPalettePanel.Builder<String>().build("provisioningActions",
+ new PropertyModel<>(spec, "provisioningActions"), new ListModel<>(pullActions.getObject()));
+ add(provisioningActions);
AjaxDropDownChoicePanel<ConflictResolutionAction> conflictResolutionAction = new AjaxDropDownChoicePanel<>(
"conflictResolutionAction", "conflictResolutionAction",
new PropertyModel<>(spec, "conflictResolutionAction"), false);
- conflictResolutionAction.setChoices(Arrays.asList(ConflictResolutionAction.values()));
+ conflictResolutionAction.setChoices(List.of(ConflictResolutionAction.values()));
conflictResolutionAction.setRequired(true);
add(conflictResolutionAction);
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder.java
index 1f2911d..ee2af97 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder.java
@@ -19,7 +19,6 @@
package org.apache.syncope.client.console.wizards;
import java.io.Serializable;
-import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.syncope.client.console.panels.CSVConfPanel;
@@ -98,6 +97,17 @@ public class CSVPushWizardBuilder extends BaseAjaxWizardBuilder<CSVPushSpec> {
private final ImplementationRestClient implRestClient = new ImplementationRestClient();
+ private final IModel<List<String>> propActions = new LoadableDetachableModel<List<String>>() {
+
+ private static final long serialVersionUID = 4659376149825914247L;
+
+ @Override
+ protected List<String> load() {
+ return implRestClient.list(IdMImplementationType.PROPAGATION_ACTIONS).stream().
+ map(EntityTO::getKey).sorted().collect(Collectors.toList());
+ }
+ };
+
private final IModel<List<String>> pushActions = new LoadableDetachableModel<List<String>>() {
private static final long serialVersionUID = 4659376149825914247L;
@@ -114,20 +124,26 @@ public class CSVPushWizardBuilder extends BaseAjaxWizardBuilder<CSVPushSpec> {
"ignorePaging", "ignorePaging", new PropertyModel<>(spec, "ignorePaging"), true);
add(ignorePaging);
+ AjaxPalettePanel<String> propagationActions =
+ new AjaxPalettePanel.Builder<String>().build("propagationActions",
+ new PropertyModel<>(spec, "propagationActions"), new ListModel<>(propActions.getObject()));
+ add(propagationActions);
+
AjaxDropDownChoicePanel<MatchingRule> matchingRule = new AjaxDropDownChoicePanel<>(
"matchingRule", "matchingRule", new PropertyModel<>(spec, "matchingRule"), false);
- matchingRule.setChoices(Arrays.asList(MatchingRule.values()));
+ matchingRule.setChoices(List.of(MatchingRule.values()));
add(matchingRule);
AjaxDropDownChoicePanel<UnmatchingRule> unmatchingRule = new AjaxDropDownChoicePanel<>(
"unmatchingRule", "unmatchingRule", new PropertyModel<>(spec, "unmatchingRule"),
false);
- unmatchingRule.setChoices(Arrays.asList(UnmatchingRule.values()));
+ unmatchingRule.setChoices(List.of(UnmatchingRule.values()));
add(unmatchingRule);
- AjaxPalettePanel<String> actions = new AjaxPalettePanel.Builder<String>().
- build("actions", new PropertyModel<>(spec, "actions"), new ListModel<>(pushActions.getObject()));
- add(actions);
+ AjaxPalettePanel<String> provisioningActions =
+ new AjaxPalettePanel.Builder<String>().build("provisioningActions",
+ new PropertyModel<>(spec, "provisioningActions"), new ListModel<>(pushActions.getObject()));
+ add(provisioningActions);
}
}
}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
index edfbed7..3346de8 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
@@ -22,7 +22,6 @@ import org.apache.syncope.client.ui.commons.wizards.any.EntityWrapper;
import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggle;
import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggleConfig;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -80,7 +79,7 @@ public class LinkedAccountPlainAttrsPanel extends AbstractAttrsWizardStep<PlainS
super(userTO,
AjaxWizard.Mode.EDIT,
new AnyTypeRestClient().read(userTO.getType()).getClasses(),
- AnyLayoutUtils.fetch(Arrays.asList(userTO.getType())).getUser().getWhichPlainAttrs(),
+ AnyLayoutUtils.fetch(List.of(userTO.getType())).getUser().getWhichPlainAttrs(),
modelObject);
this.linkedAccountTO = modelObject.getInnerObject();
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel.java
new file mode 100644
index 0000000..264bb3f
--- /dev/null
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.wizards.any;
+
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.syncope.client.console.panels.ListViewPanel;
+import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion;
+import org.apache.syncope.common.lib.to.ProvisioningReport;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.Model;
+
+public class ProvisioningReportsPanel extends Panel {
+
+ private static final long serialVersionUID = -1450755344104125918L;
+
+ public ProvisioningReportsPanel(
+ final String id, final List<ProvisioningReport> results, final PageReference pageRef) {
+ super(id);
+
+ List<ProvisioningReport> success = results.stream().
+ filter(result -> result.getStatus() == ProvisioningReport.Status.SUCCESS).
+ collect(Collectors.toList());
+ add(new Accordion("success", List.of(new AbstractTab(
+ new Model<>(MessageFormat.format(getString("success"), success.size()))) {
+
+ private static final long serialVersionUID = 1037272333056449378L;
+
+ @Override
+ public WebMarkupContainer getPanel(final String panelId) {
+ return new ListViewPanel.Builder<>(ProvisioningReport.class, pageRef).
+ setItems(success).
+ withChecks(ListViewPanel.CheckAvailability.NONE).
+ includes("name", "message").
+ build(panelId);
+ }
+ }), Model.of(-1)).setOutputMarkupId(true));
+
+ List<ProvisioningReport> failure = results.stream().
+ filter(result -> result.getStatus() == ProvisioningReport.Status.FAILURE).
+ collect(Collectors.toList());
+ add(new Accordion("failure", List.of(new AbstractTab(
+ new Model<>(MessageFormat.format(getString("failure"), failure.size()))) {
+
+ private static final long serialVersionUID = 1037272333056449378L;
+
+ @Override
+ public WebMarkupContainer getPanel(final String panelId) {
+ return new ListViewPanel.Builder<>(ProvisioningReport.class, pageRef).
+ setItems(failure).
+ withChecks(ListViewPanel.CheckAvailability.NONE).
+ includes("name", "message").
+ build(panelId);
+ }
+ }), Model.of(-1)).setOutputMarkupId(true));
+
+ List<ProvisioningReport> ignore = results.stream().
+ filter(result -> result.getStatus() == ProvisioningReport.Status.IGNORE).
+ collect(Collectors.toList());
+ add(new Accordion("ignore", List.of(new AbstractTab(
+ new Model<>(MessageFormat.format(getString("ignore"), ignore.size()))) {
+
+ private static final long serialVersionUID = 1037272333056449378L;
+
+ @Override
+ public WebMarkupContainer getPanel(final String panelId) {
+ return new ListViewPanel.Builder<>(ProvisioningReport.class, pageRef).
+ setItems(ignore).
+ withChecks(ListViewPanel.CheckAvailability.NONE).
+ includes("name", "message").
+ build(panelId);
+ }
+ }), Model.of(-1)).setOutputMarkupId(true));
+ }
+}
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask.html b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask.html
index 761b1f4..aab535e 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask.html
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask.html
@@ -22,7 +22,7 @@ under the License.
<div wicket:id="remediation">[remediation]</div>
<div wicket:id="matchingRule">[matchingRule]</div>
<div wicket:id="unmatchingRule">[unmatchingRule]</div>
- <div wicket:id="actions">[actions]</div>
+ <div wicket:id="provisioningActions">[provisioningActions]</div>
</div>
<div class="form-group">
<div wicket:id="conflictResolutionAction">[conflictResolutionAction]</div>
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask.properties
index 5527723..eed190d 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask.properties
@@ -17,6 +17,6 @@
remediation=Remediation
matchingRule=Matching rule
unmatchingRule=Unmatching rule
-actions=Actions
+provisioningActions=Pull Actions
conflictResolutionAction=Conflict resolution action
pullCorrelationRule=Correlation rule
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_fr_CA.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_fr_CA.properties
index c5e744a..fe255e2 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_fr_CA.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_fr_CA.properties
@@ -17,6 +17,6 @@
remediation=Remediation
matchingRule=R\u00e8gle de correspondance
unmatchingRule=R\u00e8gle in\u00e9gal\u00e9e
-actions=Actions
+provisioningActions=Actions de pull
conflictResolutionAction=Action de r\u00e9solution de conflits
pullCorrelationRule=R\u00e8gle de corr\u00e9lation
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_it.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_it.properties
index 02ad161..fddd717 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_it.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_it.properties
@@ -17,6 +17,6 @@
remediation=Bonifiche
matchingRule=Regola di matrching
unmatchingRule=Regola di unmatching
-actions=Azioni
+provisioningActions=Azioni di pull
conflictResolutionAction=Azione di Risoluzione Conflitti
pullCorrelationRule=Regola di Correlazione
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_ja.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_ja.properties
index 5527723..eed190d 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_ja.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_ja.properties
@@ -17,6 +17,6 @@
remediation=Remediation
matchingRule=Matching rule
unmatchingRule=Unmatching rule
-actions=Actions
+provisioningActions=Pull Actions
conflictResolutionAction=Conflict resolution action
pullCorrelationRule=Correlation rule
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_pt_BR.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_pt_BR.properties
index 5527723..eed190d 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_pt_BR.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_pt_BR.properties
@@ -17,6 +17,6 @@
remediation=Remediation
matchingRule=Matching rule
unmatchingRule=Unmatching rule
-actions=Actions
+provisioningActions=Pull Actions
conflictResolutionAction=Conflict resolution action
pullCorrelationRule=Correlation rule
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_ru.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_ru.properties
index 5527723..eed190d 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_ru.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPullWizardBuilder$PullTask_ru.properties
@@ -17,6 +17,6 @@
remediation=Remediation
matchingRule=Matching rule
unmatchingRule=Unmatching rule
-actions=Actions
+provisioningActions=Pull Actions
conflictResolutionAction=Conflict resolution action
pullCorrelationRule=Correlation rule
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.html b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.html
index 3773882..13dab03 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.html
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.html
@@ -20,11 +20,12 @@ under the License.
<wicket:panel>
<div class="form-group">
<div wicket:id="ignorePaging">[ignorePaging]</div>
+ <div wicket:id="propagationActions">[propagationActions]</div>
</div>
<div class="form-group">
<div wicket:id="matchingRule">[matchingRule]</div>
<div wicket:id="unmatchingRule">[unmatchingRule]</div>
- <div wicket:id="actions">[actions]</div>
+ <div wicket:id="provisioningActions">[provisioningActions]</div>
</div>
</wicket:panel>
</html>
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
index f269211..fa1b12b 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
@@ -16,5 +16,6 @@
# under the License.
matchingRule=Matching rule
unmatchingRule=Unmatching rule
-actions=Actions
+provisioningActions=Push Actions
ignorePaging=Include all pages?
+propagationActions=Propagation Actions
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_fr_CA.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_fr_CA.properties
index 68e7e24..4ae6771 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_fr_CA.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_fr_CA.properties
@@ -16,5 +16,6 @@
# under the License.
matchingRule=R\u00e8gle de correspondance
unmatchingRule=R\u00e8gle in\u00e9gal\u00e9e
-actions=Actions
+provisioningActions=Actions de push
ignorePaging=Inclure toutes les pages?
+propagationActions=Actions de propagation
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_it.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_it.properties
index 6dfeb3d..c26816b 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_it.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_it.properties
@@ -16,5 +16,6 @@
# under the License.
matchingRule=Regola di matrching
unmatchingRule=Regola di unmatching
-actions=Azioni
+provisioningActions=Azioni di push
ignorePaging=Includere tutte le pagine?
+propagationActions=Azioni di propagazione
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_ja.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_ja.properties
index f269211..fa1b12b 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_ja.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_ja.properties
@@ -16,5 +16,6 @@
# under the License.
matchingRule=Matching rule
unmatchingRule=Unmatching rule
-actions=Actions
+provisioningActions=Push Actions
ignorePaging=Include all pages?
+propagationActions=Propagation Actions
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_pt_BR.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_pt_BR.properties
index f269211..fa1b12b 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_pt_BR.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_pt_BR.properties
@@ -16,5 +16,6 @@
# under the License.
matchingRule=Matching rule
unmatchingRule=Unmatching rule
-actions=Actions
+provisioningActions=Push Actions
ignorePaging=Include all pages?
+propagationActions=Propagation Actions
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_ru.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_ru.properties
index f269211..fa1b12b 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_ru.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask_ru.properties
@@ -16,5 +16,6 @@
# under the License.
matchingRule=Matching rule
unmatchingRule=Unmatching rule
-actions=Actions
+provisioningActions=Push Actions
ignorePaging=Include all pages?
+propagationActions=Propagation Actions
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.html b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel.html
similarity index 74%
copy from client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.html
copy to client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel.html
index 3773882..79d6373 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.html
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel.html
@@ -18,13 +18,8 @@ under the License.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
- <div class="form-group">
- <div wicket:id="ignorePaging">[ignorePaging]</div>
- </div>
- <div class="form-group">
- <div wicket:id="matchingRule">[matchingRule]</div>
- <div wicket:id="unmatchingRule">[unmatchingRule]</div>
- <div wicket:id="actions">[actions]</div>
- </div>
+ <div wicket:id="success"/>
+ <div wicket:id="failure"/>
+ <div wicket:id="ignore"/>
</wicket:panel>
</html>
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel.properties
similarity index 87%
copy from client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
copy to client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel.properties
index f269211..709310c 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-matchingRule=Matching rule
-unmatchingRule=Unmatching rule
-actions=Actions
-ignorePaging=Include all pages?
+success=Successfully imported: {0}
+failure=Failed to import: {0}
+ignore=Ignored during import: {0}
+message=Message
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_fr_CA.properties
similarity index 84%
copy from client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
copy to client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_fr_CA.properties
index f269211..b1800a6 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_fr_CA.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-matchingRule=Matching rule
-unmatchingRule=Unmatching rule
-actions=Actions
-ignorePaging=Include all pages?
+success=Import\u00e9 avec succ\u00e8s: {0}
+failure=\u00c9chec de l''importation: {0}
+ignore=Ignor\u00e9 lors de l''importationt: {0}
+message=Message
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_it.properties
similarity index 85%
copy from client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
copy to client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_it.properties
index f269211..2888724 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_it.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-matchingRule=Matching rule
-unmatchingRule=Unmatching rule
-actions=Actions
-ignorePaging=Include all pages?
+success=Importati con successo: {0}
+failure=Errori nell''importazione: {0}
+ignore=Ignorati dall''importazione: {0}
+message=Messaggio
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_ja.properties
similarity index 87%
copy from client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
copy to client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_ja.properties
index f269211..709310c 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_ja.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-matchingRule=Matching rule
-unmatchingRule=Unmatching rule
-actions=Actions
-ignorePaging=Include all pages?
+success=Successfully imported: {0}
+failure=Failed to import: {0}
+ignore=Ignored during import: {0}
+message=Message
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_pt_BR.properties
similarity index 87%
copy from client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
copy to client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_pt_BR.properties
index f269211..709310c 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_pt_BR.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-matchingRule=Matching rule
-unmatchingRule=Unmatching rule
-actions=Actions
-ignorePaging=Include all pages?
+success=Successfully imported: {0}
+failure=Failed to import: {0}
+ignore=Ignored during import: {0}
+message=Message
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_ru.properties
similarity index 87%
copy from client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
copy to client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_ru.properties
index f269211..709310c 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/CSVPushWizardBuilder$PushTask.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/wizards/any/ProvisioningReportsPanel_ru.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-matchingRule=Matching rule
-unmatchingRule=Unmatching rule
-actions=Actions
-ignorePaging=Include all pages?
+success=Successfully imported: {0}
+failure=Failed to import: {0}
+ignore=Ignored during import: {0}
+message=Message
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseLogin.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseLogin.java
index 0627544..b177eff 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseLogin.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseLogin.java
@@ -22,7 +22,6 @@ import com.googlecode.wicket.kendo.ui.widget.notification.Notification;
import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.select.BootstrapSelect;
import java.security.AccessControlException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
@@ -260,7 +259,7 @@ public abstract class BaseLogin extends WebPage {
});
// set default language selection
- List<Locale> filtered = Collections.emptyList();
+ List<Locale> filtered = List.of();
String acceptLanguage = ((ServletWebRequest) RequestCycle.get().getRequest()).
getHeader(HttpHeaders.ACCEPT_LANGUAGE);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryDirectoryPanel.java
index cf12f0d..790f0b5 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryDirectoryPanel.java
@@ -19,7 +19,6 @@
package org.apache.syncope.client.console.audit;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -54,7 +53,7 @@ public abstract class AuditHistoryDirectoryPanel<T extends EntityTO> extends Dir
private static final long serialVersionUID = -8248734710505211261L;
- private static final List<String> EVENTS = Arrays.asList("create", "update");
+ private static final List<String> EVENTS = List.of("create", "update");
private static final SortParam<String> REST_SORT = new SortParam<>("event_date", false);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
index da28bb2..c662fb7 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
@@ -22,7 +22,6 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
@@ -176,7 +175,7 @@ public abstract class AnyDirectoryPanel<A extends AnyTO, E extends AbstractAnyRe
PreferenceManager.setList(
getRequest(), getResponse(), DisplayAttributesModalPanel.getPrefDetailView(type),
- Arrays.asList(getDefaultAttributeSelection()));
+ List.of(getDefaultAttributeSelection()));
}
columns.addAll(prefcolumns);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ConsoleLogPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ConsoleLogPanel.java
index 1d6f557..1c5c703 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ConsoleLogPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ConsoleLogPanel.java
@@ -34,8 +34,6 @@ public class ConsoleLogPanel extends AbstractLogsPanel<LoggerTO> {
private static final long serialVersionUID = -9165749229623482717L;
- private static final ConsoleLoggerController CONSOLE_LOGGER_CONTROLLER = new ConsoleLoggerController();
-
public ConsoleLogPanel(final String id, final PageReference pageReference) {
super(id, pageReference, ConsoleLoggerController.getLoggers());
}
@@ -69,8 +67,8 @@ public class ConsoleLogPanel extends AbstractLogsPanel<LoggerTO> {
}
public static void setLogLevel(final String name, final LoggerLevel level) {
- final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
- final LoggerConfig logConf = SyncopeConstants.ROOT_LOGGER.equals(name)
+ LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+ LoggerConfig logConf = SyncopeConstants.ROOT_LOGGER.equals(name)
? ctx.getConfiguration().getLoggerConfig(LogManager.ROOT_LOGGER_NAME)
: ctx.getConfiguration().getLoggerConfig(name);
logConf.setLevel(level.getLevel());
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxCharacterFieldPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxCharacterFieldPanel.java
index a880b95..8247a2a 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxCharacterFieldPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxCharacterFieldPanel.java
@@ -19,7 +19,6 @@
package org.apache.syncope.client.console.wicket.markup.html.form;
import de.agilecoders.wicket.core.markup.html.bootstrap.components.TooltipConfig;
-import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.syncope.client.ui.commons.Constants;
@@ -42,7 +41,7 @@ public class AjaxCharacterFieldPanel extends FieldPanel<Character> implements Cl
private Component questionMarkJexlHelp;
- private List<Character> choices = Collections.emptyList();
+ private List<Character> choices = List.of();
public AjaxCharacterFieldPanel(final String id, final String name, final IModel<Character> model) {
this(id, name, model, true);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java
index 2b131f9..5cd5e69 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java
@@ -20,7 +20,6 @@ package org.apache.syncope.client.console.wizards.any;
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
@@ -104,7 +103,7 @@ public abstract class AbstractAttrsWizardStep<S extends SchemaTO> extends Wizard
super();
this.anyTypeClasses = anyTypeClasses;
- this.attrs = new ListModel<>(Collections.emptyList());
+ this.attrs = new ListModel<>(List.of());
this.setOutputMarkupId(true);
@@ -134,7 +133,7 @@ public abstract class AbstractAttrsWizardStep<S extends SchemaTO> extends Wizard
protected void setSchemas(final List<String> anyTypeClasses, final Map<String, S> scs) {
List<S> allSchemas = anyTypeClasses.isEmpty()
- ? Collections.emptyList()
+ ? List.of()
: SchemaRestClient.getSchemas(getSchemaType(), null, anyTypeClasses.toArray(new String[] {}));
scs.clear();
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningReport.java b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningReport.java
similarity index 90%
rename from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningReport.java
rename to common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningReport.java
index 216ab56..a23745a 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningReport.java
+++ b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningReport.java
@@ -18,14 +18,23 @@
*/
package org.apache.syncope.common.lib.to;
+import java.io.Serializable;
import java.util.Collection;
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.common.lib.types.TraceLevel;
-public class ProvisioningReport {
+@XmlRootElement(name = "provisioningReport")
+@XmlType
+public class ProvisioningReport implements Serializable {
+ private static final long serialVersionUID = 9201119472070963385L;
+
+ @XmlEnum
public enum Status {
SUCCESS,
@@ -135,9 +144,7 @@ public class ProvisioningReport {
*/
public static String generate(final Collection<ProvisioningReport> results, final TraceLevel level) {
StringBuilder sb = new StringBuilder();
- results.forEach(result -> {
- sb.append(result.getReportString(level)).append('\n');
- });
+ results.forEach(result -> sb.append(result.getReportString(level)).append('\n'));
return sb.toString();
}
diff --git a/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AbstractCSVSpec.java b/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AbstractCSVSpec.java
index 81ba8f3..192ce44 100644
--- a/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AbstractCSVSpec.java
+++ b/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AbstractCSVSpec.java
@@ -18,6 +18,8 @@
*/
package org.apache.syncope.common.rest.api.beans;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@@ -25,11 +27,26 @@ import javax.validation.constraints.NotNull;
import javax.ws.rs.QueryParam;
import org.apache.syncope.common.lib.types.MatchingRule;
import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.syncope.common.rest.api.service.JAXRSService;
public abstract class AbstractCSVSpec implements Serializable {
private static final long serialVersionUID = 2253975790270165334L;
+ private static final String PARAM_COLUMNSEPARATOR = "columnSeparator";
+
+ private static final String PARAM_ARRAYELEMENTSEPARATOR = "arrayElementSeparator";
+
+ private static final String PARAM_QUOTECHAR = "quoteChar";
+
+ private static final String PARAM_ESCAPECHAR = "escapeChar";
+
+ private static final String PARAM_LINESEPARATOR = "lineSeparator";
+
+ private static final String PARAM_NULLVALUE = "nullValue";
+
+ private static final String PARAM_ALLOWCOMMENTS = "allowComments";
+
protected abstract static class Builder<T extends AbstractCSVSpec, B extends Builder<T, B>> {
protected T instance;
@@ -98,8 +115,8 @@ public abstract class AbstractCSVSpec implements Serializable {
}
@SuppressWarnings("unchecked")
- public B action(final String action) {
- getInstance().getActions().add(action);
+ public B provisioningAction(final String provisioningActions) {
+ getInstance().getProvisioningActions().add(provisioningActions);
return (B) this;
}
@@ -128,77 +145,98 @@ public abstract class AbstractCSVSpec implements Serializable {
protected MatchingRule matchingRule = MatchingRule.UPDATE;
- protected List<String> actions = new ArrayList<>();
+ protected List<String> provisioningActions = new ArrayList<>();
+ @Parameter(name = JAXRSService.PARAM_ANYTYPEKEY, description = "any object type", schema =
+ @Schema(implementation = String.class))
public String getAnyTypeKey() {
return anyTypeKey;
}
@NotNull
- @QueryParam("anyTypeKey")
+ @QueryParam(JAXRSService.PARAM_ANYTYPEKEY)
public void setAnyTypeKey(final String anyTypeKey) {
this.anyTypeKey = anyTypeKey;
}
+ @Parameter(name = PARAM_COLUMNSEPARATOR, description = "separator for column values", schema =
+ @Schema(implementation = char.class, defaultValue = ","))
public char getColumnSeparator() {
return columnSeparator;
}
- @QueryParam("columnSeparator")
+ @QueryParam(PARAM_COLUMNSEPARATOR)
public void setColumnSeparator(final char columnSeparator) {
this.columnSeparator = columnSeparator;
}
+ @Parameter(name = PARAM_ARRAYELEMENTSEPARATOR, description = "separator for array elements within a "
+ + "column", schema =
+ @Schema(implementation = String.class, defaultValue = ";"))
public String getArrayElementSeparator() {
return arrayElementSeparator;
}
- @QueryParam("arrayElementSeparator")
+ @QueryParam(PARAM_ARRAYELEMENTSEPARATOR)
public void setArrayElementSeparator(final String arrayElementSeparator) {
this.arrayElementSeparator = arrayElementSeparator;
}
+ @Parameter(name = PARAM_QUOTECHAR, description = "character used for quoting values "
+ + "that contain quote characters or linefeeds", schema =
+ @Schema(implementation = char.class, defaultValue = "\""))
public char getQuoteChar() {
return quoteChar;
}
- @QueryParam("quoteChar")
+ @QueryParam(PARAM_QUOTECHAR)
public void setQuoteChar(final char quoteChar) {
this.quoteChar = quoteChar;
}
+ @Parameter(name = PARAM_ESCAPECHAR, description = "if any, used to escape values; "
+ + "most commonly defined as backslash", schema =
+ @Schema(implementation = Character.class))
public Character getEscapeChar() {
return escapeChar;
}
- @QueryParam("escapeChar")
+ @QueryParam(PARAM_ESCAPECHAR)
public void setEscapeChar(final Character escapeChar) {
this.escapeChar = escapeChar;
}
+ @Parameter(name = PARAM_LINESEPARATOR, description = "character used to separate data rows", schema =
+ @Schema(implementation = String.class, defaultValue = "\\\n"))
public String getLineSeparator() {
return lineSeparator;
}
- @QueryParam("lineSeparator")
+ @QueryParam(PARAM_LINESEPARATOR)
public void setLineSeparator(final String lineSeparator) {
this.lineSeparator = lineSeparator;
}
+ @Parameter(name = PARAM_NULLVALUE, description = "when asked to write null, this string value will be used "
+ + "instead", schema =
+ @Schema(implementation = String.class, defaultValue = ""))
public String getNullValue() {
return nullValue;
}
- @QueryParam("nullValue")
+ @QueryParam(PARAM_NULLVALUE)
public void setNullValue(final String nullValue) {
this.nullValue = nullValue;
}
+ @Parameter(name = PARAM_ALLOWCOMMENTS, description = "are hash comments, e.g. lines where the first non-whitespace "
+ + "character is '#' allowed? if so, they will be skipped without processing", schema =
+ @Schema(implementation = boolean.class, defaultValue = "false"))
public boolean isAllowComments() {
return allowComments;
}
- @QueryParam("allowComments")
+ @QueryParam(PARAM_ALLOWCOMMENTS)
public void setAllowComments(final boolean allowComments) {
this.allowComments = allowComments;
}
@@ -221,12 +259,12 @@ public abstract class AbstractCSVSpec implements Serializable {
this.matchingRule = matchingRule;
}
- public List<String> getActions() {
- return actions;
+ public List<String> getProvisioningActions() {
+ return provisioningActions;
}
- @QueryParam("actions")
- public void setActions(final List<String> actions) {
- this.actions = actions;
+ @QueryParam("provisioningActions")
+ public void setProvisioningActions(final List<String> provisioningActions) {
+ this.provisioningActions = provisioningActions;
}
}
diff --git a/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/CSVPushSpec.java b/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/CSVPushSpec.java
index 7663010..0a68810 100644
--- a/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/CSVPushSpec.java
+++ b/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/CSVPushSpec.java
@@ -82,6 +82,11 @@ public class CSVPushSpec extends AbstractCSVSpec {
getInstance().setIgnorePaging(ignorePagination);
return this;
}
+
+ public Builder propagationAction(final String propagationAction) {
+ getInstance().getPropagationActions().add(propagationAction);
+ return this;
+ }
}
private List<String> fields = new ArrayList<>();
@@ -94,6 +99,8 @@ public class CSVPushSpec extends AbstractCSVSpec {
private boolean ignorePaging;
+ protected List<String> propagationActions = new ArrayList<>();
+
public List<String> getFields() {
return fields;
}
@@ -138,4 +145,13 @@ public class CSVPushSpec extends AbstractCSVSpec {
public void setIgnorePaging(final boolean ignorePaging) {
this.ignorePaging = ignorePaging;
}
+
+ public List<String> getPropagationActions() {
+ return propagationActions;
+ }
+
+ @QueryParam("propagationActions")
+ public void setPropagationActions(final List<String> propagationActions) {
+ this.propagationActions = propagationActions;
+ }
}
diff --git a/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ReconQuery.java b/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ReconQuery.java
index ddd6799..c4b91d5 100644
--- a/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ReconQuery.java
+++ b/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ReconQuery.java
@@ -20,6 +20,7 @@ package org.apache.syncope.common.rest.api.beans;
import javax.validation.constraints.NotNull;
import javax.ws.rs.QueryParam;
+import org.apache.syncope.common.rest.api.service.JAXRSService;
public class ReconQuery {
@@ -61,7 +62,7 @@ public class ReconQuery {
}
@NotNull
- @QueryParam("anyTypeKey")
+ @QueryParam(JAXRSService.PARAM_ANYTYPEKEY)
public void setAnyTypeKey(final String anyTypeKey) {
this.anyTypeKey = anyTypeKey;
}
diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecQuery.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecQuery.java
index 3b735a5..f4de253 100644
--- a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecQuery.java
+++ b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecQuery.java
@@ -49,5 +49,4 @@ public class ExecQuery extends AbstractQuery {
public void setKey(final String key) {
this.key = key;
}
-
}
diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecuteQuery.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecuteQuery.java
index 1947206..2a3ca7f 100644
--- a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecuteQuery.java
+++ b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ExecuteQuery.java
@@ -96,5 +96,4 @@ public class ExecuteQuery implements Serializable {
public void setDryRun(final Boolean dryRun) {
this.dryRun = dryRun;
}
-
}
diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java
index 455e208..abcc0e2 100644
--- a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java
+++ b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java
@@ -46,4 +46,6 @@ public interface JAXRSService {
String PARAM_MAX = "max";
+ String PARAM_ANYTYPEKEY = "anyTypeKey";
+
}
diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
index 388f82b..ccb4380 100644
--- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
+++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
@@ -18,16 +18,12 @@
*/
package org.apache.syncope.core.logic;
-import com.fasterxml.jackson.databind.MappingIterator;
-import com.fasterxml.jackson.databind.SequenceWriter;
-import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
@@ -73,7 +69,7 @@ import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.pushpull.stream.StreamConnector;
+import org.apache.syncope.core.provisioning.java.pushpull.stream.CSVStreamConnector;
import org.apache.syncope.core.provisioning.api.pushpull.SyncopeSinglePullExecutor;
import org.apache.syncope.core.provisioning.api.pushpull.SyncopeSinglePushExecutor;
import org.apache.syncope.core.provisioning.api.pushpull.stream.SyncopeStreamPullExecutor;
@@ -378,19 +374,18 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
}
}
- private CsvSchema csvSchema(final AbstractCSVSpec spec, final CsvSchema base) {
- CsvSchema schema = base.
- withColumnSeparator(spec.getColumnSeparator()).
- withArrayElementSeparator(spec.getArrayElementSeparator()).
- withQuoteChar(spec.getQuoteChar()).
- withLineSeparator(spec.getLineSeparator()).
- withNullValue(spec.getNullValue()).
- withAllowComments(spec.isAllowComments());
+ private CsvSchema.Builder csvSchema(final AbstractCSVSpec spec) {
+ CsvSchema.Builder schemaBuilder = new CsvSchema.Builder().setUseHeader(true).
+ setColumnSeparator(spec.getColumnSeparator()).
+ setArrayElementSeparator(spec.getArrayElementSeparator()).
+ setQuoteChar(spec.getQuoteChar()).
+ setLineSeparator(spec.getLineSeparator()).
+ setNullValue(spec.getNullValue()).
+ setAllowComments(spec.isAllowComments());
if (spec.getEscapeChar() != null) {
- schema = schema.withEscapeChar(spec.getEscapeChar());
+ schemaBuilder.setEscapeChar(spec.getEscapeChar());
}
-
- return schema;
+ return schemaBuilder;
}
@PreAuthorize("hasRole('" + IdRepoEntitlement.TASK_EXECUTE + "')")
@@ -473,21 +468,24 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
}
});
- CsvSchema.Builder schemaBuilder = CsvSchema.builder().setUseHeader(true);
- columns.forEach(schemaBuilder::addColumn);
- CsvSchema schema = csvSchema(spec, schemaBuilder.build());
-
PushTaskTO pushTask = new PushTaskTO();
pushTask.setMatchingRule(spec.getMatchingRule());
pushTask.setUnmatchingRule(spec.getUnmatchingRule());
- pushTask.getActions().addAll(spec.getActions());
+ pushTask.getActions().addAll(spec.getProvisioningActions());
+
+ try (CSVStreamConnector connector = new CSVStreamConnector(
+ null,
+ spec.getArrayElementSeparator(),
+ csvSchema(spec),
+ null,
+ os)) {
- try (SequenceWriter writer = new CsvMapper().writer(schema).forType(Map.class).writeValues(os)) {
return streamPushExecutor.push(
anyType,
matching,
columns,
- new StreamConnector(null, spec.getArrayElementSeparator(), null, writer),
+ connector,
+ spec.getPropagationActions(),
pushTask,
AuthContextUtils.getUsername());
} catch (Exception e) {
@@ -514,31 +512,26 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
pullTask.setRemediation(spec.isRemediation());
pullTask.setMatchingRule(spec.getMatchingRule());
pullTask.setUnmatchingRule(spec.getUnmatchingRule());
- pullTask.getActions().addAll(spec.getActions());
+ pullTask.getActions().addAll(spec.getProvisioningActions());
- CsvSchema schema = csvSchema(spec, CsvSchema.emptySchema().withHeader());
- try {
- MappingIterator<Map<String, String>> reader =
- new CsvMapper().readerFor(Map.class).with(schema).readValues(csv);
-
- List<String> columns = new ArrayList<>();
- ((CsvSchema) reader.getParserSchema()).forEach(column -> {
- if (!spec.getIgnoreColumns().contains(column.getName())) {
- columns.add(column.getName());
- }
- });
+ try (CSVStreamConnector connector = new CSVStreamConnector(
+ spec.getKeyColumn(),
+ spec.getArrayElementSeparator(),
+ csvSchema(spec),
+ csv,
+ null)) {
+ List<String> columns = connector.getColumns(spec);
if (!columns.contains(spec.getKeyColumn())) {
throw new NotFoundException("Key column '" + spec.getKeyColumn() + "'");
}
- return streamPullExecutor.pull(
- anyType,
+ return streamPullExecutor.pull(anyType,
spec.getKeyColumn(),
columns,
spec.getConflictResolutionAction(),
spec.getPullCorrelationRule(),
- new StreamConnector(spec.getKeyColumn(), spec.getArrayElementSeparator(), reader, null),
+ connector,
pullTask);
} catch (NotFoundException e) {
throw e;
diff --git a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ReconciliationLogicTest.java b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ReconciliationLogicTest.java
index 72d1a93..73064c6 100644
--- a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ReconciliationLogicTest.java
+++ b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ReconciliationLogicTest.java
@@ -110,16 +110,8 @@ public class ReconciliationLogicTest extends AbstractTest {
});
assertEquals(search.getLeft(), results.size());
- CsvSchema.Builder builder = CsvSchema.builder().setUseHeader(true);
- builder.addColumn("username");
- builder.addColumn("status");
- builder.addColumn("firstname");
- builder.addColumn("surname");
- builder.addColumn("email");
- builder.addColumn("loginDate");
- CsvSchema schema = builder.build();
-
- MappingIterator<Map<String, String>> reader = new CsvMapper().readerFor(Map.class).with(schema).readValues(in);
+ MappingIterator<Map<String, String>> reader =
+ new CsvMapper().readerFor(Map.class).with(CsvSchema.emptySchema().withHeader()).readValues(in);
for (int i = 0; i < results.size() && reader.hasNext(); i++) {
Map<String, String> row = reader.next();
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/SyncopeJexlFunctions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/SyncopeJexlFunctions.java
index 9cc011f..26d695a 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/SyncopeJexlFunctions.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/SyncopeJexlFunctions.java
@@ -65,5 +65,4 @@ public class SyncopeJexlFunctions {
Collections.reverse(headless);
return prefix + attr + '=' + StringUtils.join(headless, ',' + attr + '=');
}
-
}
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPullExecutor.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPullExecutor.java
index 8d5c241..5215e63 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPullExecutor.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPullExecutor.java
@@ -23,6 +23,7 @@ import java.util.List;
import org.apache.syncope.common.lib.to.PullTaskTO;
import org.apache.syncope.common.lib.types.ConflictResolutionAction;
import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.provisioning.api.Connector;
import org.quartz.JobExecutionException;
public interface SyncopeStreamPullExecutor {
@@ -33,7 +34,7 @@ public interface SyncopeStreamPullExecutor {
List<String> columns,
ConflictResolutionAction conflictResolutionAction,
String pullCorrelationRule,
- StreamConnector connector,
+ Connector connector,
PullTaskTO pullTaskTO)
throws JobExecutionException;
}
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPushExecutor.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPushExecutor.java
index b70a2c4..c2b1e44 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPushExecutor.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPushExecutor.java
@@ -23,6 +23,7 @@ import org.apache.syncope.common.lib.to.ProvisioningReport;
import org.apache.syncope.common.lib.to.PushTaskTO;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.provisioning.api.Connector;
import org.quartz.JobExecutionException;
public interface SyncopeStreamPushExecutor {
@@ -31,7 +32,8 @@ public interface SyncopeStreamPushExecutor {
AnyType anyType,
List<? extends Any<?>> anys,
List<String> columns,
- StreamConnector connector,
+ Connector connector,
+ List<String> propagationActions,
PushTaskTO pushTaskTO,
String executor)
throws JobExecutionException;
diff --git a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java
index 2a2b178..1e14e94 100644
--- a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java
+++ b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java
@@ -29,7 +29,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.text.ParseException;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -62,9 +61,9 @@ public class IntAttrNameParserTest {
private static final Map<AnyTypeKind, List<String>> FIELDS = new HashMap<>();
static {
- FIELDS.put(AnyTypeKind.USER, Arrays.asList("key", "username"));
- FIELDS.put(AnyTypeKind.GROUP, Arrays.asList("key", "name", "userOwner"));
- FIELDS.put(AnyTypeKind.ANY_OBJECT, Arrays.asList("key", "name"));
+ FIELDS.put(AnyTypeKind.USER, List.of("key", "username"));
+ FIELDS.put(AnyTypeKind.GROUP, List.of("key", "name", "userOwner"));
+ FIELDS.put(AnyTypeKind.ANY_OBJECT, List.of("key", "name"));
}
@Mock
diff --git a/core/provisioning-java/pom.xml b/core/provisioning-java/pom.xml
index 12fe7f5..a2c7067 100644
--- a/core/provisioning-java/pom.xml
+++ b/core/provisioning-java/pom.xml
@@ -59,6 +59,11 @@ under the License.
</dependency>
<dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-csv</artifactId>
+ </dependency>
+
+ <dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
</dependency>
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java
index 41637c6..e7a96d9 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java
@@ -19,7 +19,6 @@
package org.apache.syncope.core.provisioning.java.pushpull;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
@@ -160,7 +159,7 @@ public class OutboundMatcher {
rule.get().getFilter(any, provision),
provision,
ArrayUtils.isEmpty(linkingItems)
- ? Optional.empty() : Optional.of(Arrays.asList(linkingItems)),
+ ? Optional.empty() : Optional.of(List.of(linkingItems)),
Optional.empty()));
} else {
Optional<? extends MappingItem> connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
@@ -173,7 +172,7 @@ public class OutboundMatcher {
connObjectKeyValue.get(),
provision,
ArrayUtils.isEmpty(linkingItems)
- ? Optional.empty() : Optional.of(Arrays.asList(linkingItems)),
+ ? Optional.empty() : Optional.of(List.of(linkingItems)),
Optional.empty()).
ifPresent(result::add);
}
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/StreamConnector.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/CSVStreamConnector.java
similarity index 60%
rename from core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/StreamConnector.java
rename to core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/CSVStreamConnector.java
index 5ff51c8..6b025ae 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/StreamConnector.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/CSVStreamConnector.java
@@ -16,19 +16,27 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.syncope.core.provisioning.api.pushpull.stream;
+package org.apache.syncope.core.provisioning.java.pushpull.stream;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.databind.SequenceWriter;
+import com.fasterxml.jackson.dataformat.csv.CsvMapper;
+import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.rest.api.beans.CSVPullSpec;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.provisioning.api.Connector;
+import org.identityconnectors.framework.common.exceptions.ConnectorException;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeBuilder;
import org.identityconnectors.framework.common.objects.AttributeUtil;
@@ -43,28 +51,78 @@ import org.identityconnectors.framework.common.objects.SyncToken;
import org.identityconnectors.framework.common.objects.Uid;
import org.identityconnectors.framework.common.objects.filter.Filter;
import org.identityconnectors.framework.spi.SearchResultsHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
-public class StreamConnector implements Connector {
+public class CSVStreamConnector implements Connector, AutoCloseable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CSVStreamConnector.class);
private final String keyColumn;
private final String arrayElementsSeparator;
- private final MappingIterator<Map<String, String>> reader;
+ private final CsvSchema.Builder schemaBuilder;
+
+ private final InputStream in;
+
+ private final OutputStream out;
+
+ private MappingIterator<Map<String, String>> reader;
- private final SequenceWriter writer;
+ private SequenceWriter writer;
- public StreamConnector(
+ public CSVStreamConnector(
final String keyColumn,
final String arrayElementsSeparator,
- final MappingIterator<Map<String, String>> reader,
- final SequenceWriter writer) {
+ final CsvSchema.Builder schemaBuilder,
+ final InputStream in,
+ final OutputStream out) {
this.keyColumn = keyColumn;
this.arrayElementsSeparator = arrayElementsSeparator;
- this.reader = reader;
- this.writer = writer;
+ this.schemaBuilder = schemaBuilder;
+ this.in = in;
+ this.out = out;
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (reader != null) {
+ reader.close();
+ }
+ if (writer != null) {
+ writer.close();
+ }
+ }
+
+ public MappingIterator<Map<String, String>> reader() throws IOException {
+ synchronized (this) {
+ if (reader == null) {
+ reader = new CsvMapper().readerFor(Map.class).with(schemaBuilder.build()).readValues(in);
+ }
+ }
+ return reader;
+ }
+
+ public List<String> getColumns(final CSVPullSpec spec) throws IOException {
+ List<String> columns = new ArrayList<>();
+ ((CsvSchema) reader().getParserSchema()).forEach(column -> {
+ if (!spec.getIgnoreColumns().contains(column.getName())) {
+ columns.add(column.getName());
+ }
+ });
+ return columns;
+ }
+
+ public SequenceWriter writer() throws IOException {
+ synchronized (this) {
+ if (writer == null) {
+ writer = new CsvMapper().writerFor(Map.class).with(schemaBuilder.build()).writeValues(out);
+ }
+ }
+ return writer;
}
@Override
@@ -84,29 +142,34 @@ public class StreamConnector implements Connector {
final OperationOptions options,
final AtomicReference<Boolean> propagationAttempted) {
- if (writer != null) {
- Map<String, String> row = new HashMap<>();
- attrs.stream().filter(attr -> !AttributeUtil.isSpecial(attr)).forEach(attr -> {
- if (CollectionUtils.isEmpty(attr.getValue()) || attr.getValue().get(0) == null) {
- row.put(attr.getName(), null);
- } else if (attr.getValue().size() == 1) {
- row.put(attr.getName(), attr.getValue().get(0).toString());
- } else if (arrayElementsSeparator == null) {
- row.put(attr.getName(), attr.getValue().toString());
- } else {
- row.put(
- attr.getName(),
- attr.getValue().stream().map(Object::toString).
- collect(Collectors.joining(arrayElementsSeparator)));
- }
- });
- try {
- writer.write(row);
- } catch (IOException e) {
- throw new IllegalStateException("Could not object " + row, e);
+ synchronized (schemaBuilder) {
+ if (schemaBuilder.size() == 0) {
+ attrs.stream().filter(attr -> !AttributeUtil.isSpecial(attr)).map(Attribute::getName).
+ forEachOrdered(schemaBuilder::addColumn);
+ }
+ }
+
+ Map<String, String> row = new HashMap<>();
+ attrs.stream().filter(attr -> !AttributeUtil.isSpecial(attr)).forEach(attr -> {
+ if (CollectionUtils.isEmpty(attr.getValue()) || attr.getValue().get(0) == null) {
+ row.put(attr.getName(), null);
+ } else if (attr.getValue().size() == 1) {
+ row.put(attr.getName(), attr.getValue().get(0).toString());
+ } else if (arrayElementsSeparator == null) {
+ row.put(attr.getName(), attr.getValue().toString());
+ } else {
+ row.put(
+ attr.getName(),
+ attr.getValue().stream().map(Object::toString).
+ collect(Collectors.joining(arrayElementsSeparator)));
}
- propagationAttempted.set(Boolean.TRUE);
+ });
+ try {
+ writer().write(row);
+ } catch (IOException e) {
+ throw new ConnectorException("Could not write object " + row, e);
}
+ propagationAttempted.set(Boolean.TRUE);
return null;
}
@@ -165,9 +228,9 @@ public class StreamConnector implements Connector {
SearchResult result = new SearchResult();
- if (reader != null) {
- while (reader.hasNext()) {
- Map<String, String> row = reader.next();
+ try {
+ while (reader().hasNext()) {
+ Map<String, String> row = reader().next();
ConnectorObjectBuilder builder = new ConnectorObjectBuilder();
builder.setObjectClass(objectClass);
@@ -181,6 +244,9 @@ public class StreamConnector implements Connector {
handler.handle(builder.build());
}
+ } catch (IOException e) {
+ LOG.error("Could not read CSV from provided stream", e);
+ throw new ConnectorException(e);
}
return result;
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java
index ff6553e..2ce44a0 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java
@@ -47,8 +47,8 @@ import org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
import org.apache.syncope.common.lib.to.ProvisioningReport;
import org.apache.syncope.common.lib.types.IdMImplementationType;
+import org.apache.syncope.core.provisioning.api.Connector;
import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
-import org.apache.syncope.core.provisioning.api.pushpull.stream.StreamConnector;
import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandler;
import org.apache.syncope.core.spring.ImplementationManager;
import org.quartz.JobExecutionException;
@@ -168,7 +168,7 @@ public class StreamPullJobDelegate extends PullJobDelegate implements SyncopeStr
final List<String> columns,
final ConflictResolutionAction conflictResolutionAction,
final String pullCorrelationRule,
- final StreamConnector connector,
+ final Connector connector,
final PullTaskTO pullTaskTO) throws JobExecutionException {
LOG.debug("Executing stream pull");
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegate.java
index 1b775d4..cf18b9f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegate.java
@@ -34,11 +34,11 @@ import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.provisioning.api.Connector;
import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPushResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.GroupPushResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
-import org.apache.syncope.core.provisioning.api.pushpull.stream.StreamConnector;
import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.stream.SyncopeStreamPushExecutor;
import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
@@ -88,7 +88,9 @@ public class StreamPushJobDelegate extends PushJobDelegate implements SyncopeStr
}
private ExternalResource externalResource(
- final AnyType anyType, final List<String> columns) throws JobExecutionException {
+ final AnyType anyType,
+ final List<String> columns,
+ final List<String> propagationActions) throws JobExecutionException {
Provision provision = entityFactory.newEntity(Provision.class);
provision.setAnyType(anyType);
@@ -118,6 +120,15 @@ public class StreamPushJobDelegate extends PushJobDelegate implements SyncopeStr
resource.add(provision);
provision.setResource(resource);
+ propagationActions.forEach(key -> {
+ Implementation impl = implementationDAO.find(key);
+ if (impl == null || !IdMImplementationType.PROPAGATION_ACTIONS.equals(impl.getType())) {
+ LOG.debug("Invalid " + Implementation.class.getSimpleName() + " {}, ignoring...", key);
+ } else {
+ resource.add(impl);
+ }
+ });
+
return resource;
}
@@ -126,21 +137,22 @@ public class StreamPushJobDelegate extends PushJobDelegate implements SyncopeStr
final AnyType anyType,
final List<? extends Any<?>> anys,
final List<String> columns,
- final StreamConnector connector,
+ final Connector connector,
+ final List<String> propagationActions,
final PushTaskTO pushTaskTO,
final String executor) throws JobExecutionException {
LOG.debug("Executing stream push as {}", executor);
this.executor = executor;
- List<PushActions> actions = new ArrayList<>();
+ List<PushActions> pushActions = new ArrayList<>();
pushTaskTO.getActions().forEach(key -> {
Implementation impl = implementationDAO.find(key);
if (impl == null || !IdMImplementationType.PUSH_ACTIONS.equals(impl.getType())) {
LOG.debug("Invalid " + Implementation.class.getSimpleName() + " {}, ignoring...", key);
} else {
try {
- actions.add(ImplementationManager.build(impl));
+ pushActions.add(ImplementationManager.build(impl));
} catch (Exception e) {
LOG.warn("While building {}", impl, e);
}
@@ -148,7 +160,7 @@ public class StreamPushJobDelegate extends PushJobDelegate implements SyncopeStr
});
try {
- ExternalResource resource = externalResource(anyType, columns);
+ ExternalResource resource = externalResource(anyType, columns, propagationActions);
Provision provision = resource.getProvisions().get(0);
PushTask pushTask = entityFactory.newEntity(PushTask.class);
@@ -161,10 +173,10 @@ public class StreamPushJobDelegate extends PushJobDelegate implements SyncopeStr
pushTask.setSyncStatus(false);
profile = new ProvisioningProfile<>(connector, pushTask);
- profile.getActions().addAll(actions);
+ profile.getActions().addAll(pushActions);
profile.setConflictResolutionAction(ConflictResolutionAction.FIRSTMATCH);
- for (PushActions action : actions) {
+ for (PushActions action : pushActions) {
action.beforeAll(profile);
}
@@ -186,7 +198,7 @@ public class StreamPushJobDelegate extends PushJobDelegate implements SyncopeStr
doHandle(anys, handler, provision.getResource());
- for (PushActions action : actions) {
+ for (PushActions action : pushActions) {
action.afterAll(profile);
}
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
index 1f52585..a08c998 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
@@ -19,7 +19,6 @@
package org.apache.syncope.core.provisioning.java.utils;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
@@ -117,7 +116,7 @@ public final class MappingUtils {
attrsToGet.add(Uid.NAME);
attrsToGet.add(OperationalAttributes.ENABLE_NAME);
if (!ArrayUtils.isEmpty(moreAttrsToGet)) {
- attrsToGet.addAll(Arrays.asList(moreAttrsToGet));
+ attrsToGet.addAll(List.of(moreAttrsToGet));
}
items.filter(item -> item.getPurpose() != MappingPurpose.NONE).
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActionsTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActionsTest.java
index de4a6bb..1b833eb 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActionsTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActionsTest.java
@@ -25,9 +25,12 @@ import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.request.AnyCR;
+import org.apache.syncope.common.lib.request.AnyUR;
+import org.apache.syncope.common.lib.request.PasswordPatch;
+import org.apache.syncope.common.lib.request.UserCR;
+import org.apache.syncope.common.lib.request.UserUR;
import org.apache.syncope.common.lib.to.EntityTO;
import org.apache.syncope.common.lib.to.ProvisioningReport;
import org.apache.syncope.common.lib.to.UserTO;
@@ -53,9 +56,6 @@ public class LDAPPasswordPullActionsTest extends AbstractTest {
private ProvisioningProfile<?, ?> profile;
@Mock
- private AnyPatch anyPatch;
-
- @Mock
private UserDAO userDAO;
@Mock
@@ -64,6 +64,10 @@ public class LDAPPasswordPullActionsTest extends AbstractTest {
@InjectMocks
private LDAPPasswordPullActions ldapPasswordPullActions;
+ private AnyCR anyCR;
+
+ private AnyUR anyUR;
+
private EntityTO entity;
private String encodedPassword;
@@ -84,9 +88,10 @@ public class LDAPPasswordPullActionsTest extends AbstractTest {
public void beforeProvision() throws JobExecutionException {
String digest = "SHA256";
String password = "t3stPassw0rd";
- ReflectionTestUtils.setField(entity, "password", String.format("{%s}%s", digest, password));
+ anyCR = new UserCR.Builder(SyncopeConstants.ROOT_REALM, "username").
+ password(String.format("{%s}%s", digest, password)).build();
- ldapPasswordPullActions.beforeProvision(profile, syncDelta, entity);
+ ldapPasswordPullActions.beforeProvision(profile, syncDelta, anyCR);
assertEquals(CipherAlgorithm.valueOf(digest), ReflectionTestUtils.getField(ldapPasswordPullActions, "cipher"));
assertEquals(password, ReflectionTestUtils.getField(ldapPasswordPullActions, "encodedPassword"));
@@ -94,14 +99,11 @@ public class LDAPPasswordPullActionsTest extends AbstractTest {
@Test
public void beforeUpdate() throws JobExecutionException {
- anyPatch = new UserPatch();
- PasswordPatch passwordPatch = new PasswordPatch();
- String digest = "MD5";
- String password = "an0therTestP4ss";
- ReflectionTestUtils.setField(passwordPatch, "value", String.format("{%s}%s", digest, password));
- ReflectionTestUtils.setField(anyPatch, "password", passwordPatch);
+ anyUR = new UserUR.Builder(null).
+ password(new PasswordPatch.Builder().value("{MD5}an0therTestP4ss").build()).
+ build();
- ldapPasswordPullActions.beforeUpdate(profile, syncDelta, entity, anyPatch);
+ ldapPasswordPullActions.beforeUpdate(profile, syncDelta, entity, anyUR);
assertNull(ReflectionTestUtils.getField(ldapPasswordPullActions, "encodedPassword"));
}
@@ -126,5 +128,4 @@ public class LDAPPasswordPullActionsTest extends AbstractTest {
assertNull(ReflectionTestUtils.getField(ldapPasswordPullActions, "encodedPassword"));
assertNull(ReflectionTestUtils.getField(ldapPasswordPullActions, "cipher"));
}
-
}
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegateTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegateTest.java
index dfa523c..bb57c94 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegateTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegateTest.java
@@ -20,15 +20,11 @@ package org.apache.syncope.core.provisioning.java.pushpull.stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import com.fasterxml.jackson.databind.MappingIterator;
+import com.fasterxml.jackson.dataformat.csv.CsvSchema;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.stream.Collectors;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.PullTaskTO;
@@ -41,7 +37,7 @@ import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.common.lib.to.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.pushpull.stream.StreamConnector;
+import org.apache.syncope.common.rest.api.beans.CSVPullSpec;
import org.apache.syncope.core.provisioning.api.pushpull.stream.SyncopeStreamPullExecutor;
import org.apache.syncope.core.provisioning.java.AbstractTest;
import org.apache.syncope.core.spring.security.AuthContextUtils;
@@ -64,39 +60,51 @@ public class StreamPullJobDelegateTest extends AbstractTest {
@Test
public void pull() throws JobExecutionException, IOException {
+ List<String> columns = List.of(
+ "username",
+ "email",
+ "surname",
+ "firstname",
+ "fullname",
+ "userId");
+
+ StringBuilder csv = new StringBuilder();
+ csv.append(columns.stream().collect(Collectors.joining(",")));
+ csv.append('\n');
+ csv.append("donizetti,");
+ csv.append("donizetti@apache.org,");
+ csv.append("Donizetti,");
+ csv.append("Gaetano,");
+ csv.append("Gaetano Donizetti,");
+ csv.append("donizetti@apache.org");
+ csv.append('\n');
+
PullTaskTO pullTask = new PullTaskTO();
pullTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
pullTask.setRemediation(false);
pullTask.setMatchingRule(MatchingRule.UPDATE);
pullTask.setUnmatchingRule(UnmatchingRule.PROVISION);
- Map<String, String> user = new HashMap<>();
- user.put("username", "donizetti");
- user.put("email", "donizetti@apache.org");
- user.put("surname", "Donizetti");
- user.put("firstname", "Gaetano");
- user.put("fullname", "Gaetano Donizetti");
- user.put("userId", "donizetti@apache.org");
- Iterator<Map<String, String>> backing = List.of(user).iterator();
-
- @SuppressWarnings("unchecked")
- MappingIterator<Map<String, String>> itor = mock(MappingIterator.class);
- when(itor.hasNext()).thenAnswer(invocation -> backing.hasNext());
- when(itor.next()).thenAnswer(invocation -> backing.next());
+ List<ProvisioningReport> results = AuthContextUtils.callAsAdmin(SyncopeConstants.MASTER_DOMAIN, () -> {
+ try (CSVStreamConnector connector = new CSVStreamConnector(
+ "username",
+ ";",
+ new CsvSchema.Builder().setUseHeader(true),
+ new ByteArrayInputStream(csv.toString().getBytes()),
+ null)) {
- List<String> columns = user.keySet().stream().collect(Collectors.toList());
+ List<String> csvColumns = connector.getColumns(new CSVPullSpec());
+ assertEquals(columns, csvColumns);
- List<ProvisioningReport> results = AuthContextUtils.callAsAdmin(SyncopeConstants.MASTER_DOMAIN, () -> {
- try {
return streamPullExecutor.pull(
anyTypeDAO.findUser(),
"username",
columns,
ConflictResolutionAction.IGNORE,
null,
- new StreamConnector("username", null, itor, null),
+ connector,
pullTask);
- } catch (JobExecutionException e) {
+ } catch (Exception e) {
throw new RuntimeException(e);
}
});
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegateTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegateTest.java
index 2fcab3c..7742760 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegateTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegateTest.java
@@ -20,18 +20,17 @@ package org.apache.syncope.core.provisioning.java.pushpull.stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.fasterxml.jackson.databind.MappingIterator;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SequenceWriter;
+import com.fasterxml.jackson.dataformat.csv.CsvMapper;
+import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
-import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.ProvisioningReport;
import org.apache.syncope.common.lib.to.PushTaskTO;
@@ -39,7 +38,6 @@ import org.apache.syncope.common.lib.types.MatchingRule;
import org.apache.syncope.common.lib.types.UnmatchingRule;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.provisioning.api.pushpull.stream.StreamConnector;
import org.apache.syncope.core.provisioning.api.pushpull.stream.SyncopeStreamPushExecutor;
import org.apache.syncope.core.provisioning.java.AbstractTest;
import org.apache.syncope.core.spring.security.AuthContextUtils;
@@ -50,8 +48,6 @@ import org.springframework.transaction.annotation.Transactional;
@Transactional("Master")
public class StreamPushJobDelegateTest extends AbstractTest {
- private static final ObjectMapper MAPPER = new ObjectMapper();
-
@Autowired
private SyncopeStreamPushExecutor streamPushExecutor;
@@ -71,14 +67,19 @@ public class StreamPushJobDelegateTest extends AbstractTest {
pushTask.setUnmatchingRule(UnmatchingRule.PROVISION);
List<ProvisioningReport> results = AuthContextUtils.callAsAdmin(SyncopeConstants.MASTER_DOMAIN, () -> {
- try (SequenceWriter writer = MAPPER.writer().forType(Map.class).writeValues(os)) {
- writer.init(true);
+ try (CSVStreamConnector connector = new CSVStreamConnector(
+ null,
+ ";",
+ new CsvSchema.Builder().setUseHeader(true),
+ null,
+ os)) {
return streamPushExecutor.push(
anyTypeDAO.findUser(),
userDAO.findAll(1, 100),
- Arrays.asList("username", "firstname", "surname", "email", "status", "loginDate"),
- new StreamConnector(null, null, null, writer),
+ List.of("username", "firstname", "surname", "email", "status", "loginDate"),
+ connector,
+ List.of(),
pushTask,
"user");
} catch (Exception e) {
@@ -87,7 +88,8 @@ public class StreamPushJobDelegateTest extends AbstractTest {
});
assertEquals(userDAO.count(), results.size());
- MappingIterator<Map<String, String>> reader = MAPPER.readerFor(Map.class).readValues(in);
+ MappingIterator<Map<String, String>> reader =
+ new CsvMapper().readerFor(Map.class).with(CsvSchema.emptySchema().withHeader()).readValues(in);
for (int i = 0; i < results.size() && reader.hasNext(); i++) {
Map<String, String> row = reader.next();
@@ -97,18 +99,18 @@ public class StreamPushJobDelegateTest extends AbstractTest {
switch (row.get("username")) {
case "rossini":
- assertNull(row.get("email"));
- assertTrue(row.get("loginDate").contains(","));
+ assertEquals(StringUtils.EMPTY, row.get("email"));
+ assertTrue(row.get("loginDate").contains(";"));
break;
case "verdi":
assertEquals("verdi@syncope.org", row.get("email"));
- assertNull(row.get("loginDate"));
+ assertEquals(StringUtils.EMPTY, row.get("loginDate"));
break;
case "bellini":
- assertNull(row.get("email"));
- assertFalse(row.get("loginDate").contains(","));
+ assertEquals(StringUtils.EMPTY, row.get("email"));
+ assertFalse(row.get("loginDate").contains(";"));
break;
default:
diff --git a/core/spring/pom.xml b/core/spring/pom.xml
index 71a03c9..b301382 100644
--- a/core/spring/pom.xml
+++ b/core/spring/pom.xml
@@ -101,8 +101,13 @@ under the License.
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.apache.syncope.common.idrepo</groupId>
- <artifactId>syncope-common-idrepo-rest-api</artifactId>
+ <groupId>org.apache.syncope.common.idm</groupId>
+ <artifactId>syncope-common-idm-rest-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.common.am</groupId>
+ <artifactId>syncope-common-am-rest-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java
index 12eb10c..4924163 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java
@@ -19,7 +19,6 @@
package org.apache.syncope.client.console.rest;
import java.io.InputStream;
-import java.util.Collections;
import java.util.List;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
@@ -44,8 +43,8 @@ public class BpmnProcessRestClient extends BaseRestClient {
BpmnProcessService service = getService(BpmnProcessService.class);
MetadataMap<String, String> headers = new MetadataMap<>();
- headers.put(HttpHeaders.CONTENT_TYPE, Collections.singletonList(mediaType.toString()));
- headers.put(HttpHeaders.ACCEPT, Collections.singletonList(mediaType.toString()));
+ headers.put(HttpHeaders.CONTENT_TYPE, List.of(mediaType.toString()));
+ headers.put(HttpHeaders.ACCEPT, List.of(mediaType.toString()));
WebClient.client(service).headers(headers);
return service;
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java
index 1e7c335..c3c0a3e 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java
@@ -20,7 +20,6 @@ package org.apache.syncope.core.logic.saml2;
import java.text.ParseException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -92,7 +91,7 @@ public class SAML2UserManager {
SAML2IdP idp = idpDAO.find(idpKey);
if (idp == null) {
LOG.warn("Invalid IdP: {}", idpKey);
- return Collections.emptyList();
+ return List.of();
}
return inboundMatcher.matchByConnObjectKeyValue(
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
index acdf767..f039075 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
@@ -73,8 +73,7 @@ public class LogsITCase extends AbstractConsoleITCase {
@Test
public void readConsoleLogs() {
- TESTER.assertComponent("body:content:tabbedPanel:tabs-container:tabs:1:link",
- AjaxFallbackLink.class);
+ TESTER.assertComponent("body:content:tabbedPanel:tabs-container:tabs:1:link", AjaxFallbackLink.class);
TESTER.clickLink("body:content:tabbedPanel:tabs-container:tabs:1:link");
TESTER.assertComponent(CONTAINER_PATH, WebMarkupContainer.class);
@@ -91,6 +90,8 @@ public class LogsITCase extends AbstractConsoleITCase {
TESTER.getRequest().addParameter(
result.getPageRelativePath() + ":fields:1:field:dropDownChoiceField", "6");
+ TESTER.assertComponent(
+ result.getPageRelativePath() + ":fields:1:field:dropDownChoiceField", DropDownChoice.class);
TESTER.executeAjaxEvent(
result.getPageRelativePath() + ":fields:1:field:dropDownChoiceField", Constants.ON_CHANGE);
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReconciliationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReconciliationITCase.java
index 822bb5f..5b2a20c 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReconciliationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReconciliationITCase.java
@@ -251,17 +251,8 @@ public class ReconciliationITCase extends AbstractITCase {
PagedResult<UserTO> users = userService.search(anyQuery);
assertNotNull(users);
- CsvSchema.Builder builder = CsvSchema.builder().setUseHeader(true);
- builder.addColumn("username");
- builder.addColumn("status");
- builder.addColumn("firstname");
- builder.addColumn("surname");
- builder.addColumn("email");
- builder.addColumn("loginDate");
- CsvSchema schema = builder.build();
-
- MappingIterator<Map<String, String>> reader = new CsvMapper().readerFor(Map.class).with(schema).
- readValues((InputStream) response.getEntity());
+ MappingIterator<Map<String, String>> reader = new CsvMapper().readerFor(Map.class).
+ with(CsvSchema.emptySchema().withHeader()).readValues((InputStream) response.getEntity());
int rows = 0;
for (; reader.hasNext(); rows++) {