Project

General

Profile

1
package eu.dnetlib.msro.openaireplus.api;
2

    
3
import java.io.IOException;
4
import java.util.List;
5
import javax.annotation.Resource;
6

    
7
import com.google.common.collect.Lists;
8
import com.google.gson.Gson;
9
import eu.dnetlib.common.rmi.DNetRestDocumentation;
10
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
11
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
12
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
13
import eu.dnetlib.functionality.index.client.IndexClientFactory;
14
import eu.dnetlib.functionality.index.client.solr.SolrIndexClient;
15
import eu.dnetlib.msro.openaireplus.api.objects.ResultEntry;
16
import eu.dnetlib.msro.openaireplus.utils.OafToIndexRecordFactory;
17
import eu.dnetlib.msro.rmi.MSROException;
18
import org.apache.commons.io.IOUtils;
19
import org.apache.commons.lang.exception.ExceptionUtils;
20
import org.apache.commons.logging.Log;
21
import org.apache.commons.logging.LogFactory;
22
import org.apache.velocity.app.VelocityEngine;
23
import org.springframework.beans.factory.annotation.Autowired;
24
import org.springframework.beans.factory.annotation.Value;
25
import org.springframework.core.io.ClassPathResource;
26
import org.springframework.http.HttpStatus;
27
import org.springframework.stereotype.Controller;
28
import org.springframework.web.bind.annotation.*;
29

    
30
/**
31
 * Created by michele on 11/11/15.
32
 */
