View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.core.provisioning.java.pushpull;
20  
21  import java.util.List;
22  import java.util.Objects;
23  import java.util.stream.Collectors;
24  import org.apache.syncope.common.lib.to.Provision;
25  import org.apache.syncope.common.lib.to.ProvisioningReport;
26  import org.apache.syncope.common.lib.to.PushTaskTO;
27  import org.apache.syncope.common.lib.types.ConflictResolutionAction;
28  import org.apache.syncope.common.lib.types.MatchingRule;
29  import org.apache.syncope.common.lib.types.TaskType;
30  import org.apache.syncope.common.lib.types.UnmatchingRule;
31  import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
32  import org.apache.syncope.core.persistence.api.entity.Any;
33  import org.apache.syncope.core.persistence.api.entity.AnyType;
34  import org.apache.syncope.core.persistence.api.entity.ExternalResource;
35  import org.apache.syncope.core.persistence.api.entity.task.PushTask;
36  import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount;
37  import org.apache.syncope.core.provisioning.api.Connector;
38  import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
39  import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
40  import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler;
41  import org.apache.syncope.core.provisioning.api.pushpull.SyncopeSinglePushExecutor;
42  import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
43  import org.quartz.JobExecutionException;
44  import org.springframework.beans.factory.annotation.Autowired;
45  
46  public class SinglePushJobDelegate extends PushJobDelegate implements SyncopeSinglePushExecutor {
47  
48      @Autowired
49      protected ImplementationDAO implementationDAO;
50  
51      protected void before(
52              final ExternalResource resource,
53              final Connector connector,
54              final PushTaskTO pushTaskTO,
55              final String executor) throws JobExecutionException {
56  
57          LOG.debug("Executing push on {}", resource);
58  
59          taskType = TaskType.PUSH;
60  
61          task = entityFactory.newEntity(PushTask.class);
62          task.setResource(resource);
63          task.setMatchingRule(pushTaskTO.getMatchingRule() == null
64                  ? MatchingRule.LINK : pushTaskTO.getMatchingRule());
65          task.setUnmatchingRule(pushTaskTO.getUnmatchingRule() == null
66                  ? UnmatchingRule.ASSIGN : pushTaskTO.getUnmatchingRule());
67          task.setPerformCreate(pushTaskTO.isPerformCreate());
68          task.setPerformUpdate(pushTaskTO.isPerformUpdate());
69          task.setPerformDelete(pushTaskTO.isPerformDelete());
70          task.setSyncStatus(pushTaskTO.isSyncStatus());
71  
72          profile = new ProvisioningProfile<>(connector, task);
73          profile.setExecutor(executor);
74          profile.getActions().addAll(getPushActions(pushTaskTO.getActions().stream().
75                  map(implementationDAO::find).filter(Objects::nonNull).collect(Collectors.toList())));
76          profile.setConflictResolutionAction(ConflictResolutionAction.FIRSTMATCH);
77  
78          for (PushActions action : profile.getActions()) {
79              action.beforeAll(profile);
80          }
81      }
82  
83      @Override
84      public List<ProvisioningReport> push(
85              final ExternalResource resource,
86              final Provision provision,
87              final Connector connector,
88              final Any<?> any,
89              final PushTaskTO pushTaskTO,
90              final String executor) throws JobExecutionException {
91  
92          try {
93              before(resource, connector, pushTaskTO, executor);
94              PushResultHandlerDispatcher dispatcher = new PushResultHandlerDispatcher(profile, this);
95  
96              AnyType anyType = anyTypeDAO.find(provision.getAnyType());
97  
98              dispatcher.addHandlerSupplier(provision.getAnyType(), () -> {
99                  SyncopePushResultHandler handler;
100                 switch (anyType.getKind()) {
101                     case USER:
102                         handler = buildUserHandler();
103                         break;
104 
105                     case GROUP:
106                         handler = buildGroupHandler();
107                         break;
108 
109                     case ANY_OBJECT:
110                     default:
111                         handler = buildAnyObjectHandler();
112                 }
113                 handler.setProfile(profile);
114                 return handler;
115             });
116 
117             doHandle(List.of(any), dispatcher, resource);
118 
119             for (PushActions action : profile.getActions()) {
120                 action.afterAll(profile);
121             }
122 
123             return profile.getResults();
124         } catch (Exception e) {
125             throw e instanceof JobExecutionException
126                     ? (JobExecutionException) e
127                     : new JobExecutionException("While pushing to connector", e);
128         } finally {
129             setStatus(null);
130         }
131     }
132 
133     @Override
134     public ProvisioningReport push(
135             final ExternalResource resource,
136             final Provision provision,
137             final Connector connector,
138             final LinkedAccount account,
139             final PushTaskTO pushTaskTO,
140             final String executor) throws JobExecutionException {
141 
142         try {
143             before(resource, connector, pushTaskTO, executor);
144 
145             UserPushResultHandler handler = buildUserHandler();
146             handler.setProfile(profile);
147 
148             handler.handle(account, provision);
149 
150             for (PushActions action : profile.getActions()) {
151                 action.afterAll(profile);
152             }
153 
154             return profile.getResults().get(0);
155         } catch (Exception e) {
156             throw e instanceof JobExecutionException
157                     ? (JobExecutionException) e
158                     : new JobExecutionException("While pushing to connector", e);
159         } finally {
160             setStatus(null);
161         }
162     }
163 }