001/* 002 * Copyright 2023 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.runtime.plugins.admin.statistics; 017 018import java.lang.management.ManagementFactory; 019import java.util.ArrayList; 020import java.util.Collections; 021import java.util.List; 022import java.util.Map; 023import java.util.Map.Entry; 024import java.util.TreeMap; 025 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.avalon.framework.service.Serviceable; 029import org.apache.commons.lang3.StringUtils; 030 031import org.ametys.core.authentication.CredentialProvider; 032import org.ametys.core.authentication.CredentialProviderFactory; 033import org.ametys.core.authentication.CredentialProviderModel; 034import org.ametys.core.group.GroupDirectoryDAO; 035import org.ametys.core.group.directory.GroupDirectory; 036import org.ametys.core.group.directory.GroupDirectoryFactory; 037import org.ametys.core.user.directory.UserDirectory; 038import org.ametys.core.user.directory.UserDirectoryFactory; 039import org.ametys.core.user.population.UserPopulation; 040import org.ametys.core.user.population.UserPopulationDAO; 041import org.ametys.core.version.VersionsHandler; 042import org.ametys.runtime.config.Config; 043import org.ametys.runtime.i18n.I18nizableText; 044import org.ametys.runtime.plugin.PluginsManager; 045import org.ametys.runtime.plugin.component.PluginAware; 046import org.ametys.runtime.servlet.AnalyseFileForVirusHelper; 047 048/** 049 * All statistics of kernel 050 */ 051public class KernelStatisticsProvider implements StatisticsProvider, Serviceable, PluginAware 052{ 053 private String _id; 054 private VersionsHandler _versionsHandler; 055 private UserPopulationDAO _userPopulationDAO; 056 private UserDirectoryFactory _userDirectoryFactory; 057 private CredentialProviderFactory _credentialProviderFactory; 058 private GroupDirectoryDAO _groupDirectoryDAO; 059 private GroupDirectoryFactory _groupDirectoryFactory; 060 061 public void service(ServiceManager manager) throws ServiceException 062 { 063 _versionsHandler = (VersionsHandler) manager.lookup(VersionsHandler.ROLE); 064 _userPopulationDAO = (UserPopulationDAO) manager.lookup(UserPopulationDAO.ROLE); 065 _userDirectoryFactory = (UserDirectoryFactory) manager.lookup(UserDirectoryFactory.ROLE); 066 _credentialProviderFactory = (CredentialProviderFactory) manager.lookup(CredentialProviderFactory.ROLE); 067 _groupDirectoryDAO = (GroupDirectoryDAO) manager.lookup(GroupDirectoryDAO.ROLE); 068 _groupDirectoryFactory = (GroupDirectoryFactory) manager.lookup(GroupDirectoryFactory.ROLE); 069 } 070 071 public void setPluginInfo(String pluginName, String featureName, String id) 072 { 073 _id = id; 074 } 075 076 public Statistics getStatistics() 077 { 078 return new StatisticsNode( 079 _id, 080 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_LABEL"), 081 "ametysicon-trademark-ametys", 082 null, 083 List.of( 084 _getVersionsStatistics(), 085 _getPluginsStatistics(), 086 _getConfigurationStatistics(), 087 _getPopulationsAndGropDirectoriesStatistics(), 088 _getServerStatistics() 089 ), 090 true 091 ); 092 } 093 094 095 private Statistics _getServerStatistics() 096 { 097 return new StatisticsNode( 098 "server", 099 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_SERVER_LABEL"), 100 "ametysicon-system-server-sync", 101 null, 102 List.of( 103 new StatisticsValue( 104 "osname", 105 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_SERVER_OS_LABEL"), 106 "ametysicon-system-terminal", 107 ManagementFactory.getOperatingSystemMXBean().getName() + " (" + ManagementFactory.getOperatingSystemMXBean().getVersion() + ")" 108 ), 109 new StatisticsValue( 110 "cpu", 111 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_SERVER_CPU_LABEL"), 112 "ametysicon-trademark-jackrabbit", 113 String.valueOf(ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors()) + " x " + ManagementFactory.getOperatingSystemMXBean().getArch() 114 ), 115 new StatisticsValue( 116 "ram", 117 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_SERVER_RAM_LABEL"), 118 "ametysicon-system-sgbd", 119 ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getMax() 120 ), 121 new StatisticsValue( 122 "vmvendor", 123 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_SERVER_VMVENDOR_LABEL"), 124 "ametysicon-trademark-jstack", 125 System.getProperty("java.vendor") + " " + ManagementFactory.getRuntimeMXBean().getVmName() 126 ), 127 new StatisticsValue( 128 "vmversion", 129 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_SERVER_VMVERSION_LABEL"), 130 "ametysicon-trademark-jstack", 131 System.getProperty("java.version") 132 ), 133 new StatisticsValue( 134 "antivirus", 135 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_SERVER_ANTIVIRUS_LABEL"), 136 "ametysicon-arrow-down-in", 137 AnalyseFileForVirusHelper.isAntivirusEnabled() 138 ) 139 ), 140 false 141 ); 142 } 143 144 private Statistics _getVersionsStatistics() 145 { 146 return new StatisticsNode( 147 "versions", 148 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_VERSIONS_LABEL"), 149 "ametysicon-maths-number-zero-one", 150 null, 151 _getVersionsChildren(), 152 true 153 ); 154 } 155 156 private List<Statistics> _getVersionsChildren() 157 { 158 return _versionsHandler.getVersions().stream() 159 .map(v -> new StatisticsValue( 160 v.getName(), 161 new I18nizableText(v.getName()), 162 "ametysicon-trademark-ametys", 163 v.getVersion()) 164 ) 165 .map(Statistics.class::cast) 166 .toList(); 167 } 168 169 private Statistics _getPluginsStatistics() 170 { 171 List<String> plugins = new ArrayList<>(PluginsManager.getInstance().getBundledPluginsNames()); 172 Collections.sort(plugins); 173 174 return new StatisticsValue( 175 "plugins", 176 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_PLUGINS_LABEL"), 177 "ametysicon-puzzle-piece1", 178 plugins 179 ); 180 } 181 182 private Statistics _getPopulationsAndGropDirectoriesStatistics() 183 { 184 long populations = 0; 185 186 Map<String, Long> userDirectoriesCount = new TreeMap<>(); 187 Map<String, Long> credentialProvidersCount = new TreeMap<>(); 188 189 for (UserPopulation userPopulation : _userPopulationDAO.getUserPopulations(false)) 190 { 191 populations++; 192 193 for (UserDirectory userDirectory : userPopulation.getUserDirectories()) 194 { 195 Long value = userDirectoriesCount.getOrDefault(userDirectory.getUserDirectoryModelId(), 0L); 196 userDirectoriesCount.put(userDirectory.getUserDirectoryModelId(), value + 1); 197 } 198 199 for (CredentialProvider credentialProvider : userPopulation.getCredentialProviders()) 200 { 201 Long value = credentialProvidersCount.getOrDefault(credentialProvider.getCredentialProviderModelId(), 0L); 202 credentialProvidersCount.put(credentialProvider.getCredentialProviderModelId(), value + 1); 203 } 204 } 205 206 List<Statistics> userDirectories = new ArrayList<>(); 207 for (Entry<String, Long> entry : userDirectoriesCount.entrySet()) 208 { 209 userDirectories.add(new StatisticsValue( 210 entry.getKey(), 211 _userDirectoryFactory.getExtension(entry.getKey()).getLabel(), 212 "ametysicon-body-idcard-white", 213 entry.getValue() 214 )); 215 } 216 217 List<Statistics> credentialProviders = new ArrayList<>(); 218 for (Entry<String, Long> entry : credentialProvidersCount.entrySet()) 219 { 220 CredentialProviderModel cp = _credentialProviderFactory.getExtension(entry.getKey()); 221 credentialProviders.add(new StatisticsValue( 222 entry.getKey(), 223 cp.getLabel(), 224 StringUtils.defaultIfBlank(cp.getIconGlyph(), "ametysicon-body-idcard-badge"), 225 entry.getValue() 226 )); 227 } 228 229 long groups = 0; 230 231 Map<String, Long> groupDirectoriesCount = new TreeMap<>(); 232 for (GroupDirectory groupDirectory : _groupDirectoryDAO.getGroupDirectories()) 233 { 234 groups++; 235 236 Long value = groupDirectoriesCount.getOrDefault(groupDirectory.getGroupDirectoryModelId(), 0L); 237 groupDirectoriesCount.put(groupDirectory.getGroupDirectoryModelId(), value + 1); 238 } 239 240 List<Statistics> groupDirectories = new ArrayList<>(); 241 for (Entry<String, Long> entry : groupDirectoriesCount.entrySet()) 242 { 243 groupDirectories.add(new StatisticsValue( 244 entry.getKey(), 245 _groupDirectoryFactory.getExtension(entry.getKey()).getLabel(), 246 "ametysicon-body-people", 247 entry.getValue() 248 )); 249 } 250 251 return new StatisticsNode( 252 "populations-groupdirectories", 253 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_USERPOPULATIONSANDGROUPDIRECTORIES_LABEL"), 254 "ametysicon-body-group", 255 populations + groups, 256 List.of( 257 new StatisticsNode( 258 "populations", 259 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_USERPOPULATIONSANDGROUPDIRECTORIES_POPULATIONS_LABEL"), 260 "ametysicon-body-people", 261 populations, 262 List.of( 263 new StatisticsNode( 264 "userdirectories", 265 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_USERPOPULATIONSANDGROUPDIRECTORIES_POPULATIONS_USERDIRECTORIES_LABEL"), 266 "ametysicon-body-idcard-white", 267 null, 268 userDirectories, 269 false 270 ), 271 new StatisticsNode( 272 "credentialproviders", 273 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_USERPOPULATIONSANDGROUPDIRECTORIES_POPULATIONS_CREDENTIALPROVIDERS_LABEL"), 274 "ametysicon-body-idcard-badge", 275 null, 276 credentialProviders, 277 false 278 ) 279 ), 280 false 281 ), 282 new StatisticsNode( 283 "groupdirectories", 284 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_USERPOPULATIONSANDGROUPDIRECTORIES_GROUPDIRECTORIES_LABEL"), 285 "ametysicon-body-people", 286 groups, 287 groupDirectories, 288 false 289 ) 290 ), 291 false 292 ); 293 } 294 295 private StatisticsNode _getConfigurationStatistics() 296 { 297 boolean configProd = !Config.getInstance().getValue("runtime.mode.dev", false, true); 298 String configCaptchaType = Config.getInstance().getValue("runtime.captcha.type", false, ""); 299 Long configMaxUpload = Config.getInstance().getValue("runtime.upload.max-size", false, 0L); 300 boolean configGravatar = Config.getInstance().getValue("runtime.userprofile.imagesource.gravatar", false, true); 301 302 return new StatisticsNode( 303 "config", 304 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_CONFIG_LABEL"), 305 "ametysicon-gear39", 306 null, 307 List.of( 308 new StatisticsValue( 309 "production", 310 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_CONFIG_PRODUCTION_LABEL"), 311 "ametysicon-movie16", 312 configProd 313 ), 314 new StatisticsValue( 315 "captcha", 316 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_CONFIG_CAPTCHA_LABEL"), 317 "ametysicon-abecedary4", 318 configCaptchaType 319 ), 320 new StatisticsValue( 321 "upload", 322 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_CONFIG_UPLOAD_LABEL"), 323 "ametysicon-arrow-up-from", 324 configMaxUpload 325 ), 326 new StatisticsValue( 327 "gravatar", 328 new I18nizableText("plugin.admin", "PLUGINS_ADMIN_STATISTICS_KERNEL_CONFIG_GRAVATAR_LABEL"), 329 "ametysicon-body-idcard-black", 330 configGravatar 331 ) 332 ), 333 false 334 ); 335 } 336}