Project

General

Profile

1
package eu.dnetlib.functionality.modular.ui.repositories;
2

    
3
import java.io.StringReader;
4
import java.util.Date;
5
import java.util.HashMap;
6
import java.util.List;
7
import java.util.Map;
8

    
9
import javax.annotation.Resource;
10
import javax.servlet.http.HttpServletRequest;
11
import javax.servlet.http.HttpServletResponse;
12

    
13
import org.apache.commons.io.IOUtils;
14
import org.apache.commons.lang.exception.ExceptionUtils;
15
import org.apache.commons.lang3.StringUtils;
16
import org.apache.commons.logging.Log;
17
import org.apache.commons.logging.LogFactory;
18
import org.springframework.beans.factory.annotation.Autowired;
19
import org.springframework.beans.factory.annotation.Value;
20
import org.springframework.cache.annotation.CacheEvict;
21
import org.springframework.cache.annotation.Cacheable;
22
import org.springframework.http.HttpStatus;
23
import org.springframework.stereotype.Controller;
24
import org.springframework.ui.ModelMap;
25
import org.springframework.web.bind.annotation.ExceptionHandler;
26
import org.springframework.web.bind.annotation.RequestBody;
27
import org.springframework.web.bind.annotation.RequestMapping;
28
import org.springframework.web.bind.annotation.RequestMethod;
29
import org.springframework.web.bind.annotation.RequestParam;
30
import org.springframework.web.bind.annotation.ResponseBody;
31
import org.springframework.web.bind.annotation.ResponseStatus;
32

    
33
import com.google.common.collect.Maps;
34
import com.google.gson.Gson;
35
import com.google.gson.reflect.TypeToken;
36

    
37
import eu.dnetlib.data.collector.rmi.CollectorService;
38
import eu.dnetlib.data.collector.rmi.CollectorServiceException;
39
import eu.dnetlib.data.collector.rmi.ProtocolParameterValue;
40
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
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
52
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
53
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
54
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
55
import eu.dnetlib.functionality.modular.ui.error.ErrorMessage;
56
import eu.dnetlib.functionality.modular.ui.repositories.objects.RepoInterfaceEntry;
57
import eu.dnetlib.functionality.modular.ui.workflows.objects.sections.WorkflowSectionGrouper;
58
import eu.dnetlib.miscutils.functional.xml.ApplyXslt;
59
import eu.dnetlib.msro.workflows.sarasvati.loader.WorkflowExecutor;
60
import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
61

    
62
@Controller
63
public class RepoInternalController {
64

    
65
	@Autowired
66
	private LocalDatasourceManager<Datasource<?, ?>, Api<?>> dsManager;
67

    
68
	@Resource
69
	private UniqueServiceLocator serviceLocator;
70

    
71
	@Resource
72
	private WorkflowSectionGrouper workflowSectionGrouper;
73

    
74
	@Resource
75
	private WorkflowExecutor workflowExecutor;
76

    
77
	@Resource
78
	private RepoUIUtils repoUIUtils;
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

    
95
	private static final Log log = LogFactory.getLog(RepoInternalController.class);
96

    
97
	@RequestMapping(value = "/ui/browseRepoField.do")
98
	public @ResponseBody List<? extends BrowseTerm> browseRepoField(@RequestParam(value = "field", required = true) final String field) throws Exception {
99
		return dsManager.browseField(field);
100
	}
101

    
102
	@Cacheable(cacheNames = "repoUIJsonCache", key = "#param, #value", condition = "#refresh == false")
103
	@RequestMapping(value = "/ui/listApis.do")
104
	public @ResponseBody List<? extends SearchApisEntry> listApis(
105
			@RequestParam(value = "param", required = true) final String param,
106
			@RequestParam(value = "value", required = true) final String value,
107
			@RequestParam(value = "refresh", required = false) final String refresh) throws Exception {
108

    
109
		return dsManager.searchApis(param, value);
110
	}
111

    
112
	@RequestMapping(value = "/ui/listRepositories.json")
113
	public @ResponseBody List<SimpleDatasource> listRepositories(@RequestParam(value = "type", required = true) final String type) throws Exception {
114
		return dsManager.searchDatasourcesByType(type);
115
	}
116

    
117
	@CacheEvict("repoUIJsonCache")
118
	@RequestMapping(value = "/ui/validateRepo.do")
119
	public @ResponseBody String listRepositories(@RequestParam(value = "id", required = true) final String id,
120
			@RequestParam(value = "b", required = true) final boolean b) throws Exception {
121

    
122
		final String query = "count(/*[.//RESOURCE_TYPE/@value='MetaWorkflowDSResourceType' and .//DATAPROVIDER/@id='" + id + "'])";
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
		}
127

    
128
		final String newId = b ? serviceLocator.getService(ISRegistryService.class).validateProfile(id)
129
				: serviceLocator.getService(ISRegistryService.class).invalidateProfile(id);
130

    
131
		return newId;
132
	}
