1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.statistics.provider.matomo;
23
24 import org.opencastproject.statistics.api.StatisticsCoordinator;
25 import org.opencastproject.statistics.api.StatisticsProvider;
26 import org.opencastproject.statistics.provider.matomo.provider.BatchMatomoRequest;
27 import org.opencastproject.statistics.provider.matomo.provider.MatomoProviderConfiguration;
28 import org.opencastproject.statistics.provider.matomo.provider.MatomoTimeSeriesStatisticsProvider;
29 import org.opencastproject.util.ConfigurationException;
30
31 import org.apache.felix.fileinstall.ArtifactInstaller;
32 import org.osgi.service.component.annotations.Activate;
33 import org.osgi.service.component.annotations.Component;
34 import org.osgi.service.component.annotations.Deactivate;
35 import org.osgi.service.component.annotations.Modified;
36 import org.osgi.service.component.annotations.Reference;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import java.io.File;
41 import java.nio.charset.Charset;
42 import java.nio.file.Files;
43 import java.util.Map;
44 import java.util.concurrent.ConcurrentHashMap;
45
46
47
48
49 @Component(
50 immediate = true,
51 service = { ArtifactInstaller.class },
52 property = {
53 "service.description=Statistics Provider Matomo Service"
54 }
55 )
56 public class StatisticsProviderMatomoService implements ArtifactInstaller {
57
58
59 private static final Logger logger = LoggerFactory.getLogger(StatisticsProviderMatomoService.class);
60
61 private static final String KEY_MATOMO_API_URL = "matomo.api.url";
62 private static final String KEY_MATOMO_API_TOKEN = "matomo.api.token";
63
64 private String matomoApiUrl;
65 private String matomoApiToken;
66
67 private StatisticsCoordinator statisticsCoordinator;
68 private Map<String, StatisticsProvider> fileNameToProvider = new ConcurrentHashMap<>();
69 private Map<String, BatchMatomoRequest> methodToBatchRequest = new ConcurrentHashMap<>();
70
71
72
73
74
75
76 public BatchMatomoRequest getBatchRequest(String resourceTypeMethod) {
77 return methodToBatchRequest.get(resourceTypeMethod);
78 }
79
80
81
82
83
84
85 public void registerBatchRequest(String resourceTypeMethod, BatchMatomoRequest batchRequest) {
86 methodToBatchRequest.put(resourceTypeMethod, batchRequest);
87 }
88
89 @Reference
90 public void setStatisticsCoordinator(StatisticsCoordinator service) {
91 this.statisticsCoordinator = service;
92 }
93
94 @Activate
95 public void activate(Map<String, Object> properties) {
96 logger.info("Activating Statistics Provider Matomo Service");
97 modified(properties);
98 }
99
100 @Deactivate
101 public void deactivate() {
102 logger.info("Deactivating Statistics Provider Matomo Service");
103 }
104
105 @Override
106 public void install(File file) throws Exception {
107 final String json = new String(Files.readAllBytes(file.toPath()), Charset.forName("utf-8"));
108 final MatomoProviderConfiguration providerCfg = MatomoProviderConfiguration.fromJson(json);
109 StatisticsProvider provider;
110 switch (providerCfg.getType().toLowerCase()) {
111 case "timeseries": {
112 provider = new MatomoTimeSeriesStatisticsProvider(
113 this,
114 providerCfg.getId(),
115 providerCfg.getResourceType(),
116 providerCfg.getTitle(),
117 providerCfg.getDescription(),
118 providerCfg.getSources());
119 logger.info("Installed Matomo time series statistics provider '{}'", providerCfg.getId());
120 }
121 break;
122 default:
123 throw new ConfigurationException("Unknown Matomo statistics type: " + providerCfg.getType());
124 }
125 fileNameToProvider.put(file.getName(), provider);
126 statisticsCoordinator.addProvider(provider);
127 }
128
129 @Override
130 public void uninstall(File file) {
131 if (fileNameToProvider.containsKey(file.getName())) {
132 statisticsCoordinator.removeProvider(fileNameToProvider.get(file.getName()));
133 fileNameToProvider.remove(file.getName());
134 }
135 }
136
137 @Override
138 public boolean canHandle(File file) {
139 return "statistics".equals(file.getParentFile().getName())
140 && file.getName().endsWith(".json")
141 && file.getName().toUpperCase().startsWith("matomo.".toUpperCase());
142 }
143
144 @Override
145 public void update(File file) throws Exception {
146 uninstall(file);
147 install(file);
148 }
149
150 @Modified
151 public void modified(Map<String, Object> properties) {
152 if (properties == null) {
153 logger.info("Configuration file not found. Not connecting to Matomo API.");
154 } else if (!(properties.containsKey(KEY_MATOMO_API_TOKEN) || properties.containsKey(KEY_MATOMO_API_URL))) {
155 logger.info("No configuration available. Not connecting to Matomo API.");
156 } else {
157 final Object matomoApiUrlValue = properties.get(KEY_MATOMO_API_URL);
158 if (matomoApiUrlValue != null) {
159 matomoApiUrl = matomoApiUrlValue.toString();
160 } else {
161 throw new ConfigurationException("Matomo API URL is missing in config file.");
162 }
163 final Object matomoApiTokenValue = properties.get(KEY_MATOMO_API_TOKEN);
164 if (matomoApiTokenValue != null) {
165 matomoApiToken = matomoApiTokenValue.toString();
166 } else {
167 throw new ConfigurationException("Matomo API access token is missing in config file.");
168 }
169 logger.info("Updated Matomo API URL to '{}'", matomoApiUrl);
170 }
171 }
172
173 public String getMatomoApiUrl() {
174 return matomoApiUrl;
175 }
176
177 public String getMatomoApiToken() {
178 return matomoApiToken;
179 }
180 }