mirror of https://gitee.com/bigwinds/arangodb
236 lines
7.3 KiB
C++
236 lines
7.3 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2016 ArangoDB 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
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef ARANGODB_APPLICATION_FEATURES_APPLICATION_FEATURE_H
|
|
#define ARANGODB_APPLICATION_FEATURES_APPLICATION_FEATURE_H 1
|
|
|
|
#include "Basics/Common.h"
|
|
|
|
#include "ApplicationFeatures/ApplicationServer.h"
|
|
#include "Basics/Exceptions.h"
|
|
|
|
#include <unordered_set>
|
|
|
|
namespace arangodb {
|
|
namespace application_features {
|
|
|
|
class ApplicationFeature {
|
|
friend class ApplicationServer;
|
|
|
|
public:
|
|
ApplicationFeature() = delete;
|
|
ApplicationFeature(ApplicationFeature const&) = delete;
|
|
ApplicationFeature& operator=(ApplicationFeature const&) = delete;
|
|
|
|
ApplicationFeature(ApplicationServer& server, std::string const& name);
|
|
|
|
virtual ~ApplicationFeature();
|
|
|
|
enum class State {
|
|
UNINITIALIZED,
|
|
INITIALIZED,
|
|
VALIDATED,
|
|
PREPARED,
|
|
STARTED,
|
|
STOPPED,
|
|
UNPREPARED
|
|
};
|
|
|
|
// return the feature's name
|
|
std::string const& name() const { return _name; }
|
|
|
|
bool isOptional() const { return _optional; }
|
|
bool isRequired() const { return !_optional; }
|
|
|
|
State state() const { return _state; }
|
|
|
|
// whether or not the feature is enabled
|
|
bool isEnabled() const { return _enabled; }
|
|
|
|
// enable the feature
|
|
void enable() { setEnabled(true); }
|
|
|
|
// disable the feature entirely. if disabled, the feature's options will be
|
|
// ignored and no methods apart from `collectOptions` will be called for the
|
|
// feature
|
|
void disable() { setEnabled(false); }
|
|
|
|
// disable the feature, and perform no checks if it's optional
|
|
void forceDisable() { _enabled = false; }
|
|
|
|
// enable or disable a feature
|
|
void setEnabled(bool value) {
|
|
if (!value && !isOptional()) {
|
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
|
|
"cannot disable non-optional feature '" +
|
|
name() + "'");
|
|
}
|
|
_enabled = value;
|
|
}
|
|
|
|
// names of features required to be enabled for this feature to be enabled
|
|
std::vector<std::string> const& requires() const { return _requires; }
|
|
|
|
// register whether the feature requires elevated privileges
|
|
void requiresElevatedPrivileges(bool value) {
|
|
_requiresElevatedPrivileges = value;
|
|
}
|
|
|
|
// test whether the feature requires elevated privileges
|
|
bool requiresElevatedPrivileges() const {
|
|
return _requiresElevatedPrivileges;
|
|
}
|
|
|
|
// whether the feature starts before another
|
|
bool doesStartBefore(std::string const& other) const;
|
|
|
|
// whether the feature starts after another
|
|
bool doesStartAfter(std::string const& other) const {
|
|
return !doesStartBefore(other);
|
|
}
|
|
|
|
// add the feature's options to the global list of options. this method will
|
|
// be called regardless of whether to feature is enabled or disabled
|
|
virtual void collectOptions(std::shared_ptr<options::ProgramOptions>);
|
|
|
|
// load options from somewhere. this method will only be called for enabled
|
|
// features
|
|
virtual void loadOptions(std::shared_ptr<options::ProgramOptions>, char const* binaryPath);
|
|
|
|
// validate the feature's options. this method will only be called for active
|
|
// features, after the ApplicationServer has determined which features should
|
|
// be turned off globally. in order to abort further processing in case of
|
|
// invalid parameter values, the feature should bail out by calling
|
|
// FATAL_ERROR_EXIT.
|
|
virtual void validateOptions(std::shared_ptr<options::ProgramOptions>);
|
|
|
|
// allows process control
|
|
virtual void daemonize();
|
|
|
|
// preparation phase for feature in the preparation phase, the features must
|
|
// not start any threads. furthermore, they must not write any files under
|
|
// elevated privileges if they want other features to access them, or if they
|
|
// want to access these files with dropped privileges
|
|
virtual void prepare();
|
|
|
|
// start the feature
|
|
virtual void start();
|
|
|
|
// notify the feature about a shutdown request
|
|
virtual void beginShutdown();
|
|
|
|
// stop the feature
|
|
virtual void stop();
|
|
|
|
// shut down the feature
|
|
virtual void unprepare();
|
|
|
|
// return startup dependencies for feature
|
|
std::unordered_set<std::string> const& startsAfter() const {
|
|
return _startsAfter;
|
|
}
|
|
|
|
// return startup dependencies for feature
|
|
std::unordered_set<std::string> const& startsBefore() const {
|
|
return _startsBefore;
|
|
}
|
|
|
|
protected:
|
|
// return the ApplicationServer instance
|
|
ApplicationServer* server() const { return &_server; }
|
|
|
|
void setOptional() { setOptional(true); }
|
|
|
|
// make the feature optional (or not)
|
|
void setOptional(bool value) { _optional = value; }
|
|
|
|
// note that this feature requires another to be present
|
|
void requires(std::string const& other) { _requires.emplace_back(other); }
|
|
|
|
// register a start dependency upon another feature
|
|
void startsAfter(std::string const& other) { _startsAfter.emplace(other); }
|
|
|
|
// register a start dependency upon another feature
|
|
void startsBefore(std::string const& other) { _startsBefore.emplace(other); }
|
|
|
|
// determine all direct and indirect ancestors of a feature
|
|
std::unordered_set<std::string> ancestors() const;
|
|
|
|
void onlyEnabledWith(std::string const& other) {
|
|
_onlyEnabledWith.emplace(other);
|
|
}
|
|
|
|
// return the list of other features that this feature depends on
|
|
std::unordered_set<std::string> const& onlyEnabledWith() const {
|
|
return _onlyEnabledWith;
|
|
}
|
|
|
|
private:
|
|
// set a feature's state. this method should be called by the
|
|
// application server only
|
|
void state(State state) { _state = state; }
|
|
|
|
// determine all direct and indirect ancestors of a feature
|
|
void determineAncestors();
|
|
|
|
// pointer to application server
|
|
ApplicationServer& _server;
|
|
|
|
// name of feature
|
|
std::string const _name;
|
|
|
|
// names of other features required to be enabled if this feature
|
|
// is enabled
|
|
std::vector<std::string> _requires;
|
|
|
|
// a list of start dependencies for the feature
|
|
std::unordered_set<std::string> _startsAfter;
|
|
|
|
// a list of start dependencies for the feature
|
|
std::unordered_set<std::string> _startsBefore;
|
|
|
|
// list of direct and indirect ancestors of the feature
|
|
std::unordered_set<std::string> _ancestors;
|
|
|
|
// enable this feature only if the following other features are enabled
|
|
std::unordered_set<std::string> _onlyEnabledWith;
|
|
|
|
// state of feature
|
|
State _state;
|
|
|
|
// whether or not the feature is enabled
|
|
bool _enabled;
|
|
|
|
// whether or not the feature is optional
|
|
bool _optional;
|
|
|
|
// whether or not the feature requires elevated privileges
|
|
bool _requiresElevatedPrivileges;
|
|
|
|
bool _ancestorsDetermined;
|
|
};
|
|
|
|
} // namespace application_features
|
|
} // namespace arangodb
|
|
|
|
#endif
|