public void handleRequestBody()

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);
      }
    }
  }