Project

General

Profile

1
package eu.dnetlib.openaire.directindex.api;
2

    
3
import java.text.SimpleDateFormat;
4
import java.util.Date;
5
import javax.annotation.Resource;
6

    
7
import com.google.gson.Gson;
8
import eu.dnetlib.common.rmi.DNetRestDocumentation;
9
import eu.dnetlib.data.index.CloudIndexClientException;
10
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
11
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
12
import eu.dnetlib.functionality.index.solr.feed.StreamingInputDocumentFactory;
13
import eu.dnetlib.miscutils.functional.UnaryFunction;
14
import eu.dnetlib.openaire.directindex.objects.ResultEntry;
15
import eu.dnetlib.openaire.directindex.utils.OafToIndexRecordFactory;
16
import org.apache.commons.lang.exception.ExceptionUtils;
17
import org.apache.commons.logging.Log;
18
import org.apache.commons.logging.LogFactory;
19
import org.apache.solr.client.solrj.impl.CloudSolrClient;
20
import org.apache.solr.common.SolrInputDocument;
21
import org.apache.velocity.app.VelocityEngine;
22
import org.springframework.beans.factory.annotation.Autowired;
23
import org.springframework.beans.factory.annotation.Value;
24
import org.springframework.http.HttpStatus;
25
import org.springframework.stereotype.Controller;
26
import org.springframework.web.bind.annotation.*;
27

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

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

    
37
	@Value(value = "${openaire.api.community}")
38
	private String community_api;
39

    
40
	@Value(value = "oaf.schema.location")
41
	private String oafSchemaLocation;
42

    
43
	@Resource
44
	private UniqueServiceLocator serviceLocator;
45

    
46
	@Resource
47
	private OafToIndexRecordFactory oafToIndexRecordFactory;
48

    
49
	@Resource
50
	private RecentResultsQueue recentResultsQueue;
51

    
52
	@Resource(name = "openaireplusApisVelocityEngine")
53
	private VelocityEngine velocityEngine;
54

    
55
	@Resource(name = "indexClientManager")
56
	private IndexClientManager clientManager;
57

    
58
	@Resource(name = "resultSubmitterService")
59
	private ResultSubmitterService submitterService;
60

    
61
	@Autowired
62
	private IndexDSRetriever indexDSRetriever;
63

    
64
	@RequestMapping(value = { "/api/admin/autocommit/active" }, method = RequestMethod.GET)
65
	public @ResponseBody Boolean getAutocommit() throws DirecIndexApiException {
66
		return submitterService.isAutocommitactive();
67
	}
68

    
69
	@RequestMapping(value = { "/api/admin/autocommit/active" }, method = RequestMethod.POST)
70
	public @ResponseBody Boolean setAutocommit(@RequestParam(value = "active", required = true) final Boolean active) throws DirecIndexApiException {
71
		submitterService.setAutocommitactive(active);
72
		log.info(String.format("automatic commit, active '%s', frequency '%s'", submitterService.isAutocommitactive(), submitterService.getCommitfrquency()));
73
		return submitterService.isAutocommitactive();
74
	}
75

    
76
	@RequestMapping(value="/api/admin/evictCache", method=RequestMethod.GET)
77
	@ResponseStatus(value = HttpStatus.OK)
78
	public void evictCache(){
79
		indexDSRetriever.evictCache();
80
	}
81

    
82
	@Deprecated
83
	@RequestMapping(value = { "/api/publications/feedJson", "/api/results/feedJson" }, method = RequestMethod.POST)
84
	public @ResponseBody String feedObjectJson(@RequestParam(value = "json", required = true) final String json,
85
			@RequestParam(value = "commit", required = false, defaultValue = "true") final boolean commit) throws DirecIndexApiException {
86
		log.debug(json);
87
		final ResultEntry pub = new Gson().fromJson(json, ResultEntry.class);
88
		return feedObject(pub, commit);
89
	}
90

    
91

    
92
	@RequestMapping(value = { "/api/results/feedObject" }, method = RequestMethod.POST)
93
	public @ResponseBody String feedResult(@RequestBody final ResultEntry pub,
94
			@RequestParam(value = "commit", required = false, defaultValue = "true") final boolean commit)
95
			throws DirecIndexApiException {
96
		return feed(pub,commit);
97

    
98
	}
99

    
100
	@Deprecated
101
	@RequestMapping(value = { "/api/publications/feedObject" }, method = RequestMethod.POST)
102
	public @ResponseBody String feedObject(@RequestBody final ResultEntry pub,
103
			@RequestParam(value = "commit", required = false, defaultValue = "true") final boolean commit)
104
			throws DirecIndexApiException {
105
		return feed(pub, commit);
106
	}
107

    
108

    
109
	@RequestMapping(value = "/api/result/{openaireId}", method = RequestMethod.DELETE)
110
	public @ResponseBody boolean deleteResultWithOpenaireId(
111
			@PathVariable(value = "openaireId") final String openaireId,
112
			@RequestParam(value = "commit", required = false, defaultValue = "true") final boolean commit) throws DirecIndexApiException {
113

    
114
		return deleteResult(openaireId);
115
	}
