1
|
package eu.dnetlib.openaire.exporter.datasource;
|
2
|
|
3
|
import java.util.List;
|
4
|
import javax.validation.Valid;
|
5
|
|
6
|
import eu.dnetlib.common.rmi.DNetRestDocumentation;
|
7
|
import eu.dnetlib.enabling.datasources.common.DsmException;
|
8
|
import eu.dnetlib.enabling.datasources.common.DsmForbiddenException;
|
9
|
import eu.dnetlib.openaire.exporter.AbstractExporterController;
|
10
|
import eu.dnetlib.openaire.exporter.OperationManager;
|
11
|
import eu.dnetlib.openaire.exporter.model.ApiDetailsResponse;
|
12
|
import eu.dnetlib.openaire.exporter.model.DatasourceResponse;
|
13
|
import eu.dnetlib.openaire.exporter.model.Response;
|
14
|
import eu.dnetlib.openaire.exporter.model.datasource.*;
|
15
|
import eu.dnetlib.openaire.exporter.vocabularies.Country;
|
16
|
import io.swagger.annotations.ApiOperation;
|
17
|
import io.swagger.annotations.ApiResponse;
|
18
|
import io.swagger.annotations.ApiResponses;
|
19
|
import org.apache.commons.lang3.StringUtils;
|
20
|
import org.apache.commons.lang3.time.StopWatch;
|
21
|
import org.apache.http.HttpStatus;
|
22
|
import org.springframework.beans.factory.annotation.Autowired;
|
23
|
import org.springframework.web.bind.annotation.*;
|
24
|
|
25
|
@RestController
|
26
|
@DNetRestDocumentation
|
27
|
@io.swagger.annotations.Api(value = "datasources", description = "the datasource manager API")
|
28
|
public class DatasourcesApiController extends AbstractExporterController {
|
29
|
|
30
|
@Autowired
|
31
|
private DatasourceManagerCore dsmCore;
|
32
|
|
33
|
@RequestMapping(value = "/ds/countries", produces = { "application/json" }, method = RequestMethod.GET)
|
34
|
@ApiOperation(
|
35
|
value = "list the datasource countries",
|
36
|
notes = "list the datasource countries",
|
37
|
tags = { DS, R },
|
38
|
response = Country[].class)
|
39
|
@ApiResponses(value = {
|
40
|
@ApiResponse(code = 200, message = "OK", response = Country[].class),
|
41
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
42
|
public List<Country> listCountries() throws DsmException {
|
43
|
return dsmCore.listCountries();
|
44
|
}
|
45
|
|
46
|
@RequestMapping(value = "/ds/search/{page}/{size}", produces = { "application/json" }, method = RequestMethod.POST)
|
47
|
@ApiOperation(
|
48
|
value = "search datasources",
|
49
|
notes = "Returns list of Datasource details.",
|
50
|
tags = { DS, R },
|
51
|
response = DatasourceResponse.class)
|
52
|
@ApiResponses(value = {
|
53
|
@ApiResponse(code = 200, message = "OK", response = DatasourceResponse.class),
|
54
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
55
|
public DatasourceResponse search(
|
56
|
@RequestParam final RequestSort requestSortBy,
|
57
|
@RequestParam final RequestSortOrder order,
|
58
|
@RequestBody final RequestFilter requestFilter,
|
59
|
@PathVariable final int page,
|
60
|
@PathVariable final int size) throws DsmException {
|
61
|
final StopWatch stop = StopWatch.createStarted();
|
62
|
final DatasourceResponse rsp = dsmCore.search(requestSortBy, order, requestFilter, page, size);
|
63
|
return prepareResponse(page, size, stop, rsp);
|
64
|
}
|
65
|
|
66
|
@RequestMapping(value = "/ds/api/{dsId}", produces = { "application/json" }, method = RequestMethod.GET)
|
67
|
@ApiOperation(
|
68
|
value = "get the list of API for a given datasource",
|
69
|
notes = "Returns the list of API for a given datasource.",
|
70
|
tags = { API, R },
|
71
|
response = ApiDetailsResponse.class)
|
72
|
@ApiResponses(value = {
|
73
|
@ApiResponse(code = 200, message = "OK", response = ApiDetailsResponse.class),
|
74
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
75
|
public ApiDetailsResponse getApi(
|
76
|
@PathVariable final String dsId) throws DsmException {
|
77
|
|
78
|
final StopWatch stop = StopWatch.createStarted();
|
79
|
final ApiDetailsResponse rsp = dsmCore.getApis(dsId);
|
80
|
return prepareResponse(0, rsp.getApi().size(), stop, rsp);
|
81
|
}
|
82
|
|
83
|
@RequestMapping(value = "/api/baseurl/{page}/{size}", produces = { "application/json" }, method = RequestMethod.POST)
|
84
|
@ApiOperation(
|
85
|
value = "search for the list of base URLs of Datasource APIs managed by a user",
|
86
|
notes = "Returns the list of base URLs of Datasource APIs managed by a user",
|
87
|
tags = { DS, API, R },
|
88
|
response = String[].class)
|
89
|
@ApiResponses(value = {
|
90
|
@ApiResponse(code = 200, message = "OK", response = String[].class),
|
91
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
92
|
public List<String> searchBaseUrls(
|
93
|
@RequestBody final RequestFilter requestFilter,
|
94
|
@PathVariable final int page,
|
95
|
@PathVariable final int size) throws DsmException {
|
96
|
|
97
|
return dsmCore.findBaseURLs(requestFilter, page, size);
|
98
|
}
|
99
|
|
100
|
@RequestMapping(value = "/ds/api/{apiId}", method = RequestMethod.DELETE)
|
101
|
@ApiOperation(
|
102
|
value = "delete an API",
|
103
|
notes = "delete an API, if removable",
|
104
|
tags = { API, W })
|
105
|
@ApiResponses(value = {
|
106
|
@ApiResponse(code = 200, message = "OK"),
|
107
|
@ApiResponse(code = 403, message = "Api not removable", response = ErrorMessage.class) })
|
108
|
public void deleteApi(@PathVariable final String apiId) throws DsmException, DsmForbiddenException {
|
109
|
dsmCore.deleteApi(apiId);
|
110
|
}
|
111
|
|
112
|
@RequestMapping(value = "/ds/manage", method = RequestMethod.POST)
|
113
|
@ApiOperation(
|
114
|
value = "set the managed status for a given datasource",
|
115
|
notes = "set the managed status for a given datasource",
|
116
|
tags = { DS, W })
|
117
|
@ApiResponses(value = {
|
118
|
@ApiResponse(code = 200, message = "OK"),
|
119
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
120
|
public void setManaged(
|
121
|
@RequestParam final String id,
|
122
|
@RequestParam final boolean managed) throws DsmException {
|
123
|
|
124
|
dsmCore.setManaged(id, managed);
|
125
|
}
|
126
|
|
127
|
@RequestMapping(value = "/ds/managed/{dsId}", method = RequestMethod.GET)
|
128
|
@ApiOperation(
|
129
|
value = "get the datasource managed status",
|
130
|
notes = "get the datasource managed status",
|
131
|
tags = { DS, R })
|
132
|
@ApiResponses(value = {
|
133
|
@ApiResponse(code = 200, message = "OK"),
|
134
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
135
|
public boolean isManaged(@PathVariable final String id) throws DsmException {
|
136
|
return dsmCore.isManaged(id);
|
137
|
}
|
138
|
|
139
|
@RequestMapping(value = "/ds/add", method = RequestMethod.POST)
|
140
|
@ApiOperation(
|
141
|
value = "add a new Datasource",
|
142
|
notes = "add a new Datasource",
|
143
|
tags = { DS, W })
|
144
|
@ApiResponses(value = {
|
145
|
@ApiResponse(code = 200, message = "OK"),
|
146
|
@ApiResponse(code = 400, message = "Malformed request", response = ErrorMessage[].class),
|
147
|
@ApiResponse(code = 500, message = "Unexpected error", response = ErrorMessage.class) })
|
148
|
public void saveDs(@Valid @RequestBody final DatasourceDetails datasource) throws DsmException {
|
149
|
|
150
|
if (dsmCore.exist(datasource)) { // TODO further check that the DS doesn't have any API
|
151
|
throw new DsmException(HttpStatus.SC_CONFLICT, String.format("cannot register, datasource already defined '%s'", datasource.getId()));
|
152
|
}
|
153
|
dsmCore.save(datasource);
|
154
|
}
|
155
|
|
156
|
@RequestMapping(value = "/ds/logourl", method = RequestMethod.POST)
|
157
|
@ApiOperation(
|
158
|
value = "update a datasource name",
|
159
|
notes = "update a datasource name",
|
160
|
tags = { DS, W })
|
161
|
@ApiResponses(value = {
|
162
|
@ApiResponse(code = 200, message = "OK"),
|
163
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
164
|
public void updateDatasourceLogoURL(
|
165
|
@RequestParam final String dsId,
|
166
|
@RequestParam final String logourl) throws DsmException {
|
167
|
|
168
|
dsmCore.updateDatasourceLogoUrl(dsId, logourl);
|
169
|
}
|
170
|
|
171
|
@RequestMapping(value = "/ds/name", method = RequestMethod.POST)
|
172
|
@ApiOperation(
|
173
|
value = "update a datasource name",
|
174
|
notes = "update a datasource name",
|
175
|
tags = { DS, W })
|
176
|
@ApiResponses(value = {
|
177
|
@ApiResponse(code = 200, message = "OK"),
|
178
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
179
|
public void updateDatasourceName(
|
180
|
@RequestParam final String dsId,
|
181
|
@RequestParam final String officialname,
|
182
|
@RequestParam final String englishname) throws DsmException {
|
183
|
|
184
|
dsmCore.updateDatasourcename(dsId, officialname, englishname);
|
185
|
}
|
186
|
|
187
|
@RequestMapping(value = "/ds/coordinates", method = RequestMethod.POST)
|
188
|
@ApiOperation(
|
189
|
value = "update the datasource coordinates (latitude, longitude)",
|
190
|
notes = "update the datasource coordinates (latitude, longitude)",
|
191
|
tags = { DS, W })
|
192
|
@ApiResponses(value = {
|
193
|
@ApiResponse(code = 200, message = "OK"),
|
194
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
195
|
public void updateCoordinates(
|
196
|
@RequestParam final String dsId,
|
197
|
@RequestParam final Double latitude,
|
198
|
@RequestParam final Double longitude) throws DsmException {
|
199
|
|
200
|
dsmCore.updateCoordinates(dsId, latitude, longitude);
|
201
|
}
|
202
|
|
203
|
@RequestMapping(value = "/ds/timezone", method = RequestMethod.POST)
|
204
|
@ApiOperation(
|
205
|
value = "update a datasource timezone",
|
206
|
notes = "update a datasource timezone",
|
207
|
tags = { DS, W } )
|
208
|
@ApiResponses(value = {
|
209
|
@ApiResponse(code = 200, message = "OK"),
|
210
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
211
|
public void updateTimezone(
|
212
|
@RequestParam final String dsId,
|
213
|
@RequestParam final String timezone) throws DsmException {
|
214
|
|
215
|
dsmCore.updateTimezone(dsId, timezone);
|
216
|
}
|
217
|
|
218
|
@RequestMapping(value = "/ds/typology", method = RequestMethod.POST)
|
219
|
@ApiOperation(
|
220
|
value = "update a datasource typology code",
|
221
|
notes = "update a datasource typology code",
|
222
|
tags = { DS, W } )
|
223
|
@ApiResponses(value = {
|
224
|
@ApiResponse(code = 200, message = "OK"),
|
225
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
226
|
public void updateTypology(
|
227
|
@RequestParam final String dsId,
|
228
|
@RequestParam final String typology) throws DsmException {
|
229
|
|
230
|
dsmCore.updateDsTypology(dsId, typology);
|
231
|
}
|
232
|
|
233
|
@RequestMapping(value = "/ds/registeredby", method = RequestMethod.POST)
|
234
|
@ApiOperation(
|
235
|
value = "update a datasource registeredBy",
|
236
|
notes = "update a datasource registeredBy",
|
237
|
tags = { DS, W } )
|
238
|
@ApiResponses(value = {
|
239
|
@ApiResponse(code = 200, message = "OK"),
|
240
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
241
|
public void updateRegisteringUser(
|
242
|
@RequestParam final String dsId,
|
243
|
@RequestParam final String registeredBy) throws DsmException {
|
244
|
|
245
|
dsmCore.updateDsRegisteringUser(dsId, registeredBy);
|
246
|
}
|
247
|
|
248
|
@RequestMapping(value = "/ds/platform", method = RequestMethod.POST)
|
249
|
@ApiOperation(
|
250
|
value = "update a datasource platform",
|
251
|
notes = "update a datasource platform",
|
252
|
tags = { DS, W } )
|
253
|
@ApiResponses(value = {
|
254
|
@ApiResponse(code = 200, message = "OK"),
|
255
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
256
|
public void updatePlatform(
|
257
|
@RequestParam final String dsId,
|
258
|
@RequestParam final String platform) throws DsmException {
|
259
|
|
260
|
dsmCore.updateDsPlatform(dsId, platform);
|
261
|
}
|
262
|
|
263
|
@RequestMapping(value = "/ds/api/baseurl", method = RequestMethod.POST)
|
264
|
@ApiOperation(
|
265
|
value = "update the base URL of a datasource API",
|
266
|
notes = "update the base URL of a datasource API",
|
267
|
tags = { API, W })
|
268
|
@ApiResponses(value = {
|
269
|
@ApiResponse(code = 200, message = "OK"),
|
270
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
271
|
public void updateBaseUrl(
|
272
|
@RequestParam final String dsId,
|
273
|
@RequestParam final String apiId,
|
274
|
@RequestParam final String baseUrl) throws DsmException {
|
275
|
|
276
|
dsmCore.updateApiBaseurl(dsId, apiId, baseUrl);
|
277
|
}
|
278
|
|
279
|
@RequestMapping(value = "/ds/api/compliance", method = RequestMethod.POST)
|
280
|
@ApiOperation(
|
281
|
value = "update the compatibility of a datasource API",
|
282
|
notes = "update the compatibility of a datasource API",
|
283
|
tags = { API, W })
|
284
|
@ApiResponses(value = {
|
285
|
@ApiResponse(code = 200, message = "OK"),
|
286
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
287
|
public void updateCompliance(
|
288
|
@RequestParam final String dsId,
|
289
|
@RequestParam final String apiId,
|
290
|
@RequestParam final String compliance,
|
291
|
@RequestParam(required = false, defaultValue = "false") boolean override) throws DsmException {
|
292
|
|
293
|
dsmCore.updateApiCompatibility(dsId, apiId, compliance, override);
|
294
|
}
|
295
|
|
296
|
@RequestMapping(value = "/ds/api/add", method = RequestMethod.POST)
|
297
|
@ApiOperation(
|
298
|
value = "adds a new API to one Datasource",
|
299
|
notes = "adds an API to one Datasource",
|
300
|
tags = { API, W })
|
301
|
@ApiResponses(value = {
|
302
|
@ApiResponse(code = 200, message = "OK"),
|
303
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
304
|
public void addApi(@RequestBody final ApiDetails api) throws DsmException {
|
305
|
if (StringUtils.isBlank(api.getDatasource())) {
|
306
|
throw new DsmException(HttpStatus.SC_BAD_REQUEST, "missing datasource id");
|
307
|
}
|
308
|
dsmCore.addApi(api);
|
309
|
}
|
310
|
|
311
|
// MANAGEMENT
|
312
|
|
313
|
@Autowired
|
314
|
private OperationManager operationManager;
|
315
|
|
316
|
@RequestMapping(value = "/dsm/ops", method = RequestMethod.GET)
|
317
|
@ApiOperation(
|
318
|
value = "get the number of pending operations",
|
319
|
notes = "get the number of pending operations",
|
320
|
tags = { R, M })
|
321
|
@ApiResponses(value = {
|
322
|
@ApiResponse(code = 200, message = "OK"),
|
323
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
324
|
public int getOps() throws DsmException {
|
325
|
return operationManager.getOpSize();
|
326
|
}
|
327
|
|
328
|
@RequestMapping(value = "/dsm/killops", method = RequestMethod.POST)
|
329
|
@ApiOperation(
|
330
|
value = "interrupts the pending operations",
|
331
|
notes = "return the number of interrupted operations",
|
332
|
tags = { W, M })
|
333
|
@ApiResponses(value = {
|
334
|
@ApiResponse(code = 200, message = "OK"),
|
335
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
336
|
public int killOps() throws DsmException {
|
337
|
return operationManager.dropAll();
|
338
|
}
|
339
|
|
340
|
@RequestMapping(value = "/dsm/dropcache", method = RequestMethod.POST)
|
341
|
@ApiOperation(
|
342
|
value = "drop the caches",
|
343
|
notes = "drop the internal caches",
|
344
|
tags = { W, M })
|
345
|
@ApiResponses(value = {
|
346
|
@ApiResponse(code = 200, message = "OK"),
|
347
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
348
|
public void dropCache() throws DsmException {
|
349
|
dsmCore.dropCaches();
|
350
|
}
|
351
|
|
352
|
|
353
|
// OLD DEPRECATED METHODS
|
354
|
|
355
|
@ApiOperation(value = "search datasources by name", notes = "Returns list of Datasource details.", tags = { D })
|
356
|
@ApiResponses(value = {
|
357
|
@ApiResponse(code = 200, message = "OK", response = DatasourceResponse.class),
|
358
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
359
|
@RequestMapping(value = "/ds/search/name/{page}/{size}", produces = { "application/json" }, method = RequestMethod.GET)
|
360
|
DatasourceResponse searchByName(String name, int page, int size) throws DsmException {
|
361
|
final RequestSort sort = RequestSort.id;
|
362
|
final RequestSortOrder order = RequestSortOrder.ASCENDING;
|
363
|
final RequestFilter filter = new RequestFilter();
|
364
|
filter.put(FilterName.englishname, name);
|
365
|
|
366
|
return dsmCore.search(sort, order, filter, page, size);
|
367
|
}
|
368
|
|
369
|
@ApiOperation(value = "search datasources by contact email", notes = "Returns list of Datasource details.", tags = { D })
|
370
|
@ApiResponses(value = {
|
371
|
@ApiResponse(code = 200, message = "OK", response = DatasourceResponse.class),
|
372
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
373
|
@RequestMapping(value = "/ds/search/email/{page}/{size}", produces = { "application/json" }, method = RequestMethod.GET)
|
374
|
DatasourceResponse searchByContactemail(String contactemail, int page, int size) throws DsmException {
|
375
|
final RequestSort sort = RequestSort.id;
|
376
|
final RequestSortOrder order = RequestSortOrder.ASCENDING;
|
377
|
final RequestFilter filter = new RequestFilter();
|
378
|
filter.put(FilterName.contactemail, contactemail);
|
379
|
|
380
|
return dsmCore.search(sort, order, filter, page, size);
|
381
|
}
|
382
|
|
383
|
@ApiOperation(value = "search datasources by country", notes = "Returns list of Datasource details.", tags = { D })
|
384
|
@ApiResponses(value = {
|
385
|
@ApiResponse(code = 200, message = "OK", response = DatasourceResponse.class),
|
386
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
387
|
@RequestMapping(value = "/ds/search/country/{page}/{size}", produces = { "application/json" }, method = RequestMethod.GET)
|
388
|
DatasourceResponse searchByCountry(String country, Boolean managed, int page, int size) throws DsmException {
|
389
|
final RequestSort sort = RequestSort.id;
|
390
|
final RequestSortOrder order = RequestSortOrder.ASCENDING;
|
391
|
final RequestFilter filter = new RequestFilter();
|
392
|
filter.put(FilterName.country, country);
|
393
|
filter.put(FilterName.managed, managed);
|
394
|
|
395
|
return dsmCore.search(sort, order, filter, page, size);
|
396
|
}
|
397
|
|
398
|
@ApiOperation(value = "search datasources by registering user", notes = "Returns list of Datasource details.", tags = { D })
|
399
|
@ApiResponses(value = {
|
400
|
@ApiResponse(code = 200, message = "OK", response = DatasourceResponse.class),
|
401
|
@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
|
402
|
@RequestMapping(value = "/ds/search/registeredby/{page}/{size}", produces = { "application/json" }, method = RequestMethod.GET)
|
403
|
DatasourceResponse searchByRegisteringUser(String registeredBy, int page, int size) throws DsmException {
|
404
|
final RequestSort sort = RequestSort.id;
|
405
|
final RequestSortOrder order = RequestSortOrder.ASCENDING;
|
406
|
final RequestFilter filter = new RequestFilter();
|
407
|
filter.put(FilterName.registeredby, registeredBy);
|
408
|
|
409
|
return dsmCore.search(sort, order, filter, page, size);
|
410
|
}
|
411
|
|
412
|
// HELPERS
|
413
|
|
414
|
private <T extends Response> T prepareResponse(int page, int size, final StopWatch stop, final Response rsp) {
|
415
|
rsp.getHeader()
|
416
|
.setTime(stop.getTime())
|
417
|
.setPage(page)
|
418
|
.setSize(size);
|
419
|
return (T) rsp;
|
420
|
}
|
421
|
}
|