aboutsummaryrefslogtreecommitdiff
path: root/src/commands
diff options
context:
space:
mode:
authorAlex Vakulenko <avakulenko@google.com>2015-11-23 09:35:37 -0800
committerAlex Vakulenko <avakulenko@google.com>2015-11-23 18:06:51 +0000
commit36bf1b5778249e1ef807a92b24046783d84bfb40 (patch)
tree5ec48cc370058a90e84817656a9b0c2ba623f8c5 /src/commands
parent03cd192eceb46f936ad89e6ae04dac130202e18c (diff)
downloadlibweave-36bf1b5778249e1ef807a92b24046783d84bfb40.tar.gz
Remove schema validation from command parameters/returns
Do not use ObjectSchema and instead pass parameters, progress and return values as opaque JSON objects. BUG: 25841230 Change-Id: I0ea5fc31d526b1e5d6c66453b613e7284aa3fcac Reviewed-on: https://weave-review.googlesource.com/1611 Reviewed-by: Vitaly Buka <vitalybuka@google.com>
Diffstat (limited to 'src/commands')
-rw-r--r--src/commands/command_instance.cc86
-rw-r--r--src/commands/command_instance.h12
-rw-r--r--src/commands/command_instance_unittest.cc33
3 files changed, 40 insertions, 91 deletions
diff --git a/src/commands/command_instance.cc b/src/commands/command_instance.cc
index f152d82..aa71b0e 100644
--- a/src/commands/command_instance.cc
+++ b/src/commands/command_instance.cc
@@ -12,9 +12,7 @@
#include "src/commands/command_definition.h"
#include "src/commands/command_dictionary.h"
#include "src/commands/command_queue.h"
-#include "src/commands/prop_types.h"
#include "src/commands/schema_constants.h"
-#include "src/commands/schema_utils.h"
#include "src/json_error_codes.h"
#include "src/utils.h"
@@ -68,12 +66,12 @@ LIBWEAVE_EXPORT EnumToStringMap<Command::Origin>::EnumToStringMap()
CommandInstance::CommandInstance(const std::string& name,
Command::Origin origin,
const CommandDefinition* command_definition,
- const ValueMap& parameters)
+ const base::DictionaryValue& parameters)
: name_{name},
origin_{origin},
- command_definition_{command_definition},
- parameters_{parameters} {
+ command_definition_{command_definition} {
CHECK(command_definition_);
+ parameters_.MergeDictionary(&parameters);
}
CommandInstance::~CommandInstance() {
@@ -97,15 +95,15 @@ Command::Origin CommandInstance::GetOrigin() const {
}
std::unique_ptr<base::DictionaryValue> CommandInstance::GetParameters() const {
- return TypedValueToJson(parameters_);
+ return std::unique_ptr<base::DictionaryValue>(parameters_.DeepCopy());
}
std::unique_ptr<base::DictionaryValue> CommandInstance::GetProgress() const {
- return TypedValueToJson(progress_);
+ return std::unique_ptr<base::DictionaryValue>(progress_.DeepCopy());
}
std::unique_ptr<base::DictionaryValue> CommandInstance::GetResults() const {
- return TypedValueToJson(results_);
+ return std::unique_ptr<base::DictionaryValue>(results_.DeepCopy());
}
const Error* CommandInstance::GetError() const {
@@ -114,21 +112,13 @@ const Error* CommandInstance::GetError() const {
bool CommandInstance::SetProgress(const base::DictionaryValue& progress,
ErrorPtr* error) {
- if (!command_definition_)
- return ReportDestroyedError(error);
- ObjectPropType obj_prop_type;
- obj_prop_type.SetObjectSchema(command_definition_->GetProgress()->Clone());
-
- ValueMap obj;
- if (!TypedValueFromJson(&progress, &obj_prop_type, &obj, error))
- return false;
-
// Change status even if progress unchanged, e.g. 0% -> 0%.
if (!SetStatus(State::kInProgress, error))
return false;
- if (obj != progress_) {
- progress_ = obj;
+ if (!progress_.Equals(&progress)) {
+ progress_.Clear();
+ progress_.MergeDictionary(&progress);
FOR_EACH_OBSERVER(Observer, observers_, OnProgressChanged());
}
@@ -137,17 +127,9 @@ bool CommandInstance::SetProgress(const base::DictionaryValue& progress,
bool CommandInstance::Complete(const base::DictionaryValue& results,
ErrorPtr* error) {
- if (!command_definition_)
- return ReportDestroyedError(error);
- ObjectPropType obj_prop_type;
- obj_prop_type.SetObjectSchema(command_definition_->GetResults()->Clone());
-
- ValueMap obj;
- if (!TypedValueFromJson(&results, &obj_prop_type, &obj, error))
- return false;
-
- if (obj != results_) {
- results_ = obj;
+ if (!results_.Equals(&results)) {
+ results_.Clear();
+ results_.MergeDictionary(&results);
FOR_EACH_OBSERVER(Observer, observers_, OnResultsChanged());
}
// Change status even if result is unchanged.
@@ -171,36 +153,29 @@ namespace {
// On success, returns |true| and the validated parameters and values through
// |parameters|. Otherwise returns |false| and additional error information in
// |error|.
-bool GetCommandParameters(const base::DictionaryValue* json,
- const CommandDefinition* command_def,
- ValueMap* parameters,
- ErrorPtr* error) {
+std::unique_ptr<base::DictionaryValue> GetCommandParameters(
+ const base::DictionaryValue* json,
+ const CommandDefinition* command_def,
+ ErrorPtr* error) {
// Get the command parameters from 'parameters' property.
- base::DictionaryValue no_params; // Placeholder when no params are specified.
- const base::DictionaryValue* params = nullptr;
+ std::unique_ptr<base::DictionaryValue> params;
const base::Value* params_value = nullptr;
if (json->Get(commands::attributes::kCommand_Parameters, &params_value)) {
// Make sure the "parameters" property is actually an object.
- if (!params_value->GetAsDictionary(&params)) {
+ const base::DictionaryValue* params_dict = nullptr;
+ if (!params_value->GetAsDictionary(&params_dict)) {
Error::AddToPrintf(error, FROM_HERE, errors::json::kDomain,
errors::json::kObjectExpected,
"Property '%s' must be a JSON object",
commands::attributes::kCommand_Parameters);
- return false;
+ return params;
}
+ params.reset(params_dict->DeepCopy());
} else {
// "parameters" are not specified. Assume empty param list.
- params = &no_params;
+ params.reset(new base::DictionaryValue);
}
-
- // Now read in the parameters and validate their values against the command
- // definition schema.
- ObjectPropType obj_prop_type;
- obj_prop_type.SetObjectSchema(command_def->GetParameters()->Clone());
- if (!TypedValueFromJson(params, &obj_prop_type, parameters, error)) {
- return false;
- }
- return true;
+ return params;
}
} // anonymous namespace
@@ -246,8 +221,8 @@ std::unique_ptr<CommandInstance> CommandInstance::FromJson(
return instance;
}
- ValueMap parameters;
- if (!GetCommandParameters(json, command_def, &parameters, error)) {
+ auto parameters = GetCommandParameters(json, command_def, error);
+ if (!parameters) {
Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
errors::commands::kCommandFailed,
"Failed to validate command '%s'", command_name.c_str());
@@ -255,7 +230,7 @@ std::unique_ptr<CommandInstance> CommandInstance::FromJson(
}
instance.reset(
- new CommandInstance{command_name, origin, command_def, parameters});
+ new CommandInstance{command_name, origin, command_def, *parameters});
if (!command_id->empty())
instance->SetID(*command_id);
@@ -268,12 +243,9 @@ std::unique_ptr<base::DictionaryValue> CommandInstance::ToJson() const {
json->SetString(commands::attributes::kCommand_Id, id_);
json->SetString(commands::attributes::kCommand_Name, name_);
- json->Set(commands::attributes::kCommand_Parameters,
- TypedValueToJson(parameters_).release());
- json->Set(commands::attributes::kCommand_Progress,
- TypedValueToJson(progress_).release());
- json->Set(commands::attributes::kCommand_Results,
- TypedValueToJson(results_).release());
+ json->Set(commands::attributes::kCommand_Parameters, parameters_.DeepCopy());
+ json->Set(commands::attributes::kCommand_Progress, progress_.DeepCopy());
+ json->Set(commands::attributes::kCommand_Results, results_.DeepCopy());
json->SetString(commands::attributes::kCommand_State, EnumToString(state_));
if (error_) {
json->Set(commands::attributes::kCommand_Error,
diff --git a/src/commands/command_instance.h b/src/commands/command_instance.h
index 5a2ebf7..30ef907 100644
--- a/src/commands/command_instance.h
+++ b/src/commands/command_instance.h
@@ -44,12 +44,12 @@ class CommandInstance final : public Command {
};
// Construct a command instance given the full command |name| which must
- // be in format "<package_name>.<command_name>", a command |category| and
- // a list of parameters and their values specified in |parameters|.
+ // be in format "<package_name>.<command_name>" and a list of parameters and
+ // their values specified in |parameters|.
CommandInstance(const std::string& name,
Command::Origin origin,
const CommandDefinition* command_definition,
- const ValueMap& parameters);
+ const base::DictionaryValue& parameters);
~CommandInstance() override;
// Command overrides.
@@ -124,11 +124,11 @@ class CommandInstance final : public Command {
// Command definition.
const CommandDefinition* command_definition_{nullptr};
// Command parameters and their values.
- ValueMap parameters_;
+ base::DictionaryValue parameters_;
// Current command execution progress.
- ValueMap progress_;
+ base::DictionaryValue progress_;
// Command results.
- ValueMap results_;
+ base::DictionaryValue results_;
// Current command state.
Command::State state_ = Command::State::kQueued;
// Error encountered during execution of the command.
diff --git a/src/commands/command_instance_unittest.cc b/src/commands/command_instance_unittest.cc
index 4e208ed..a03e92b 100644
--- a/src/commands/command_instance_unittest.cc
+++ b/src/commands/command_instance_unittest.cc
@@ -7,8 +7,6 @@
#include <gtest/gtest.h>
#include "src/commands/command_dictionary.h"
-#include "src/commands/prop_types.h"
-#include "src/commands/schema_utils.h"
#include "src/commands/unittest_utils.h"
namespace weave {
@@ -70,14 +68,12 @@ class CommandInstanceTest : public ::testing::Test {
} // anonymous namespace
TEST_F(CommandInstanceTest, Test) {
- StringPropType str_prop;
- IntPropType int_prop;
- ValueMap params;
- params["phrase"] =
- str_prop.CreateValue(base::StringValue{"iPityDaFool"}, nullptr);
- params["volume"] = int_prop.CreateValue(base::FundamentalValue{5}, nullptr);
+ auto params = CreateDictionaryValue(R"({
+ 'phrase': 'iPityDaFool',
+ 'volume': 5
+ })");
CommandInstance instance{"robot.speak", Command::Origin::kCloud,
- dict_.FindCommand("robot.speak"), params};
+ dict_.FindCommand("robot.speak"), *params};
EXPECT_TRUE(
instance.Complete(*CreateDictionaryValue("{'foo': 239}"), nullptr));
@@ -174,25 +170,6 @@ TEST_F(CommandInstanceTest, FromJson_ParamsNotObject) {
EXPECT_EQ("command_failed", error->GetCode());
}
-TEST_F(CommandInstanceTest, FromJson_ParamError) {
- auto json = CreateDictionaryValue(R"({
- 'name': 'robot.speak',
- 'parameters': {
- 'phrase': 'iPityDaFool',
- 'volume': 20
- }
- })");
- ErrorPtr error;
- auto instance = CommandInstance::FromJson(json.get(), Command::Origin::kCloud,
- dict_, nullptr, &error);
- EXPECT_EQ(nullptr, instance.get());
- auto first = error->GetFirstError();
- EXPECT_EQ("out_of_range", first->GetCode());
- auto inner = error->GetInnerError();
- EXPECT_EQ("invalid_parameter_value", inner->GetCode());
- EXPECT_EQ("command_failed", error->GetCode());
-}
-
TEST_F(CommandInstanceTest, ToJson) {
auto json = CreateDictionaryValue(R"({
'name': 'robot.jump',