1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.activeinstalls.internal.client.data

File DatePingDataProvider.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart9.png
38% of files have more coverage

Code metrics

4
32
3
1
152
94
7
0.22
10.67
3
2.33

Classes

Class Line # Actions
DatePingDataProvider 53 32 0% 7 4
0.897435989.7%
 

Contributing tests

This file is covered by 2 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.activeinstalls.internal.client.data;
21   
22    import java.util.Collections;
23    import java.util.HashMap;
24    import java.util.Map;
25   
26    import javax.inject.Inject;
27    import javax.inject.Named;
28    import javax.inject.Singleton;
29   
30    import org.apache.commons.lang.exception.ExceptionUtils;
31    import org.slf4j.Logger;
32    import org.xwiki.activeinstalls.internal.JestClientManager;
33    import org.xwiki.activeinstalls.internal.client.PingDataProvider;
34    import org.xwiki.component.annotation.Component;
35    import org.xwiki.instance.InstanceIdManager;
36   
37    import io.searchbox.client.JestResult;
38    import io.searchbox.core.Search;
39    import io.searchbox.params.SearchType;
40    import net.sf.json.JSONObject;
41   
42    /**
43    * Provide the date of the first ping and the elapsed days since the first ping. We do that to make it simpler to
44    * perform complex queries on the ping data later on (for example to be able to query the average duration an instance
45    * is used: < 1 day, 2-7 days, 7-30 days, 30-365 days, > 365 days).
46    *
47    * @version $Id: 9b9d3d56f5c10f1eb014eee12e22895805254b6c $
48    * @since 6.1M1
49    */
50    @Component
51    @Named("date")
52    @Singleton
 
53    public class DatePingDataProvider implements PingDataProvider
54    {
55    private static final String PROPERTY_FIRST_PING_DATE = "firstPingDate";
56   
57    private static final String PROPERTY_SINCE_DAYS = "sinceDays";
58   
59    private static final String PROPERTY_SERVER_TIME = "serverTime";
60   
61    private static final String PROPERTY_VALUE = "value";
62   
63    private static final String PROPERTY_TYPE = "type";
64   
65    private static final String PROPERTY_MIN = "min";
66   
67    private static final String ERROR_MESSAGE = "Failed to compute the first ping date and the number of elapsed days "
68    + "since the first ping. This information has not been added to the Active Installs ping data. Reason [{}]";
69   
70    @Inject
71    private JestClientManager jestClientManager;
72   
73    @Inject
74    private InstanceIdManager instanceIdManager;
75   
76    @Inject
77    private Logger logger;
78   
 
79  2 toggle @Override
80    public Map<String, Object> provideMapping()
81    {
82  2 Map<String, Object> propertiesMap = new HashMap<>();
83  2 propertiesMap.put(PROPERTY_FIRST_PING_DATE, Collections.singletonMap(PROPERTY_TYPE, "date"));
84  2 propertiesMap.put(PROPERTY_SINCE_DAYS, Collections.singletonMap(PROPERTY_TYPE, "long"));
85  2 return propertiesMap;
86    }
87   
 
88  2 toggle @Override
89    public Map<String, Object> provideData()
90    {
91  2 Map<String, Object> jsonMap = new HashMap<>();
92  2 try {
93  2 String instanceId = this.instanceIdManager.getInstanceId().toString();
94  2 Search search = new Search.Builder(constructSearchJSON(instanceId))
95    .addIndex(JestClientManager.INDEX)
96    .addType(JestClientManager.TYPE)
97    .setSearchType(SearchType.COUNT)
98    .build();
99  2 JestResult result = this.jestClientManager.getClient().execute(search);
100   
101  2 if (!result.isSucceeded()) {
102  0 this.logger.warn(ERROR_MESSAGE, result.getErrorMessage());
103  0 return jsonMap;
104    }
105   
106  2 @SuppressWarnings("unchecked")
107    Map<String, Object> aggregationsMap = (Map<String, Object>) result.getValue("aggregations");
108   
109    // Get the current server time and the first timestamp of the ping for this instance id and compute the
110    // since days from them.
111  2 @SuppressWarnings("unchecked")
112    Map<String, Object> serverTimeMap = (Map<String, Object>) aggregationsMap.get(PROPERTY_SERVER_TIME);
113  2 Object serverTimeObject = serverTimeMap.get(PROPERTY_VALUE);
114  2 @SuppressWarnings("unchecked")
115    Map<String, Object> firstPingDateMap = (Map<String, Object>) aggregationsMap.get(PROPERTY_FIRST_PING_DATE);
116  2 Object firstPingDateObject = firstPingDateMap.get(PROPERTY_VALUE);
117   
118  2 if (serverTimeObject != null && firstPingDateObject != null) {
119  1 long sinceDays = Math.round(((double) serverTimeObject - (double) firstPingDateObject) / 86400000D);
120  1 jsonMap.put(PROPERTY_SINCE_DAYS, sinceDays);
121  1 long firstPingDate = Math.round((double) firstPingDateObject);
122  1 jsonMap.put(PROPERTY_FIRST_PING_DATE, firstPingDate);
123    } else {
124    // This means it's the first ping and thus there was no previous _timestamp. Thus we set the since Days
125    // to 0.
126  1 jsonMap.put(PROPERTY_SINCE_DAYS, 0);
127    }
128    } catch (Exception e) {
129    // If this fails we just don't send this information but we still send the other piece of information.
130    // However we log a warning since it's a problem that needs to be seen and looked at.
131  0 this.logger.warn(ERROR_MESSAGE, ExceptionUtils.getRootCauseMessage(e));
132    }
133  2 return jsonMap;
134    }
135   
 
136  2 toggle private String constructSearchJSON(String instanceId)
137    {
138  2 Map<String, Object> jsonMap = new HashMap<>();
139   
140  2 jsonMap.put("query", Collections.singletonMap("term", Collections.singletonMap("instanceId", instanceId)));
141   
142  2 Map<String, Object> aggsMap = new HashMap<>();
143  2 aggsMap.put(PROPERTY_SERVER_TIME, Collections.singletonMap(PROPERTY_MIN,
144    Collections.singletonMap("script", "time()")));
145  2 aggsMap.put(PROPERTY_FIRST_PING_DATE, Collections.singletonMap(PROPERTY_MIN,
146    Collections.singletonMap("field", "_timestamp")));
147   
148  2 jsonMap.put("aggs", aggsMap);
149   
150  2 return JSONObject.fromObject(jsonMap).toString();
151    }
152    }