133

    
134
	@RequestMapping(value = "/ui/getRepoDetails.do")
135
	public void getRepoDetails(final HttpServletResponse response, @RequestParam(value = "id", required = true) final String id) throws Exception {
136
		String profile;
137
		try {
138
			profile = serviceLocator.getService(ISLookUpService.class).getResourceProfile(id);
139
		} catch (final ISLookUpDocumentNotFoundException e) {
140
			profile = serviceLocator.getService(ISLookUpService.class)
141
					.getResourceProfileByQuery("collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType')/*[.//DATASOURCE_ORIGINAL_ID='"
142
							+ id + "']");
143
		}
144

    
145
		final ApplyXslt xslt =
146
				new ApplyXslt(IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/functionality/modular/ui/repositories/xslt/repoDetails.xslt")));
147

    
148
		IOUtils.copy(new StringReader(xslt.evaluate(profile)), response.getOutputStream());
149
	}
150

    
151
	@RequestMapping("/ui/repoMetaWf.new")
152
	public @ResponseBody String newDataProviderWorkflow(@RequestParam(value = "id", required = true) final String repoId,
153
			@RequestParam(value = "name", required = true) final String repoName,
154
			@RequestParam(value = "iface", required = true) final String ifaceId,
155
			@RequestParam(value = "wf", required = true) final String wfId) throws Exception {
156

    
157
		final Map<String, Object> params = Maps.newHashMap();
158
		params.put(WorkflowsConstants.DATAPROVIDER_ID, repoId);
159
		params.put(WorkflowsConstants.DATAPROVIDER_NAME, repoName);
160
		params.put(WorkflowsConstants.DATAPROVIDER_INTERFACE, ifaceId);
161

    
162
		return workflowExecutor.startProcess(wfId, params);
163
	}
164

    
165
	@RequestMapping("/ui/repoMetaWf.destroy")
166
	public @ResponseBody String destroyDataProviderWorkflow(@RequestParam(value = "destroyWf", required = true) final String destroyWfId)
167
			throws Exception {
168
		return workflowExecutor.startProcess(destroyWfId, null);
169
	}
170

    
171
	@RequestMapping("/ui/repoApi.get")
172
	public @ResponseBody RepoInterfaceEntry getRepoApi(@RequestParam(value = "repoId", required = true) final String repoId,
173
			@RequestParam(value = "ifaceId", required = true) final String ifaceId) throws Exception {
174

    
175
		try {
176
			return repoUIUtils.getApi(repoId, ifaceId);
177
		} catch (final ISLookUpDocumentNotFoundException e) {
178

    
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));
181
			dsManager.setActive(repoId, ifaceId, dsManager.isActive(repoId, ifaceId));
182
			return repoUIUtils.getApi(repoId, ifaceId);
183
		}
184
	}
185

    
186
	@RequestMapping("/ui/repoApi.update")
187
	public @ResponseBody boolean updateRepoApi(
188
			@RequestParam(value = "id", required = true) final String repoId,
189
			@RequestParam(value = "iface", required = true) final String ifaceId,
190
			@RequestParam(value = "accessParams", required = false) final String accessParamsJson,
191
			@RequestParam(value = "mdIdPath", required = false) final String mdIdPath) throws Exception {
192

    
193
		if (!StringUtils.isEmpty(accessParamsJson)) {
194
			final Map<String, String> params = new Gson().fromJson(accessParamsJson, new TypeToken<Map<String, String>>() {}.getType());
195
			final String baseUrl = params.remove("baseUrl");
196
			dsManager.updateApiDetails(repoId, ifaceId, mdIdPath, baseUrl, params);
197
		}
198

    
199
		return true;
200
	}
