1919import org .springframework .data .domain .AuditorAware ;
2020import org .springframework .data .domain .Page ;
2121import org .springframework .data .domain .Pageable ;
22+ import org .springframework .data .mongodb .core .FindAndModifyOptions ;
2223import org .springframework .data .mongodb .core .MongoTemplate ;
2324import org .springframework .data .mongodb .core .query .Criteria ;
2425import org .springframework .data .mongodb .core .query .Query ;
@@ -43,9 +44,11 @@ public class UserGroupServiceImpl implements UserGroupService {
4344 private static final String USER_GROUP_INSTITUTION_ID_REQUIRED_MESSAGE = "A user group institution id is required" ;
4445 private static final String USER_GROUP_PARENT_INSTITUTION_ID_REQUIRED_MESSAGE = "A user group parent institution id is required" ;
4546 private static final String MEMBERS_REQUIRED = "Members are required" ;
47+ private static final String GROUP_NAME_REQUIRED = "A group name is required" ;
4648 private static final String MEMBER_ID_REQUIRED = "A member id is required" ;
49+ private static final String GROUP_NAME_FORBIDDEN = "Group name cannot start with 'Ente Aggregatore'" ;
4750 private static final String GROUP_NAME_ALREADY_EXISTS = "A group with the same name already exists in ACTIVE or SUSPENDED state" ;
48- private static final String GROUP_PARENT_ALREADY_EXISTS = "A group with the same institutionId-parentInstitutionId-productId already exists in ACTIVE or SUSPENDED state " ;
51+ private static final String ENTE_AGGREGATORE_PLACEHOLDER = "Ente Aggregatore " ;
4952 private final List <String > allowedSortingParams ;
5053 private final UserGroupRepository repository ;
5154 private final MongoTemplate mongoTemplate ;
@@ -70,7 +73,7 @@ public UserGroupOperations createGroup(UserGroupOperations group) {
7073 Assert .state (authentication .getPrincipal () instanceof SelfCareUser , "Not SelfCareUser principal" );
7174 Assert .notNull (group , "A group is required" );
7275
73- checkGroupUniqueness (group .getId (), group .getName (), group .getProductId (), group .getInstitutionId (), group . getParentInstitutionId () );
76+ checkGroupUniqueness (group .getId (), group .getName (), group .getProductId (), group .getInstitutionId ());
7477 return insertUserGroupEntity (group );
7578 }
7679
@@ -89,21 +92,30 @@ public void addMember(String id, UUID memberId) {
8992 }
9093
9194 @ Override
92- public void addMembers (String institutionId , String parentInstitutionId , String productId , Set <UUID > members ) {
93- log .trace ("addMembers start" );
94- log .debug ("addMembers institutionId = {}, parentInstitutionId = {}, members = {}" ,
95- Encode .forJava (institutionId ), Encode .forJava (parentInstitutionId ), Encode .forJava (members .toString ()));
96- Assert .notNull (institutionId , USER_GROUP_INSTITUTION_ID_REQUIRED_MESSAGE );
97- Assert .notNull (parentInstitutionId , USER_GROUP_PARENT_INSTITUTION_ID_REQUIRED_MESSAGE );
98- Assert .notNull (members , MEMBERS_REQUIRED );
99- UserGroupFilter userGroupFilter = UserGroupFilter .builder ()
100- .institutionId (institutionId )
101- .parentInstitutionId (parentInstitutionId )
102- .productId (productId )
103- .build ();
104- String groupId = findGroupId (userGroupFilter );
105- insertMembers (groupId , members );
106- log .trace ("addMembers end" );
95+ public void createGroupOrAddMembers (UserGroupOperations userGroupOperations ) {
96+ log .trace ("createGroupOrAddMembers start" );
97+ log .debug ("createGroupOrAddMembers institutionId = {}, parentInstitutionId = {}, members = {}" ,
98+ Encode .forJava (userGroupOperations .getInstitutionId ()), Encode .forJava (userGroupOperations .getParentInstitutionId ()), Encode .forJava (userGroupOperations .getMembers ().toString ()));
99+ Assert .notNull (userGroupOperations .getInstitutionId (), USER_GROUP_INSTITUTION_ID_REQUIRED_MESSAGE );
100+ Assert .notNull (userGroupOperations .getParentInstitutionId (), USER_GROUP_PARENT_INSTITUTION_ID_REQUIRED_MESSAGE );
101+ Assert .notNull (userGroupOperations .getMembers (), MEMBERS_REQUIRED );
102+
103+ Query query = new Query (Criteria .where (UserGroupEntity .Fields .institutionId ).is (userGroupOperations .getInstitutionId ())
104+ .and (UserGroupEntity .Fields .productId ).is (userGroupOperations .getProductId ())
105+ .and (UserGroupEntity .Fields .parentInstitutionId ).is (userGroupOperations .getParentInstitutionId ())
106+ .and (UserGroupEntity .Fields .status ).in (List .of (UserGroupStatus .ACTIVE , UserGroupStatus .SUSPENDED )));
107+
108+ Update update = new Update ()
109+ .setOnInsert (UserGroupEntity .Fields .name , ENTE_AGGREGATORE_PLACEHOLDER + userGroupOperations .getName ())
110+ .setOnInsert (UserGroupEntity .Fields .description , userGroupOperations .getDescription ())
111+ .setOnInsert (UserGroupEntity .Fields .status , UserGroupStatus .ACTIVE )
112+ .addToSet (UserGroupEntity .Fields .members ).each (userGroupOperations .getMembers ());
113+
114+ FindAndModifyOptions options = FindAndModifyOptions .options ()
115+ .upsert (true );
116+
117+ mongoTemplate .findAndModify (query , update , options , UserGroupEntity .class );
118+ log .trace ("createGroupOrAddMembers end" );
107119 }
108120
109121 @ Override
@@ -213,7 +225,8 @@ public UserGroupOperations updateGroup(String id, UserGroupOperations group) {
213225 if (UserGroupStatus .SUSPENDED .equals (foundGroup .getStatus ())) {
214226 throw new ResourceUpdateException (TRYING_TO_MODIFY_SUSPENDED_GROUP );
215227 }
216- checkGroupUniqueness (id , group .getName (), foundGroup .getProductId (), foundGroup .getInstitutionId (), foundGroup .getParentInstitutionId ());
228+
229+ checkGroupUniqueness (id , group .getName (), foundGroup .getProductId (), foundGroup .getInstitutionId ());
217230
218231 foundGroup .setMembers (group .getMembers ());
219232 foundGroup .setName (group .getName ());
@@ -238,36 +251,26 @@ private UserGroupEntity insertUserGroupEntity(UserGroupOperations group) {
238251 return insert ;
239252 }
240253
241- private void checkGroupUniqueness (String currentGroupId , String groupName , String productId , String institutionId , String parentInstitutionId ) {
242- UserGroupFilter filter = new UserGroupFilter ();
243- filter .setProductId (productId );
244- filter .setInstitutionId (institutionId );
245- filter .setStatus (Arrays .asList (UserGroupStatus .ACTIVE , UserGroupStatus .SUSPENDED ));
254+ private void checkGroupUniqueness (String currentGroupId , String groupName , String productId , String institutionId ) {
246255
247- Page <UserGroupOperations > existingGroups = findAll (filter , Pageable .unpaged ());
256+ Assert .notNull (groupName , GROUP_NAME_REQUIRED );
257+ Assert .isTrue (!groupName .startsWith (ENTE_AGGREGATORE_PLACEHOLDER ), GROUP_NAME_FORBIDDEN );
248258
249- // verify if there's no other group with the same name (but different groupId)
250- boolean isSameName = existingGroups .stream ().anyMatch (g ->
251- g .getName ().equals (groupName ) && !g .getId ().equals (currentGroupId ));
259+ Query query = new Query (
260+ Criteria .where (UserGroupEntity .Fields .institutionId ).is (institutionId )
261+ .and (UserGroupEntity .Fields .productId ).is (productId )
262+ .and (UserGroupEntity .Fields .status ).in (List .of (UserGroupStatus .ACTIVE , UserGroupStatus .SUSPENDED ))
263+ );
252264
253- // when parentInsitutionId is not null, verify if there's no other group with same institutionId-parentInstitutionId-productId (but different groupId)
254- boolean isDuplicate = parentInstitutionId != null && existingGroups .stream ().anyMatch (g ->
255- Objects .equals (g .getInstitutionId (), institutionId )
256- && Objects .equals (g .getProductId (), productId )
257- && Objects .equals (g .getParentInstitutionId (), parentInstitutionId )
258- && !g .getId ().equals (currentGroupId ));
265+ List <UserGroupEntity > foundGroups = mongoTemplate .find (query , UserGroupEntity .class );
266+
267+ boolean isSameName = foundGroups .stream ().anyMatch (g ->
268+ g .getName ().equals (groupName ) && !g .getId ().equals (currentGroupId ));
259269
260270 if (isSameName ) {
261271 log .warn ("Attempted to create/update group with duplicate name: {}" , groupName );
262272 throw new ResourceAlreadyExistsException (GROUP_NAME_ALREADY_EXISTS );
263- }
264-
265- if (isDuplicate ) {
266- log .warn ("Attempted to create/update group with duplicate institutionId: {}, parentInstitutionId: {} and productId: {}" ,
267- institutionId , parentInstitutionId , productId );
268- throw new ResourceAlreadyExistsException (GROUP_PARENT_ALREADY_EXISTS );
269- }
270- }
273+ } }
271274
272275 private Query createActiveGroupQuery (String id ) {
273276 return Query .query (Criteria .where (UserGroupEntity .Fields .ID ).is (id )
@@ -303,26 +306,6 @@ private String findGroupId(UserGroupFilter userGroupFilter) {
303306 return foundGroups .getContent ().get (0 ).getId ();
304307 }
305308
306- private void insertMembers (String id , Set <UUID > memberIds ) {
307- log .trace ("insertMembers start" );
308- log .debug ("insertMembers id = {}, memberIds = {}" , Encode .forJava (id ), Encode .forJava (memberIds .toString ()));
309-
310- // convert UUIDs
311- Object [] userIdsAsStrings = memberIds .stream ()
312- .map (UUID ::toString )
313- .toArray ();
314-
315- mongoTemplate .updateFirst (
316- createActiveGroupQuery (id ),
317- new Update ()
318- .addToSet (UserGroupEntity .Fields .members ).each (userIdsAsStrings )
319- .set (UserGroupEntity .Fields .modifiedBy , auditorAware .getCurrentAuditor ().orElse (null ))
320- .currentDate (UserGroupEntity .Fields .modifiedAt ),
321- UserGroupEntity .class );
322-
323- log .trace ("insertMembers end" );
324- }
325-
326309 private void removeMembersWithParentInstitutionId (String id , Set <UUID > memberIds ) {
327310 log .trace ("removeMembersWithParentInstitutionId start" );
328311 log .debug ("removeMembersWithParentInstitutionId id = {}, memberIds = {}" , Encode .forJava (id ), Encode .forJava (memberIds .toString ()));
0 commit comments