001/*
002 *  Copyright 2022 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.workspaces.chat;
017
018import java.util.HashSet;
019import java.util.List;
020import java.util.Set;
021import java.util.stream.Collectors;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.cocoon.components.ContextHelper;
026import org.quartz.JobExecutionContext;
027
028import org.ametys.core.schedule.progression.ContainerProgressionTracker;
029import org.ametys.core.user.UserIdentity;
030import org.ametys.plugins.core.impl.schedule.AbstractStaticSchedulable;
031import org.ametys.plugins.workspaces.members.ProjectMemberManager;
032import org.ametys.plugins.workspaces.members.ProjectMemberManager.ProjectMember;
033import org.ametys.plugins.workspaces.project.ProjectManager;
034import org.ametys.plugins.workspaces.project.objects.Project;
035import org.ametys.runtime.config.Config;
036
037/**
038 * Job to ensure that chat server is synchronized with ametys: users and chatrooms. 
039 */
040public class ServersSynchronizationSchedulable extends AbstractStaticSchedulable
041{
042    private ChatHelper _chatHelper;
043    private ProjectManager _projectManager;
044    private ProjectMemberManager _projectMemberManager;
045
046    @Override
047    public void service(ServiceManager manager) throws ServiceException
048    {
049        super.service(manager);
050        _chatHelper = (ChatHelper) manager.lookup(ChatHelper.ROLE);
051        _projectManager = (ProjectManager) manager.lookup(ProjectManager.ROLE);
052        _projectMemberManager = (ProjectMemberManager) manager.lookup(ProjectMemberManager.ROLE);
053    }
054    
055    @Override
056    public void execute(JobExecutionContext context, ContainerProgressionTracker progressionTracker) throws Exception
057    {
058        if (!Config.getInstance().<Boolean>getValue("workspaces.chat.active"))
059        {
060            return;
061        }
062        
063        ContextHelper.getRequest(_context).setAttribute("site", Config.getInstance().getValue("workspaces.catalog.site.name"));
064        
065        int errors = 0;
066        
067        // The set of users already updated to ensure to update only once each user
068        Set<UserIdentity> handledUsers = new HashSet<>();
069        
070        for (String projectName : _projectManager.getProjectNames())
071        {
072            Project project = _projectManager.getProject(projectName);
073            
074            try
075            {
076                // Ensure that chatroom exists
077                _chatHelper.getRoom(projectName, true);
078                
079                // Prepare correct user lis
080                Set<ProjectMember> projectMembers = _projectMemberManager.getProjectMembers(project, true);
081                List<UserIdentity> projectMemersIdentities = projectMembers.stream().map(pm -> pm.getUser().getIdentity()).collect(Collectors.toList());
082                
083                // Remove any user in the chatroom
084                _chatHelper.removeAllUsersFromRoom(projectName, projectMemersIdentities);
085                
086                for (UserIdentity userIdentity : projectMemersIdentities)
087                {
088                    try
089                    {
090                        if (!handledUsers.contains(userIdentity))
091                        {
092                            // Ensure user exists
093                            _chatHelper.getUser(userIdentity, true);
094                            
095                            // Update existing users
096                            _chatHelper.updateUserInfos(userIdentity, false);
097                            
098                            handledUsers.add(userIdentity);
099                        }
100                        
101                        // Add user to the chat room
102                        _chatHelper.addUserToRoom(userIdentity, projectName);
103                    }
104                    catch (Exception e)
105                    {
106                        getLogger().error("An error occurred when syncronizing user " + UserIdentity.userIdentityToString(userIdentity) + " with project " + projectName, e);
107                        errors++;
108                    }
109                }
110            }
111            catch (Exception e)
112            {
113                getLogger().error("An error occurred when syncronizing project " + projectName, e);
114                errors++;
115            }
116        }
117        
118        if (errors > 0)
119        {
120            throw new IllegalStateException(errors + " errors occurred while synchronizing chat server. See previous log to know more");
121        }
122    }
123
124}