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.user.UserIdentity;
029import org.ametys.plugins.core.impl.schedule.AbstractStaticSchedulable;
030import org.ametys.plugins.workspaces.members.ProjectMemberManager;
031import org.ametys.plugins.workspaces.members.ProjectMemberManager.ProjectMember;
032import org.ametys.plugins.workspaces.project.ProjectManager;
033import org.ametys.plugins.workspaces.project.objects.Project;
034import org.ametys.runtime.config.Config;
035
036/**
037 * Job to ensure that chat server is synchronized with ametys: users and chatrooms. 
038 */
039public class ServersSynchronizationSchedulable extends AbstractStaticSchedulable
040{
041    private ChatHelper _chatHelper;
042    private ProjectManager _projectManager;
043    private ProjectMemberManager _projectMemberManager;
044
045    @Override
046    public void service(ServiceManager manager) throws ServiceException
047    {
048        super.service(manager);
049        _chatHelper = (ChatHelper) manager.lookup(ChatHelper.ROLE);
050        _projectManager = (ProjectManager) manager.lookup(ProjectManager.ROLE);
051        _projectMemberManager = (ProjectMemberManager) manager.lookup(ProjectMemberManager.ROLE);
052    }
053    
054    @Override
055    public void execute(JobExecutionContext context) throws Exception
056    {
057        if (!Config.getInstance().<Boolean>getValue("workspaces.chat.active"))
058        {
059            return;
060        }
061        
062        ContextHelper.getRequest(_context).setAttribute("site", Config.getInstance().getValue("workspaces.catalog.site.name"));
063        
064        int errors = 0;
065        
066        // The set of users already updated to ensure to update only once each user
067        Set<UserIdentity> handledUsers = new HashSet<>();
068        
069        for (String projectName : _projectManager.getProjectNames())
070        {
071            Project project = _projectManager.getProject(projectName);
072            
073            try
074            {
075                // Ensure that chatroom exists
076                _chatHelper.getRoom(projectName, true);
077                
078                // Prepare correct user lis
079                Set<ProjectMember> projectMembers = _projectMemberManager.getProjectMembers(project, true);
080                List<UserIdentity> projectMemersIdentities = projectMembers.stream().map(pm -> pm.getUser().getIdentity()).collect(Collectors.toList());
081                
082                // Remove any user in the chatroom
083                _chatHelper.removeAllUsersFromRoom(projectName, projectMemersIdentities);
084                
085                for (UserIdentity userIdentity : projectMemersIdentities)
086                {
087                    try
088                    {
089                        if (!handledUsers.contains(userIdentity))
090                        {
091                            // Ensure user exists
092                            _chatHelper.getUser(userIdentity, true);
093                            
094                            // Update existing users
095                            _chatHelper.updateUserInfos(userIdentity, false);
096                            
097                            handledUsers.add(userIdentity);
098                        }
099                        
100                        // Add user to the chat room
101                        _chatHelper.addUserToRoom(userIdentity, projectName);
102                    }
103                    catch (Exception e)
104                    {
105                        getLogger().error("An error occurred when syncronizing user " + UserIdentity.userIdentityToString(userIdentity) + " with project " + projectName, e);
106                        errors++;
107                    }
108                }
109            }
110            catch (Exception e)
111            {
112                getLogger().error("An error occurred when syncronizing project " + projectName, e);
113                errors++;
114            }
115        }
116        
117        if (errors > 0)
118        {
119            throw new IllegalStateException(errors + " errors occurred while synchronizing chat server. See previous log to know more");
120        }
121    }
122
123}