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