View Javadoc

1   /*
2    * Copyright (C) 2017-2019 Centre National d'Etudes Spatiales (CNES).
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 3.0 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not, write to the Free Software
16   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17   * MA 02110-1301  USA
18   */
19  package fr.cnes.doi.services;
20  
21  import fr.cnes.doi.utils.Utils;
22  import java.util.Map;
23  import java.util.concurrent.ConcurrentHashMap;
24  import org.apache.logging.log4j.LogManager;
25  import org.apache.logging.log4j.Logger;
26  import org.restlet.data.Method;
27  
28  /**
29   * Speed monitoring (average time to answer requests).
30   *
31   * @author Jean-Christophe Malapert (jean-christophe.malapert@cnes.fr)
32   */
33  public class DoiMonitoring {
34  
35      /**
36       * Logger.
37       */
38      private static final Logger LOG = LogManager.getLogger(Utils.APP_LOGGER_NAME);
39  
40      /**
41       * Hash map of records to compute average time to answer requests.
42       */
43      private final Map<String, DoiMonitoringRecord> applications = new ConcurrentHashMap<>();
44  
45      /**
46       * Registers the features to monitor.
47       *
48       * @param name Method
49       * @param path path URI
50       * @param description Feature's description
51       */
52      public void register(final Method name, final String path, final String description) {
53          LOG.traceEntry("Parameters : {}, {}, {}", name, path, description);
54          this.applications.put(name.getName() + path, new DoiMonitoringRecord(description, 0.0f, 0));
55          LOG.traceExit();
56      }
57  
58      /**
59       * Add Measurement.
60       *
61       * @param name method
62       * @param path path URI
63       * @param duration duration in ms
64       */
65      public void addMeasurement(final Method name,
66              final String path,
67              final float duration) {
68          LOG.traceEntry("Parameters : {} {} {}", name.getName(), path, duration);
69          final String identifier = name.getName() + path;
70          if (this.applications.containsKey(identifier)) {
71              final DoiMonitoringRecord record = this.applications.get(name.getName() + path);
72              final float previousSpeedAverage = (float) record.getAverage();
73              final int previousNbAccess = (int) record.getNbAccess();
74              final float newSpeedAverage = (previousSpeedAverage * previousNbAccess + duration) / (previousNbAccess + 1);
75              LOG.info("{} | speed average = {} ms | duration = {} ms", identifier, newSpeedAverage,
76                      duration);
77              record.setAverage(newSpeedAverage);
78              record.setNbAccess(previousNbAccess + 1);
79          } else {
80              LOG.info("Unable to add the measurement : Unknown feature");
81          }
82          LOG.traceExit();
83      }
84  
85      /**
86       * Checks if the features is registered.
87       *
88       * @param name method
89       * @param path Path URI
90       * @return True when the feature is registered
91       */
92      public boolean isRegistered(final Method name,
93              final String path) {
94          LOG.traceEntry("Parameters : {} and {}", name.getName(), path);
95          final String identifier = name.getName() + path;
96          final boolean isRegistered = this.applications.containsKey(identifier);
97          LOG.debug("{} {}  is registered : {}", name, path, isRegistered);
98          return LOG.traceExit(isRegistered);
99      }
100 
101     /**
102      * Returns the average speed of the measurement.
103      *
104      * @param name method name
105      * @param path path URI
106      * @return the average speed
107      */
108     public float getCurrentAverage(final Method name,
109             final String path) {
110         LOG.traceEntry("Parameters : {} and {}", name.getName(), path);
111         final float average;
112         final String identifier = name.getName() + path;
113         if (isRegistered(name, path)) {
114             average = this.applications.get(identifier).getAverage();
115         } else {
116             throw LOG.throwing(new IllegalArgumentException(identifier + " is not registered"));
117         }
118         return LOG.traceExit(average);
119     }
120 
121     /**
122      * Returns the description.
123      *
124      * @param name method name
125      * @param path path URI
126      * @return the description
127      */
128     public String getDescription(final Method name,
129             final String path) {
130         LOG.traceEntry("Parameters : {} and {}", name.getName(), path);
131         final String identifier = name.getName() + path;
132         final String description = this.applications.get(identifier).getDescription();
133         return LOG.traceExit(description);
134     }
135 
136 }