blob: e755e79eb5115702743be200f4a3f674242bfe36 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_CONNECTIVITY_WEAVE_ADAPTATION_WEAVE_CONFIG_MANAGER_H_
#define SRC_CONNECTIVITY_WEAVE_ADAPTATION_WEAVE_CONFIG_MANAGER_H_
#include <cstdint>
#include <mutex>
#include <string>
#include <vector>
#pragma GCC diagnostic push
#include <Weave/Core/WeaveError.h>
#include <Weave/DeviceLayer/WeaveDeviceError.h>
#pragma GCC diagnostic pop
#include "rapidjson/document.h"
namespace nl {
namespace Weave {
namespace DeviceLayer {
namespace Internal {
extern const char kEnvironmentStorePath[];
// Abstract class that defines the reader interface for the config store.
class WeaveConfigReader {
public:
virtual ~WeaveConfigReader() = default;
virtual WEAVE_ERROR ReadConfigValue(const std::string& key, bool* value) const = 0;
virtual WEAVE_ERROR ReadConfigValue(const std::string& key, uint16_t* value) const = 0;
virtual WEAVE_ERROR ReadConfigValue(const std::string& key, uint32_t* value) const = 0;
virtual WEAVE_ERROR ReadConfigValue(const std::string& key, uint64_t* value) const = 0;
virtual WEAVE_ERROR ReadConfigValueArray(const std::string& key,
std::vector<std::string>& out) const = 0;
virtual WEAVE_ERROR ReadConfigValueStr(const std::string& key, char* value, size_t value_size,
size_t* out_size) const = 0;
virtual WEAVE_ERROR ReadConfigValueBin(const std::string& key, uint8_t* value, size_t value_size,
size_t* out_size) const = 0;
virtual bool ConfigValueExists(const std::string& key) const = 0;
};
// Abstract class that defines the writer interface for the config store.
class WeaveConfigWriter {
public:
virtual ~WeaveConfigWriter() = default;
virtual WEAVE_ERROR WriteConfigValue(const std::string& key, bool value) = 0;
virtual WEAVE_ERROR WriteConfigValue(const std::string& key, uint32_t value) = 0;
virtual WEAVE_ERROR WriteConfigValue(const std::string& key, uint64_t value) = 0;
virtual WEAVE_ERROR WriteConfigValueArray(const std::string& key,
std::vector<std::string>& value) = 0;
virtual WEAVE_ERROR WriteConfigValueStr(const std::string& key, const char* value,
size_t value_size) = 0;
virtual WEAVE_ERROR WriteConfigValueBin(const std::string& key, const uint8_t* value,
size_t value_size) = 0;
virtual WEAVE_ERROR ClearConfigValue(const std::string& key) = 0;
virtual WEAVE_ERROR FactoryResetConfig() = 0;
};
// Singleton class that accepts read/write calls to store key-value pairs.
//
// This class loads a JSON file from a fixed location and uses it as its backing
// store. Read requests are handled by quering the in-memory RapidJSON object,
// while writes update both the in-memory object and commits the JSON to disk.
//
// It is up to callers of this class to not open the same path across multiple
// instances, to prevent R/W interleaving and corrupting the backing file.
//
class WeaveConfigManager : public WeaveConfigReader, WeaveConfigWriter {
public:
explicit WeaveConfigManager(std::string path);
~WeaveConfigManager() = default;
WeaveConfigManager(const WeaveConfigManager&) = delete;
WeaveConfigManager(WeaveConfigManager&&) = delete;
WeaveConfigManager& operator=(const WeaveConfigManager&) = delete;
WeaveConfigManager& operator=(WeaveConfigManager&&) = delete;
WEAVE_ERROR ReadConfigValue(const std::string& key, bool* value) const override;
WEAVE_ERROR ReadConfigValue(const std::string& key, uint16_t* value) const override;
WEAVE_ERROR ReadConfigValue(const std::string& key, uint32_t* value) const override;
WEAVE_ERROR ReadConfigValue(const std::string& key, uint64_t* value) const override;
WEAVE_ERROR ReadConfigValueArray(const std::string& key,
std::vector<std::string>& out) const override;
WEAVE_ERROR ReadConfigValueStr(const std::string& key, char* value, size_t value_size,
size_t* out_size) const override;
WEAVE_ERROR ReadConfigValueBin(const std::string& key, uint8_t* value, size_t value_size,
size_t* out_size) const override;
bool ConfigValueExists(const std::string& key) const override;
WEAVE_ERROR WriteConfigValue(const std::string& key, bool value) override;
WEAVE_ERROR WriteConfigValue(const std::string& key, uint32_t value) override;
WEAVE_ERROR WriteConfigValue(const std::string& key, uint64_t value) override;
WEAVE_ERROR WriteConfigValueArray(const std::string& key,
std::vector<std::string>& value) override;
WEAVE_ERROR WriteConfigValueStr(const std::string& key, const char* value,
size_t value_size) override;
WEAVE_ERROR WriteConfigValueBin(const std::string& key, const uint8_t* value,
size_t value_size) override;
WEAVE_ERROR ClearConfigValue(const std::string& key) override;
WEAVE_ERROR FactoryResetConfig() override;
// Manager-only interface to set the given values on this configuration. The values in the
// existing configuration will be overridden if should_replace is true.
WEAVE_ERROR SetConfiguration(const std::string& path, const std::string& schema_path,
bool should_replace);
// Returns a read/write interface to this instance of WeaveConfigManager.
static std::unique_ptr<WeaveConfigManager> CreateInstance(const std::string& path) {
return std::make_unique<WeaveConfigManager>(path);
}
private:
WeaveConfigManager();
WEAVE_ERROR ReadKVPair(const std::string& key, rapidjson::Value& value) const;
WEAVE_ERROR WriteKVPair(const std::string& key, rapidjson::Value& value);
WEAVE_ERROR CommitKVPairs();
friend WeaveConfigManager& WeaveConfigMgr(void);
static WeaveConfigManager& GetInstance();
const std::string config_store_path_;
mutable rapidjson::Document config_;
mutable std::mutex config_mutex_;
};
// Convenience inline function to access the instance of WeaveConfigManager.
inline WeaveConfigManager& WeaveConfigMgr(void) { return WeaveConfigManager::GetInstance(); }
} // namespace Internal
} // namespace DeviceLayer
} // namespace Weave
} // namespace nl
#endif // SRC_CONNECTIVITY_WEAVE_ADAPTATION_WEAVE_CONFIG_MANAGER_H_