1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.client.console.status;
20
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.stream.Collectors;
24 import org.apache.commons.lang3.StringUtils;
25 import org.apache.syncope.client.console.SyncopeConsoleSession;
26 import org.apache.syncope.client.console.SyncopeWebApplication;
27 import org.apache.syncope.client.console.commons.RealmsUtils;
28 import org.apache.syncope.client.console.pages.BasePage;
29 import org.apache.syncope.client.console.panels.MultilevelPanel;
30 import org.apache.syncope.client.console.rest.ImplementationRestClient;
31 import org.apache.syncope.client.console.rest.RealmRestClient;
32 import org.apache.syncope.client.console.rest.ReconciliationRestClient;
33 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxSearchFieldPanel;
34 import org.apache.syncope.client.ui.commons.Constants;
35 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel;
36 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
37 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPalettePanel;
38 import org.apache.syncope.common.lib.SyncopeConstants;
39 import org.apache.syncope.common.lib.to.ImplementationTO;
40 import org.apache.syncope.common.lib.to.ProvisioningTaskTO;
41 import org.apache.syncope.common.lib.to.PullTaskTO;
42 import org.apache.syncope.common.lib.to.PushTaskTO;
43 import org.apache.syncope.common.lib.to.RealmTO;
44 import org.apache.syncope.common.lib.types.IdMImplementationType;
45 import org.apache.syncope.common.lib.types.MatchingRule;
46 import org.apache.syncope.common.lib.types.UnmatchingRule;
47 import org.apache.syncope.common.rest.api.beans.ReconQuery;
48 import org.apache.wicket.PageReference;
49 import org.apache.wicket.ajax.AjaxRequestTarget;
50 import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
51 import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteSettings;
52 import org.apache.wicket.markup.html.basic.Label;
53 import org.apache.wicket.markup.html.form.Form;
54 import org.apache.wicket.model.CompoundPropertyModel;
55 import org.apache.wicket.model.IModel;
56 import org.apache.wicket.model.LoadableDetachableModel;
57 import org.apache.wicket.model.PropertyModel;
58 import org.apache.wicket.model.util.ListModel;
59 import org.apache.wicket.spring.injection.annot.SpringBean;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62
63 public class ReconTaskPanel extends MultilevelPanel.SecondLevel {
64
65 private static final long serialVersionUID = 5870444905957760434L;
66
67 protected static final Logger LOG = LoggerFactory.getLogger(ReconTaskPanel.class);
68
69 @SpringBean
70 protected ImplementationRestClient implementationRestClient;
71
72 @SpringBean
73 protected RealmRestClient realmRestClient;
74
75 @SpringBean
76 protected ReconciliationRestClient reconciliationRestClient;
77
78 protected final IModel<List<String>> pullActions = new LoadableDetachableModel<>() {
79
80 private static final long serialVersionUID = 5275935387613157437L;
81
82 @Override
83 protected List<String> load() {
84 return implementationRestClient.list(IdMImplementationType.PULL_ACTIONS).stream().
85 map(ImplementationTO::getKey).sorted().collect(Collectors.toList());
86 }
87 };
88
89 protected final IModel<List<String>> pushActions = new LoadableDetachableModel<>() {
90
91 private static final long serialVersionUID = 5275935387613157437L;
92
93 @Override
94 protected List<String> load() {
95 return implementationRestClient.list(IdMImplementationType.PUSH_ACTIONS).stream().
96 map(ImplementationTO::getKey).sorted().collect(Collectors.toList());
97 }
98 };
99
100 public ReconTaskPanel(
101 final String resource,
102 final ProvisioningTaskTO taskTO,
103 final String anyType,
104 final String anyKey,
105 final boolean isOnSyncope,
106 final MultilevelPanel multiLevelPanelRef,
107 final PageReference pageRef) {
108
109 this(resource, taskTO, anyType, anyKey, null, isOnSyncope, multiLevelPanelRef, pageRef);
110 }
111
112 public ReconTaskPanel(
113 final String resource,
114 final ProvisioningTaskTO taskTO,
115 final String anyType,
116 final String anyKey,
117 final String fiql,
118 final boolean isOnSyncope,
119 final MultilevelPanel multiLevelPanelRef,
120 final PageReference pageRef) {
121
122 Form<ProvisioningTaskTO> form = new Form<>("form", new CompoundPropertyModel<>(taskTO));
123 add(form);
124
125 if (taskTO instanceof PushTaskTO) {
126 form.add(new Label("realm", ""));
127 form.add(new Label("remediation", ""));
128 } else {
129 boolean fullRealmsTree = SyncopeWebApplication.get().fullRealmsTree(realmRestClient);
130 AutoCompleteSettings settings = new AutoCompleteSettings();
131 settings.setShowCompleteListOnFocusGain(fullRealmsTree);
132 settings.setShowListOnEmptyInput(fullRealmsTree);
133
134 AjaxSearchFieldPanel realm = new AjaxSearchFieldPanel(
135 "realm", "destinationRealm", new PropertyModel<>(taskTO, "destinationRealm"), settings) {
136
137 private static final long serialVersionUID = -6390474600233486704L;
138
139 @Override
140 protected Iterator<String> getChoices(final String input) {
141 return (RealmsUtils.checkInput(input)
142 ? (realmRestClient.search(fullRealmsTree
143 ? RealmsUtils.buildRootQuery()
144 : RealmsUtils.buildKeywordQuery(input)).getResult())
145 : List.<RealmTO>of()).stream().
146 map(RealmTO::getFullPath).collect(Collectors.toList()).iterator();
147 }
148 };
149
150 realm.addRequiredLabel();
151 realm.setOutputMarkupId(true);
152
153 if (StringUtils.isBlank(PullTaskTO.class.cast(taskTO).getDestinationRealm())) {
154 realm.getField().setModelObject(SyncopeConstants.ROOT_REALM);
155 }
156 if (isOnSyncope) {
157 realm.setEnabled(false);
158 }
159 form.add(realm);
160
161 form.add(new AjaxCheckBoxPanel(
162 "remediation", "remediation", new PropertyModel<>(taskTO, "remediation"), false));
163 }
164
165 AjaxPalettePanel<String> actions = new AjaxPalettePanel.Builder<String>().
166 setAllowMoveAll(true).setAllowOrder(true).
167 build("actions",
168 new PropertyModel<>(taskTO, "actions"),
169 new ListModel<>(taskTO instanceof PushTaskTO
170 ? pushActions.getObject() : pullActions.getObject()));
171 actions.setOutputMarkupId(true);
172 form.add(actions);
173
174 AjaxDropDownChoicePanel<MatchingRule> matchingRule = new AjaxDropDownChoicePanel<>(
175 "matchingRule", "matchingRule", new PropertyModel<>(taskTO, "matchingRule"), false);
176 matchingRule.setChoices(List.of(MatchingRule.values()));
177 form.add(matchingRule);
178
179 AjaxDropDownChoicePanel<UnmatchingRule> unmatchingRule = new AjaxDropDownChoicePanel<>(
180 "unmatchingRule", "unmatchingRule", new PropertyModel<>(taskTO, "unmatchingRule"),
181 false);
182 unmatchingRule.setChoices(List.of(UnmatchingRule.values()));
183 form.add(unmatchingRule);
184
185 taskTO.setPerformCreate(true);
186 AjaxCheckBoxPanel performCreate = new AjaxCheckBoxPanel(
187 "performCreate", "performCreate", new PropertyModel<>(taskTO, "performCreate"), false);
188 form.add(performCreate);
189
190 taskTO.setPerformUpdate(true);
191 AjaxCheckBoxPanel performUpdate = new AjaxCheckBoxPanel(
192 "performUpdate", "performUpdate", new PropertyModel<>(taskTO, "performUpdate"), false);
193 form.add(performUpdate);
194
195 taskTO.setPerformDelete(true);
196 AjaxCheckBoxPanel performDelete = new AjaxCheckBoxPanel(
197 "performDelete", "performDelete", new PropertyModel<>(taskTO, "performDelete"), false);
198 form.add(performDelete);
199
200 taskTO.setSyncStatus(true);
201 AjaxCheckBoxPanel syncStatus = new AjaxCheckBoxPanel(
202 "syncStatus", "syncStatus", new PropertyModel<>(taskTO, "syncStatus"), false);
203 form.add(syncStatus);
204
205 form.add(new AjaxSubmitLink("reconcile") {
206
207 private static final long serialVersionUID = -817438685948164787L;
208
209 @Override
210 protected void onSubmit(final AjaxRequestTarget target) {
211 ReconQuery reconQuery = new ReconQuery.Builder(anyType, resource).anyKey(anyKey).fiql(fiql).build();
212 try {
213 if (taskTO instanceof PushTaskTO) {
214 reconciliationRestClient.push(reconQuery, (PushTaskTO) form.getModelObject());
215 } else {
216 reconciliationRestClient.pull(reconQuery, (PullTaskTO) form.getModelObject());
217 }
218
219 SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
220 } catch (Exception e) {
221 LOG.error("While attempting reconciliation using query {} on {}",
222 reconQuery, form.getModelObject(), e);
223 SyncopeConsoleSession.get().onException(e);
224 }
225 multiLevelPanelRef.prev(target);
226 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
227 }
228 });
229 }
230 }