Revision 58375
Added by Michele Artini about 4 years ago
modules/dnet-modular-repositories-ui/trunk/src/main/java/eu/dnetlib/functionality/modular/ui/repositories/RepoInternalController.java | ||
---|---|---|
2 | 2 |
|
3 | 3 |
import java.io.StringReader; |
4 | 4 |
import java.util.Date; |
5 |
import java.util.HashMap; |
|
5 | 6 |
import java.util.List; |
6 | 7 |
import java.util.Map; |
7 | 8 |
|
... | ... | |
10 | 11 |
import javax.servlet.http.HttpServletResponse; |
11 | 12 |
|
12 | 13 |
import org.apache.commons.io.IOUtils; |
13 |
import org.apache.commons.lang.StringUtils; |
|
14 | 14 |
import org.apache.commons.lang.exception.ExceptionUtils; |
15 |
import org.apache.commons.lang3.StringUtils; |
|
15 | 16 |
import org.apache.commons.logging.Log; |
16 | 17 |
import org.apache.commons.logging.LogFactory; |
17 | 18 |
import org.springframework.beans.factory.annotation.Autowired; |
19 |
import org.springframework.beans.factory.annotation.Value; |
|
18 | 20 |
import org.springframework.cache.annotation.CacheEvict; |
19 | 21 |
import org.springframework.cache.annotation.Cacheable; |
20 | 22 |
import org.springframework.http.HttpStatus; |
21 | 23 |
import org.springframework.stereotype.Controller; |
22 | 24 |
import org.springframework.ui.ModelMap; |
23 | 25 |
import org.springframework.web.bind.annotation.ExceptionHandler; |
26 |
import org.springframework.web.bind.annotation.RequestBody; |
|
24 | 27 |
import org.springframework.web.bind.annotation.RequestMapping; |
28 |
import org.springframework.web.bind.annotation.RequestMethod; |
|
25 | 29 |
import org.springframework.web.bind.annotation.RequestParam; |
26 | 30 |
import org.springframework.web.bind.annotation.ResponseBody; |
27 | 31 |
import org.springframework.web.bind.annotation.ResponseStatus; |
... | ... | |
73 | 77 |
@Resource |
74 | 78 |
private RepoUIUtils repoUIUtils; |
75 | 79 |
|
80 |
@Value("${repo.ui.mdstore.sync.desc}") |
|
81 |
private String syncDescription; |
|
82 |
|
|
83 |
@Value("${repo.ui.mdstore.sync.baseUrl}") |
|
84 |
private String syncApi; |
|
85 |
|
|
86 |
@Value("${services.mdstore.mongodb.db}") |
|
87 |
private String mongoDb; |
|
88 |
|
|
89 |
@Value("${services.mdstore.mongodb.host}") |
|
90 |
private String mongoHost; |
|
91 |
|
|
92 |
@Value("${services.mdstore.mongodb.port}") |
|
93 |
private int mongoPort; |
|
94 |
|
|
76 | 95 |
private static final Log log = LogFactory.getLog(RepoInternalController.class); |
77 | 96 |
|
78 | 97 |
@RequestMapping(value = "/ui/browseRepoField.do") |
... | ... | |
101 | 120 |
@RequestParam(value = "b", required = true) final boolean b) throws Exception { |
102 | 121 |
|
103 | 122 |
final String query = "count(/*[.//RESOURCE_TYPE/@value='MetaWorkflowDSResourceType' and .//DATAPROVIDER/@id='" + id + "'])"; |
104 |
if (!b && Integer.parseInt(serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(query)) > 0) { throw new Exception("Repo " + id |
|
105 |
+ " can be invalidated: it is related to some metawfs"); } |
|
123 |
if (!b && Integer.parseInt(serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(query)) > 0) { |
|
124 |
throw new Exception("Repo " + id |
|
125 |
+ " can be invalidated: it is related to some metawfs"); |
|
126 |
} |
|
106 | 127 |
|
107 | 128 |
final String newId = b ? serviceLocator.getService(ISRegistryService.class).validateProfile(id) |
108 | 129 |
: serviceLocator.getService(ISRegistryService.class).invalidateProfile(id); |
... | ... | |
116 | 137 |
try { |
117 | 138 |
profile = serviceLocator.getService(ISLookUpService.class).getResourceProfile(id); |
118 | 139 |
} catch (final ISLookUpDocumentNotFoundException e) { |
119 |
profile = serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery( |
|
120 |
"collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType')/*[.//DATASOURCE_ORIGINAL_ID='" + id + "']"); |
|
140 |
profile = serviceLocator.getService(ISLookUpService.class) |
|
141 |
.getResourceProfileByQuery("collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType')/*[.//DATASOURCE_ORIGINAL_ID='" |
|
142 |
+ id + "']"); |
|
121 | 143 |
} |
122 | 144 |
|
123 |
final ApplyXslt xslt = new ApplyXslt(IOUtils.toString(getClass().getResourceAsStream(
|
|
124 |
"/eu/dnetlib/functionality/modular/ui/repositories/xslt/repoDetails.xslt"))); |
|
145 |
final ApplyXslt xslt = |
|
146 |
new ApplyXslt(IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/functionality/modular/ui/repositories/xslt/repoDetails.xslt")));
|
|
125 | 147 |
|
126 | 148 |
IOUtils.copy(new StringReader(xslt.evaluate(profile)), response.getOutputStream()); |
127 | 149 |
} |
... | ... | |
152 | 174 |
|
153 | 175 |
try { |
154 | 176 |
return repoUIUtils.getApi(repoId, ifaceId); |
155 |
} catch (ISLookUpDocumentNotFoundException e) { |
|
177 |
} catch (final ISLookUpDocumentNotFoundException e) {
|
|
156 | 178 |
|
157 |
log.warn(String.format("the Interface '%s' is not available for repository '%s', try to sync DB and profiles via the DatasourceManager", ifaceId, repoId)); |
|
179 |
log.warn(String |
|
180 |
.format("the Interface '%s' is not available for repository '%s', try to sync DB and profiles via the DatasourceManager", ifaceId, repoId)); |
|
158 | 181 |
dsManager.setActive(repoId, ifaceId, dsManager.isActive(repoId, ifaceId)); |
159 | 182 |
return repoUIUtils.getApi(repoId, ifaceId); |
160 | 183 |
} |
... | ... | |
177 | 200 |
} |
178 | 201 |
|
179 | 202 |
@RequestMapping("/ui/repoApi.delete") |
180 |
public @ResponseBody boolean updateRepoApi(
|
|
203 |
public @ResponseBody boolean deleteRepoApi(
|
|
181 | 204 |
@RequestParam(value = "repo", required = true) final String repoId, |
182 | 205 |
@RequestParam(value = "iface", required = true) final String ifaceId) throws Exception { |
183 | 206 |
dsManager.deleteApi(repoId, ifaceId); |
... | ... | |
210 | 233 |
} |
211 | 234 |
|
212 | 235 |
@RequestMapping("/ui/repos/repoApi.html") |
213 |
public void resetRepoApiCompliance(final ModelMap map) throws Exception {} |
|
236 |
public void repoApiHtml(final ModelMap map) throws Exception { |
|
237 |
if (StringUtils.isNoneBlank(syncDescription, syncApi)) { |
|
238 |
map.addAttribute("syncDesc", syncDescription); |
|
239 |
map.addAttribute("mongoDB", mongoDb); |
|
240 |
map.addAttribute("mongoUrl", String.format("mongodb://%s:%s", mongoHost, mongoPort)); |
|
241 |
} |
|
242 |
} |
|
214 | 243 |
|
215 | 244 |
@RequestMapping("/ui/repoApi.new") |
216 | 245 |
public @ResponseBody boolean addRepoApi(@RequestParam(value = "repoId", required = true) final String repoId, |
... | ... | |
252 | 281 |
return serviceLocator.getService(CollectorService.class).listValidValuesForParam(protocol, baseUrl, param, null); |
253 | 282 |
} |
254 | 283 |
|
284 |
@RequestMapping(value = "/ui/remoteDatasource/apis", method = RequestMethod.GET) |
|
285 |
public @ResponseBody Map<String, String> listRemoteApis(@RequestParam(value = "repo", required = true) final String repoId) { |
|
286 |
// TODO |
|
287 |
return new HashMap<>(); |
|
288 |
} |
|
289 |
|
|
290 |
@RequestMapping(value = "/ui/remoteDatasource/api", method = RequestMethod.POST) |
|
291 |
public @ResponseBody Map<String, String> listRemoteApis(@RequestParam(value = "repo", required = true) final String repoId, |
|
292 |
@RequestBody final Api<ApiParam> api) { |
|
293 |
// TODO |
|
294 |
return new HashMap<>(); |
|
295 |
} |
|
296 |
|
|
255 | 297 |
@ExceptionHandler(Exception.class) |
256 | 298 |
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) |
257 | 299 |
public @ResponseBody ErrorMessage handleException(final HttpServletRequest req, final Exception e) { |
modules/dnet-modular-repositories-ui/trunk/src/main/resources/eu/dnetlib/functionality/modular/ui/repositories/applicationContext-modular-ui-repositories.properties | ||
---|---|---|
8 | 8 |
repo.ui.addRepo.show = true |
9 | 9 |
repo.ui.validator.address = http://dev.openaire.research-infrastructures.eu:8880/validator/compatibility/browseHistory |
10 | 10 |
repo.ui.validatorService.address = http://dev.openaire.research-infrastructures.eu:8880/validator-service |
11 |
|
|
12 |
repo.ui.mdstore.sync.desc = sync with beta |
|
13 |
repo.ui.mdstore.sync.baseUrl = http://xxxxxx |
modules/dnet-modular-repositories-ui/trunk/src/main/resources/eu/dnetlib/functionality/modular/ui/views/ui/repos/repoApi.st | ||
---|---|---|
82 | 82 |
|
83 | 83 |
<div class="input-group input-group-sm col-xs-12 col-md-6" style="padding: 10px; float: left;"> |
84 | 84 |
<span class="input-group-addon" style="width: 150px;"><b>Last aggregation</b></span> |
85 |
<ng-api-mdstore-info label="Collect" date="currentRepoApi.collDate" total="currentRepoApi.collTotal" id="currentRepoApi.collMdId"></ng-api-mdstore-info> |
|
86 |
<ng-api-mdstore-info label="Transform" date="currentRepoApi.aggrDate" total="currentRepoApi.aggrTotal" id="currentRepoApi.aggrMdId"></ng-api-mdstore-info> |
|
85 |
<ng-api-mdstore-info label="Collect" date="currentRepoApi.collDate" total="currentRepoApi.collTotal" id="currentRepoApi.collMdId" sync-description="$syncDesc$" sync-function="showCreateRemoteSyncApi('$mongoUrl$','$mongoDB$',currentRepoApi.collMdId, 'remoteCollectedMdStore')"></ng-api-mdstore-info>
|
|
86 |
<ng-api-mdstore-info label="Transform" date="currentRepoApi.aggrDate" total="currentRepoApi.aggrTotal" id="currentRepoApi.aggrMdId" sync-description="$syncDesc$" sync-function="showCreateRemoteSyncApi('$mongoUrl$','$mongoDB$',currentRepoApi.aggrMdId, 'remoteAggregatedMdStore')"></ng-api-mdstore-info>
|
|
87 | 87 |
<ng-api-objectstore-info label="Download" date="currentRepoApi.downloadDate" total="currentRepoApi.downloadTotal" id="currentRepoApi.downloadObjId"></ng-api-objectstore-info> |
88 | 88 |
</div> |
89 | 89 |
|
... | ... | |
241 | 241 |
</div> |
242 | 242 |
</div> |
243 | 243 |
|
244 |
<div id="remoteSyncApiModal" class="modal fade" tabindex="-1" role="dialog"> |
|
245 |
<div class="modal-dialog modal-lg"> |
|
246 |
<div class="modal-content"> |
|
247 |
<div class="modal-header"> |
|
248 |
<button type="button" class="close" data-dismiss="modal">×</button> |
|
249 |
<h4 class="modal-title">Create remote API</h4> |
|
250 |
</div> |
|
251 |
<div class="modal-body"> |
|
252 |
The following API will be created on ...: |
|
253 |
<br /><br /> |
|
254 |
<pre>{{newSyncApi | json}}</pre> |
|
255 |
</div> |
|
256 |
<div class="modal-footer"> |
|
257 |
<button type="button" class="btn btn-primary" data-dismiss="modal">Confirm</button> |
|
258 |
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button> |
|
259 |
</div> |
|
260 |
</div> |
|
261 |
</div> |
|
262 |
</div> |
|
244 | 263 |
|
245 | 264 |
$ui/repos/repoDetails()$ |
246 | 265 |
$ui/workflows/common/atomwf()$ |
modules/dnet-modular-repositories-ui/trunk/src/main/resources/eu/dnetlib/web/resources/html/ngApiMdstoreInfo.html | ||
---|---|---|
1 |
<div class="form-control"> |
|
2 |
<b>{{label}}:</b> |
|
3 |
<span ng-show="date"> |
|
4 |
{{date | date:'yyyy-MM-dd HH:mm:ss'}} |
|
5 |
</span> |
|
6 |
<span ng-hide="date"> |
|
7 |
<i>not yet available</i> |
|
8 |
</span> |
|
9 |
<span class="pull-right"> |
|
10 |
<span ng-hide="id" ng-class="{'text-success' : total > 0, 'text-danger' : total == 0}"> |
|
11 |
<b>Total:</b> {{total}} |
|
1 |
<div class="input-group"> |
|
2 |
<div class="form-control"> |
|
3 |
<b>{{label}}:</b> |
|
4 |
<span ng-show="date"> |
|
5 |
{{date | date:'yyyy-MM-dd HH:mm:ss'}} |
|
12 | 6 |
</span> |
13 |
<a ng-show="id" href="../inspector/mdstore.do?id={{id}}"> |
|
14 |
<b>Total:</b> {{total}} |
|
15 |
</a> |
|
7 |
<span ng-hide="date"> |
|
8 |
<i>not yet available</i> |
|
9 |
</span> |
|
10 |
<span class="pull-right"> |
|
11 |
<span ng-hide="id" ng-class="{'text-success' : total > 0, 'text-danger' : total == 0}"> |
|
12 |
<b>Total:</b> {{total}} |
|
13 |
</span> |
|
14 |
<a ng-show="id" href="../inspector/mdstore.do?id={{id}}"> |
|
15 |
<b>Total:</b> {{total}} |
|
16 |
</a> |
|
17 |
</span> |
|
18 |
</div> |
|
19 |
<span class="input-group-btn" ng-if="id && syncDescription"> |
|
20 |
<button class="btn btn-default" ng-click="syncFunction()">{{syncDescription}}</button> |
|
16 | 21 |
</span> |
17 |
</div> |
|
18 |
|
|
22 |
</div> |
modules/dnet-modular-repositories-ui/trunk/src/main/resources/eu/dnetlib/web/resources/js/repos.js | ||
---|---|---|
20 | 20 |
'label' : '@', |
21 | 21 |
'date' : '=', |
22 | 22 |
'total' : '=', |
23 |
'id' : '=' |
|
23 |
'id' : '=', |
|
24 |
'syncDescription' : '@', |
|
25 |
'syncFunction' : '&', |
|
24 | 26 |
}, |
25 | 27 |
templateUrl: '../resources/html/ngApiMdstoreInfo.html' |
26 | 28 |
} |
modules/dnet-modular-repositories-ui/trunk/src/main/resources/eu/dnetlib/web/resources/js/repoControllers.js | ||
---|---|---|
103 | 103 |
$scope.currentRepoApi = {}; |
104 | 104 |
$scope.currentSets = []; |
105 | 105 |
$scope.selectedSets = []; |
106 |
|
|
107 |
$scope.newSyncApi = {}; |
|
106 | 108 |
|
107 | 109 |
$scope.loadApi = function() { |
108 | 110 |
$scope.showSpinner(); |
... | ... | |
389 | 391 |
} |
390 | 392 |
); |
391 | 393 |
} |
394 |
|
|
395 |
$scope.showCreateRemoteSyncApi = function(mongoUrl, mongoDB, mdId, apiSuffix) { |
|
396 |
|
|
397 |
var path = "//*[local-name()='header']/*[local-name()='identifier']"; |
|
398 |
angular.forEach($scope.currentRepoApi.otherParams, function(p) { |
|
399 |
if (p.id=='metadata_identifier_path') { |
|
400 |
path = p.value; |
|
401 |
} |
|
402 |
}); |
|
403 |
|
|
404 |
var compliance = "UNKNOWN"; |
|
405 |
angular.forEach($scope.currentRepoApi.commonParams, function(p) { |
|
406 |
if (p.id=='compliance') { |
|
407 |
compliance = p.value; |
|
408 |
} |
|
409 |
}); |
|
410 |
|
|
411 |
$scope.newSyncApi = { |
|
412 |
'dsId' : $routeParams.repoId, |
|
413 |
'apiId' : 'api_________::' + $routeParams.repoId + "::" + apiSuffix, |
|
414 |
'compatibility' : compliance, |
|
415 |
'contentdescription' : 'metadata', |
|
416 |
'protocol' : 'remoteMdstore', |
|
417 |
'baseurl' : mongoUrl, |
|
418 |
'apiParams' : { |
|
419 |
'remote_database' : mongoDB, |
|
420 |
'remote_mdstore_id' : mdId |
|
421 |
}, |
|
422 |
'metadataIdentifierPath' : path |
|
423 |
}; |
|
424 |
|
|
425 |
$('#remoteSyncApiModal').modal('show'); |
|
426 |
|
|
427 |
} |
|
392 | 428 |
|
393 | 429 |
$scope.loadApi(); |
394 | 430 |
} |
Also available in: Unified diff
remoteMdstore API creation in other infrastructure (partial implementation)