Return-Path: X-Original-To: apmail-syncope-commits-archive@www.apache.org Delivered-To: apmail-syncope-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 68A3210325 for ; Sat, 14 Dec 2013 09:01:44 +0000 (UTC) Received: (qmail 59299 invoked by uid 500); 14 Dec 2013 09:01:44 -0000 Delivered-To: apmail-syncope-commits-archive@syncope.apache.org Received: (qmail 59251 invoked by uid 500); 14 Dec 2013 09:01:41 -0000 Mailing-List: contact commits-help@syncope.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@syncope.apache.org Delivered-To: mailing list commits@syncope.apache.org Received: (qmail 59235 invoked by uid 99); 14 Dec 2013 09:01:40 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 14 Dec 2013 09:01:40 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 14 Dec 2013 09:01:35 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id B8FF02388A29; Sat, 14 Dec 2013 09:01:13 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1550905 - in /syncope/branches/1_1_X: common/src/main/java/org/apache/syncope/common/util/ core/src/main/java/org/apache/syncope/core/rest/controller/ core/src/main/java/org/apache/syncope/core/rest/data/ core/src/test/java/org/apache/sync... Date: Sat, 14 Dec 2013 09:01:13 -0000 To: commits@syncope.apache.org From: fmartelli@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20131214090113.B8FF02388A29@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: fmartelli Date: Sat Dec 14 09:01:12 2013 New Revision: 1550905 URL: http://svn.apache.org/r1550905 Log: Fixes SYNCOPE-459 on the branch 1.1.X Modified: syncope/branches/1_1_X/common/src/main/java/org/apache/syncope/common/util/AttributableOperations.java syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java syncope/branches/1_1_X/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java Modified: syncope/branches/1_1_X/common/src/main/java/org/apache/syncope/common/util/AttributableOperations.java URL: http://svn.apache.org/viewvc/syncope/branches/1_1_X/common/src/main/java/org/apache/syncope/common/util/AttributableOperations.java?rev=1550905&r1=1550904&r2=1550905&view=diff ============================================================================== --- syncope/branches/1_1_X/common/src/main/java/org/apache/syncope/common/util/AttributableOperations.java (original) +++ syncope/branches/1_1_X/common/src/main/java/org/apache/syncope/common/util/AttributableOperations.java Sat Dec 14 09:01:12 2013 @@ -72,7 +72,18 @@ public final class AttributableOperation ? new HashSet(originalAttrs.get(entry.getKey()).getValues()) : Collections.emptySet(); - if (!updatedValues.equals(originalValues)) { + if (!originalAttrs.containsKey(entry.getKey())) { + // SYNCOPE-459: take care of user virtual attributes without any value + updatedValues.remove(""); + mod.setValuesToBeAdded(new ArrayList(updatedValues)); + + if (virtuals) { + result.addVirtualAttributeToBeUpdated(mod); + } else { + result.addAttributeToBeUpdated(mod); + } + + } else if (!updatedValues.equals(originalValues)) { // avoid unwanted inputs updatedValues.remove(""); if (!entry.getValue().isReadonly()) { Modified: syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java URL: http://svn.apache.org/viewvc/syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java?rev=1550905&r1=1550904&r2=1550905&view=diff ============================================================================== --- syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java (original) +++ syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java Sat Dec 14 09:01:12 2013 @@ -302,7 +302,7 @@ public class UserController extends Abst actual.getVirtualAttributesToBeRemoved(), actual.getVirtualAttributesToBeUpdated()); } else { // 2b. generate the propagation task list in two phases: first the ones containing password, - // the the rest (with no password) + // the rest (with no password) final PropagationByResource origPropByRes = new PropagationByResource(); origPropByRes.merge(updated.getPropByRes()); @@ -347,11 +347,21 @@ public class UserController extends Abst PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class); - try { - taskExecutor.execute(tasks, propagationReporter); - } catch (PropagationException e) { - LOG.error("Error propagation primary resource", e); - propagationReporter.onPrimaryResourceFailure(tasks); + + if (tasks.isEmpty()) { + // SYNCOPE-459: take care of user virtual attributes ... + binder.forceVirtualAttributes( + updated.getResult().getKey(), + actual.getVirtualAttributesToBeRemoved(), + actual.getVirtualAttributesToBeUpdated()); + + } else { + try { + taskExecutor.execute(tasks, propagationReporter); + } catch (PropagationException e) { + LOG.error("Error propagation primary resource", e); + propagationReporter.onPrimaryResourceFailure(tasks); + } } // 4. prepare result, including propagation status on external resources @@ -486,7 +496,7 @@ public class UserController extends Abst List tasks = propagationManager.getUserUpdateTaskIds( new WorkflowResult>(new SimpleEntry(updated.getResult(), null), - updated.getPropByRes(), updated.getPerformedTasks())); + updated.getPropByRes(), updated.getPerformedTasks())); taskExecutor.execute(tasks); @@ -527,9 +537,9 @@ public class UserController extends Abst if (updated.getPropByRes() != null && !updated.getPropByRes().isEmpty()) { List tasks = propagationManager.getUserUpdateTaskIds( new WorkflowResult>( - new SimpleEntry(updated.getResult().getKey(), Boolean.TRUE), - updated.getPropByRes(), - updated.getPerformedTasks()), + new SimpleEntry(updated.getResult().getKey(), Boolean.TRUE), + updated.getPropByRes(), + updated.getPerformedTasks()), updated.getResult().getValue(), true, null, Modified: syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java URL: http://svn.apache.org/viewvc/syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java?rev=1550905&r1=1550904&r2=1550905&view=diff ============================================================================== --- syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java (original) +++ syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java Sat Dec 14 09:01:12 2013 @@ -155,7 +155,7 @@ public abstract class AbstractAttributab LOG.debug("Ignoring invalid virtual schema {}", virSchemaName); } } - + return virtualSchema; } Modified: syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java URL: http://svn.apache.org/viewvc/syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java?rev=1550905&r1=1550904&r2=1550905&view=diff ============================================================================== --- syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java (original) +++ syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java Sat Dec 14 09:01:12 2013 @@ -53,7 +53,7 @@ import org.springframework.stereotype.Co import org.springframework.transaction.annotation.Transactional; @Component -@Transactional(rollbackFor = {Throwable.class}) +@Transactional(rollbackFor = { Throwable.class }) public class RoleDataBinder extends AbstractAttributableDataBinder { @Autowired Modified: syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java URL: http://svn.apache.org/viewvc/syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java?rev=1550905&r1=1550904&r2=1550905&view=diff ============================================================================== --- syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java (original) +++ syncope/branches/1_1_X/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java Sat Dec 14 09:01:12 2013 @@ -23,6 +23,7 @@ import java.util.HashSet; import java.util.Set; import javax.annotation.Resource; import org.apache.commons.lang.StringUtils; +import org.apache.syncope.common.mod.AttributeMod; import org.apache.syncope.common.mod.MembershipMod; import org.apache.syncope.common.mod.UserMod; import org.apache.syncope.common.to.MembershipTO; @@ -62,11 +63,11 @@ import org.springframework.stereotype.Co import org.springframework.transaction.annotation.Transactional; @Component -@Transactional(rollbackFor = {Throwable.class}) +@Transactional(rollbackFor = { Throwable.class }) public class UserDataBinder extends AbstractAttributableDataBinder { - private static final String[] IGNORE_USER_PROPERTIES = {"memberships", "attributes", "derivedAttributes", - "virtualAttributes", "resources"}; + private static final String[] IGNORE_USER_PROPERTIES = { "memberships", "attributes", "derivedAttributes", + "virtualAttributes", "resources" }; @Autowired private ConnObjectUtil connObjectUtil; @@ -408,4 +409,24 @@ public class UserDataBinder extends Abst public UserTO getUserTO(final Long userId) { return getUserTO(getUserFromId(userId)); } + + /** + * SYNCOPE-459: force virtual attribute changes. + *
+ * To be used in case of no propagation task defined. + * + * @param id attributable id + * @param vAttrsToBeRemoved virtual attribute to be removed. + * @param vAttrsToBeUpdated virtyal attribute to be updated. + */ + public void forceVirtualAttributes( + final Long id, final Set vAttrsToBeRemoved, final Set vAttrsToBeUpdated) { + final SyncopeUser syncopeUser = getUserFromId(id); + + fillVirtual( + syncopeUser, + vAttrsToBeRemoved, + vAttrsToBeUpdated, + AttributableUtil.getInstance(syncopeUser)); + } } Modified: syncope/branches/1_1_X/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java URL: http://svn.apache.org/viewvc/syncope/branches/1_1_X/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java?rev=1550905&r1=1550904&r2=1550905&view=diff ============================================================================== --- syncope/branches/1_1_X/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java (original) +++ syncope/branches/1_1_X/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java Sat Dec 14 09:01:12 2013 @@ -519,4 +519,32 @@ public class VirAttrTestITCase extends A roleService.delete(roleTO.getId()); // ------------------------------------------- } + + @Test + public void issueSYNCOPE459() { + UserTO userTO = getUniqueSampleTO("syncope459@apache.org"); + userTO.getResources().clear(); + userTO.getMemberships().clear(); + userTO.getVirtualAttributes().clear(); + + final AttributeTO virtualReadOnly = attributeTO("virtualReadOnly", ""); + virtualReadOnly.getValues().clear(); + + userTO.addVirtualAttribute(virtualReadOnly); + + userTO = createUser(userTO); + + assertNotNull(userTO.getVirtualAttributeMap().get("virtualReadOnly")); + + UserMod userMod = new UserMod(); + userMod.setId(userTO.getId()); + + AttributeMod virtualdata = new AttributeMod(); + virtualdata.setSchema("virtualdata"); + + userMod.addVirtualAttributeToBeUpdated(virtualdata); + + userTO = userService.update(userTO.getId(), userMod); + assertNotNull(userTO.getVirtualAttributeMap().get("virtualdata")); + } }