Project

General

Profile

1
package eu.dnetlib.msro.openaireplus.workflows.nodes.index;
2

    
3
import java.io.IOException;
4
import java.io.InputStream;
5
import java.io.StringReader;
6
import java.io.StringWriter;
7
import javax.annotation.Resource;
8
import javax.xml.transform.Transformer;
9
import javax.xml.transform.TransformerException;
10
import javax.xml.transform.TransformerFactory;
11
import javax.xml.transform.stream.StreamResult;
12
import javax.xml.transform.stream.StreamSource;
13

    
14
import com.googlecode.sarasvati.Arc;
15
import com.googlecode.sarasvati.NodeToken;
16
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
17
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
18
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
19
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
20
import eu.dnetlib.miscutils.datetime.DateUtils;
21
import eu.dnetlib.miscutils.functional.hash.Hashing;
22
import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
23
import org.apache.commons.io.IOUtils;
24
import org.apache.commons.lang.StringUtils;
25
import org.apache.commons.logging.Log;
26
import org.apache.commons.logging.LogFactory;
27
import org.springframework.beans.factory.annotation.Required;
28
import org.springframework.core.io.ClassPathResource;
29

    
30
public class PrepareIndexDataJobNode extends SimpleJobNode {
31

    
32
	/**
33
	 * logger.
34
	 */
35
	private static final Log log = LogFactory.getLog(PrepareIndexDataJobNode.class); // NOPMD by marko on 11/24/08 5:02 PM
36

    
37
	@Resource
38
	private UniqueServiceLocator serviceLocator;
39

    
40
	/**
41
	 * Stylesheet which transforms a layout to another stylesheet which converts a input record to a index record.
42
	 */
43
	private String layoutToRecordStylesheet;
44

    
45
	private String outputRecordsPathParam;
46

    
47
	private String rottenRecordsPathParam;
48

    
49
	private String hbaseTable;
50

    
51
	private String oafSchemaLocationProperty;
52

    
53
	@Override
54
	protected String execute(final NodeToken token) throws Exception {
55

    
56
		log.info("start preparing job");
57

    
58
		final String xslt = prepareXslt(env("format", token), env("layout", token));
59

    
60
		token.getEnv().setAttribute("index.xslt", xslt);
61

    
62
		if (!StringUtils.isBlank(getOutputRecordsPathParam())) {
63
			token.getEnv().setAttribute(getOutputRecordsPathParam(), "/tmp" + getFileName(token, "indexrecords"));
64
		}
65
		if (!StringUtils.isBlank(getRottenRecordsPathParam())) {
66
			token.getEnv().setAttribute(getRottenRecordsPathParam(), "/tmp" + getFileName(token, "rottenrecords"));
67
		}
68

    
69
		token.getEnv().setAttribute("index.solr.url", getIndexSolrUrlZk());
70
		token.getEnv().setAttribute("index.solr.collection", getCollectionName(token));
71

    
72
		token.getEnv().setAttribute("index.shutdown.wait.time", getIndexSolrShutdownWait());
73
		token.getEnv().setAttribute("index.buffer.flush.threshold", getIndexBufferFlushTreshold());
74
		token.getEnv().setAttribute("index.solr.sim.mode", isFeedingSimulationMode());
75

    
76
		token.getEnv().setAttribute("index.feed.timestamp", DateUtils.now_ISO8601());
77

    
78
		token.getEnv().setAttribute(getOafSchemaLocationProperty(), getPropertyFetcher().getProperty(getOafSchemaLocationProperty()));
79

    
80
		return Arc.DEFAULT_ARC;
81
	}
82

    
83
	protected String tableName(final NodeToken token) {
84
		if (token.getEnv().hasAttribute("hbaseTable")) {
85
			String table = token.getEnv().getAttribute("hbaseTable");
86
			log.debug("found override value in wfEnv for 'hbaseTable' param: " + table);
87
			return table;
88
		}
89
		return getHbaseTable();
90
	}
91

    
92
	public String getIndexSolrUrlZk() throws ISLookUpException {
93
		return getServiceConfigValue(
94
				"for $x in /RESOURCE_PROFILE[.//RESOURCE_TYPE/@value='IndexServiceResourceType'] return $x//PROTOCOL[./@name='solr']/@address/string()");
95
	}
96

    
97
	public String getIndexSolrShutdownWait() throws ISLookUpException {
98
		return queryForServiceProperty("solr:feedingShutdownTolerance");
99
	}
100

    
101
	public String getIndexBufferFlushTreshold() throws ISLookUpException {
102
		return queryForServiceProperty("solr:feedingBufferFlushThreshold");
103
	}
104

    
105
	public String isFeedingSimulationMode() throws ISLookUpException {
106
		return queryForServiceProperty("solr:feedingSimulationMode");
107
	}
108

    
109
	private String queryForServiceProperty(final String key) throws ISLookUpException {
110
		return getServiceConfigValue(
111
				"for $x in /RESOURCE_PROFILE[.//RESOURCE_TYPE/@value='IndexServiceResourceType'] return $x//SERVICE_PROPERTIES/PROPERTY[./@ key='"
112
						+ key + "']/@value/string()");
113
	}
114

    
115
	private String getServiceConfigValue(final String xquery) throws ISLookUpException {
116
		log.debug("quering for service property: " + xquery);
117
		final String res = serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(xquery);
118
		if (StringUtils.isBlank(res)) { throw new IllegalStateException("unable to find unique service property, xquery: " + xquery); }
119
		return res;
120
	}
121

    
122
	private String getFileName(final NodeToken token, final String fileNamePrefix) {
123
		return "/" + fileNamePrefix + "_" + tableName(token) + "_" + token.getEnv().getAttribute("format") + ".seq";
124
	}
125

    
126
	private String getCollectionName(final NodeToken token) {
127
		return env("format", token) + "-" + env("layout", token) + "-" + env("interpretation", token);
128
	}
129

    
130
	private String env(final String s, final NodeToken token) {
131
		return token.getEnv().getAttribute(s);
132
	}
133

    
134
	/**
135
	 * Transforms each OAF record into a index record.
136
	 *
137
	 * @param format         format
138
	 * @param layout         layout
139
	 * @return resultset with transformed records
140
	 * @throws ISLookUpException    could happen
141
	 * @throws IOException          could happen
142
	 * @throws TransformerException could happen
143
	 */
144
	protected String prepareXslt(final String format, final String layout) throws ISLookUpException, IOException, TransformerException {
145

    
146
		final TransformerFactory factory = TransformerFactory.newInstance();
147
		final Transformer layoutTransformer = factory.newTransformer(new StreamSource(new StringReader(readXslt(getLayoutToRecordStylesheet()))));
148

    
149
		final StreamResult layoutToXsltXslt = new StreamResult(new StringWriter());
150

    
151
		layoutTransformer.setParameter("format", format);
152
		layoutTransformer.transform(new StreamSource(new StringReader(getLayoutSource(format, layout))), layoutToXsltXslt);
153

    
154
		return new String(Hashing.encodeBase64(layoutToXsltXslt.getWriter().toString()));
155
	}
156

    
157
	private String readXslt(final String s) throws IOException {
158
		ClassPathResource resource = new ClassPathResource(s);
159
		InputStream inputStream = resource.getInputStream();
160
		return IOUtils.toString(inputStream);
161
	}
162

    
163
	private String getLayoutSource(final String format, final String layout) throws ISLookUpDocumentNotFoundException, ISLookUpException {
164
		return serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(
165
				"collection('')//RESOURCE_PROFILE[.//RESOURCE_TYPE/@value = 'MDFormatDSResourceType' and .//NAME='" + format + "']//LAYOUT[@name='" + layout
166
						+ "']");
167
	}
168

    
169
	public String getLayoutToRecordStylesheet() {
170
		return layoutToRecordStylesheet;
171
	}
172

    
173
	public void setLayoutToRecordStylesheet(final String layoutToRecordStylesheet) {
174
		this.layoutToRecordStylesheet = layoutToRecordStylesheet;
175
	}
176

    
177
	public String getHbaseTable() {
178
		return hbaseTable;
179
	}
180

    
181
	@Required
182
	public void setHbaseTable(final String hbaseTable) {
183
		this.hbaseTable = hbaseTable;
184
	}
185

    
186
	public String getOutputRecordsPathParam() {
187
		return outputRecordsPathParam;
188
	}
189

    
190
	public void setOutputRecordsPathParam(final String outputRecordsPathParam) {
191
		this.outputRecordsPathParam = outputRecordsPathParam;
192
	}
193

    
194
	public String getRottenRecordsPathParam() {
195
		return rottenRecordsPathParam;
196
	}
197

    
198
	public void setRottenRecordsPathParam(final String rottenRecordsPathParam) {
199
		this.rottenRecordsPathParam = rottenRecordsPathParam;
200
	}
201

    
202
	public String getOafSchemaLocationProperty() {
203
		return oafSchemaLocationProperty;
204
	}
205

    
206
	public void setOafSchemaLocationProperty(final String oafSchemaLocationProperty) {
207
		this.oafSchemaLocationProperty = oafSchemaLocationProperty;
208
	}
209

    
210
}
(7-7/10)