/mongodb/src/main/java/org/restheart/mongodb/handlers/document/PutDocumentHandler.java
https://github.com/SoftInstigate/restheart · Java · 157 lines · 90 code · 21 blank · 46 comment · 14 complexity · c365bc801ad9de40c23ba06b1f108a9c MD5 · raw file
- /*-
- * ========================LICENSE_START=================================
- * restheart-mongodb
- * %%
- * Copyright (C) 2014 - 2020 SoftInstigate
- * %%
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- * =========================LICENSE_END==================================
- */
- package org.restheart.mongodb.handlers.document;
- import io.undertow.server.HttpServerExchange;
- import io.undertow.util.Headers;
- import org.bson.BsonDocument;
- import org.bson.BsonValue;
- import org.restheart.exchange.MongoRequest;
- import org.restheart.exchange.MongoResponse;
- import org.restheart.exchange.OperationResult;
- import org.restheart.handlers.PipelinedHandler;
- import org.restheart.mongodb.db.DocumentDAO;
- import org.restheart.mongodb.utils.ResponseHelper;
- import org.restheart.utils.HttpStatus;
- /**
- *
- * @author Andrea Di Cesare {@literal <andrea@softinstigate.com>}
- */
- public class PutDocumentHandler extends PipelinedHandler {
- private final DocumentDAO documentDAO;
- /**
- * Default ctor
- */
- public PutDocumentHandler() {
- this(null, new DocumentDAO());
- }
- /**
- * Default ctor
- *
- * @param next
- */
- public PutDocumentHandler(PipelinedHandler next) {
- this(next, new DocumentDAO());
- }
- /**
- * Creates a new instance of PutDocumentHandler
- *
- * @param next
- * @param documentDAO
- */
- public PutDocumentHandler(PipelinedHandler next, DocumentDAO documentDAO) {
- super(next);
- this.documentDAO = documentDAO;
- }
- /**
- *
- * @param exchange
- * @throws Exception
- */
- @Override
- public void handleRequest(HttpServerExchange exchange) throws Exception {
- var request = MongoRequest.of(exchange);
- var response = MongoResponse.of(exchange);
-
- if (request.isInError()) {
- next(exchange);
- return;
- }
-
- BsonValue _content = request.getContent();
- if (_content == null) {
- _content = new BsonDocument();
- }
- // cannot PUT an array
- if (!_content.isDocument()) {
- response.setInError(
- HttpStatus.SC_NOT_ACCEPTABLE,
- "data must be a josn object");
- next(exchange);
- return;
- }
- BsonDocument content = _content.asDocument();
- BsonValue id = request.getDocumentId();
- if (content.get("_id") == null) {
- content.put("_id", id);
- } else if (!content.get("_id").equals(id)) {
- response.setInError(
- HttpStatus.SC_NOT_ACCEPTABLE,
- "_id in content body is different than id in URL");
- next(exchange);
- return;
- }
- String etag = request.getETag();
- OperationResult result = this.documentDAO.upsertDocument(
- request.getClientSession(),
- request.getDBName(),
- request.getCollectionName(),
- request.getDocumentId(),
- request.getFiltersDocument(),
- request.getShardKey(),
- content,
- etag,
- false,
- request.isETagCheckRequired());
- response.setDbOperationResult(result);
- // inject the etag
- if (result.getEtag() != null) {
- ResponseHelper.injectEtagHeader(exchange, result.getEtag());
- }
-
- if (result.getHttpCode() == HttpStatus.SC_CONFLICT) {
- response.setInError(
- HttpStatus.SC_CONFLICT,
- "The document's ETag must be provided using the '"
- + Headers.IF_MATCH
- + "' header");
- next(exchange);
- return;
- }
-
- // handle the case of duplicate key error
- if (result.getHttpCode() == HttpStatus.SC_EXPECTATION_FAILED) {
- response.setInError(
- HttpStatus.SC_EXPECTATION_FAILED,
- ResponseHelper.getMessageFromErrorCode(11000));
- next(exchange);
- return;
- }
-
- response.setStatusCode(result.getHttpCode());
- next(exchange);
- }
- }