201

    
202
	@RequestMapping("/ui/repoApi.delete")
203
	public @ResponseBody boolean deleteRepoApi(
204
			@RequestParam(value = "repo", required = true) final String repoId,
205
			@RequestParam(value = "iface", required = true) final String ifaceId) throws Exception {
206
		dsManager.deleteApi(repoId, ifaceId);
207
		return true;
208
	}
209

    
210
	@CacheEvict("repoUIJsonCache")
211
	@RequestMapping("/ui/repoApiCompliance.update")
212
	public @ResponseBody boolean updateRepoApiCompliance(@RequestParam(value = "id", required = true) final String repoId,
213
			@RequestParam(value = "iface", required = true) final String ifaceId,
214
			@RequestParam(value = "compliance", required = true) final String compliance) throws Exception {
215

    
216
		log.debug("SET COMPLIANCE TO " + compliance);
217

    
218
		dsManager.updateCompliance(repoId, ifaceId, compliance, true);
219

    
220
		return true;
221
	}
222

    
223
	@CacheEvict("repoUIJsonCache")
224
	@RequestMapping("/ui/repoApiCompliance.reset")
225
	public @ResponseBody boolean resetRepoApiCompliance(@RequestParam(value = "id", required = true) final String repoId,
226
			@RequestParam(value = "iface", required = true) final String ifaceId) throws Exception {
227

    
228
		log.debug("RESET COMPLIANCE");
229

    
230
		dsManager.updateCompliance(repoId, ifaceId, null, true);
231

    
232
		return true;
233
	}
234

    
235
	@RequestMapping("/ui/repos/repoApi.html")
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
	}
243

    
244
	@RequestMapping("/ui/repoApi.new")
245
	public @ResponseBody boolean addRepoApi(@RequestParam(value = "repoId", required = true) final String repoId,
246
			@RequestParam(value = "iface", required = true) final String ifaceJson) throws DsmException {
247
		final Api<ApiParam> iface = new Gson().fromJson(ifaceJson, new TypeToken<Api<ApiParamImpl>>() {}.getType());
248

    
249
		iface.setDatasource(repoId);
250

    
251
		log.info("Adding api " + iface.getId() + " to repository " + repoId);
252

    
253
		dsManager.addApi(iface);
254

    
255
		return true;
256
	}
257

    
258
	@RequestMapping("/ui/repo.new")
259
	public @ResponseBody boolean addRepoApi(@RequestParam(value = "repo", required = true) final String repoJson) throws DsmException {
260
		final Datasource<Organization<?>, Identity> ds = new Gson().fromJson(repoJson, new TypeToken<Datasource<Organization<?>, Identity>>() {}.getType());
261
		final Date now = new Date();
262
		ds.setDateofcollection(new java.sql.Date(now.getTime()));
263

    
264
		if (StringUtils.isBlank(ds.getEnglishname())) {
265
			ds.setEnglishname(ds.getOfficialname());
266
		}
267

    
268
		log.info("Adding datasource " + ds.getId() + " - name " + ds.getOfficialname());
269

    
270
		dsManager.saveDs(ds);
271

    
272
		return true;
273
	}
274

    
275
	@RequestMapping("/ui/listValidValuesForParam.do")
276
	public @ResponseBody List<ProtocolParameterValue> listValidValuesForParam(
277
			@RequestParam(value = "protocol", required = true) final String protocol,
278
			@RequestParam(value = "param", required = true) final String param,
279
			@RequestParam(value = "baseUrl", required = true) final String baseUrl) throws CollectorServiceException {
280

    
281
		return serviceLocator.getService(CollectorService.class).listValidValuesForParam(protocol, baseUrl, param, null);
282
	}
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

    
297
	@ExceptionHandler(Exception.class)
298
	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
299
	public @ResponseBody ErrorMessage handleException(final HttpServletRequest req, final Exception e) {
300
		log.error("Error processing " + req.getRequestURI(), e);
301
		return new ErrorMessage(e.getMessage(), ExceptionUtils.getStackTrace(e));
302
	}
303

    
304
}
(5-5/7)