//////////////////////////////////////////////////////////////////////////////// /// DISCLAIMER /// /// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany /// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// /// Copyright holder is ArangoDB GmbH, Cologne, Germany /// /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// #include "RocksDBRestWalHandler.h" #include "Basics/VelocyPackHelper.h" #include "Cluster/ClusterMethods.h" #include "Cluster/ServerState.h" #include "RestServer/TransactionManagerFeature.h" #include "RocksDBEngine/RocksDBCommon.h" #include "RocksDBEngine/RocksDBEngine.h" #include "StorageEngine/EngineSelectorFeature.h" #include "StorageEngine/TransactionManager.h" #include using namespace arangodb; using namespace arangodb::rest; RocksDBRestWalHandler::RocksDBRestWalHandler(GeneralRequest* request, GeneralResponse* response) : RestVocbaseBaseHandler(request, response) {} RestStatus RocksDBRestWalHandler::execute() { std::vector const& suffixes = _request->suffixes(); if (suffixes.size() != 1) { generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER, "expecting /_admin/wal/"); return RestStatus::DONE; } std::string const& operation = suffixes[0]; // extract the sub-request type auto const type = _request->requestType(); if (operation == "transactions") { if (type == rest::RequestType::GET) { transactions(); return RestStatus::DONE; } } else if (operation == "flush") { if (type == rest::RequestType::PUT) { flush(); return RestStatus::DONE; } } else if (operation == "properties") { if (type == rest::RequestType::GET || type == rest::RequestType::PUT) { properties(); return RestStatus::DONE; } } else { generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER, "expecting /_admin/wal/"); return RestStatus::DONE; } generateError(rest::ResponseCode::METHOD_NOT_ALLOWED, TRI_ERROR_HTTP_METHOD_NOT_ALLOWED); return RestStatus::DONE; } void RocksDBRestWalHandler::properties() { // not supported on rocksdb generateResult(rest::ResponseCode::NOT_IMPLEMENTED, basics::VelocyPackHelper::EmptyObjectValue()); } void RocksDBRestWalHandler::flush() { std::shared_ptr parsedRequest; VPackSlice slice; try { slice = _request->payload(); } catch (...) { generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER, "invalid body value. expecting object"); return; } if (!slice.isObject() && !slice.isNone()) { generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER, "invalid body value. expecting object"); } bool waitForSync = false; bool waitForCollector = false; if (slice.isObject()) { // got a request body VPackSlice value = slice.get("waitForSync"); if (value.isString()) { waitForSync = (value.copyString() == "true"); } else if (value.isBoolean()) { waitForSync = value.getBoolean(); } value = slice.get("waitForCollector"); if (value.isString()) { waitForCollector = (value.copyString() == "true"); } else if (value.isBoolean()) { waitForCollector = value.getBoolean(); } } else { // no request body bool found; { std::string const& v = _request->value("waitForSync", found); if (found) { waitForSync = (v == "1" || v == "true"); } } { std::string const& v = _request->value("waitForCollector", found); if (found) { waitForCollector = (v == "1" || v == "true"); } } } int res = TRI_ERROR_NO_ERROR; if (ServerState::instance()->isCoordinator()) { res = flushWalOnAllDBServers(waitForSync, waitForCollector); } else { if (waitForSync) { static_cast(EngineSelectorFeature::ENGINE)->syncWal(); } } if (res != TRI_ERROR_NO_ERROR) { THROW_ARANGO_EXCEPTION(res); } generateResult(rest::ResponseCode::OK, basics::VelocyPackHelper::EmptyObjectValue()); } void RocksDBRestWalHandler::transactions() { TransactionManager* mngr = TransactionManagerFeature::manager(); VPackBuilder builder; builder.openObject(); builder.add("runningTransactions", VPackValue(mngr->getActiveTransactionCount())); // lastCollectedId /*{ auto value = std::get<1>(info); if (value == UINT64_MAX) { builder.add("minLastCollected", VPackValue(VPackValueType::Null)); } else { builder.add("minLastCollected", VPackValue(value)); } } // lastSealedId { auto value = std::get<2>(info); if (value == UINT64_MAX) { builder.add("minLastSealed", VPackValue(VPackValueType::Null)); } else { builder.add("minLastSealed", VPackValue(value)); } }*/ builder.close(); generateResult(rest::ResponseCode::NOT_IMPLEMENTED, builder.slice()); }