Re: Potential userlogic update issue
Hi, The updateAttr function in my prior email exists within my 'logic' class. I.e. org.apache.syncope.core.logic.AttributeLogic The second code block within the same email is what would/could exist within the Rest-CXF class of the extension. If I remove the @Transactional annotation on the updateAttr function, I start getting 'Could not find EntityManager for domain Master' exceptions, from my userDAO.findByUsername() call, (userDAO being autowired within the logic class). I have also tried passing through the UserDAO from the LogicContext class however that does not work either. On Tuesday, 28 November 2023 at 13:14, Francesco Chicchiriccò wrote: > 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 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(""); updateAttr(updateAttrTO1, >> "ExampleAttribute"); >> >> // - >> // Syncope value - "" >> // Downstream LDAP resource - N/A >> // - >> >> UpdateAttrTO updateAttrTO2 = new UpdateAttrTO(); >> updateAttrTO2.setKey("user123"); >> updateAttrTO2.setAttrVal(""); >> updateAttr(updateAttrTO2, "ExampleAttribute"); >> >> // >> // Syncope value - "" >> // Downstream LDAP resource - "" >> // >> ``` >> >> 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/
Re: Potential userlogic update issue
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 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(""); updateAttr(updateAttrTO1, "ExampleAttribute"); // - // Syncope value - "" // Downstream LDAP resource - N/A // - UpdateAttrTO updateAttrTO2 = new UpdateAttrTO(); updateAttrTO2.setKey("user123"); updateAttrTO2.setAttrVal(""); updateAttr(updateAttrTO2, "ExampleAttribute"); // // Syncope value - "" // Downstream LDAP resource - "" // ``` 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/
Potential userlogic update issue
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 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("");updateAttr(updateAttrTO1, "ExampleAttribute"); // - // Syncope value - "" // Downstream LDAP resource - N/A // - UpdateAttrTO updateAttrTO2 = new UpdateAttrTO(); updateAttrTO2.setKey("user123"); updateAttrTO2.setAttrVal(""); updateAttr(updateAttrTO2, "ExampleAttribute"); // // Syncope value - "" // Downstream LDAP resource - "" // ``` Hopefully I explained the situation sufficiently, if not please let me know and I can try to give some more detail. Kind Regards,GCHQDeveloper29.