Project

General

Profile

1 26600 sandro.lab
package eu.dnetlib.functionality.modular.ui.repositories;
2
3 58380 michele.ar
import java.io.IOException;
4 38837 michele.ar
import java.util.Date;
5 26600 sandro.lab
import java.util.List;
6
import java.util.Map;
7
8
import javax.annotation.Resource;
9 44315 michele.ar
import javax.servlet.http.HttpServletRequest;
10 26600 sandro.lab
import javax.servlet.http.HttpServletResponse;
11
12
import org.apache.commons.io.IOUtils;
13 43828 michele.ar
import org.apache.commons.lang.exception.ExceptionUtils;
14 58375 michele.ar
import org.apache.commons.lang3.StringUtils;
15 26600 sandro.lab
import org.apache.commons.logging.Log;
16
import org.apache.commons.logging.LogFactory;
17 50485 michele.ar
import org.springframework.beans.factory.annotation.Autowired;
18 58375 michele.ar
import org.springframework.beans.factory.annotation.Value;
19 48102 claudio.at
import org.springframework.cache.annotation.CacheEvict;
20
import org.springframework.cache.annotation.Cacheable;
21 43828 michele.ar
import org.springframework.http.HttpStatus;
22 26600 sandro.lab
import org.springframework.stereotype.Controller;
23 30166 michele.ar
import org.springframework.ui.ModelMap;
24 43828 michele.ar
import org.springframework.web.bind.annotation.ExceptionHandler;
25 58375 michele.ar
import org.springframework.web.bind.annotation.RequestBody;
26 26600 sandro.lab
import org.springframework.web.bind.annotation.RequestMapping;
27 58375 michele.ar
import org.springframework.web.bind.annotation.RequestMethod;
28 26600 sandro.lab
import org.springframework.web.bind.annotation.RequestParam;
29
import org.springframework.web.bind.annotation.ResponseBody;
30 43828 michele.ar
import org.springframework.web.bind.annotation.ResponseStatus;
31 58380 michele.ar
import org.springframework.web.client.RestTemplate;
32 26600 sandro.lab
33
import com.google.common.collect.Maps;
34
import com.google.gson.Gson;
35 50485 michele.ar
import com.google.gson.reflect.TypeToken;
36 26600 sandro.lab
37 33250 michele.ar
import eu.dnetlib.data.collector.rmi.CollectorService;
38
import eu.dnetlib.data.collector.rmi.CollectorServiceException;
39
import eu.dnetlib.data.collector.rmi.ProtocolParameterValue;
40 50485 michele.ar
import eu.dnetlib.enabling.datasources.common.Api;
41
import eu.dnetlib.enabling.datasources.common.ApiParam;
42
import eu.dnetlib.enabling.datasources.common.ApiParamImpl;
43
import eu.dnetlib.enabling.datasources.common.BrowseTerm;
44
import eu.dnetlib.enabling.datasources.common.Datasource;
45
import eu.dnetlib.enabling.datasources.common.DsmException;
46
import eu.dnetlib.enabling.datasources.common.Identity;
47
import eu.dnetlib.enabling.datasources.common.LocalDatasourceManager;
48
import eu.dnetlib.enabling.datasources.common.Organization;
49
import eu.dnetlib.enabling.datasources.common.SearchApisEntry;
50
import eu.dnetlib.enabling.datasources.common.SimpleDatasource;
51 33882 michele.ar
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
52 26600 sandro.lab
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
53
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
54 32669 michele.ar
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
55 44315 michele.ar
import eu.dnetlib.functionality.modular.ui.error.ErrorMessage;
56 26600 sandro.lab
import eu.dnetlib.functionality.modular.ui.repositories.objects.RepoInterfaceEntry;
57
import eu.dnetlib.functionality.modular.ui.workflows.objects.sections.WorkflowSectionGrouper;
58
import eu.dnetlib.msro.workflows.sarasvati.loader.WorkflowExecutor;
59
import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
60
61
@Controller
62
public class RepoInternalController {
63
64 50485 michele.ar
	@Autowired
65
	private LocalDatasourceManager<Datasource<?, ?>, Api<?>> dsManager;
66
67 32669 michele.ar
	@Resource
68
	private UniqueServiceLocator serviceLocator;
69 26600 sandro.lab
70
	@Resource
71
	private WorkflowSectionGrouper workflowSectionGrouper;
72
73
	@Resource
74
	private WorkflowExecutor workflowExecutor;
75
76
	@Resource
77
	private RepoUIUtils repoUIUtils;
78 32669 michele.ar
79 58380 michele.ar
	@Value("${repo.ui.mdstore.sync.button}")
80
	private String syncButton;
81
82 58384 michele.ar
	@Value("${repo.ui.mdstore.sync.remote.desc}")
83 58380 michele.ar
	private String syncDesc;
84 58375 michele.ar
85 58384 michele.ar
	@Value("${repo.ui.mdstore.sync.remote.api.baseUrl}")
86 58380 michele.ar
	private String syncApiBaseUrl;
87 58375 michele.ar
88 58384 michele.ar
	@Value("${repo.ui.mdstore.sync.remote.is.baseUrl}")
89 58380 michele.ar
	private String syncISBaseUrl;
90
91 58384 michele.ar
	@Value("${repo.ui.mdstore.sync.local.mongodb.url}")
92
	private String mongoUrl;
93
94 58375 michele.ar
	@Value("${services.mdstore.mongodb.db}")
95
	private String mongoDb;
96
97 26600 sandro.lab
	private static final Log log = LogFactory.getLog(RepoInternalController.class);
98 32669 michele.ar
99 29896 michele.ar
	@RequestMapping(value = "/ui/browseRepoField.do")
100 50485 michele.ar
	public @ResponseBody List<? extends BrowseTerm> browseRepoField(@RequestParam(value = "field", required = true) final String field) throws Exception {
101
		return dsManager.browseField(field);
102 26600 sandro.lab
	}
103
104 48102 claudio.at
	@Cacheable(cacheNames = "repoUIJsonCache", key = "#param, #value", condition = "#refresh == false")
105 30812 michele.ar
	@RequestMapping(value = "/ui/listApis.do")
106 50485 michele.ar
	public @ResponseBody List<? extends SearchApisEntry> listApis(
107 61885 michele.ar
		@RequestParam(value = "param", required = true) final String param,
108
		@RequestParam(value = "value", required = true) final String value,
109
		@RequestParam(value = "refresh", required = false) final String refresh) throws Exception {
110 32669 michele.ar
111 50485 michele.ar
		return dsManager.searchApis(param, value);
112 26600 sandro.lab
	}
113
114 30812 michele.ar
	@RequestMapping(value = "/ui/listRepositories.json")
115 50485 michele.ar
	public @ResponseBody List<SimpleDatasource> listRepositories(@RequestParam(value = "type", required = true) final String type) throws Exception {
116
		return dsManager.searchDatasourcesByType(type);
117 26600 sandro.lab
	}
118
119 48102 claudio.at
	@CacheEvict("repoUIJsonCache")
120 26600 sandro.lab
	@RequestMapping(value = "/ui/validateRepo.do")
121 43828 michele.ar
	public @ResponseBody String listRepositories(@RequestParam(value = "id", required = true) final String id,
122 61885 michele.ar
		@RequestParam(value = "b", required = true) final boolean b) throws Exception {
123 26600 sandro.lab
124
		final String query = "count(/*[.//RESOURCE_TYPE/@value='MetaWorkflowDSResourceType' and .//DATAPROVIDER/@id='" + id + "'])";
125 58375 michele.ar
		if (!b && Integer.parseInt(serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(query)) > 0) {
126
			throw new Exception("Repo " + id
127 61885 michele.ar
				+ " can be invalidated: it is related to some metawfs");
128 58375 michele.ar
		}
129 26600 sandro.lab
130 43828 michele.ar
		final String newId = b ? serviceLocator.getService(ISRegistryService.class).validateProfile(id)
131 61885 michele.ar
			: serviceLocator.getService(ISRegistryService.class).invalidateProfile(id);
132 32669 michele.ar
133 26600 sandro.lab
		return newId;
134
	}
135
136
	@RequestMapping(value = "/ui/getRepoDetails.do")
137 62012 michele.ar
	public @ResponseBody Datasource<?, ?> getRepoDetails(final HttpServletResponse response, @RequestParam(value = "id", required = true) final String id)
138
		throws Exception {
139
		return dsManager.getDs(id);
140 26600 sandro.lab
	}
141
142
	@RequestMapping("/ui/repoMetaWf.new")
143 43828 michele.ar
	public @ResponseBody String newDataProviderWorkflow(@RequestParam(value = "id", required = true) final String repoId,
144 61885 michele.ar
		@RequestParam(value = "name", required = true) final String repoName,
145
		@RequestParam(value = "iface", required = true) final String ifaceId,
146
		@RequestParam(value = "wf", required = true) final String wfId) throws Exception {
147 26600 sandro.lab
148
		final Map<String, Object> params = Maps.newHashMap();
149
		params.put(WorkflowsConstants.DATAPROVIDER_ID, repoId);
150
		params.put(WorkflowsConstants.DATAPROVIDER_NAME, repoName);
151
		params.put(WorkflowsConstants.DATAPROVIDER_INTERFACE, ifaceId);
152
153
		return workflowExecutor.startProcess(wfId, params);
154
	}
155
156
	@RequestMapping("/ui/repoMetaWf.destroy")
157 43828 michele.ar
	public @ResponseBody String destroyDataProviderWorkflow(@RequestParam(value = "destroyWf", required = true) final String destroyWfId)
158 61885 michele.ar
		throws Exception {
159 26600 sandro.lab
		return workflowExecutor.startProcess(destroyWfId, null);
160
	}
161
162
	@RequestMapping("/ui/repoApi.get")
163 43828 michele.ar
	public @ResponseBody RepoInterfaceEntry getRepoApi(@RequestParam(value = "repoId", required = true) final String repoId,
164 61885 michele.ar
		@RequestParam(value = "ifaceId", required = true) final String ifaceId) throws Exception {
165 55604 claudio.at
166
		try {
167
			return repoUIUtils.getApi(repoId, ifaceId);
168 58375 michele.ar
		} catch (final ISLookUpDocumentNotFoundException e) {
169 55604 claudio.at
170 58375 michele.ar
			log.warn(String
171 61885 michele.ar
				.format("the Interface '%s' is not available for repository '%s', try to sync DB and profiles via the DatasourceManager", ifaceId, repoId));
172 55604 claudio.at
			dsManager.setActive(repoId, ifaceId, dsManager.isActive(repoId, ifaceId));
173
			return repoUIUtils.getApi(repoId, ifaceId);
174
		}
175 26600 sandro.lab
	}
176
177
	@RequestMapping("/ui/repoApi.update")
178 43828 michele.ar
	public @ResponseBody boolean updateRepoApi(
179 61885 michele.ar
		@RequestParam(value = "id", required = true) final String repoId,
180
		@RequestParam(value = "iface", required = true) final String ifaceId,
181
		@RequestParam(value = "accessParams", required = false) final String accessParamsJson,
182
		@RequestParam(value = "mdIdPath", required = false) final String mdIdPath) throws Exception {
183 43848 michele.ar
184 30870 michele.ar
		if (!StringUtils.isEmpty(accessParamsJson)) {
185 50485 michele.ar
			final Map<String, String> params = new Gson().fromJson(accessParamsJson, new TypeToken<Map<String, String>>() {}.getType());
186
			final String baseUrl = params.remove("baseUrl");
187
			dsManager.updateApiDetails(repoId, ifaceId, mdIdPath, baseUrl, params);
188 26600 sandro.lab
		}
189 43848 michele.ar
190 26600 sandro.lab
		return true;
191
	}
192 32669 michele.ar
193 43828 michele.ar
	@RequestMapping("/ui/repoApi.delete")
194 58375 michele.ar
	public @ResponseBody boolean deleteRepoApi(
195 61885 michele.ar
		@RequestParam(value = "repo", required = true) final String repoId,
196
		@RequestParam(value = "iface", required = true) final String ifaceId) throws Exception {
197 50485 michele.ar
		dsManager.deleteApi(repoId, ifaceId);
198
		return true;
199 43828 michele.ar
	}
200
201 48102 claudio.at
	@CacheEvict("repoUIJsonCache")
202 29884 michele.ar
	@RequestMapping("/ui/repoApiCompliance.update")
203 43828 michele.ar
	public @ResponseBody boolean updateRepoApiCompliance(@RequestParam(value = "id", required = true) final String repoId,
204 61885 michele.ar
		@RequestParam(value = "iface", required = true) final String ifaceId,
205
		@RequestParam(value = "compliance", required = true) final String compliance) throws Exception {
206 32669 michele.ar
207 29884 michele.ar
		log.debug("SET COMPLIANCE TO " + compliance);
208 32669 michele.ar
209 50485 michele.ar
		dsManager.updateCompliance(repoId, ifaceId, compliance, true);
210 32669 michele.ar
211 29920 michele.ar
		return true;
212 29884 michele.ar
	}
213 32669 michele.ar
214 48102 claudio.at
	@CacheEvict("repoUIJsonCache")
215 29884 michele.ar
	@RequestMapping("/ui/repoApiCompliance.reset")
216 43828 michele.ar
	public @ResponseBody boolean resetRepoApiCompliance(@RequestParam(value = "id", required = true) final String repoId,
217 61885 michele.ar
		@RequestParam(value = "iface", required = true) final String ifaceId) throws Exception {
218 28876 michele.ar
219 29884 michele.ar
		log.debug("RESET COMPLIANCE");
220 32669 michele.ar
221 50485 michele.ar
		dsManager.updateCompliance(repoId, ifaceId, null, true);
222 32669 michele.ar
223 29920 michele.ar
		return true;
224 29884 michele.ar
	}
225 32669 michele.ar
226 30166 michele.ar
	@RequestMapping("/ui/repos/repoApi.html")
227 58375 michele.ar
	public void repoApiHtml(final ModelMap map) throws Exception {
228 58380 michele.ar
		if (StringUtils.isNoneBlank(syncButton, syncDesc, syncApiBaseUrl, syncISBaseUrl)) {
229
			map.addAttribute("syncButton", syncButton);
230
			map.addAttribute("syncDesc", syncDesc);
231
			map.addAttribute("syncISBaseUrl", syncISBaseUrl);
232 58375 michele.ar
			map.addAttribute("mongoDB", mongoDb);
233 58384 michele.ar
			map.addAttribute("mongoUrl", mongoUrl);
234 58375 michele.ar
		}
235
	}
236 29884 michele.ar
237 32999 michele.ar
	@RequestMapping("/ui/repoApi.new")
238 43828 michele.ar
	public @ResponseBody boolean addRepoApi(@RequestParam(value = "repoId", required = true) final String repoId,
239 61885 michele.ar
		@RequestParam(value = "iface", required = true) final String ifaceJson) throws DsmException {
240 50485 michele.ar
		final Api<ApiParam> iface = new Gson().fromJson(ifaceJson, new TypeToken<Api<ApiParamImpl>>() {}.getType());
241 33226 michele.ar
242 50485 michele.ar
		iface.setDatasource(repoId);
243 33226 michele.ar
244 50485 michele.ar
		log.info("Adding api " + iface.getId() + " to repository " + repoId);
245
246
		dsManager.addApi(iface);
247
248
		return true;
249 32999 michele.ar
	}
250 33250 michele.ar
251 38837 michele.ar
	@RequestMapping("/ui/repo.new")
252 50485 michele.ar
	public @ResponseBody boolean addRepoApi(@RequestParam(value = "repo", required = true) final String repoJson) throws DsmException {
253
		final Datasource<Organization<?>, Identity> ds = new Gson().fromJson(repoJson, new TypeToken<Datasource<Organization<?>, Identity>>() {}.getType());
254
		final Date now = new Date();
255
		ds.setDateofcollection(new java.sql.Date(now.getTime()));
256 38837 michele.ar
257 50485 michele.ar
		if (StringUtils.isBlank(ds.getEnglishname())) {
258
			ds.setEnglishname(ds.getOfficialname());
259 38837 michele.ar
		}
260
261 61885 michele.ar
		if (StringUtils.isBlank(ds.getProvenanceaction())) {
262
			ds.setProvenanceaction("user:insert");
263
		}
264
265 50485 michele.ar
		log.info("Adding datasource " + ds.getId() + " - name " + ds.getOfficialname());
266 38837 michele.ar
267 50485 michele.ar
		dsManager.saveDs(ds);
268 38837 michele.ar
269 50485 michele.ar
		return true;
270 38837 michele.ar
	}
271
272 33250 michele.ar
	@RequestMapping("/ui/listValidValuesForParam.do")
273 43828 michele.ar
	public @ResponseBody List<ProtocolParameterValue> listValidValuesForParam(
274 61885 michele.ar
		@RequestParam(value = "protocol", required = true) final String protocol,
275
		@RequestParam(value = "param", required = true) final String param,
276
		@RequestParam(value = "baseUrl", required = true) final String baseUrl) throws CollectorServiceException {
277 33250 michele.ar
278
		return serviceLocator.getService(CollectorService.class).listValidValuesForParam(protocol, baseUrl, param, null);
279
	}
280 43828 michele.ar
281 58375 michele.ar
	@RequestMapping(value = "/ui/remoteDatasource/apis", method = RequestMethod.GET)
282 58380 michele.ar
	public void listRemoteApis(@RequestParam(value = "repo", required = true) final String repoId,
283 61885 michele.ar
		final HttpServletResponse response) throws IOException {
284 58380 michele.ar
285
		final RestTemplate restTemplate = new RestTemplate();
286
287
		final String res = restTemplate.getForObject(syncApiBaseUrl + "/ds/api/" + repoId, String.class);
288
289
		response.setContentType("application/json;charset=UTF-8");
290
291
		IOUtils.write(res, response.getOutputStream());
292 58375 michele.ar
	}
293
294
	@RequestMapping(value = "/ui/remoteDatasource/api", method = RequestMethod.POST)
295 58380 michele.ar
	public void saveRemoteApi(@RequestBody final Api<ApiParamImpl> api, final HttpServletResponse response) throws IOException {
296
297
		final String url = syncApiBaseUrl + "/ds/api/add";
298
299
		log.info("Adding new remote API:");
300
		log.info(" - repo id: " + api.getDatasource());
301
		log.info(" - api id: " + api.getId());
302
		log.info(" - rest call: " + url);
303 58384 michele.ar
		log.info(" - json: " + new Gson().toJson(api));
304 58380 michele.ar
305
		final RestTemplate restTemplate = new RestTemplate();
306
307 58384 michele.ar
		restTemplate.postForObject(url, api, Void.class);
308 58380 michele.ar
309 58384 michele.ar
		listRemoteApis(api.getDatasource(), response);
310 58375 michele.ar
	}
311
312 43828 michele.ar
	@ExceptionHandler(Exception.class)
313
	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
314 44315 michele.ar
	public @ResponseBody ErrorMessage handleException(final HttpServletRequest req, final Exception e) {
315
		log.error("Error processing " + req.getRequestURI(), e);
316
		return new ErrorMessage(e.getMessage(), ExceptionUtils.getStackTrace(e));
317 43828 michele.ar
	}
318
319 26600 sandro.lab
}