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
		try {
108
			return feedObject(pub, commit);
109
		} catch (final Throwable e) {
110
			throw new MSROException("Error adding publication: " + e.getMessage(), e);
111
		}
112
	}
113

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

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

    
130
			for (IndexDsInfo idx : idxList) {
131
				CloudIndexClient idxClient = null;
132
				try {
133
					idxClient = CloudIndexClientFactory.newIndexClient(idx.getIndexBaseUrl(), idx.getColl(), false);
134
					idxClient.feed(oafRecord, idx.getIndexDsId(), oafToIndexRecordFactory.newTransformer(idx.getFormat()), commit);
135
				} catch (final Throwable e) {
136
					throw new MSROException("Error adding publication: " + e.getMessage(), e);
137
				} finally {
138
					if (idxClient != null) {
139
						idxClient.close();
140
					}
141
				}
142
			}
143
			recentResultsQueue.add(oafRecord);
144
			return pub.getOpenaireId();
145
		} catch (final Throwable e) {
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
				CloudIndexClient idxClient = null;
200
				try {
201
					idxClient = CloudIndexClientFactory.newIndexClient(idx.getIndexBaseUrl(), idx.getColl(), false);
202
					idxClient.remove(openaireId, commit);
203
					log.info("Deleted result with id: " + openaireId + " from: " + idx.getIndexBaseUrl());
204
				} catch (final Throwable e) {
205
					throw new MSROException("Error deleting publication: " + e.getMessage(), e);
206
				} finally {
207
					if (idxClient != null) {
208
						idxClient.close();
209
					}
210
				}
211
			}
212
			recentResultsQueue.remove(openaireId);
213
			return true;
214
		} catch (IOException | ISLookUpException e) {
215
			throw new MSROException("Error deleting publication: " + e.getMessage(), e);
216
		}
217
	}
218

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

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

    
231
		final String queryUrl = IOUtils.toString(findSolrIndexUrl.getInputStream());
232
		final String queryDs = IOUtils.toString(findIndexDsInfo.getInputStream());
233

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

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

    
245
	public class ErrorMessage {
246

    
247
		private final String message;
248
		private final String stacktrace;
249

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

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

    
259
		public String getMessage() {
260
			return this.message;
261
		}
262

    
263
		public String getStacktrace() {
264
			return this.stacktrace;
265
		}
266

    
267
	}
268

    
269
}
(2-2/3)