116

    
117
	@RequestMapping(value = "/api/results", method = RequestMethod.DELETE)
118
	public @ResponseBody boolean deleteResultWithOriginalId(
119
			@RequestParam(value = "originalId", required = true) final String originalId,
120
			@RequestParam(value = "collectedFromId", required = true) final String collectedFromId,
121
			@RequestParam(value = "commit", required = false, defaultValue = "true") final boolean commit) throws Exception {
122

    
123
		final String openaireId = ResultEntry.calculateOpenaireId(originalId, collectedFromId, serviceLocator.getService(ISLookUpService.class));
124
		return deleteResult(openaireId);
125
	}
126

    
127
	@Deprecated
128
	@RequestMapping(value = { "/api/publications/deleteObject", "/api/results/delete" }, method = RequestMethod.POST)
129
	public @ResponseBody boolean deleteResultPost(
130
			@RequestParam(value = "originalId", required = true) final String originalId,
131
			@RequestParam(value = "collectedFromId", required = true) final String collectedFromId,
132
			@RequestParam(value = "commit", required = false, defaultValue = "true") final boolean commit) throws Exception {
133

    
134
		final String openaireId = ResultEntry.calculateOpenaireId(originalId, collectedFromId, serviceLocator.getService(ISLookUpService.class));
135
		return deleteResult(openaireId);
136
	}
137

    
138
	@Deprecated
139
	private String feed(final ResultEntry pub, final boolean commit) throws DirecIndexApiException {
140
		return feed(pub);
141
	}
142

    
143
	private String feed(final ResultEntry pub) throws DirecIndexApiException {
144
		log.debug(pub);
145
		try {
146
			final IndexDsInfo info = indexDSRetriever.calculateCurrentIndexDsInfo();
147
			final String oafRecord = pub.asOafRecord(velocityEngine, serviceLocator.getService(ISLookUpService.class), oafSchemaLocation, community_api);
148
			final SolrInputDocument solrDocument = prepareSolrDocument(oafRecord, info.getIndexDsId(), oafToIndexRecordFactory.newTransformer(info.getFormat()));
149

    
150
			clientManager.getClient(info).add(solrDocument);
151
			recentResultsQueue.add(oafRecord);
152

    
153
			return pub.getOpenaireId();
154
		} catch (final Throwable e) {
155
			log.error("Error saving record", e);
156
			log.debug(pub.toString());
157
			throw new DirecIndexApiException("Error adding publication: " + e.getMessage(), e);
158
		}
159
	}
160

    
161
	private SolrInputDocument prepareSolrDocument(String record, String indexDsId, UnaryFunction<String, String> toIndexRecord) throws CloudIndexClientException {
162
		try {
163
			StreamingInputDocumentFactory documentFactory = new StreamingInputDocumentFactory();
164
			String version = (new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss'Z'")).format(new Date());
165
			String indexRecord = (String)toIndexRecord.evaluate(record);
166
			if (log.isDebugEnabled()) {
167
				log.debug("***************************************\nSubmitting index record:\n" + indexRecord + "\n***************************************\n");
168
			}
169

    
170
			return documentFactory.parseDocument(version, indexRecord, indexDsId, "dnetResult");
171
		} catch (Throwable e) {
172
			throw new CloudIndexClientException("Error creating solr document", e);
173
		}
174
	}
175

    
176
	private boolean deleteResult(final String openaireId) throws DirecIndexApiException {
177
		try {
178
			IndexDsInfo info = indexDSRetriever.calculateCurrentIndexDsInfo();
179
			String query = String.format("objidentifier:\"%s\" OR resultdupid:\"%s\"", openaireId, openaireId);
180
			final CloudSolrClient client = clientManager.getClient(info);
181
			client.deleteByQuery(info.getColl(), query);
182
			log.info("Deleted result with id: " + openaireId + " from: " + info.getIndexBaseUrl());
183

    
184
			recentResultsQueue.remove(openaireId);
185
			return true;
186
		} catch (Throwable e) {
187
			throw new DirecIndexApiException("Error deleting publication: " + e.getMessage(), e);
188
		}
189
	}
190

    
191
	@ExceptionHandler(Exception.class)
192
	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
193
	public @ResponseBody ErrorMessage handleException(final Exception e) {
194
		log.error("Error in direct index API", e);
195
		return new ErrorMessage(e);
196
	}
197

    
198
	public class ErrorMessage {
199

    
200
		private final String message;
201
		private final String stacktrace;
202

    
203
		public ErrorMessage(final Exception e) {
204
			this(e.getMessage(), ExceptionUtils.getStackTrace(e));
205
		}
206

    
207
		public ErrorMessage(final String message, final String stacktrace) {
208
			this.message = message;
209
			this.stacktrace = stacktrace;
210
		}
211

    
212
		public String getMessage() {
213
			return this.message;
214
		}
215

    
216
		public String getStacktrace() {
217
			return this.stacktrace;
218
		}
219

    
220
	}
221

    
222
}
(6-6/8)