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.data.index.CloudIndexClient;
11
import eu.dnetlib.data.index.CloudIndexClientFactory;
12
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
13
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
14
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
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.Value;
24
import org.springframework.core.io.ClassPathResource;
25
import org.springframework.http.HttpStatus;
26
import org.springframework.stereotype.Controller;
27
import org.springframework.web.bind.annotation.*;
28

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

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

    
38
	public class IndexDsInfo {
39

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

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

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

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

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

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

    
68
	}
69

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

    
73
	@Resource
74
	private UniqueServiceLocator serviceLocator;
75

    
76
	@Resource
77
	private OafToIndexRecordFactory oafToIndexRecordFactory;
78

    
79
	@Resource
80
	private RecentResultsQueue recentResultsQueue;
81

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

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

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

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

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

    
108
		try {
109
			return feedObject(pub, commit);
110
		} catch (final Throwable e) {
111
			throw new MSROException("Error adding publication: " + e.getMessage(), e);
112
		}
113
	}
114

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

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

    
131
			for (IndexDsInfo idx : idxList) {
132
				CloudIndexClient idxClient = null;
133
				try {
134
					idxClient = CloudIndexClientFactory.newIndexClient(idx.getIndexBaseUrl(), idx.getColl(), false);
135
					idxClient.feed(oafRecord, idx.getIndexDsId(), oafToIndexRecordFactory.newTransformer(idx.getFormat()), commit);
136
				} catch (final Throwable e) {
137
					throw new MSROException("Error adding publication: " + e.getMessage(), e);
138
				} finally {
139
					if (idxClient != null) {
140
						idxClient.close();
141
					}
142
				}
143
			}
144
			recentResultsQueue.add(oafRecord);
145
			return pub.getOpenaireId();
146
		} catch (final Throwable e) {
147
			log.debug(pub.toString());
148
			throw new MSROException("Error adding publication: " + e.getMessage(), e);
149
		}
150
	}
151

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

    
159
		return deleteResult(openaireId, commit);
160
	}
161

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

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

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

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

    
187
	private boolean deleteResult(final String openaireId, final boolean commit) throws MSROException {
188

    
189
		final List<IndexDsInfo> idxList;
190
		try {
191
			idxList = calculateCurrentIndexDsInfo();
192

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

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

    
200
			for (IndexDsInfo idx : idxList) {
201
				CloudIndexClient idxClient = null;
202
				try {
203
					idxClient = CloudIndexClientFactory.newIndexClient(idx.getIndexBaseUrl(), idx.getColl(), false);
204
					idxClient.remove(openaireId, commit);
205
					log.info("Deleted result with id: " + openaireId + " from: " + idx.getIndexBaseUrl());
206
				} catch (final Throwable e) {
207
					throw new MSROException("Error deleting publication: " + e.getMessage(), e);
208
				} finally {
209
					if (idxClient != null) {
210
						idxClient.close();
211
					}
212
				}
213
			}
214
			recentResultsQueue.remove(openaireId);
215
			return true;
216
		} catch (IOException | ISLookUpException e) {
217
			throw new MSROException("Error deleting publication: " + e.getMessage(), e);
218
		}
219
	}
220

    
221
	@ExceptionHandler(Exception.class)
222
	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
223
	public
224
	@ResponseBody
225
	ErrorMessage handleException(final Exception e) {
226
		log.error("Error in direct index API", e);
227
		return new ErrorMessage(e);
228
	}
229

    
230
	private List<IndexDsInfo> calculateCurrentIndexDsInfo() throws IOException, ISLookUpException {
231
		final List<IndexDsInfo> list = Lists.newArrayList();
232

    
233
		final String queryUrl = IOUtils.toString(findSolrIndexUrl.getInputStream());
234
		final String queryDs = IOUtils.toString(findIndexDsInfo.getInputStream());
235

    
236
		final ISLookUpService lu = serviceLocator.getService(ISLookUpService.class);
237
		final String indexBaseUrl = lu.getResourceProfileByQuery(queryUrl);
238

    
239
		final List<String> idxDs = lu.quickSearchProfile(queryDs);
240
		for (String idx : idxDs) {
241
			final String[] arr = idx.split("@@@");
242
			list.add(new IndexDsInfo(indexBaseUrl, arr[0].trim(), arr[1].trim(), arr[2].trim()));
243
		}
244
		return list;
245
	}
246

    
247
	public class ErrorMessage {
248

    
249
		private final String message;
250
		private final String stacktrace;
251

    
252
		public ErrorMessage(final Exception e) {
253
			this(e.getMessage(), ExceptionUtils.getStackTrace(e));
254
		}
255

    
256
		public ErrorMessage(final String message, final String stacktrace) {
257
			this.message = message;
258
			this.stacktrace = stacktrace;
259
		}
260

    
261
		public String getMessage() {
262
			return this.message;
263
		}
264

    
265
		public String getStacktrace() {
266
			return this.stacktrace;
267
		}
268

    
269
	}
270

    
271
}
(2-2/3)