Hi,
I assume the code below lies inside a REST service implementation class.
Basically, it manipulates payload objects (UserCR, AttrPatch and so on) then
invokes UserLogic for actual processing.
If so, then you should remove @Transactional from such method as by doing so
you are essentially breaking the transaction mechanism as managed by UserLogic.
HTH
Regards.
On 28/11/23 11:53, GCHQDeveloper29 wrote:
Hi there,
I'm hoping to gain some advice (or report a bug in the case I've not just been
a fool!).
I'm currently on version 3.0.4, although plan to move to 3.0.5 soon, and am
using version 1.5.7 of the LDAP connector.
I have a slightly different version of the following function sat behind a rest
endpoint, but am observing peculiar behaviour when calling the rest endpoint
(hence triggering an update in userLogic).
```
@Transactional
public Response updateAttr(final UpdateAttrTO updateAttrTO, final String
attribute)
{
// key can either be the username or the UUID of the user
String key = updateAttrTO.getKey();
String attrVal = updateAttrTO.getAttrVal();
try {
// getUser gets the user object, first trying by username, then by UUID
User user = getUser(key);
String uuid = user.getKey();
String username = user.getUsername();
// Create the patch and user update request
Attr attr = new Attr.Builder(attribute)
.value(attrVal)
.build();
AttrPatch patch = new AttrPatch.Builder(attr)
.operation(attrVal == "" ? PatchOperation.DELETE :
PatchOperation.ADD_REPLACE)
.build();
UserUR userUR = new UserUR.Builder(uuid)
.plainAttr(patch)
.build();
// Attempt to patch the user
ProvisioningResult<UserTO> provisioningResult =
userLogic.update(userUR, false);
return Response.ok().build();
}
// Catch if a user cannot be found
catch (NotFoundException e)
{
return Response.status(400, e.getLocalizedMessage()).build();
}
// Catch any other unanticipated error
catch (Exception e)
{
return Response.status(500, e.getLocalizedMessage()).build();
}
}
```
The above function can be called as below (I use rest parameters in actuality):
```
UpdateAttrTO updateAttrTO = new UpdateAttrTO();
updateAttrTO.setKey("ExampleKey");
updateAttrTO.setAttrVal("ExampleAttrVal");
return updateAttr(updateAttrTO, "ExampleAttribute");
```
When I do this, the value gets updated within syncopes database, however the
propogation task (to an LDAP connector), updates the downstream resource with
the previous value.
For example, if I were to do the following for a user "user123", that does not initially
have "ExampleAttribute" set, the downstream resource is always one value behind:
```
// ----
// Syncope value - N/A
// Downstream LDAP resource - N/A
// ----
UpdateAttrTO updateAttrTO1 = new UpdateAttrTO();
updateAttrTO1.setKey("user123");
updateAttrTO1.setAttrVal("1111");
updateAttr(updateAttrTO1, "ExampleAttribute");
// -----
// Syncope value - "1111"
// Downstream LDAP resource - N/A
// -----
UpdateAttrTO updateAttrTO2 = new UpdateAttrTO();
updateAttrTO2.setKey("user123");
updateAttrTO2.setAttrVal("2222");
updateAttr(updateAttrTO2, "ExampleAttribute");
// ----
// Syncope value - "2222"
// Downstream LDAP resource - "1111"
// ----
```
Hopefully I explained the situation sufficiently, if not please let me know and
I can try to give some more detail.
Kind Regards,
GCHQDeveloper29.
--
Francesco Chicchiriccò
Tirasa - Open Source Excellence
http://www.tirasa.net/
Member at The Apache Software Foundation
Syncope, Cocoon, Olingo, CXF, OpenJPA, PonyMail
http://home.apache.org/~ilgrosso/