001package org.apache.archiva.rest.services; 002/* 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 */ 020 021import org.apache.archiva.admin.model.RepositoryAdminException; 022import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin; 023import org.apache.archiva.components.cache.Cache; 024import org.apache.archiva.components.cache.CacheStatistics; 025import org.apache.archiva.components.taskqueue.TaskQueue; 026import org.apache.archiva.components.taskqueue.TaskQueueException; 027import org.apache.archiva.repository.scanner.RepositoryScanner; 028import org.apache.archiva.repository.scanner.RepositoryScannerInstance; 029import org.apache.archiva.rest.api.model.CacheEntry; 030import org.apache.archiva.rest.api.model.ConsumerScanningStatistics; 031import org.apache.archiva.rest.api.model.QueueEntry; 032import org.apache.archiva.rest.api.model.RepositoryScannerStatistics; 033import org.apache.archiva.rest.api.services.ArchivaRestServiceException; 034import org.apache.archiva.rest.api.services.SystemStatusService; 035import org.apache.archiva.rest.services.utils.ConsumerScanningStatisticsComparator; 036import org.springframework.context.ApplicationContext; 037import org.springframework.stereotype.Service; 038 039import javax.inject.Inject; 040import javax.ws.rs.core.Response; 041import java.text.DecimalFormat; 042import java.text.SimpleDateFormat; 043import java.util.ArrayList; 044import java.util.Collections; 045import java.util.Comparator; 046import java.util.Date; 047import java.util.List; 048import java.util.Locale; 049import java.util.Map; 050import java.util.Set; 051 052/** 053 * @author Olivier Lamy 054 * @since 1.4-M3 055 */ 056@Service( "systemStatusService#rest" ) 057public class DefaultSystemStatusService 058 extends AbstractRestService 059 implements SystemStatusService 060{ 061 062 063 private Map<String, TaskQueue> queues = null; 064 065 private Map<String, Cache> caches = null; 066 067 private RepositoryScanner scanner; 068 069 ManagedRepositoryAdmin managedRepositoryAdmin; 070 071 // display spring scheduled 072 //@Inject @Named (value="springScheduler"); 073 074 075 @Inject 076 public DefaultSystemStatusService( ApplicationContext applicationContext, RepositoryScanner scanner ) 077 { 078 this.scanner = scanner; 079 080 queues = getBeansOfType( applicationContext, TaskQueue.class ); 081 082 caches = getBeansOfType( applicationContext, Cache.class ); 083 084 managedRepositoryAdmin = applicationContext.getBean( ManagedRepositoryAdmin.class ); 085 } 086 087 @Override 088 public String getMemoryStatus() 089 throws ArchivaRestServiceException 090 { 091 Runtime runtime = Runtime.getRuntime(); 092 093 long total = runtime.totalMemory(); 094 long used = total - runtime.freeMemory(); 095 long max = runtime.maxMemory(); 096 return formatMemory( used ) + "/" + formatMemory( total ) + " (Max: " + formatMemory( max ) + ")"; 097 } 098 099 private static String formatMemory( long l ) 100 { 101 return l / ( 1024 * 1024 ) + "M"; 102 } 103 104 @Override 105 public String getCurrentServerTime( String locale ) 106 throws ArchivaRestServiceException 107 { 108 SimpleDateFormat sdf = new SimpleDateFormat( "EEE, d MMM yyyy HH:mm:ss Z", new Locale( locale ) ); 109 return sdf.format( new Date() ); 110 } 111 112 @Override 113 public List<QueueEntry> getQueueEntries() 114 throws ArchivaRestServiceException 115 { 116 try 117 { 118 List<QueueEntry> queueEntries = new ArrayList<QueueEntry>( queues.size() ); 119 for ( Map.Entry<String, TaskQueue> entry : queues.entrySet() ) 120 { 121 queueEntries.add( new QueueEntry( entry.getKey(), entry.getValue().getQueueSnapshot().size() ) ); 122 } 123 124 return queueEntries; 125 } 126 catch ( TaskQueueException e ) 127 { 128 log.error( e.getMessage(), e ); 129 throw new ArchivaRestServiceException( e.getMessage(), 130 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e ); 131 } 132 } 133 134 // Used for generics 135 private class CacheEntryComparator implements Comparator<CacheEntry> 136 { 137 138 @Override 139 public int compare( CacheEntry o1, CacheEntry o2 ) 140 { 141 return o1.compareTo( o2 ); 142 } 143 } 144 145 @Override 146 public List<CacheEntry> getCacheEntries() 147 throws ArchivaRestServiceException 148 { 149 List<CacheEntry> cacheEntries = new ArrayList<CacheEntry>( caches.size() ); 150 DecimalFormat decimalFormat = new DecimalFormat( "#%" ); 151 152 for ( Map.Entry<String, Cache> entry : caches.entrySet() ) 153 { 154 CacheStatistics cacheStatistics = entry.getValue().getStatistics(); 155 156 cacheEntries.add( new CacheEntry( entry.getKey(), cacheStatistics.getSize(), cacheStatistics.getCacheHits(), 157 cacheStatistics.getCacheMiss(), 158 decimalFormat.format( cacheStatistics.getCacheHitRate() ).toString(), 159 cacheStatistics.getInMemorySize() ) ); 160 } 161 162 Collections.sort( cacheEntries, new CacheEntryComparator() ); 163 164 return cacheEntries; 165 } 166 167 @Override 168 public Boolean clearCache( String cacheKey ) 169 throws ArchivaRestServiceException 170 { 171 Cache cache = caches.get( cacheKey ); 172 if ( cache == null ) 173 { 174 throw new ArchivaRestServiceException( "no cache for key: " + cacheKey, 175 Response.Status.BAD_REQUEST.getStatusCode(), null ); 176 } 177 178 cache.clear(); 179 return Boolean.TRUE; 180 } 181 182 @Override 183 public Boolean clearAllCaches() 184 throws ArchivaRestServiceException 185 { 186 for ( Cache cache : caches.values() ) 187 { 188 cache.clear(); 189 } 190 return Boolean.TRUE; 191 } 192 193 @Override 194 public List<RepositoryScannerStatistics> getRepositoryScannerStatistics() 195 throws ArchivaRestServiceException 196 { 197 Set<RepositoryScannerInstance> repositoryScannerInstances = scanner.getInProgressScans(); 198 if ( repositoryScannerInstances.isEmpty() ) 199 { 200 return Collections.emptyList(); 201 } 202 List<RepositoryScannerStatistics> repositoryScannerStatisticsList = 203 new ArrayList<RepositoryScannerStatistics>( repositoryScannerInstances.size() ); 204 205 206 for ( RepositoryScannerInstance instance : repositoryScannerInstances ) 207 { 208 RepositoryScannerStatistics repositoryScannerStatistics = new RepositoryScannerStatistics(); 209 repositoryScannerStatisticsList.add( repositoryScannerStatistics ); 210 try 211 { 212 repositoryScannerStatistics.setManagedRepository( managedRepositoryAdmin.getManagedRepository( instance.getRepository().getId()) ); 213 } 214 catch ( RepositoryAdminException e ) 215 { 216 log.error("Could not retrieve repository '{}'", instance.getRepository().getId()); 217 } 218 repositoryScannerStatistics.setNewFileCount( instance.getStats().getNewFileCount() ); 219 repositoryScannerStatistics.setTotalFileCount( instance.getStats().getTotalFileCount() ); 220 repositoryScannerStatistics.setConsumerScanningStatistics( mapConsumerScanningStatistics( instance ) ); 221 } 222 223 return repositoryScannerStatisticsList; 224 } 225 226 private List<ConsumerScanningStatistics> mapConsumerScanningStatistics( RepositoryScannerInstance instance ) 227 { 228 DecimalFormat decimalFormat = new DecimalFormat( "###.##" ); 229 if ( instance.getConsumerCounts() == null ) 230 { 231 return Collections.emptyList(); 232 } 233 List<ConsumerScanningStatistics> ret = 234 new ArrayList<ConsumerScanningStatistics>( instance.getConsumerCounts().size() ); 235 for ( Map.Entry<String, Long> entry : instance.getConsumerCounts().entrySet() ) 236 { 237 ConsumerScanningStatistics consumerScanningStatistics = new ConsumerScanningStatistics(); 238 consumerScanningStatistics.setConsumerKey( entry.getKey() ); 239 consumerScanningStatistics.setCount( entry.getValue() ); 240 consumerScanningStatistics.setTime( instance.getConsumerTimings().get( entry.getKey() ) ); 241 if ( consumerScanningStatistics.getCount() > 0 ) 242 { 243 consumerScanningStatistics.setAverage( decimalFormat.format( 244 consumerScanningStatistics.getTime() / consumerScanningStatistics.getCount() ) ); 245 } 246 ret.add( consumerScanningStatistics ); 247 } 248 Collections.sort( ret, ConsumerScanningStatisticsComparator.INSTANCE ); 249 return ret; 250 } 251}