/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.restapi.system;
import java.util.Calendar;
import java.util.List;
import java.util.Set;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.olat.admin.sysinfo.manager.SessionStatsManager;
import org.olat.admin.sysinfo.model.SessionsStats;
import org.olat.basesecurity.BaseSecurity;
import org.olat.basesecurity.Constants;
import org.olat.core.CoreSpringFactory;
import org.olat.core.id.Identity;
import org.olat.core.util.SessionInfo;
import org.olat.core.util.UserSession;
import org.olat.core.util.WorkThreadInformations;
import org.olat.core.util.session.UserSessionManager;
import org.olat.course.CourseModule;
import org.olat.group.BusinessGroupService;
import org.olat.portfolio.manager.InvitationDAO;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryManager;
import org.olat.restapi.system.vo.OpenOLATStatisticsVO;
import org.olat.restapi.system.vo.RepositoryStatisticsVO;
import org.olat.restapi.system.vo.SessionsVO;
import org.olat.restapi.system.vo.TasksVO;
import org.olat.restapi.system.vo.UserStatisticsVO;
/**
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class OpenOLATStatisticsWebService implements Sampler {
private final IndexerWebService indexerWebService = new IndexerWebService();
/**
* Return the statistics about OpenOLAT, users count, courses count...
* @response.representation.200.qname {http://www.example.com}releaseVO
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc The verison of the instance
* @response.representation.200.example {@link org.olat.restapi.system.vo.Examples#SAMPLE_OO_STATSVO}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @param request The HTTP request
* @return The statistics about OpenOLAT
*/
@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getStatistics() {
OpenOLATStatisticsVO stats = new OpenOLATStatisticsVO();
stats.setSessions(getSessionsVO());
stats.setUserStatistics(getUserStatisticsVO());
stats.setRepositoryStatistics(getRepositoryStatisticsVO());
stats.setIndexerStatistics(indexerWebService.getIndexerStatistics());
return Response.ok(stats).build();
}
/**
* Return the statistics about OpenOLAT users
* @response.representation.200.qname {http://www.example.com}releaseVO
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc The verison of the instance
* @response.representation.200.example {@link org.olat.restapi.system.vo.Examples#SAMPLE_OO_USERSSTATSVO}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @param request The HTTP request
* @return The statistics about OpenOLAT users
*/
@GET
@Path("users")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getUserStatistics() {
UserStatisticsVO stats = getUserStatisticsVO();
return Response.ok(stats).build();
}
/**
* Return the statistics about the repository, courses count, published courses...
* @response.representation.200.qname {http://www.example.com}releaseVO
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc The verison of the instance
* @response.representation.200.example {@link org.olat.restapi.system.vo.Examples#SAMPLE_OO_REPOSTATSVO}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @param request The HTTP request
* @return The statistics about the repository
*/
@GET
@Path("repository")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getRepositoryStatistics() {
RepositoryStatisticsVO stats = getRepositoryStatisticsVO();
return Response.ok(stats).build();
}
/**
* Return the statistics about the indexer
* @response.representation.200.qname {http://www.example.com}releaseVO
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc The verison of the instance
* @response.representation.200.example {@link org.olat.restapi.system.vo.Examples#SAMPLE_OO_INDEXERSTATSVO}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @param request The HTTP request
* @return The statistics about the indexer
*/
@Path("indexer")
public IndexerWebService getIndexerStatistics() {
return indexerWebService;
}
/**
* Return some statistics about session.
* @response.representation.200.qname {http://www.example.com}sessionVO
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc A short summary about sessions
* @response.representation.200.example {@link org.olat.restapi.system.vo.Examples#SAMPLE_SESSIONVO}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @param request The HTTP request
* @return The statistics about sessions
*/
@GET
@Path("sessions")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getSessions() {
SessionsVO vo = getSessionsVO();
return Response.ok(vo).build();
}
/**
* Return some statistics about long running tasks.
* @response.representation.200.qname {http://www.example.com}taskVOes
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc A short summary about sessions
* @response.representation.200.example {@link org.olat.restapi.system.vo.Examples#SAMPLE_SESSIONVO}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @param request The HTTP request
* @return The statistics about sessions
*/
@GET
@Path("tasks")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getTasks() {
TasksVO vo = getTasksVO();
return Response.ok(vo).build();
}
private UserStatisticsVO getUserStatisticsVO() {
UserStatisticsVO stats = new UserStatisticsVO();
BaseSecurity securityManager = CoreSpringFactory.getImpl(BaseSecurity.class);
// activeUserCount="88" // registered and activated identities, same as in GUI
long countActiveUsers = securityManager.countIdentitiesByPowerSearch(null, null, false, null, null, null, null, null, null, null, Constants.USERSTATUS_ACTIVE);
stats.setActiveUserCount(countActiveUsers);
// active last day
Calendar lastDay = Calendar.getInstance();
lastDay.add(Calendar.DATE, -1);
long activeUserCountDay = securityManager.countUniqueUserLoginsSince(lastDay.getTime());
stats.setActiveUserCountLastDay(activeUserCountDay);
// active last week
Calendar lastWeek = Calendar.getInstance();
lastWeek.add(Calendar.DATE, -7);
long activeUserCountWeek = securityManager.countUniqueUserLoginsSince(lastWeek.getTime());
stats.setActiveUserCountLastWeek(activeUserCountWeek);
// active last month
Calendar lastMonth = Calendar.getInstance();
lastMonth.add(Calendar.MONTH, -1);
long activeUserCountMonth = securityManager.countUniqueUserLoginsSince(lastMonth.getTime());
stats.setActiveUserCountLastMonth(activeUserCountMonth);
// active last 6 month
Calendar last6Month = Calendar.getInstance();
last6Month.add(Calendar.MONTH, -6);
long activeUserCount6Month = securityManager.countUniqueUserLoginsSince(last6Month.getTime());
stats.setActiveUserCountLast6Month(activeUserCount6Month);
// externalUserCount="12" // EP invite identities, later maybe also used in courses for MOOCS, external experts etc)
long invitationsCount = CoreSpringFactory.getImpl(InvitationDAO.class).countInvitations();
stats.setExternalUserCount(invitationsCount);
// blockedUserCount="0" // identities in login blocked state
long blockedUserCount = securityManager.countIdentitiesByPowerSearch(null, null, true, null, null, null, null, null, null, null, Identity.STATUS_LOGIN_DENIED);
stats.setBlockedUserCount(blockedUserCount);
// deletedUserCount="943" // deleted identities
long deletedUserCount = securityManager.countIdentitiesByPowerSearch(null, null, true, null, null, null, null, null, null, null, Identity.STATUS_DELETED);
stats.setDeletedUserCount(deletedUserCount);
// totalUserCount="1043" // Sum of all above
long countUsers = securityManager.countIdentitiesByPowerSearch(null, null, false, null, null, null, null, null, null, null, null);
stats.setTotalUserCount(countUsers);
BusinessGroupService bgs = CoreSpringFactory.getImpl(BusinessGroupService.class);
long countGroups = bgs.countBusinessGroups(null, null);
stats.setTotalGroupCount(countGroups);
return stats;
}
private RepositoryStatisticsVO getRepositoryStatisticsVO() {
RepositoryStatisticsVO stats = new RepositoryStatisticsVO();
RepositoryManager repoMgr = CoreSpringFactory.getImpl(RepositoryManager.class);
int allCourses = repoMgr.countByTypeLimitAccess(CourseModule.ORES_TYPE_COURSE, RepositoryEntry.ACC_OWNERS);
int publishedCourses = repoMgr.countByTypeLimitAccess(CourseModule.ORES_TYPE_COURSE, RepositoryEntry.ACC_USERS);
stats.setCoursesCount(allCourses);
stats.setPublishedCoursesCount(publishedCourses);
return stats;
}
private TasksVO getTasksVO() {
TasksVO tasks = new TasksVO();
List<String> longRunningTaskList = WorkThreadInformations.getLongRunningTasks();
String[] longRunningTasks = longRunningTaskList.toArray(new String[longRunningTaskList.size()]);
tasks.setLongRunningTasks(longRunningTasks);
return tasks;
}
protected SessionsVO getSessionsVO() {
SessionsVO vo = new SessionsVO();
SessionStatsManager sessionStatsManager = CoreSpringFactory.getImpl(SessionStatsManager.class);
UserSessionManager sessionManager = CoreSpringFactory.getImpl(UserSessionManager.class);
vo.setCount(sessionManager.getUserSessionsCnt());
Set<UserSession> userSessions = sessionManager.getAuthenticatedUserSessions();
int webdavcount = 0;
int secureWebdavCount = 0;
int authenticatedcount = 0;
int secureAuthenticatedCount = 0;
int restCount = 0;
int secureRestCount = 0;
for (UserSession usess:userSessions) {
SessionInfo sessInfo = usess.getSessionInfo();
if (sessInfo.isWebDAV()) {
webdavcount++;
if (sessInfo.isSecure()) {
secureWebdavCount++;
}
} else if (sessInfo.isREST()) {
restCount++;
if (sessInfo.isSecure()) {
secureRestCount++;
}
} else {
authenticatedcount++;
if (sessInfo.isSecure()) {
secureAuthenticatedCount++;
}
}
}
vo.setAuthenticatedCount(authenticatedcount);
vo.setSecureAuthenticatedCount(secureAuthenticatedCount);
vo.setWebdavCount(webdavcount);
vo.setSecureWebdavCount(secureWebdavCount);
vo.setRestCount(restCount);
vo.setSecureRestCount(secureRestCount);
//Instant messaging
vo.setInstantMessagingCount(-1);
SessionsStats statsLastMinute = sessionStatsManager.getSessionsStatsLast(60);
SessionsStats statsLast5Minutes = sessionStatsManager.getSessionsStatsLast(300);
vo.setAuthenticatedClickCountLastMinute(statsLastMinute.getAuthenticatedClickCalls());
vo.setAuthenticatedClickCountLastFiveMinutes(statsLast5Minutes.getAuthenticatedPollerCalls());
vo.setAuthenticatedPollCountLastMinute(statsLastMinute.getAuthenticatedPollerCalls());
vo.setAuthenticatedPollCountLastFiveMinutes(statsLast5Minutes.getAuthenticatedPollerCalls());
vo.setRequestLastMinute(statsLastMinute.getRequests());
vo.setRequestLastFiveMinutes(statsLast5Minutes.getRequests());
vo.setConcurrentDispatchThreads(sessionStatsManager.getConcurrentCounter());
return vo;
}
@Override
public void takeSample() {
SessionStatsManager manager = CoreSpringFactory.getImpl(SessionStatsManager.class);
if(manager != null) {//check if the manager is loaded
manager.takeSample();
}
}
}