33
@Controller
34
@DNetRestDocumentation
35
public class OpenaireResultSubmitter {
36

    
37
	private static final Log log = LogFactory.getLog(OpenaireResultSubmitter.class);
38

    
39
	public class IndexDsInfo {
40

    
41
		private final String indexBaseUrl;
42
		private final String indexDsId;
43
		private final String format;
44
		private final String coll;
45

    
46
		public IndexDsInfo(final String indexBaseUrl, final String indexDsId, final String format, final String coll) {
47
			this.indexBaseUrl = indexBaseUrl;
48
			this.indexDsId = indexDsId;
49
			this.format = format;
50
			this.coll = coll;
51
		}
52

    
53
		public String getIndexBaseUrl() {
54
			return indexBaseUrl;
55
		}
56

    
57
		public String getIndexDsId() {
58
			return indexDsId;
59
		}
60

    
61
		public String getFormat() {
62
			return format;
63
		}
64

    
65
		public String getColl() {
66
			return coll;
67
		}
68

    
69
	}
70

    
71
	@Value(value = "oaf.schema.location")
72
	private String oafSchemaLocation;
73

    
74
	@Resource
75
	private UniqueServiceLocator serviceLocator;
76

    
77
	@Resource
78
	private OafToIndexRecordFactory oafToIndexRecordFactory;
79

    
80
	@Resource
81
	private RecentResultsQueue recentResultsQueue;
82

    
83
	@Resource(name = "openaireplusApisVelocityEngine")
84
	private VelocityEngine velocityEngine;
85

    
86
	@Value(value = "${openaireplus.msro.api.findSolrIndexUrl.xquery}")
87
	private ClassPathResource findSolrIndexUrl;
88

    
89
	@Value(value = "${openaireplus.msro.api.findIndexDsInfo.xquery}")
90
	private ClassPathResource findIndexDsInfo;
91

    
92
	@Autowired
93
	private IndexClientFactory indexClientFactory;
94

    
95
	@Deprecated
96
	@RequestMapping(value = { "/api/publications/feedJson", "/api/results/feedJson" }, method = RequestMethod.POST)
97
	public
98
	@ResponseBody
99
	String feedObjectJson(@RequestParam(value = "json", required = true) final String json,
100
			@RequestParam(value = "commit", required = false, defaultValue = "true") final boolean commit) throws MSROException {
101
		final ResultEntry pub = new Gson().fromJson(json, ResultEntry.class);
102
		return feedObject(pub, commit);
103
	}
104

    
105
	@RequestMapping(value = { "/api/results/feedObject" }, method = RequestMethod.POST)
106
	public
107
	@ResponseBody
108
	String feedResult(@RequestBody final ResultEntry pub,
109
			@RequestParam(value = "commit", required = false, defaultValue = "true") final boolean commit)
110
			throws MSROException {
111

    
112
		try {
113
			return feedObject(pub, commit);
114
		} catch (final Throwable e) {
115
			throw new MSROException("Error adding publication: " + e.getMessage(), e);
116
		}
117
	}
118

    
119
	@RequestMapping(value = { "/api/publications/feedObject" }, method = RequestMethod.POST)
120
	public
121
	@ResponseBody
122
	String feedObject(@RequestBody final ResultEntry pub,
123
			@RequestParam(value = "commit", required = false, defaultValue = "true") final boolean commit)
124
			throws MSROException {
125

    
126
		final List<IndexDsInfo> idxList;
127
		try {
128
			idxList = calculateCurrentIndexDsInfo();
129
			if (idxList == null || idxList.isEmpty()) {
130
				throw new MSROException("Cannot add result: " + pub.getAnyId() + " : No public Search Service found");
131
			}
132
			if (idxList.size() > 1) log.warn("Found more than 1 public search service");
133
			final String oafRecord = pub.asOafRecord(velocityEngine, serviceLocator.getService(ISLookUpService.class), oafSchemaLocation);
134

    
135
			for (IndexDsInfo idx : idxList) {
136
				try(SolrIndexClient idxClient = (SolrIndexClient) indexClientFactory.getClient(idx.getColl())) {
137
					idxClient.feed(oafRecord, idx.getIndexDsId(), oafToIndexRecordFactory.newTransformer(idx.getFormat()), commit);
138
				} catch (final Throwable e) {
139
					throw new MSROException("Error adding publication: " + e.getMessage(), e);
140
				}
141
			}
142
			recentResultsQueue.add(oafRecord);
143
			return pub.getOpenaireId();
144
		} catch (final Throwable e) {
145
			log.debug(pub.toString());
146
			throw new MSROException("Error adding publication: " + e.getMessage(), e);
147
		}
148
	}
149

    
150
	@RequestMapping(value = "/api/result/{openaireId}", method = RequestMethod.DELETE)
151
	public
152
	@ResponseBody
153
	boolean deleteResultWithOpenaireId(
154
			@PathVariable(value = "openaireId") final String openaireId,
155
			@RequestParam(value = "commit", required = false, defaultValue = "true") final boolean commit) throws MSROException {
156

    
157
		return deleteResult(openaireId, commit);
158
	}
159

    
160
	@RequestMapping(value = "/api/results", method = RequestMethod.DELETE)
161
	public
162
	@ResponseBody
163
	boolean deleteResultWithOriginalId(
164
			@RequestParam(value = "originalId", required = true) final String originalId,
165
			@RequestParam(value = "collectedFromId", required = true) final String collectedFromId,
166
			@RequestParam(value = "commit", required = false, defaultValue = "true") final boolean commit) throws Exception {
167

    
168
		final String openaireId = ResultEntry.calculateOpenaireId(originalId, collectedFromId, serviceLocator.getService(ISLookUpService.class));
169
		return deleteResult(openaireId, commit);
170
	}
171

    
172
	@Deprecated
173
	@RequestMapping(value = { "/api/publications/deleteObject", "/api/results/delete" }, method = RequestMethod.POST)
174
	public
175
	@ResponseBody
176
	boolean deleteResultPost(
177
			@RequestParam(value = "originalId", required = true) final String originalId,
178
			@RequestParam(value = "collectedFromId", required = true) final String collectedFromId,
179
			@RequestParam(value = "commit", required = false, defaultValue = "true") final boolean commit) throws Exception {
180

    
181
		final String openaireId = ResultEntry.calculateOpenaireId(originalId, collectedFromId, serviceLocator.getService(ISLookUpService.class));
182
		return deleteResult(openaireId, commit);
183
	}
184

    
185
	private boolean deleteResult(final String openaireId, final boolean commit) throws MSROException {
186

    
187
		final List<IndexDsInfo> idxList;
188
		try {
189
			idxList = calculateCurrentIndexDsInfo();
190

    
191
			if (idxList == null || idxList.isEmpty()) {
192
				throw new MSROException("Cannot delete result: " + openaireId + " : No public Search Service found");
193
			}
194
			if (idxList.size() > 1) log.warn("Found more than 1 public search service");
195

    
196
			//			final String objId = ResultEntry.calculateOpenaireId(originalId, collectedFromId, serviceLocator.getService(ISLookUpService.class));
197

    
198
			for (IndexDsInfo idx : idxList) {
199

    
200
				try(SolrIndexClient idxClient = (SolrIndexClient) indexClientFactory.getClient(idx.getColl())) {
201
					idxClient.remove(openaireId, commit);
202
					log.info("Deleted result with id: " + openaireId + " from: " + idx.getIndexBaseUrl());
203
				} catch (final Throwable e) {
204
					throw new MSROException("Error deleting publication: " + e.getMessage(), e);
205
				}
206
			}
207
			recentResultsQueue.remove(openaireId);
208
			return true;
209
		} catch (IOException | ISLookUpException e) {
210
			throw new MSROException("Error deleting publication: " + e.getMessage(), e);
211
		}
212
	}
213

    
214
	@ExceptionHandler(Exception.class)
215
	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
216
	public
217
	@ResponseBody
218
	ErrorMessage handleException(final Exception e) {
219
		log.error("Error in direct index API", e);
220
		return new ErrorMessage(e);
221
	}
222

    
223
	private List<IndexDsInfo> calculateCurrentIndexDsInfo() throws IOException, ISLookUpException {
224
		final List<IndexDsInfo> list = Lists.newArrayList();
225

    
226
		final String queryUrl = IOUtils.toString(findSolrIndexUrl.getInputStream());
227
		final String queryDs = IOUtils.toString(findIndexDsInfo.getInputStream());
228

    
229
		final ISLookUpService lu = serviceLocator.getService(ISLookUpService.class);
230
		final String indexBaseUrl = lu.getResourceProfileByQuery(queryUrl);
231

    
232
		final List<String> idxDs = lu.quickSearchProfile(queryDs);
233
		for (String idx : idxDs) {
234
			final String[] arr = idx.split("@@@");
235
			list.add(new IndexDsInfo(indexBaseUrl, arr[0].trim(), arr[1].trim(), arr[2].trim()));
236
		}
237
		return list;
238
	}
239

    
240
	public class ErrorMessage {
241

    
242
		private final String message;
243
		private final String stacktrace;
244

    
245
		public ErrorMessage(final Exception e) {
246
			this(e.getMessage(), ExceptionUtils.getStackTrace(e));
247
		}
248

    
249
		public ErrorMessage(final String message, final String stacktrace) {
250
			this.message = message;
251
			this.stacktrace = stacktrace;
252
		}
253

    
254
		public String getMessage() {
255
			return this.message;
256
		}
257

    
258
		public String getStacktrace() {
259
			return this.stacktrace;
260
		}
261

    
262
	}
263

    
264
}
(2-2/3)