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.redback.components.cache.Cache; 022import org.apache.archiva.redback.components.cache.CacheStatistics; 023import org.apache.archiva.redback.components.taskqueue.TaskQueue; 024import org.apache.archiva.redback.components.taskqueue.TaskQueueException; 025import org.apache.archiva.repository.scanner.RepositoryScanner; 026import org.apache.archiva.repository.scanner.RepositoryScannerInstance; 027import org.apache.archiva.rest.api.model.CacheEntry; 028import org.apache.archiva.rest.api.model.ConsumerScanningStatistics; 029import org.apache.archiva.rest.api.model.QueueEntry; 030import org.apache.archiva.rest.api.model.RepositoryScannerStatistics; 031import org.apache.archiva.rest.api.services.ArchivaRestServiceException; 032import org.apache.archiva.rest.api.services.SystemStatusService; 033import org.apache.archiva.rest.services.utils.ConsumerScanningStatisticsComparator; 034import org.springframework.context.ApplicationContext; 035import org.springframework.stereotype.Service; 036 037import javax.inject.Inject; 038import javax.ws.rs.core.Response; 039import java.text.DecimalFormat; 040import java.text.SimpleDateFormat; 041import java.util.ArrayList; 042import java.util.Collections; 043import java.util.Date; 044import java.util.List; 045import java.util.Locale; 046import java.util.Map; 047import java.util.Set; 048 049/** 050 * @author Olivier Lamy 051 * @since 1.4-M3 052 */ 053@Service( "systemStatusService#rest" ) 054public class DefaultSystemStatusService 055 extends AbstractRestService 056 implements SystemStatusService 057{ 058 059 060 private Map<String, TaskQueue> queues = null; 061 062 private Map<String, Cache> caches = null; 063 064 private RepositoryScanner scanner; 065 066 // display spring scheduled 067 //@Inject @Named (value="springScheduler"); 068 069 070 @Inject 071 public DefaultSystemStatusService( ApplicationContext applicationContext, RepositoryScanner scanner ) 072 { 073 this.scanner = scanner; 074 075 queues = getBeansOfType( applicationContext, TaskQueue.class ); 076 077 caches = getBeansOfType( applicationContext, Cache.class ); 078 } 079 080 @Override 081 public String getMemoryStatus() 082 throws ArchivaRestServiceException 083 { 084 Runtime runtime = Runtime.getRuntime(); 085 086 long total = runtime.totalMemory(); 087 long used = total - runtime.freeMemory(); 088 long max = runtime.maxMemory(); 089 return formatMemory( used ) + "/" + formatMemory( total ) + " (Max: " + formatMemory( max ) + ")"; 090 } 091 092 private static String formatMemory( long l ) 093 { 094 return l / ( 1024 * 1024 ) + "M"; 095 } 096 097 @Override 098 public String getCurrentServerTime( String locale ) 099 throws ArchivaRestServiceException 100 { 101 SimpleDateFormat sdf = new SimpleDateFormat( "EEE, d MMM yyyy HH:mm:ss Z", new Locale( locale ) ); 102 return sdf.format( new Date() ); 103 } 104 105 @Override 106 public List<QueueEntry> getQueueEntries() 107 throws ArchivaRestServiceException 108 { 109 try 110 { 111 List<QueueEntry> queueEntries = new ArrayList<QueueEntry>( queues.size() ); 112 for ( Map.Entry<String, TaskQueue> entry : queues.entrySet() ) 113 { 114 queueEntries.add( new QueueEntry( entry.getKey(), entry.getValue().getQueueSnapshot().size() ) ); 115 } 116 117 return queueEntries; 118 } 119 catch ( TaskQueueException e ) 120 { 121 log.error( e.getMessage(), e ); 122 throw new ArchivaRestServiceException( e.getMessage(), 123 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e ); 124 } 125 } 126 127 @Override 128 public List<CacheEntry> getCacheEntries() 129 throws ArchivaRestServiceException 130 { 131 List<CacheEntry> cacheEntries = new ArrayList<CacheEntry>( caches.size() ); 132 DecimalFormat decimalFormat = new DecimalFormat( "#%" ); 133 134 for ( Map.Entry<String, Cache> entry : caches.entrySet() ) 135 { 136 CacheStatistics cacheStatistics = entry.getValue().getStatistics(); 137 138 cacheEntries.add( new CacheEntry( entry.getKey(), cacheStatistics.getSize(), cacheStatistics.getCacheHits(), 139 cacheStatistics.getCacheMiss(), 140 decimalFormat.format( cacheStatistics.getCacheHitRate() ).toString(), 141 cacheStatistics.getInMemorySize() ) ); 142 } 143 144 Collections.sort( cacheEntries ); 145 146 return cacheEntries; 147 } 148 149 @Override 150 public Boolean clearCache( String cacheKey ) 151 throws ArchivaRestServiceException 152 { 153 Cache cache = caches.get( cacheKey ); 154 if ( cache == null ) 155 { 156 throw new ArchivaRestServiceException( "no cache for key: " + cacheKey, 157 Response.Status.BAD_REQUEST.getStatusCode(), null ); 158 } 159 160 cache.clear(); 161 return Boolean.TRUE; 162 } 163 164 @Override 165 public Boolean clearAllCaches() 166 throws ArchivaRestServiceException 167 { 168 for ( Cache cache : caches.values() ) 169 { 170 cache.clear(); 171 } 172 return Boolean.TRUE; 173 } 174 175 @Override 176 public List<RepositoryScannerStatistics> getRepositoryScannerStatistics() 177 throws ArchivaRestServiceException 178 { 179 Set<RepositoryScannerInstance> repositoryScannerInstances = scanner.getInProgressScans(); 180 if ( repositoryScannerInstances.isEmpty() ) 181 { 182 return Collections.emptyList(); 183 } 184 List<RepositoryScannerStatistics> repositoryScannerStatisticsList = 185 new ArrayList<RepositoryScannerStatistics>( repositoryScannerInstances.size() ); 186 187 for ( RepositoryScannerInstance instance : repositoryScannerInstances ) 188 { 189 RepositoryScannerStatistics repositoryScannerStatistics = new RepositoryScannerStatistics(); 190 repositoryScannerStatisticsList.add( repositoryScannerStatistics ); 191 repositoryScannerStatistics.setManagedRepository( instance.getRepository() ); 192 repositoryScannerStatistics.setNewFileCount( instance.getStats().getNewFileCount() ); 193 repositoryScannerStatistics.setTotalFileCount( instance.getStats().getTotalFileCount() ); 194 repositoryScannerStatistics.setConsumerScanningStatistics( mapConsumerScanningStatistics( instance ) ); 195 } 196 197 return repositoryScannerStatisticsList; 198 } 199 200 private List<ConsumerScanningStatistics> mapConsumerScanningStatistics( RepositoryScannerInstance instance ) 201 { 202 DecimalFormat decimalFormat = new DecimalFormat( "###.##" ); 203 if ( instance.getConsumerCounts() == null ) 204 { 205 return Collections.emptyList(); 206 } 207 List<ConsumerScanningStatistics> ret = 208 new ArrayList<ConsumerScanningStatistics>( instance.getConsumerCounts().size() ); 209 for ( Map.Entry<String, Long> entry : instance.getConsumerCounts().entrySet() ) 210 { 211 ConsumerScanningStatistics consumerScanningStatistics = new ConsumerScanningStatistics(); 212 consumerScanningStatistics.setConsumerKey( entry.getKey() ); 213 consumerScanningStatistics.setCount( entry.getValue() ); 214 consumerScanningStatistics.setTime( instance.getConsumerTimings().get( entry.getKey() ) ); 215 if ( consumerScanningStatistics.getCount() > 0 ) 216 { 217 consumerScanningStatistics.setAverage( decimalFormat.format( 218 consumerScanningStatistics.getTime() / consumerScanningStatistics.getCount() ) ); 219 } 220 ret.add( consumerScanningStatistics ); 221 } 222 Collections.sort( ret, ConsumerScanningStatisticsComparator.INSTANCE ); 223 return ret; 224 } 225}