1
package org.apache.solr.util;
4
* Licensed to the Apache Software Foundation (ASF) under one or more
5
* contributor license agreements. See the NOTICE file distributed with
6
* this work for additional information regarding copyright ownership.
7
* The ASF licenses this file to You under the Apache License, Version 2.0
8
* (the "License"); you may not use this file except in compliance with
9
* the License. You may obtain a copy of the License at
11
* http://www.apache.org/licenses/LICENSE-2.0
13
* Unless required by applicable law or agreed to in writing, software
14
* distributed under the License is distributed on an "AS IS" BASIS,
15
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
* See the License for the specific language governing permissions and
17
* limitations under the License.
21
import java.io.FileInputStream;
22
import java.io.IOException;
23
import java.io.InputStream;
24
import java.io.ByteArrayInputStream;
25
import java.io.OutputStream;
26
import java.io.UnsupportedEncodingException;
28
import java.util.HashSet;
29
import java.net.HttpURLConnection;
30
import java.net.MalformedURLException;
31
import java.net.ProtocolException;
35
* A simple utility class for posting raw updates to a Solr server,
36
* has a main method so it can be run on the command line.
39
public class SimplePostTool {
40
public static final String DEFAULT_POST_URL = "http://localhost:8983/solr/update";
41
public static final String VERSION_OF_THIS_TOOL = "1.4";
43
private static final String DEFAULT_COMMIT = "yes";
44
private static final String DEFAULT_OPTIMIZE = "no";
45
private static final String DEFAULT_OUT = "no";
47
private static final String DEFAULT_DATA_TYPE = "application/xml";
49
private static final String DATA_MODE_FILES = "files";
50
private static final String DATA_MODE_ARGS = "args";
51
private static final String DATA_MODE_STDIN = "stdin";
52
private static final String DEFAULT_DATA_MODE = DATA_MODE_FILES;
54
private static final Set<String> DATA_MODES = new HashSet<String>();
56
DATA_MODES.add(DATA_MODE_FILES);
57
DATA_MODES.add(DATA_MODE_ARGS);
58
DATA_MODES.add(DATA_MODE_STDIN);
61
protected URL solrUrl;
63
public static void main(String[] args) {
64
info("version " + VERSION_OF_THIS_TOOL);
66
if (0 < args.length && ("-help".equals(args[0]) || "--help".equals(args[0]) || "-h".equals(args[0]))) {
68
("This is a simple command line tool for POSTing raw data to a Solr\n"+
69
"port. Data can be read from files specified as commandline args,\n"+
70
"as raw commandline arg strings, or via STDIN.\n"+
72
" java -jar post.jar *.xml\n"+
73
" java -Ddata=args -jar post.jar '<delete><id>42</id></delete>'\n"+
74
" java -Ddata=stdin -jar post.jar < hd.xml\n"+
75
" java -Durl=http://localhost:8983/solr/update/csv -Dtype=text/csv -jar post.jar *.csv\n"+
76
" java -Durl=http://localhost:8983/solr/update/json -Dtype=application/json -jar post.jar *.json\n"+
77
" java -Durl=http://localhost:8983/solr/update/extract?literal.id=a -Dtype=application/pdf -jar post.jar a.pdf\n"+
78
"Other options controlled by System Properties include the Solr\n"+
79
"URL to POST to, the Content-Type of the data, whether a commit\n"+
80
"or optimize should be executed, and whether the response should\n"+
81
"be written to STDOUT. These are the defaults for all System Properties:\n"+
82
" -Ddata=" + DEFAULT_DATA_MODE + "\n"+
83
" -Dtype=" + DEFAULT_DATA_TYPE + "\n"+
84
" -Durl=" + DEFAULT_POST_URL + "\n"+
85
" -Dcommit=" + DEFAULT_COMMIT + "\n"+
86
" -Doptimize=" + DEFAULT_OPTIMIZE + "\n"+
87
" -Dout=" + DEFAULT_OUT + "\n");
91
OutputStream out = null;
95
u = new URL(System.getProperty("url", DEFAULT_POST_URL));
96
} catch (MalformedURLException e) {
97
fatal("System Property 'url' is not a valid URL: " + u);
99
final SimplePostTool t = new SimplePostTool(u);
101
final String mode = System.getProperty("data", DEFAULT_DATA_MODE);
102
if (! DATA_MODES.contains(mode)) {
103
fatal("System Property 'data' is not valid for this tool: " + mode);
106
if ("yes".equals(System.getProperty("out", DEFAULT_OUT))) {
111
if (DATA_MODE_FILES.equals(mode)) {
112
if (0 < args.length) {
113
info("POSTing files to " + u + "..");
114
t.postFiles(args, 0, out);
116
info("No files specified. (Use -h for help)");
119
} else if (DATA_MODE_ARGS.equals(mode)) {
120
if (0 < args.length) {
121
info("POSTing args to " + u + "..");
122
for (String a : args) {
123
t.postData(SimplePostTool.stringToStream(a), null, out);
127
} else if (DATA_MODE_STDIN.equals(mode)) {
128
info("POSTing stdin to " + u + "..");
129
t.postData(System.in, null, out);
131
if ("yes".equals(System.getProperty("commit",DEFAULT_COMMIT))) {
132
info("COMMITting Solr index changes..");
135
if ("yes".equals(System.getProperty("optimize",DEFAULT_OPTIMIZE))) {
136
info("Performing an OPTIMIZE..");
140
} catch(RuntimeException e) {
142
fatal("RuntimeException " + e);
146
/** Post all filenames provided in args, return the number of files posted*/
147
int postFiles(String [] args,int startIndexInArgs, OutputStream out) {
149
for (int j = startIndexInArgs; j < args.length; j++) {
150
File srcFile = new File(args[j]);
151
if (srcFile.canRead()) {
152
info("POSTing file " + srcFile.getName());
153
postFile(srcFile, out);
156
warn("Cannot read input file: " + srcFile);
162
static void warn(String msg) {
163
System.err.println("SimplePostTool: WARNING: " + msg);
166
static void info(String msg) {
167
System.out.println("SimplePostTool: " + msg);
170
static void fatal(String msg) {
171
System.err.println("SimplePostTool: FATAL: " + msg);
176
* Constructs an instance for posting data to the specified Solr URL
177
* (ie: "http://localhost:8983/solr/update")
179
public SimplePostTool(URL solrUrl) {
180
this.solrUrl = solrUrl;
184
* Does a simple commit operation
186
public void commit() {
187
doGet(appendParam(solrUrl.toString(), "commit=true"));
191
* Does a simple optimize operation
193
public void optimize() {
194
doGet(appendParam(solrUrl.toString(), "optimize=true"));
197
private String appendParam(String url, String param) {
198
return url + (url.indexOf('?')>0 ? "&" : "?") + param;
202
* Opens the file and posts it's contents to the solrUrl,
203
* writes to response to output.
204
* @throws UnsupportedEncodingException
206
public void postFile(File file, OutputStream output) {
208
InputStream is = null;
210
is = new FileInputStream(file);
211
postData(is, (int)file.length(), output);
212
} catch (IOException e) {
213
fatal("Can't open/read file: " + file);
216
if(is!=null) is.close();
217
} catch (IOException e) {
218
fatal("IOException while closing file: "+ e);
224
* Performs a simple get on the given URL
227
public void doGet(String url) {
230
} catch (MalformedURLException e) {
231
fatal("The specified URL "+url+" is not a valid URL. Please check");
236
* Performs a simple get on the given URL
239
public void doGet(URL url) {
241
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
242
if (HttpURLConnection.HTTP_OK != urlc.getResponseCode()) {
243
fatal("Solr returned an error #" + urlc.getResponseCode() +
244
" " + urlc.getResponseMessage());
246
} catch (IOException e) {
247
fatal("An error occured posting data to "+url+". Please check that Solr is running.");
252
* Reads data from the data stream and posts it to solr,
253
* writes to the response to output
255
public void postData(InputStream data, Integer length, OutputStream output) {
257
final String type = System.getProperty("type", DEFAULT_DATA_TYPE);
259
HttpURLConnection urlc = null;
262
urlc = (HttpURLConnection) solrUrl.openConnection();
264
urlc.setRequestMethod("POST");
265
} catch (ProtocolException e) {
266
fatal("Shouldn't happen: HttpURLConnection doesn't support POST??"+e);
269
urlc.setDoOutput(true);
270
urlc.setDoInput(true);
271
urlc.setUseCaches(false);
272
urlc.setAllowUserInteraction(false);
273
urlc.setRequestProperty("Content-type", type);
275
if (null != length) urlc.setFixedLengthStreamingMode(length);
277
} catch (IOException e) {
278
fatal("Connection error (is Solr running at " + solrUrl + " ?): " + e);
281
OutputStream out = null;
283
out = urlc.getOutputStream();
285
} catch (IOException e) {
286
fatal("IOException while posting data: " + e);
288
try { if(out!=null) out.close(); } catch (IOException x) { /*NOOP*/ }
291
InputStream in = null;
293
if (HttpURLConnection.HTTP_OK != urlc.getResponseCode()) {
294
fatal("Solr returned an error #" + urlc.getResponseCode() +
295
" " + urlc.getResponseMessage());
298
in = urlc.getInputStream();
300
} catch (IOException e) {
301
fatal("IOException while reading response: " + e);
303
try { if(in!=null) in.close(); } catch (IOException x) { /*NOOP*/ }
307
if(urlc!=null) urlc.disconnect();
311
private static InputStream stringToStream(String s) {
312
InputStream is = null;
314
is = new ByteArrayInputStream(s.getBytes("UTF-8"));
315
} catch (UnsupportedEncodingException e) {
316
fatal("Shouldn't happen: UTF-8 not supported?!?!?!");
322
* Pipes everything from the source to the dest. If dest is null,
323
* then everything is read fro msource and thrown away.
325
private static void pipe(InputStream source, OutputStream dest) throws IOException {
326
byte[] buf = new byte[1024];
328
while ( (read = source.read(buf) ) >= 0) {
329
if (null != dest) dest.write(buf, 0, read);
331
if (null != dest) dest.flush();