in solr/core/src/java/org/apache/solr/handler/BlobHandler.java [87:264]
public void handleRequestBody(final SolrQueryRequest req, SolrQueryResponse rsp)
throws Exception {
String httpMethod = req.getHttpMethod();
String path = (String) req.getContext().get("path");
RequestHandlerUtils.setWt(req, JSON);
List<String> pieces = StrUtils.splitSmart(path, '/');
String blobName = null;
if (pieces.size() >= 3) blobName = pieces.get(2);
if ("POST".equals(httpMethod)) {
if (blobName == null || blobName.isEmpty()) {
rsp.add("error", "Name not found");
return;
}
String err = SolrConfigHandler.validateName(blobName);
if (err != null) {
log.warn("no blob name");
rsp.add("error", err);
return;
}
if (req.getContentStreams() == null) {
log.warn("no content stream");
rsp.add("error", "No stream");
return;
}
for (ContentStream stream : req.getContentStreams()) {
ByteBuffer payload;
try (InputStream is = boundedInputStream(stream.getStream(), maxSize)) {
payload = Utils.toByteArray(is);
}
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(payload.array(), payload.arrayOffset() + payload.position(), payload.limit());
String md5 = new String(Hex.encodeHex(m.digest()));
int duplicateCount = req.getSearcher().count(new TermQuery(new Term("md5", md5)));
if (duplicateCount > 0) {
rsp.add("error", "duplicate entry");
forward(
req,
null,
new MapSolrParams(
Map.of("q", "md5:" + md5, "fl", "id,size,version,timestamp,blobName")),
rsp);
log.warn("duplicate entry for blob : {}", blobName);
return;
}
TopFieldDocs docs =
req.getSearcher()
.search(
new TermQuery(new Term("blobName", blobName)),
1,
new Sort(new SortField("version", SortField.Type.LONG, true)));
long version = 0;
if (docs.totalHits.value > 0) {
Document doc = req.getSearcher().getDocFetcher().doc(docs.scoreDocs[0].doc);
Number n = doc.getField("version").numericValue();
version = n.longValue();
}
version++;
String id = blobName + "/" + version;
Map<String, Object> doc =
Map.of(
ID,
id,
CommonParams.TYPE,
"blob",
"md5",
md5,
"blobName",
blobName,
VERSION,
version,
"timestamp",
new Date(),
"size",
payload.limit(),
"blob",
payload);
verifyWithRealtimeGet(blobName, version, req, doc);
if (log.isInfoEnabled()) {
log.info(
StrUtils.formatString(
"inserting new blob {0} ,size {1}, md5 {2}",
doc.get(ID), String.valueOf(payload.limit()), md5));
}
indexMap(req, rsp, doc);
if (log.isInfoEnabled()) {
log.info(
" Successfully Added and committed a blob with id {} and size {} ",
id,
payload.limit());
}
break;
}
} else {
int version = -1;
if (pieces.size() > 3) {
try {
version = Integer.parseInt(pieces.get(3));
} catch (NumberFormatException e) {
rsp.add("error", "Invalid version" + pieces.get(3));
return;
}
}
if (ReplicationAPIBase.FILE_STREAM.equals(req.getParams().get(CommonParams.WT))) {
if (blobName == null) {
throw new SolrException(
SolrException.ErrorCode.NOT_FOUND,
"Please send the request in the format /blob/<blobName>/<version>");
} else {
String q = "blobName:{0}";
if (version != -1) q = "id:{0}/{1}";
QParser qparser = QParser.getParser(StrUtils.formatString(q, blobName, version), req);
final TopDocs docs =
req.getSearcher()
.search(
qparser.parse(),
1,
new Sort(new SortField("version", SortField.Type.LONG, true)));
if (docs.totalHits.value > 0) {
rsp.add(
ReplicationAPIBase.FILE_STREAM,
new SolrCore.RawWriter() {
@Override
public void write(OutputStream os) throws IOException {
Document doc = req.getSearcher().getDocFetcher().doc(docs.scoreDocs[0].doc);
IndexableField sf = doc.getField("blob");
FieldType fieldType = req.getSchema().getField("blob").getType();
ByteBuffer buf = (ByteBuffer) fieldType.toObject(sf);
if (buf == null) {
// should never happen unless a user wrote this document directly
throw new SolrException(
SolrException.ErrorCode.NOT_FOUND,
"Invalid document . No field called blob");
} else {
os.write(buf.array(), buf.arrayOffset(), buf.limit());
}
}
});
} else {
throw new SolrException(
SolrException.ErrorCode.NOT_FOUND,
StrUtils.formatString(
"Invalid combination of blobName {0} and version {1}", blobName, version));
}
}
} else {
String q = "*:*";
if (blobName != null) {
q = "blobName:{0}";
if (version != -1) {
q = "id:{0}/{1}";
}
}
forward(
req,
null,
new MapSolrParams(
Map.of(
"q",
StrUtils.formatString(q, blobName, version),
"fl",
"id,size,version,timestamp,blobName,md5",
SORT,
"version desc")),
rsp);
}
}
}