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