From: Harish Kumara Marappa Date: Thu, 29 Oct 2015 16:59:29 +0000 (+0530) Subject: Collection resource support. X-Git-Tag: 1.2.0+RC1~764^2~16 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=258bca9409deb041e30084c9b4568ad7f1c19dbf;p=platform%2Fupstream%2Fiotivity.git Collection resource support. Change details: 1. Implementation of collection resource. 2. Extended SimulatorResourceModel to support vector types. Change-Id: Id808b73749dcf00a0746e2118cfbcad221175552 Signed-off-by: Harish Kumara Marappa Reviewed-on: https://gerrit.iotivity.org/gerrit/3977 Tested-by: jenkins-iotivity Reviewed-by: Madan Lanka --- diff --git a/service/simulator/SConscript b/service/simulator/SConscript index 260cb0b..b77e5dc 100755 --- a/service/simulator/SConscript +++ b/service/simulator/SConscript @@ -36,7 +36,7 @@ target_os = env.get('TARGET_OS') ###################################################################### # Build flags ###################################################################### -simulator_env.AppendUnique(CPPPATH = ['inc', 'src/client-controller', 'src/service-provider', 'src/common']) +simulator_env.AppendUnique(CPPPATH = ['inc', 'src/client', 'src/server', 'src/common']) simulator_env.AppendUnique(CPPPATH = [ '../../resource/include/', '../../resource/csdk/stack/include', @@ -86,4 +86,4 @@ simulator_env.InstallTarget(simulatorsdk, 'libSimulator') #Build sample application SConscript('examples/server/SConscript') -SConscript('examples/client-controller/SConscript') +SConscript('examples/client/SConscript') \ No newline at end of file diff --git a/service/simulator/examples/README.txt b/service/simulator/examples/README.txt deleted file mode 100755 index f0ab383..0000000 --- a/service/simulator/examples/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -Command to run Service Provider with Resource definitions provided throught RAML file : -./simulator-server PATH-TO-RAML-FILE - diff --git a/service/simulator/examples/client-controller/SConscript b/service/simulator/examples/client/SConscript similarity index 85% rename from service/simulator/examples/client-controller/SConscript rename to service/simulator/examples/client/SConscript index 7149b6b..bcf4ec0 100644 --- a/service/simulator/examples/client-controller/SConscript +++ b/service/simulator/examples/client/SConscript @@ -22,7 +22,7 @@ if sim_env.get('SECURED') == '1': ###################################################################### # Source files and Targets ###################################################################### -clientcontroller = sim_env.Program('client-controller', 'client_controller.cpp') +client = sim_env.Program('simulator-client', 'simulator_client.cpp') -Alias("clientcontroller", clientcontroller) -env.AppendTarget('clientcontroller') +Alias("simulatorclient", client) +env.AppendTarget('client') diff --git a/service/simulator/examples/client-controller/client_controller.cpp b/service/simulator/examples/client/simulator_client.cpp similarity index 90% rename from service/simulator/examples/client-controller/client_controller.cpp rename to service/simulator/examples/client/simulator_client.cpp index 18df736..9577d83 100644 --- a/service/simulator/examples/client-controller/client_controller.cpp +++ b/service/simulator/examples/client/simulator_client.cpp @@ -34,6 +34,21 @@ std::string getOperationStateString(OperationState state) return "OP_UNKNOWN"; } +std::string getPropertyTypeString(SimulatorResourceModel::AttributeProperty::Type type) +{ + switch(type) + { + case SimulatorResourceModel::AttributeProperty::Type::RANGE: + return "RANGE"; + case SimulatorResourceModel::AttributeProperty::Type::VALUE_SET: + return "VALUE_SET"; + default: + break; + } + + return "UNKNOWN"; +} + class AppLogger : public ILogger { public: @@ -202,15 +217,10 @@ class ClientController [](std::string uid, SimulatorResult errorCode, SimulatorResourceModelSP rep, int seq) { std::cout << "\nObserve notification received ###[errorcode: " << errorCode << - " seq: " << seq << "UID: " << uid << "]" << std::endl; - std::map attributes = rep->getAttributes(); - for (auto & attribute : attributes) - { - std::cout << (attribute.second).getName() << " : {" << std::endl; - std::cout << "value: " << (attribute.second).valueToString().c_str() << std::endl; - std::cout << "}" << std::endl; - } - std::cout << std::endl; + " seq: " << seq << "UID: " << uid << "]" << std::endl; + + std::cout << "Representation is: " << std::endl; + std::cout << rep->toString() << std::endl; }; try @@ -260,16 +270,7 @@ class ClientController << std::endl; std::cout << "UID is: " << uId << std::endl; std::cout << "Representation is: " << std::endl; - std::map attributes = - rep->getAttributes(); - for (auto & attribute : attributes) - { - std::cout << (attribute.second).getName() << " : {" << std::endl; - std::cout << "value: " << (attribute.second).valueToString().c_str() - << std::endl; - std::cout << "}" << std::endl; - } - std::cout << std::endl; + std::cout << rep->toString() << std::endl; }; try @@ -307,24 +308,15 @@ class ClientController << std::endl; std::cout << "UID is: " << uId << std::endl; std::cout << "Representation is: " << std::endl; - std::map attributes = - rep->getAttributes(); - for (auto & attribute : attributes) - { - std::cout << (attribute.second).getName() << " : {" << std::endl; - std::cout << "value: " << (attribute.second).valueToString().c_str() - << std::endl; - std::cout << "}" << std::endl; - } - std::cout << std::endl; + std::cout << rep->toString() << std::endl; }; try { SimulatorResourceModelSP rep = std::make_shared(); std::string value = "off"; - rep->addAttribute("power", value); - rep->addAttribute("intensity", 5); + rep->add("power", value); + rep->add("intensity", 5); resource->put(std::map (), rep, callback); std::cout << "PUT is successfull!" << std::endl; @@ -359,24 +351,15 @@ class ClientController << std::endl; std::cout << "UID is: " << uId << std::endl; std::cout << "Representation is: " << std::endl; - std::map attributes = - rep->getAttributes(); - for (auto & attribute : attributes) - { - std::cout << (attribute.second).getName() << " : {" << std::endl; - std::cout << "value: " << (attribute.second).valueToString().c_str() - << std::endl; - std::cout << "}" << std::endl; - } - std::cout << std::endl; + std::cout << rep->toString() << std::endl; }; try { SimulatorResourceModelSP rep = std::make_shared(); std::string value = "on"; - rep->addAttribute("power", value); - rep->addAttribute("intensity", 7); + rep->add("power", value); + rep->add("intensity", 7); resource->post(std::map (), rep, callback); std::cout << "POST is successfull!" << std::endl; @@ -515,8 +498,33 @@ class ClientController std::cout << "Enter the config path: "; std::cin >> configPath; - resource->configure(configPath); - std::cout << "configuration is successfull!" << std::endl; + SimulatorResourceModelSP representation = resource->configure(configPath); + if (representation) + { + std::cout << "configuration is successfull!" << std::endl; + std::map attributes = + representation->getAttributes(); + std::cout << "##### Attributes [" << attributes.size() << "]" << std::endl; + for (auto & attribute : attributes) + { + std::cout << (attribute.second).getName() << " : {" << std::endl; + std::cout << "value: " << (attribute.second).toString() << std::endl; + SimulatorResourceModel::AttributeProperty prop = (attribute.second).getProperty(); + std::cout << "Supported values given by : " << getPropertyTypeString(prop.type()) << std::endl; + if (SimulatorResourceModel::AttributeProperty::Type::RANGE == prop.type()) + { + std::cout << "Min: " << prop.min() << std::endl; + std::cout << "Max: " << prop.max() << std::endl; + } + else if (SimulatorResourceModel::AttributeProperty::Type::VALUE_SET == prop.type()) + { + std::cout << "Value set: " << prop.valueSetToString() << std::endl; + } + + std::cout << "}" << std::endl << std::endl; + } + std::cout << "#############################" << std::endl; + } } catch (InvalidArgsException &e) { diff --git a/service/simulator/examples/server/SConscript b/service/simulator/examples/server/SConscript index 9a5b38e..cb028dd 100644 --- a/service/simulator/examples/server/SConscript +++ b/service/simulator/examples/server/SConscript @@ -22,7 +22,7 @@ if sim_env.get('SECURED') == '1': ###################################################################### # Source files and Targets ###################################################################### -simulatorserver = sim_env.Program('simulator-server', 'service_provider.cpp') +server = sim_env.Program('simulator-server', 'simulator_server.cpp') -Alias("simulatorserver", simulatorserver) -env.AppendTarget('simulatorserver') +Alias("server", server) +env.AppendTarget('server') diff --git a/service/simulator/examples/server/service_provider.cpp b/service/simulator/examples/server/service_provider.cpp deleted file mode 100644 index 3cb3c13..0000000 --- a/service/simulator/examples/server/service_provider.cpp +++ /dev/null @@ -1,613 +0,0 @@ -/****************************************************************** - * - * Copyright 2015 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -#include "simulator_manager.h" - -class AppLogger : public ILogger -{ - public: - void write(std::string time, ILogger::Level level, std::string message) - { - std::cout << "[APPLogger] " << time << " " << ILogger::getString(level) << " " - << message; - } -}; -std::shared_ptr gAppLogger(new AppLogger()); - -class SimLightResource -{ - public: - void startTest() - { - printMenu(); - bool cont = true; - while (cont) - { - int choice = -1; - std::cout << "Enter your choice: "; - std::cin >> choice; - if (choice < 0 || choice > 10) - { - std::cout << "Invaild choice !" << std::endl; continue; - } - - switch (choice) - { - case 1 : simulateResource(); break; - case 2 : displayResource(); break; - case 3 : deleteResource(); break; - case 4 : updateAttributePower(); break; - case 5 : updateAttributeIntensity(); break; - case 6 : automateResourceUpdate(); break; - case 7 : automateAttributeUpdate(); break; - case 8 : stopAutomation(); break; - case 9 : getObservers(); break; - case 10: printMenu(); break; - case 0: cont = false; - } - } - } - - private: - void printMenu() - { - std::cout << "########### LIGHT RESOURCE TESTING ###########" << std::endl; - std::cout << "1. Simulate resource" << std::endl; - std::cout << "2. Display resource information" << std::endl; - std::cout << "3. Delete resource" << std::endl; - std::cout << "4. Update attribute \"power\"" << std::endl; - std::cout << "5. Update attribute \"intensity\"" << std::endl; - std::cout << "6. Automate resource update" << std::endl; - std::cout << "7. Automate attributes update" << std::endl; - std::cout << "8. Stop Automation" << std::endl; - std::cout << "9. Get Observers of a resource" << std::endl; - std::cout << "10: Help" << std::endl; - std::cout << "0. Exit" << std::endl; - std::cout << "#######################################" << std::endl; - } - - int selectResource() - { - if (0 == m_resources.size()) - { - std::cout << "No resouces!" << std::endl; - return -1; - } - - int index = 1; - for (auto & resource : m_resources) - { - std::cout << index++ << ": " << resource->getURI().c_str() << std::endl; - } - - int choice = -1; - std::cout << "Choose the resource: "; - std::cin >> choice; - - if (choice < 1 || choice > index - 1) - { - std::cout << "Invalid choice !" << std::endl; - choice = -1; - } - - return choice; - } - - void onResourceModelChanged(const std::string &uri, - const SimulatorResourceModel &resModel) - { - std::cout << "[callback] Resource model is changed URI: " << uri.c_str() - << " Count : " << resModel.size() << std::endl; - std::cout << "#### Modified attributes are ####" << std::endl; - for (auto & attribute : resModel.getAttributes()) - { - std::cout << attribute.second.getName() << " : " - << attribute.second.valueToString().c_str() << std::endl; - } - std::cout << "########################" << std::endl; - } - - void simulateResource() - { - SimulatorResourceServer::ResourceModelChangedCB callback = std::bind( - &SimLightResource::onResourceModelChanged, this, std::placeholders::_1, - std::placeholders::_2); - - try - { - std::string configPath; - std::cout << "Enter RAML path: "; - std::cin>>configPath; - SimulatorResourceServerSP resource = - SimulatorManager::getInstance()->createResource(configPath, callback); - m_resources.push_back(resource); - std::cout << "Resource created successfully! URI= " << resource->getURI().c_str() - << std::endl; - } - catch (InvalidArgsException &e) - { - std::cout << "InvalidArgsException occured [code : " << e.code() << " Detail: " - << e.what() << "]" << std::endl; - } - catch (SimulatorException &e) - { - std::cout << "SimulatorException occured [code : " << e.code() << " Detail: " - << e.what() << "]" << std::endl; - } - } - - void deleteResource() - { - int choice = -1; - std::cout << "1. Delete single resource" << std::endl; - std::cout << "2. Delete resources on resource types" << std::endl; - std::cout << "3. Delete all resources" << std::endl; - - std::cout << "Enter your choice: "; - std::cin >> choice; - if (choice < 1 || choice > 3) - { - std::cout << "Invalid choice !" << std::endl; - return; - } - - switch (choice) - { - case 1: - { - int index = selectResource(); - if (-1 == index) - return; - - SimulatorManager::getInstance()->deleteResource(m_resources[index - 1]); - std::cout << "Resource deleted successfully! " << std::endl; - m_resources.erase(m_resources.begin() + (index - 1)); - - } break; - - case 2: - { - std::string resourceType; - std::cout << "Enter resource type: "; - std::cin >> resourceType; - if (resourceType.empty()) - { - std::cout << "Invalid resource type!" << std::endl; - break; - } - - try - { - SimulatorManager::getInstance()->deleteResource(resourceType); - std::cout << "Resources of type \"" << resourceType << "\"" << - " deleted successfully! " << std::endl; - std::vector::iterator ite = m_resources.begin(); - while (ite != m_resources.end()) - { - if (!resourceType.compare((*ite)->getResourceType())) - { - ite = m_resources.erase(ite); - continue; - } - ite++; - } - } - catch (InvalidArgsException &e) - { - std::cout << "InvalidArgsException occured [code : " << e.code() - << " Detail: " << e.what() << "]" << std::endl; - } - catch (SimulatorException &e) - { - std::cout << "SimulatorException occured [code : " << e.code() - << " Detail: " << e.what() << "]" << std::endl; - } - } break; - - case 3: - { - SimulatorManager::getInstance()->deleteResource(); - std::cout << "All resources deleted successfully! " << std::endl; - m_resources.clear(); - } break; - } - - } - - void updateAttributePower() - { - int index = selectResource(); - if (-1 == index) - return; - - SimulatorResourceServerSP resource = m_resources[index - 1]; - SimulatorResourceModel resModel = resource->getModel(); - SimulatorResourceModel::Attribute powerAttribute; - resModel.getAttribute("power", powerAttribute); - - int allowedValuesSize = powerAttribute.getAllowedValuesSize(); - if (0 == allowedValuesSize) - { - std::cout << "This attribute does not have allowed values!" << std::endl; - return; - } - - std::cout << "Setting the new values from allowed values list to power attribute" << - std::endl; - // Update all possible values from allowed values - for (int index = 0; index < allowedValuesSize; index++) - { - // Update the new value and display the resource model after modifying - resource->updateFromAllowedValues("power", index); - std::cout << "Attribute value is modified ####" << std::endl; - - // Display the resource to user to verify the changed attribute value - displayResource(resource); - std::cout << std::endl << std::endl; - - // Get user input for continuing this operation - if ((index + 1) < allowedValuesSize) - { - int choice; - std::cout << "Would you like to change attribute value again ? (1/0): "; - std::cin >> choice; - if (0 == choice) - break; - } - } - - std::cout << "All the allowed values are tried!" << std::endl; - } - - void updateAttributeIntensity() - { - int index = selectResource(); - if (-1 == index) - return; - - SimulatorResourceServerSP resource = m_resources[index - 1]; - SimulatorResourceModel resModel = resource->getModel(); - SimulatorResourceModel::Attribute intensityAttribute; - resModel.getAttribute("intensity", intensityAttribute); - - int min, max; - intensityAttribute.getRange(min, max); - if (!min && !max) - { - std::cout << "This attribute does not have range!" << std::endl; - return; - } - - std::cout << "Setting the new values from allowed values list to intensity attribute" - << std::endl; - // Update all possible values from allowed values - for (int index = min; index <= max; index++) - { - // Update the new value and display the resource model after modifying - resource->updateAttributeValue("intensity", index); - std::cout << "Attribute value is modified ####" << std::endl; - - // Display the resource to user to verify the changed attribute value - displayResource(resource); - std::cout << std::endl << std::endl; - - // Get user input for continuing this operation - if ((index + 1) <= max) - { - int choice; - std::cout << "Would you like to change attribute value again ? (1/0): "; - std::cin >> choice; - if (0 == choice) - break; - } - } - - std::cout << "All the allowed values are tried!" << std::endl; - } - - void displayResource() - { - int index = selectResource(); - if (-1 == index) - return; - - SimulatorResourceServerSP resource = m_resources[index - 1]; - displayResource(resource); - } - - void displayResource(SimulatorResourceServerSP resource) - { - std::cout << "#############################" << std::endl; - std::cout << "Name: " << resource->getName().c_str() << std::endl; - std::cout << "URI: " << resource->getURI().c_str() << std::endl; - std::cout << "R. Type: " << resource->getResourceType().c_str() << std::endl; - std::cout << "I. Type: " << resource->getInterfaceType().c_str() << std::endl; - - // Attributes - SimulatorResourceModel resModel = resource->getModel(); - std::map attributes = - resModel.getAttributes(); - std::cout << "##### Attributes [" << attributes.size() << "]" << std::endl; - for (auto & attribute : attributes) - { - std::cout << (attribute.second).getName() << " : {" << std::endl; - std::cout << "value: " << (attribute.second).valueToString().c_str() << std::endl; - int min, max; - (attribute.second).getRange(min, max); - std::cout << "min: " << min << std::endl; - std::cout << "max: " << max << std::endl; - std::cout << "allowed values : "; - std::cout << "[ "; - for (auto & value : (attribute.second).allowedValuesToString()) - std::cout << value << " "; - std::cout << "]" << std::endl; - std::cout << "}" << std::endl << std::endl; - } - std::cout << "#############################" << std::endl; - } - - void onUpdateAutomationCompleted(const std::string &uri, - const int id) - { - std::cout << "Update automation is completed [URI: " << uri.c_str() - << " AutomationID: " << id << "] ###" << std::endl; - } - - void automateResourceUpdate() - { - int index = selectResource(); - if (-1 == index) - return; - - AutomationType type = AutomationType::NORMAL; - int choice = 0; - std::cout << "Press 1 if you want recurrent automation: "; - std::cin >> choice; - if (1 == choice) - type = AutomationType::RECURRENT; - - try - { - int id = m_resources[index - 1]->startUpdateAutomation(type, 500, - std::bind(&SimLightResource::onUpdateAutomationCompleted, this, - std::placeholders::_1, std::placeholders::_2)); - - std::cout << "startUpdateAutomation() returned succces : " << id << std::endl; - } - catch (SimulatorException &e) - { - std::cout << "SimulatorException occured [code : " << e.code() << " Detail: " << - e.what() << "]" << std::endl; - } - } - - void automateAttributeUpdate() - { - int index = selectResource(); - if (-1 == index) - return; - - SimulatorResourceServerSP resource = m_resources[index - 1]; - SimulatorResourceModel resModel = resource->getModel(); - std::map attributes = - resModel.getAttributes(); - int size = 0; - for (auto & attribute : attributes) - { - std::cout << ++size << ": " << attribute.first.c_str() << std::endl; - } - - if (0 == size) - { - std::cout << "This resource doest not contain any attributes!" << std::endl; - return; - } - - int choice = -1; - std::cout << "Select the attribute which you want to automate for updation: " << - std::endl; - std::cin >> choice; - if (choice < 0 || choice > size) - { - std::cout << "Invalid selection!" << std::endl; - return; - } - - int count = 0; - std::string attributeName; - for (auto & attribute : attributes) - { - if (count == choice - 1) - { - attributeName = attribute.first; - break; - } - - count++; - } - - AutomationType type = AutomationType::NORMAL; - std::cout << "Press 1 if you want recurrent automation: "; - std::cin >> choice; - if (1 == choice) - type = AutomationType::RECURRENT; - - std::cout << "Requesting attribute automation for " << attributeName.c_str() << - std::endl; - - try - { - - int id = resource->startUpdateAutomation(attributeName, type, 500, - std::bind(&SimLightResource::onUpdateAutomationCompleted, this, - std::placeholders::_1, std::placeholders::_2)); - std::cout << "startUpdateAutomation() returned succces : " << id << std::endl; - } - catch (SimulatorException &e) - { - std::cout << "SimulatorException occured [Error: " << e.code() << " Details: " << - e.what() << "]" << std::endl; - } - } - - void stopAutomation() - { - int index = selectResource(); - if (-1 == index) - return; - - SimulatorResourceServerSP resource = m_resources[index - 1]; - - // Select the automation to stop - std::vector ids; - { - std::vector rids = resource->getResourceAutomationIds(); - std::vector aids = resource->getAttributeAutomationIds(); - ids.insert(ids.end(), rids.begin(), rids.end()); - ids.insert(ids.end(), aids.begin(), aids.end()); - } - - if (!ids.size()) - { - std::cout << "No automation operation is going on this resource right now!" << - std::endl; - return; - } - - for (auto & id : ids) - std::cout << id << " "; - - int automationid; - std::cout << "\nEnter automation id: " << std::endl; - std::cin >> automationid; - resource->stopUpdateAutomation(automationid); - } - - void onObserverChanged(const std::string &uri, ObservationStatus state, - const ObserverInfo &observerInfo) - { - std::cout << "[callback] Observer notification received..." << uri.c_str() << std::endl; - std::ostringstream out; - out << "ID: " << (int) observerInfo.id << std::endl; - out << " [address: " << observerInfo.address << " port: " << observerInfo.port - << "]" << std::endl; - std::cout << out.str(); - } - - void getObservers() - { - int index = selectResource(); - if (-1 == index) - return; - - SimulatorResourceServerSP resource = m_resources[index - 1]; - - SimulatorResourceServer::ObserverCB callback = std::bind( - &SimLightResource::onObserverChanged, this, std::placeholders::_1, - std::placeholders::_2, std::placeholders::_3); - resource->setObserverCallback(callback); - - std::vector observersList = resource->getObserversList(); - - std::cout << "##### Number of Observers [" << observersList.size() << "]" << std::endl; - for (auto & observerInfo : observersList) - { - std::cout << " ID : " << (int) observerInfo.id << " [address: " << - observerInfo.address << " port: " << observerInfo.port << "]" << std::endl; - } - std::cout << "########################" << std::endl; - } - - private: - std::vector m_resources; -}; - -void printMainMenu() -{ - std::cout << "############### MAIN MENU###############" << std::endl; - std::cout << "1. Test simulation of resource" << std::endl; - std::cout << "2. Set Logger" << std::endl; - std::cout << "3. Help" << std::endl; - std::cout << "0. Exit" << std::endl; - std::cout << "######################################" << std::endl; -} - -void setLogger() -{ - std::cout << "1. Default console logger" << std::endl; - std::cout << "2. Default file logger" << std::endl; - std::cout << "3. custom logger" << std::endl; - - int choice = -1; - std::cin >> choice; - if (choice <= 0 || choice > 3) - { - std::cout << "Invalid selection !" << std::endl; - return; - } - - switch (choice) - { - case 1: - { - if (false == SimulatorManager::getInstance()->setConsoleLogger()) - std::cout << "Failed to set the default console logger" << std::endl; - } break; - case 2: - { - std::string filePath; - std::cout << "Enter the file path (without file name) : "; - std::cin >> filePath; - if (false == SimulatorManager::getInstance()->setFileLogger(filePath)) - std::cout << "Failed to set default file logger" << std::endl; - } break; - case 3: SimulatorManager::getInstance()->setLogger(gAppLogger); - } -} - -int main(int argc, char *argv[]) -{ - SimLightResource lightResource; - - printMainMenu(); - bool cont = true; - while (cont == true) - { - int choice = -1; - std::cout << "Enter your choice: "; - std::cin >> choice; - if (choice < 0 || choice > 3) - { - std::cout << "Invaild choice !" << std::endl; continue; - } - - switch (choice) - { - case 1: lightResource.startTest(); - std::cout << "Welcome back to main menu !" << std::endl; - break; - case 2: setLogger(); break; - case 3: printMainMenu(); break; - case 0: cont = false; - } - } - - std::cout << "Terminating test !!!" << std::endl; -} diff --git a/service/simulator/examples/server/simulator_server.cpp b/service/simulator/examples/server/simulator_server.cpp new file mode 100644 index 0000000..56114ce --- /dev/null +++ b/service/simulator/examples/server/simulator_server.cpp @@ -0,0 +1,437 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +#include "simulator_manager.h" + +std::vector g_singleResources; + +std::string getPropertyTypeString(SimulatorResourceModel::AttributeProperty::Type type) +{ + switch(type) + { + case SimulatorResourceModel::AttributeProperty::Type::RANGE: + return "RANGE"; + case SimulatorResourceModel::AttributeProperty::Type::VALUE_SET: + return "VALUE_SET"; + default: + break; + } + + return "UNKNOWN"; +} + +class AppLogger : public ILogger +{ + public: + void write(std::string time, ILogger::Level level, std::string message) + { + std::cout << "[APPLogger] " << time << " " << ILogger::getString(level) << " " + << message; + } +}; +std::shared_ptr gAppLogger(new AppLogger()); + +int selectResource() +{ + if (0 == g_singleResources.size()) + { + std::cout << "No resouces!" << std::endl; + return -1; + } + + int index = 1; + for (auto & resource : g_singleResources) + { + std::cout << index++ << ": " << resource->getURI().c_str() << std::endl; + } + + int choice = -1; + std::cout << "Choose the resource: "; + std::cin >> choice; + + if (choice < 1 || choice > index - 1) + { + std::cout << "Invalid choice !" << std::endl; + choice = -1; + } + + return choice; +} + +void simulateResource() +{ + try + { + // Resource model change callback + SimulatorResource::ResourceModelChangedCallback modelChangeCB = + [](const std::string &uri, SimulatorResourceModel &resModel) + { + std::cout << "[callback] Resource model is changed URI: " << uri.c_str() << std::endl; + std::cout << "#### Modified attributes are ####" << std::endl; + std::cout << "#### Updated resource model ####" << std::endl; + std::cout << resModel.toString() << std::endl; + std::cout << "########################" << std::endl; + }; + + // Observer added/removed callback + SimulatorResource::ObserverCallback observerCB = + [] (const std::string &uri, ObservationStatus state, const ObserverInfo &observerInfo) + { + std::cout << "[callback] Observer notification received..." << uri << std::endl; + + std::ostringstream out; + out << "ID: " << (int) observerInfo.id << std::endl; + out << " [address: " << observerInfo.address << " port: " << observerInfo.port + << "]" << std::endl; + std::cout << out.str(); + }; + + // Get the RAML file path from user + std::string configPath; + std::cout << "Enter RAML path: "; + std::cin>>configPath; + + SimulatorResourceSP resource = + SimulatorManager::getInstance()->createResource(configPath); + + SimulatorSingleResourceSP singleRes = + std::dynamic_pointer_cast(resource); + singleRes->setModelChangeCallback(modelChangeCB); + singleRes->setObserverCallback(observerCB); + + g_singleResources.push_back(singleRes); + + std::cout << "Resource created successfully! URI= " << resource->getURI() << std::endl; + } + catch (InvalidArgsException &e) + { + std::cout << "InvalidArgsException occured [code : " << e.code() << " Detail: " + << e.what() << "]" << std::endl; + } + catch (SimulatorException &e) + { + std::cout << "SimulatorException occured [code : " << e.code() << " Detail: " + << e.what() << "]" << std::endl; + } +} + +void displayResource() +{ + int index = selectResource(); + if (-1 == index) + return; + + SimulatorSingleResourceSP resource = g_singleResources[index - 1]; + + std::cout << "#############################" << std::endl; + std::cout << "Name: " << resource->getName() << std::endl; + std::cout << "URI: " << resource->getURI() << std::endl; + std::cout << "Resource type: " << resource->getResourceType() << std::endl; + std::cout << "Interface type:"; + for (auto &interfaceType : resource->getInterface()) + std::cout << " " << interfaceType; + + // Attributes + SimulatorResourceModel resModel = resource->getResourceModel(); + std::map attributes = + resModel.getAttributes(); + std::cout << "##### Attributes [" << attributes.size() << "]" << std::endl; + for (auto & attribute : attributes) + { + std::cout << (attribute.second).getName() << " : {" << std::endl; + std::cout << "value: " << (attribute.second).toString() << std::endl; + SimulatorResourceModel::AttributeProperty prop = (attribute.second).getProperty(); + std::cout << "Supported values given by : " << getPropertyTypeString(prop.type()) << std::endl; + if (SimulatorResourceModel::AttributeProperty::Type::RANGE == prop.type()) + { + std::cout << "Min: " << prop.min() << std::endl; + std::cout << "Max: " << prop.max() << std::endl; + } + else if (SimulatorResourceModel::AttributeProperty::Type::VALUE_SET == prop.type()) + { + std::cout << "Value set: " << prop.valueSetToString() << std::endl; + } + + std::cout << "}" << std::endl << std::endl; + } + std::cout << "#############################" << std::endl; +} + +void startResource() +{ + int index = selectResource(); + if (-1 == index) + return; + + SimulatorSingleResourceSP resource = g_singleResources[index - 1]; + resource->start(); + std::cout << "Resource started!" << std::endl; +} + +void stopResource() +{ + int index = selectResource(); + if (-1 == index) + return; + + SimulatorSingleResourceSP resource = g_singleResources[index - 1]; + resource->stop(); + std::cout << "Resource stopped!" << std::endl; +} + +void automateResourceUpdate() +{ + updateCompleteCallback callback = [](const std::string &uri, const int id) + { + std::cout << "Update automation is completed [URI: " << uri + << " AutomationID: " << id << "] ###" << std::endl; + }; + + int index = selectResource(); + if (-1 == index) + return; + + AutomationType type = AutomationType::NORMAL; + int choice = 0; + std::cout << "Press 1 if you want recurrent automation: "; + std::cin >> choice; + if (1 == choice) + type = AutomationType::RECURRENT; + + try + { + int id = g_singleResources[index - 1]->startResourceUpdation(type, -1, callback); + + std::cout << "startUpdateAutomation() returned succces : " << id << std::endl; + } + catch (SimulatorException &e) + { + std::cout << "SimulatorException occured [code : " << e.code() << " Detail: " << + e.what() << "]" << std::endl; + } +} + +void automateAttributeUpdate() +{ + updateCompleteCallback callback = [](const std::string &uri, const int id) + { + std::cout << "Update automation is completed [URI: " << uri + << " AutomationID: " << id << "] ###" << std::endl; + }; + + int index = selectResource(); + if (-1 == index) + return; + + SimulatorSingleResourceSP resource = g_singleResources[index - 1]; + SimulatorResourceModel resModel = resource->getResourceModel(); + std::map attributes = + resModel.getAttributes(); + int size = 0; + for (auto & attribute : attributes) + { + std::cout << ++size << ": " << attribute.first.c_str() << std::endl; + } + + if (0 == size) + { + std::cout << "This resource doest not contain any attributes!" << std::endl; + return; + } + + int choice = -1; + std::cout << "Select the attribute which you want to automate for updation: " << + std::endl; + std::cin >> choice; + if (choice < 0 || choice > size) + { + std::cout << "Invalid selection!" << std::endl; + return; + } + + int count = 0; + std::string attributeName; + for (auto & attribute : attributes) + { + if (count == choice - 1) + { + attributeName = attribute.first; + break; + } + + count++; + } + + AutomationType type = AutomationType::NORMAL; + std::cout << "Press 1 if you want recurrent automation: "; + std::cin >> choice; + if (1 == choice) + type = AutomationType::RECURRENT; + + std::cout << "Requesting attribute automation for " << attributeName << + std::endl; + + try + { + + int id = resource->startAttributeUpdation(attributeName, type, -1, callback); + std::cout << "startUpdateAutomation() returned succces : " << id << std::endl; + } + catch (SimulatorException &e) + { + std::cout << "SimulatorException occured [Error: " << e.code() << " Details: " << + e.what() << "]" << std::endl; + } +} + +void stopAutomation() +{ + int index = selectResource(); + if (-1 == index) + return; + + SimulatorSingleResourceSP resource = g_singleResources[index - 1]; + + // Select the automation to stop + std::vector ids; + { + std::vector rids = resource->getResourceUpdationIds(); + std::vector aids = resource->getAttributeUpdationIds(); + ids.insert(ids.end(), rids.begin(), rids.end()); + ids.insert(ids.end(), aids.begin(), aids.end()); + } + + if (!ids.size()) + { + std::cout << "No automation operation is going on this resource right now!" << + std::endl; + return; + } + + for (auto & id : ids) + std::cout << id << " "; + + int automationid; + std::cout << "\nEnter automation id: " << std::endl; + std::cin >> automationid; + resource->stopUpdation(automationid); +} + +void getObservers() +{ + int index = selectResource(); + if (-1 == index) + return; + + SimulatorSingleResourceSP resource = g_singleResources[index - 1]; + + std::vector observersList = resource->getObserversList(); + + std::cout << "##### Number of Observers [" << observersList.size() << "]" << std::endl; + for (auto & observerInfo : observersList) + { + std::cout << " ID : " << (int) observerInfo.id << " [address: " << + observerInfo.address << " port: " << observerInfo.port << "]" << std::endl; + } + std::cout << "########################" << std::endl; +} + +void printMainMenu() +{ + std::cout << "############### MAIN MENU###############" << std::endl; + std::cout << "1. Simulate resource" << std::endl; + std::cout << "2. Display resource information" << std::endl; + std::cout << "3. Start resource" << std::endl; + std::cout << "4. Stop resource" << std::endl; + std::cout << "5. Automate resource update" << std::endl; + std::cout << "6. Automate attributes update" << std::endl; + std::cout << "7. Stop Automation" << std::endl; + std::cout << "8. Get Observers of a resource" << std::endl; + std::cout << "9. Set Logger" << std::endl; + std::cout << "10. Help" << std::endl; + std::cout << "0. Exit" << std::endl; + std::cout << "######################################" << std::endl; +} + +void setLogger() +{ + std::cout << "1. Default console logger" << std::endl; + std::cout << "2. Default file logger" << std::endl; + std::cout << "3. custom logger" << std::endl; + + int choice = -1; + std::cin >> choice; + if (choice <= 0 || choice > 3) + { + std::cout << "Invalid selection !" << std::endl; + return; + } + + switch (choice) + { + case 1: + { + if (false == SimulatorManager::getInstance()->setConsoleLogger()) + std::cout << "Failed to set the default console logger" << std::endl; + } break; + case 2: + { + std::string filePath; + std::cout << "Enter the file path (without file name) : "; + std::cin >> filePath; + if (false == SimulatorManager::getInstance()->setFileLogger(filePath)) + std::cout << "Failed to set default file logger" << std::endl; + } break; + case 3: SimulatorManager::getInstance()->setLogger(gAppLogger); + } +} + +int main(int argc, char *argv[]) +{ + printMainMenu(); + bool cont = true; + while (cont == true) + { + int choice = -1; + std::cout << "Enter your choice: "; + std::cin >> choice; + if (choice < 0 || choice > 10) + { + std::cout << "Invaild choice !" << std::endl; continue; + } + + switch (choice) + { + case 1 : simulateResource(); break; + case 2 : displayResource(); break; + case 3 : startResource(); break; + case 4 : stopResource(); break; + case 5 : automateResourceUpdate(); break; + case 6 : automateAttributeUpdate(); break; + case 7 : stopAutomation(); break; + case 8 : getObservers(); break; + case 9: setLogger(); break; + case 10: printMainMenu(); break; + case 0: cont = false; + } + } + + std::cout << "Terminating test !!!" << std::endl; +} diff --git a/service/simulator/inc/simulator_collection_resource.h b/service/simulator/inc/simulator_collection_resource.h new file mode 100644 index 0000000..88addd0 --- /dev/null +++ b/service/simulator/inc/simulator_collection_resource.h @@ -0,0 +1,68 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +#ifndef SIMULATOR_COLLECTION_RESOURCE_H_ +#define SIMULATOR_COLLECTION_RESOURCE_H_ + +#include "simulator_resource.h" + +class SimulatorCollectionResource : public SimulatorResource +{ + public: + + /** + * API to get list of resources types which collection supports. + * + * @return List of supported resources types. + */ + virtual std::vector getSupportedResources() = 0; + + /** + * API to add a child resource to collection. + * + * @param resource - SimulatorResource shared object. + */ + virtual void addChildResource(SimulatorResourceSP &resource) = 0; + + /** + * API to remove a child resource from collection. + * + * @param resource - SimulatorResource shared object. + */ + virtual void removeChildResource(SimulatorResourceSP &resource) = 0; + + /** + * API to remove a child resource from collection. + * + * @param uri - URI of child resource to be removed. + */ + virtual void removeChildResource(const std::string &uri) = 0; + + /** + * API to get child resources of collection. + * + * @return List of child resources of collection. + */ + virtual std::vector getChildResources() = 0; +}; + +typedef std::shared_ptr SimulatorCollectionResourceSP; + +#endif diff --git a/service/simulator/inc/simulator_manager.h b/service/simulator/inc/simulator_manager.h index 662ea3e..5b3d76e 100644 --- a/service/simulator/inc/simulator_manager.h +++ b/service/simulator/inc/simulator_manager.h @@ -32,7 +32,8 @@ #include "simulator_client_types.h" #include "simulator_device_info.h" #include "simulator_platform_info.h" -#include "simulator_resource_server.h" +#include "simulator_single_resource.h" +#include "simulator_collection_resource.h" #include "simulator_remote_resource.h" #include "simulator_exceptions.h" #include "simulator_logger.h" @@ -57,15 +58,13 @@ class SimulatorManager * RAML file. * * @param configPath - RAML configuration file path. - * @param callback - Callback method for receiving notifications when resource model changes. * - * @return SimulatorResourceServer shared object representing simulated/created resource. + * @return SimulatorResource shared object representing simulated/created resource. * * NOTE: API would throw @InvalidArgsException when invalid arguments passed, and * @SimulatorException if any other error occured. */ - std::shared_ptr createResource(const std::string &configPath, - SimulatorResourceServer::ResourceModelChangedCB callback); + std::shared_ptr createResource(const std::string &configPath); /** * This method is for creating multiple resources of same type based on the input data @@ -75,45 +74,20 @@ class SimulatorManager * @param count - Number of resource to be created. * @param callback - Callback method for receiving notifications when resource model changes. * - * @return vector of SimulatorResourceServer shared objects representing simulated/created + * @return vector of SimulatorResource shared objects representing simulated/created * resources. * * NOTE: API would throw @InvalidArgsException when invalid arguments passed, and * @SimulatorException if any other error occured. */ - std::vector> createResource( - const std::string &configPath, unsigned short count, - SimulatorResourceServer::ResourceModelChangedCB callback); - - /** - * This method is for obtaining a list of created resources. - * - * @param resourceType - Resource type. Empty value will fetch all resources. - * Default value is empty string. - * - * @return vector of SimulatorResourceServer shared objects representing simulated/created - */ - std::vector> getResources( - const std::string &resourceType = ""); + std::vector> createResource( + const std::string &configPath, unsigned int count); - /** - * This method is for deleting/unregistering resource. - * - * @param resource - SimulatorResourceServer shared object. - * - * NOTE: API would throw @InvalidArgsException when invalid arguments passed - */ - void deleteResource(const std::shared_ptr &resource); + std::shared_ptr createSingleResource( + const std::string &name, const std::string &uri, const std::string &resourceType); - /** - * This method is for deleting multiple resources based on resource type. - * - * @param resourceType - Resource type. Empty value will delete all the resources. - * Default value is empty string. - * - * NOTE: API would throw @InvalidArgsException when invalid arguments passed - */ - void deleteResource(const std::string &resourceType = ""); + std::shared_ptr createCollectionResource( + const std::string &name, const std::string &uri, const std::string &resourceType); /** * API for discovering all type of resources. diff --git a/service/simulator/inc/simulator_remote_resource.h b/service/simulator/inc/simulator_remote_resource.h index 5388bcc..917b6ac 100644 --- a/service/simulator/inc/simulator_remote_resource.h +++ b/service/simulator/inc/simulator_remote_resource.h @@ -30,12 +30,14 @@ #include "simulator_client_types.h" #include "simulator_resource_model.h" +#include "simulator_uncopyable.h" +#include "simulator_exceptions.h" /** * @class SimulatorRemoteResource * @brief This class provides a set of functions for the client to hande the resources currently running on the servers. */ -class SimulatorRemoteResource +class SimulatorRemoteResource : public UnCopyable { public: @@ -150,7 +152,7 @@ class SimulatorRemoteResource virtual void stopVerification(int id) = 0; - virtual void configure(const std::string &path) = 0; + virtual SimulatorResourceModelSP configure(const std::string &path) = 0; }; typedef std::shared_ptr SimulatorRemoteResourceSP; diff --git a/service/simulator/inc/simulator_resource.h b/service/simulator/inc/simulator_resource.h new file mode 100644 index 0000000..074a308 --- /dev/null +++ b/service/simulator/inc/simulator_resource.h @@ -0,0 +1,200 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +#ifndef SIMULATOR_RESOURCE_H_ +#define SIMULATOR_RESOURCE_H_ + +#include "simulator_server_types.h" +#include "simulator_resource_model.h" +#include "simulator_uncopyable.h" +#include "simulator_exceptions.h" + +class SimulatorResource : public UnCopyable +{ + public: + enum class Type + { + SINGLE_RESOURCE, + COLLECTION_RESOURCE + }; + + /** + * Callback method for receiving notifications when resource representation model changes. + * + * @param uri - URI of resource whose representation model got changed. + * @param resModel - Resource model. + */ + typedef std::function + ResourceModelChangedCallback; + + /** + * Callback method for receiving notifications when observer is registered/unregistered + * with resource. + * + * @param uri - Resource URI + * @param state - OBSERVE_REGISTER if observer is registered, otherwise OBSERVE_UNREGISTER. + * @param observerInfo - Information about observer. + */ + typedef std::function + ObserverCallback; + + /** + * API to get the name of the resource. + * + * @return Resource name. + */ + virtual std::string getName() const = 0; + + /** + * API to get the type which indicates whether resource is single or collection resource. + * + * @return Type of resource. + */ + virtual SimulatorResource::Type getType() const = 0; + + /** + * API to get the resource URI. + * + * @return Resource URI. + */ + virtual std::string getURI() const = 0; + + /** + * API to get the resource type. + * + * @return Resource type. + */ + virtual std::string getResourceType() const = 0; + + /** + * API to get the interfaces resource is bound with. + * + * @return Interface type. + */ + virtual std::vector getInterface() const = 0; + + /** + * API to set the name of the resource. + * + * @param name - Name to be set. + * + * NOTE: API throws @InvalidArgsException, @SimulatorException exceptions. + */ + virtual void setName(const std::string &name) = 0; + + /** + * API to set the resource URI. + * + * @param uri - URI to be set. + * + * NOTE: API throws @InvalidArgsException, @SimulatorException exceptions. + */ + virtual void setURI(const std::string &uri) = 0; + + /** + * API to set the resource type. + * + * @param resourceType - resource type string. + * + * NOTE: API throws @InvalidArgsException, @SimulatorException exceptions. + */ + virtual void setResourceType(const std::string &resourceType) = 0; + + /** + * API to add interface type for resource. + * + * @param interfaceType - interface to be added for resource. + * + * NOTE: API throws @InvalidArgsException, @SimulatorException exceptions. + */ + virtual void addInterface(std::string interfaceType) = 0; + + /** + * API to make the resource observable or not. + * + * @param state - true make the resource observable, otherwise non-observable. + * + * NOTE: API throws @SimulatorException exceptions. + */ + virtual void setObservable(bool state) = 0; + + /** + * API to set the callback for receiving the notifications when + * observer is registered or unregistered with resource. + * + * @param callback - Callback to be set for receiving the notifications. + */ + virtual void setObserverCallback(ObserverCallback callback) = 0; + + /** + * API to get the observable state of resource. + * + * @return bool - true if resource is observable, otherwise false. + */ + virtual bool isObservable() = 0; + + /** + * API to get the start state of resource. + * + * @return bool - true if resource is started, otherwise false. + */ + virtual bool isStarted() = 0; + + /** + * API to start the resource. + * + * NOTE: API throws @SimulatorException exception. + */ + virtual void start() = 0; + + /** + * API to stop the resource. + * + * NOTE: API throws @SimulatorException exception. + */ + virtual void stop() = 0; + + /** + * API to get observers which are registered with resource. + * + * @return vector of ObserverInfo. + */ + virtual std::vector getObserversList() = 0; + + /** + * API to notify current resource model to specific observer. + * + * @param id - Observer ID to notify. + * + * NOTE: API throws @SimulatorException exception. + */ + virtual void notify(int id) = 0; + + /** + * API to notify all registered observers. + * + * NOTE: API throws @SimulatorException exception. + */ + virtual void notifyAll() = 0; +}; + +typedef std::shared_ptr SimulatorResourceSP; + +#endif diff --git a/service/simulator/inc/simulator_resource_model.h b/service/simulator/inc/simulator_resource_model.h index d596ed9..5ea64c0 100644 --- a/service/simulator/inc/simulator_resource_model.h +++ b/service/simulator/inc/simulator_resource_model.h @@ -28,10 +28,11 @@ #ifndef SIMULATOR_RESOURCE_MODEL_H_ #define SIMULATOR_RESOURCE_MODEL_H_ -#include -#include #include "OCPlatform.h" -#include +#include + +class OCRepresentationBuilder; +class ToStringConverter; /** * @class SimulatorResourceModel @@ -40,300 +41,212 @@ class SimulatorResourceModel { public: - SimulatorResourceModel() = default; - SimulatorResourceModel(const SimulatorResourceModel &) = default; - SimulatorResourceModel &operator=(const SimulatorResourceModel &) = default; - SimulatorResourceModel(SimulatorResourceModel &&) = default; - SimulatorResourceModel &operator=(SimulatorResourceModel && ) = default; + friend class OCRepresentationBuilder; + friend class ToStringConverter; + + typedef boost::variant < + int, + double, + bool, + std::string, + SimulatorResourceModel, + + std::vector, + std::vector, + std::vector, + std::vector, + std::vector, + + std::vector>, + std::vector>, + std::vector>, + std::vector>, + std::vector>, + + std::vector>>, + std::vector>>, + std::vector>>, + std::vector>>, + std::vector>> + > ValueVariant; + + enum class ValueType + { + UNKNOWN, + INTEGER, + DOUBLE, + BOOLEAN, + STRING, + RESOURCE_MODEL, + VECTOR + }; - /** - * @class Attribute - * @brief This class represents a resource attribute whose values can be generic. - */ - class Attribute + class TypeInfo { public: - typedef boost::variant < - int, - double, - bool, - std::string - > ValueVariant; - - enum class ValueType + TypeInfo(ValueType, ValueType, int); + TypeInfo(const TypeInfo &) = default; + TypeInfo &operator=(const TypeInfo &) = default; + TypeInfo(TypeInfo &&) = default; + TypeInfo &operator=(TypeInfo &&) = default; + + ValueType type() const; + ValueType baseType() const; + int depth() const; + bool operator ==(const TypeInfo &) const; + bool operator !=(const TypeInfo &) const; + + private: + ValueType m_type; + ValueType m_baseType; + int m_depth; + }; + + class AttributeProperty + { + public: + enum class Type { UNKNOWN, - INTEGER, - DOUBLE, - BOOLEAN, - STRING + RANGE, + VALUE_SET }; - Attribute() - { - m_min = INT_MIN; - m_max = INT_MAX; - m_updateInterval = -1; - } + AttributeProperty(); + AttributeProperty(const AttributeProperty &) = default; + AttributeProperty &operator=(const AttributeProperty &) = default; + AttributeProperty(AttributeProperty &&) = default; + AttributeProperty &operator=(AttributeProperty &&) = default; + + explicit AttributeProperty(int min, int max); + explicit AttributeProperty(const std::vector &valueSet); + explicit AttributeProperty(const std::vector &valueSet); + explicit AttributeProperty(const std::vector &valueSet); + explicit AttributeProperty(const std::vector &valueSet); + explicit AttributeProperty(const std::vector &valueSet); + + Type type() const; + int min() const; + int max() const; + int valueSetSize() const; + std::vector valueSet() const; + std::string valueSetToString() const; - Attribute(const std::string &attrName) - { - m_name = attrName; - m_min = INT_MIN; - m_max = INT_MAX; - m_updateInterval = -1; - } + private: + Type m_type; + int m_min; + int m_max; + std::vector m_valueSet; + }; - /** - * API to get attribute's name. - * - * @return Attribute name. - */ - std::string getName(void) const; - - /** - * API to set the name of attribute. - * - * @param name - Attribute name. - */ - void setName(const std::string &name); - - /** - * API to get attribute's value. - * - * @return value of attribute. - */ - template - T getValue() const - { - T val = T(); - return boost::get(m_value); - } + class Attribute + { + public: + Attribute(const std::string &name) : m_name(name) {} + Attribute() = default; + Attribute(const Attribute &) = default; + Attribute &operator=(const Attribute &) = default; + Attribute(Attribute &&) = default; + Attribute &operator=(Attribute &&) = default; - /** - * API to get attribute's value. - * - * @return value of attribute as ValueVariant. - */ - ValueVariant &getValue() - { - return m_value; - } + std::string getName() const; + TypeInfo getType() const; + const AttributeProperty &getProperty() const; + AttributeProperty &getProperty(); - /** - * API to get attribute's value type. - * - * @return ValueType enum. - */ - ValueType getValueType() const; - - /** - * API to set the attribute's value. - * - * @param value - value to be set. - */ - template - void setValue(const T &value) - { - m_value = value; - } + void setName(const std::string &); + void setProperty(const AttributeProperty &); - /** - * API to set the attribute's value from allowed values container. - * - * @param allowedValueIndex - Index of value to be set from allowed vaules container. - */ - void setFromAllowedValue(unsigned int index); - - /** - * API to get range of attribute's value. - */ - void getRange(int &min, int &max) const; - - /** - * API to set range of attribute's value. - * - * @param min - minimum value could be set as attribute value. - * @param max - maximum value could be set as attribute value. - */ - void setRange(const int &min, const int &max); - - /** - * API to set the values to allowed values set. - * - * @param values - vector of values which will be set as allowed values. - */ template - bool setAllowedValues(const std::vector &values) + void setValue(const T &value) { - ValueVariant temp = values.at(0); - if (temp.which() != m_value.which()) - { - return false; - } - - m_allowedValues.addValues(values); - return true; + m_value = std::make_shared(value); } - /** - * API to get the number of values present in allowed values set. - * - * @return Size of the allowed values. - */ - int getAllowedValuesSize() const; + ValueVariant getValue() const { return *m_value; } - /** - * API to get the string representation of the value. - * - * @return Attribute's value as a string. - */ - std::string valueToString() const; - - /** - * API to get the string representation of all the allowed values. - * - * @return All allowed values as a string. - */ - std::vector allowedValuesToString() const; - - void addValuetoRepresentation(OC::OCRepresentation &rep, - const std::string &key) const; - - bool compare(Attribute &attribute); - - std::vector getAllowedValues() const; - - int getUpdateFrequencyTime() {return m_updateInterval;} - void setUpdateFrequencyTime(int interval) {m_updateInterval = interval;} + std::string toString() const; private: - class AllowedValues - { - public: - template - void addValue(const T &value) - { - ValueVariant temp = value; - m_values.push_back(temp); - } - - template - void addValues(const std::vector &values) - { - for (auto value : values) - { - ValueVariant vValue = value; - m_values.push_back(vValue); - } - } - - ValueVariant &at(unsigned int index); - int size() const; - std::vector toString() const; - std::vector getValues() const; - private: - std::vector m_values; - }; - std::string m_name; - ValueVariant m_value; - int m_max; - int m_min; - AllowedValues m_allowedValues; - int m_updateInterval; + std::shared_ptr m_value; + AttributeProperty m_property; }; - /** - * API to get the number of attributes in the resource model. - * - * @return Number of attributes. - */ - int size() const { return m_attributes.size(); } - - /** - * API to get the value of an attribute. - * - * @param attrName - Attribute name - * @param value - Attribute value - * - * @return true if attribute exists, otherwise false. - */ - bool getAttribute(const std::string &attrName, Attribute &value); - - /** - * API to get the entire list of attributes in the form of key-value pair. - * Attribute name is the key and an instance of Attribute is the value. - * - * @return A map of all the attributes - */ - std::map getAttributes() const; - - /** - * API to add new attribute to resource model. - * - * @param attrName - Attribute name - * @param attrValue - Attribute value - */ + SimulatorResourceModel() = default; + SimulatorResourceModel(const SimulatorResourceModel &) = default; + SimulatorResourceModel &operator=(const SimulatorResourceModel &) = default; + SimulatorResourceModel(SimulatorResourceModel &&) = default; + SimulatorResourceModel &operator=(SimulatorResourceModel && ) = default; + template - void addAttribute(const std::string &attrName, const T &attrValue) + bool add(const std::string &key, T value) { - if (m_attributes.end() == m_attributes.find(attrName)) - { - m_attributes[attrName] = Attribute(attrName); - m_attributes[attrName].setValue(attrValue); - } + ValueVariant newValue = value; + return setAttributeValue(key, newValue, true, false); } - /** - * API to add new attribute to resource model. - * - * @param attr - Attribute pointer - * - */ - void addAttribute(const Attribute &attribute, bool overwrite = false); - - /** - * API to set range of attribute value. - * - * @param attrName - Attribute name. - * @param min - Minimum value could be set as attribute value. - * @param max - Maximum value could be set as attribute value. - */ - void setRange(const std::string &attrName, const int min, const int max); - - OC::OCRepresentation getOCRepresentation() const; - static std::shared_ptr create(const OC::OCRepresentation &ocRep); + bool add(const Attribute &attribute); template - void setAllowedValues(const std::string &attrName, const std::vector &values) + T get(const std::string &key) const { - if (m_attributes.end() != m_attributes.find(attrName)) - m_attributes[attrName].setAllowedValues(values); + T val = T(); + auto x = m_attributes.find(key); + if (x != m_attributes.end()) + { + val = boost::get(x->second); + } + return val; } - bool update(OC::OCRepresentation &ocRep); - - bool update(std::shared_ptr &repModel); - template - void updateAttribute(const std::string &attrName, const T &value) + bool updateValue(const std::string &key, T value, bool forcewrite = false) { - if (m_attributes.end() != m_attributes.find(attrName)) - m_attributes[attrName].setValue(value); + ValueVariant newValue = value; + return setAttributeValue(key, newValue, false, forcewrite); } - void updateAttributeFromAllowedValues(const std::string &attrName, unsigned int index); + bool updateValue(const Attribute &attribute, bool forcewrite = false); + + bool containsAttribute(const std::string &key); + + bool setAttributeProperty(const std::string &key, const AttributeProperty &property); + + bool getAttributeProperty(const std::string &key, AttributeProperty &property); + + int size() const; + + TypeInfo getType(const std::string &key); + + std::map getAttributes(); + + bool getAttribute(const std::string &key, Attribute &attribute); + + bool removeAttribute(const std::string &key); + + bool update(OC::OCRepresentation &ocRep); + + OC::OCRepresentation getOCRepresentation(); + + bool match(const SimulatorResourceModel &resModel, bool strict = false); - void removeAttribute(const std::string &attrName); + std::string toString() const; - void setUpdateInterval(const std::string &attrName, int interval); + static SimulatorResourceModel build(const OC::OCRepresentation &ocRep); private: - std::map m_attributes; + TypeInfo getTypeInfo(const ValueVariant &value) const; + bool setAttributeValue(const std::string &key, const ValueVariant &newValue, + bool create, bool overwrite); + bool match(const std::string &key, const ValueVariant &newValue); + bool update(SimulatorResourceModel &resModel); + std::map getValues() const; + + std::map m_attributes; + std::map m_attrProperties; }; typedef std::shared_ptr SimulatorResourceModelSP; -typedef std::shared_ptr AttributeSP; #endif diff --git a/service/simulator/inc/simulator_resource_server.h b/service/simulator/inc/simulator_resource_server.h deleted file mode 100644 index b6f61a1..0000000 --- a/service/simulator/inc/simulator_resource_server.h +++ /dev/null @@ -1,290 +0,0 @@ -/****************************************************************** - * - * Copyright 2015 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -/** - * @file simulator_resource_server.h - * - * @brief This file contains a class which represents a simulator resource that provides a set - * of functions for operating a resource and performing automation on attribute values. - */ - -#ifndef SIMULATOR_RESOURCE_SERVER_H_ -#define SIMULATOR_RESOURCE_SERVER_H_ - -#include "simulator_server_types.h" -#include "simulator_resource_model.h" -#include "simulator_exceptions.h" - -enum class ObservationStatus : unsigned char -{ - OBSERVE_REGISTER, - OBSERVE_UNREGISTER -}; - -typedef struct -{ - uint8_t id; - std::string address; - uint16_t port; -} ObserverInfo; - -/** - * @class SimulatorResourceServer - * @brief This class provides a set of functions for operating and automating a resource. - */ -class SimulatorResourceServer -{ - public: - /** - * Callback method for receiving notifications when resource model gets changed. - * - * @param uri - Resource URI - * @param resModel - Resource model - */ - typedef std::function - ResourceModelChangedCB; - - /** - * Callback method for receiving notifications when observer is registered/unregistered - * with resource. - * - * @param uri - Resource URI - * @param state - OBSERVE_REGISTER if observer is registered, otherwise OBSERVE_UNREGISTER. - * @param observerInfo - Information about observer. - */ - typedef std::function - ObserverCB; - - SimulatorResourceServer(); - - virtual ~SimulatorResourceServer() {}; - - /** - * API to get the resource URI. - * - * @return Resource URI - */ - std::string getURI() const; - - /** - * API to get the resource URI. - * - * @return Resource Type - */ - std::string getResourceType() const; - - /** - * API to get the interface type of the resource. - * - * @return Interface type of the resource - */ - std::string getInterfaceType() const; - - /** - * API to get the name of the resource. - * - * @return Resource name - */ - std::string getName() const; - - /** - * API to add a new attribute to the resource model. - * - * @param attribute - Attribute to be add to model. - */ - void addAttribute(SimulatorResourceModel::Attribute &attribute); - - /** - * API to set the value range of an attribute. - * This method is intended to be used for attributes whose values are numbers only. - * - * @param attrName - Name of the attribute - * @param min - Minimum value of the range - * @param max - Maximum value of the range - */ - void setRange(const std::string &attrName, const int min, const int max); - - /** - * API to set the allowed values of an attribute. - * - * @param attrName - Name of the attribute - * @param values - Allowed values - */ - template - void setAllowedValues(const std::string &attrName, const std::vector &values) - { - m_resModel.setAllowedValues(attrName, values); - } - - /** - * API to set the update interval time for automation. - * - * @param attrName - Name of the attribute - * @param interval - Interval time in miliseconds for attribute value update automation - */ - void setUpdateInterval(const std::string &attrName, int interval); - - /** - * API to update the value of an attribute. - * - * @param attrName - Name of the attribute - * @param value - Value of the attribute - */ - template - void updateAttributeValue(const std::string &attrName, const T &value) - { - m_resModel.updateAttribute(attrName, value); - - // Notify all the subscribers - notifyAll(); - } - - /** - * API to update the attribute's value by taking the index of the value - * in the allowed values range. - * - * @param attrName - Name of the attribute - * @param allowedValueIndex - Index of the value in the allowed values range - */ - void updateFromAllowedValues(const std::string &attrName, unsigned int index); - - /** - * API to remove an attribute from the resource model. - * - * @param attName - Name of the attribute to be removed - */ - void removeAttribute(const std::string &attName); - - /** - * API to get the object of SimulatorResourceModel. - * Attributes of the resource are accessed using this object. - * - * @return Resource model of the resource. - */ - SimulatorResourceModel getModel() const; - - /** - * API to get the observable state of resource. - * - * @return bool - true if resource is observable, otherwise false. - */ - virtual bool isObservable() const = 0; - - /** - * API to start the attribute value automation for all attributes. - * Once started, values for the attributes will be selected randomly from their allowed range - * and the updated values will be notified to all the observers of the resource. - * - * @param type - Automation type. - * @param callback - Callback to get notifiy when update automation is finished. - * @param id - Identifier for automation. - * - * @return ID representing update automation session. - * NOTE: API throws @InvalidArgsException, @SimulatorException exceptions. - */ - virtual int startUpdateAutomation(AutomationType type, int updateInterval, - updateCompleteCallback callback) = 0; - - /** - * This method is used to start the attribute value automation for a specific attribute. - * Once started, values for the attribute will be selected randomly from its allowed range - * and the updated value will be notified to all the observers of the resource. - * - * @param attrName - Name of the attribute to be automated. - * @param type - Automation type. - * @param updateInterval -Interval time in milliseconds for attribute value update automation. - * @param callback - Callback to get notifiy when update automation is finished. - * @param id - Identifier for automation. - * - * @return ID representing update automation session. - * NOTE: API throws @InvalidArgsException, @SimulatorException exceptions. - */ - virtual int startUpdateAutomation(const std::string &attrName, AutomationType type, - int updateInterval, updateCompleteCallback callback) = 0; - - /** - * API to get the Ids of all ongoing resource update automation . - * - * @return vector of resource automation ids. - */ - virtual std::vector getResourceAutomationIds() = 0; - - /** - * API to get the Ids of all ongoing attribute update automation . - * - * @return vector of attribute automation ids. - */ - virtual std::vector getAttributeAutomationIds() = 0; - - /** - * API to stop the resource/attribute automation. - * - * @param id - Identifier for automation. - */ - virtual void stopUpdateAutomation(const int id) = 0; - - /** - * API to set the callback for receiving the notifications when the - * resource model changes. - * - * @param callback - Callback to be set for receiving the notifications. - */ - virtual void setModelChangeCallback(ResourceModelChangedCB callback) = 0; - - /** - * API to set the callback for receiving the notifications when - * observer is registered or unregistered with resource. - * - * @param callback - Callback to be set for receiving the notifications. - */ - virtual void setObserverCallback(ObserverCB callback) = 0; - - /** - * API to get observers which are registered with resource. - * - * @return vector of ObserverInfo. - */ - virtual std::vector getObserversList() = 0; - - /** - * API to notify current resource model to specific observer. - * - * NOTE: API throws @SimulatorException exception. - */ - virtual void notify(uint8_t id) = 0; - - /** - * API to notify all registered observers. - * - * NOTE: API throws @SimulatorException exception. - */ - virtual void notifyAll() = 0; - - protected: - std::string m_name; - std::string m_uri; - std::string m_resourceType; - std::string m_interfaceType; - SimulatorResourceModel m_resModel; -}; - -typedef std::shared_ptr SimulatorResourceServerSP; - -#endif diff --git a/service/simulator/inc/simulator_server_types.h b/service/simulator/inc/simulator_server_types.h index 2449d0a..9d92977 100644 --- a/service/simulator/inc/simulator_server_types.h +++ b/service/simulator/inc/simulator_server_types.h @@ -24,6 +24,19 @@ #include #include +enum class ObservationStatus +{ + REGISTER, + UNREGISTER +}; + +typedef struct +{ + uint8_t id; + std::string address; + uint16_t port; +} ObserverInfo; + enum class AutomationType { NORMAL, diff --git a/service/simulator/inc/simulator_single_resource.h b/service/simulator/inc/simulator_single_resource.h new file mode 100644 index 0000000..6025f88 --- /dev/null +++ b/service/simulator/inc/simulator_single_resource.h @@ -0,0 +1,197 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file simulator_single_resource.h + * + * @brief This file contains a class which represents a simulator resource that provides a set + * of functions for operating a resource and performing automation on attribute values. + */ + +#ifndef SIMULATOR_SINGLE_RESOURCE_H_ +#define SIMULATOR_SINGLE_RESOURCE_H_ + +#include "simulator_resource.h" + +/** + * @class SimulatorSingleResource + * @brief This class provides a set of APIs for handling simulated resource. + */ +class SimulatorSingleResource : public SimulatorResource +{ + public: + + /** + * API to get attribute from resource's resource model. + * + * @param attrName - Attribute's name. + * @param attribute - A attribute of resource's resource model. + * + * @return bool - true on success, otherwise false. + */ + virtual bool getAttribute(const std::string &attrName, + SimulatorResourceModel::Attribute &attribute) = 0; + + /** + * API to add a new attribute to the resource model. + * + * @param attribute - Attribute to be add to model. + * @param notify - If value is true then notification will be send to observers on success. + * This flag is set to true by default. + * + * NOTE: API throws @SimulatorException exceptions on failure. + */ + virtual void addAttribute(const SimulatorResourceModel::Attribute &attribute, + bool notify = true) = 0; + + /** + * API to get property of attribute's value. + * + * @param attrName - Attribute's name. + * @param property - Property which was set to attribute's value. + * + * @return bool - true on success, otherwise false. + */ + virtual bool getAttributeProperty(const std::string &attrName, + SimulatorResourceModel::AttributeProperty &property) = 0; + + /** + * API to set property of attribute's value. + * + * @param attrName - Attribute's name. + * @param property - Property to be set for attribute's value. + * + * @return bool - true on success, otherwise false. + */ + virtual bool setAttributeProperty(const std::string &attrName, + const SimulatorResourceModel::AttributeProperty &property) = 0; + + /** + * API to remove an attribute from the resource model. + * + * @param attrName - Name of the attribute to be removed. + * @param notify - If value is true then notification will be send to observers on success. + * This flag is set to true by default. + * + * @return bool - true on success, otherwise false. + */ + virtual bool removeAttribute(const std::string &attrName, bool notify = true) = 0; + + /** + * API to update the value of an attribute. + * + * @param attrName - Name of the attribute. + * @param value - Value of the attribute. + * @param notify - If value is true then notification will be send to observers on success. + * This flag is set to true by default. + */ + template + bool updateAttributeValue(const std::string &attrName, const T &value, bool notify = true) + { + SimulatorResourceModel::Attribute attribute(attrName); + attribute.setValue(value); + return updateAttributeValue(attribute, notify); + } + + /** + * API to update the value of an attribute. + * + * @param attribute - A resource model attribute. + * @param notify - If value is true then notification will be send to observers on success. + * This flag is set to true by default. + * + * @return bool - true on success, otherwise false. + */ + virtual bool updateAttributeValue(const SimulatorResourceModel::Attribute &attribute, + bool notify = true) = 0; + + /** + * API to get SimulatorResourceModel of resource. + * + * @return Resource model of the resource. + */ + virtual SimulatorResourceModel getResourceModel() = 0; + + /** + * API to set the callback for receiving the notifications when the + * resource model changes. + * + * @param callback - Callback to be set for receiving the notifications. + */ + virtual void setModelChangeCallback(ResourceModelChangedCallback callback) = 0; + + /** + * API to start the attribute value update automation for all attributes. + * Values for the attributes will be selected from their allowed range + * and the updated resource model will be notified to all the observers of the resource. + * + * @param type - Automation type. + * @param updateInterval - Time in milliseconds to be set as interval between updating + * attribute values. + * @param callback - Callback to get notifiy when update automation is finished. + * + * @return ID representing update automation session. + * NOTE: API throws @InvalidArgsException, @SimulatorException exceptions. + */ + virtual int startResourceUpdation(AutomationType type, int updateInterval, + updateCompleteCallback callback) = 0; + + /** + * This method is used to start the attribute value update automation for + * specific attribute. Values for the attribute will be selected from its allowed range + * and the updated resource model will be notified to all the observers of the resource. + * + * @param attrName - Name of the attribute to be automated. + * @param type - Automation type. + * @param updateInterval - Time in milliseconds to be set as interval between updating + * attribute values. + * @param callback - Callback to get notifiy when update automation is finished. + * + * @return ID representing update automation session. + * NOTE: API throws @InvalidArgsException, @SimulatorException exceptions. + */ + virtual int startAttributeUpdation(const std::string &attrName, AutomationType type, + int updateInterval, updateCompleteCallback callback) = 0; + + /** + * API to get the Ids of all ongoing resource update automation . + * + * @return vector of resource automation ids. + */ + virtual std::vector getResourceUpdationIds() = 0; + + /** + * API to get the Ids of all ongoing attribute update automation . + * + * @return vector of attribute automation ids. + */ + virtual std::vector getAttributeUpdationIds() = 0; + + /** + * API to stop the resource/attribute automation. + * + * @param id - Identifier for automation. + */ + virtual void stopUpdation(int id) = 0; +}; + +typedef std::shared_ptr SimulatorSingleResourceSP; + +#endif diff --git a/service/simulator/src/service-provider/simulator_resource_creator.h b/service/simulator/inc/simulator_uncopyable.h similarity index 69% rename from service/simulator/src/service-provider/simulator_resource_creator.h rename to service/simulator/inc/simulator_uncopyable.h index 7a9a87d..7d87e38 100644 --- a/service/simulator/src/service-provider/simulator_resource_creator.h +++ b/service/simulator/inc/simulator_uncopyable.h @@ -18,19 +18,16 @@ * ******************************************************************/ -#ifndef SIMULATOR_RESOURCE_CREATOR_H_ -#define SIMULATOR_RESOURCE_CREATOR_H_ +#ifndef SIMULATOR_UNCOPYABLE_H_ +#define SIMULATOR_UNCOPYABLE_H_ -#include "simulator_resource_server_impl.h" - -class SimulatorResourceCreator +class UnCopyable { public: - SimulatorResourceServerImplSP createResource(const std::string &configPath); - - private: - std::string constructURI(const std::string &uri); - static unsigned int s_id; + UnCopyable() = default; + UnCopyable(const UnCopyable &) = delete; + UnCopyable &operator=(const UnCopyable &) = delete; + virtual ~UnCopyable() {}; }; #endif diff --git a/service/simulator/src/client-controller/simulator_client.cpp b/service/simulator/src/client-controller/simulator_client.cpp deleted file mode 100644 index 71645c9..0000000 --- a/service/simulator/src/client-controller/simulator_client.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/****************************************************************** - * - * Copyright 2015 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -#include "simulator_client.h" -#include "simulator_remote_resource_impl.h" -#include "simulator_logger.h" -#include "simulator_utils.h" -#include "logger.h" - -#define TAG "SIMULATOR_CLIENT" - -SimulatorClient *SimulatorClient::getInstance() -{ - static SimulatorClient s_instance; - return &s_instance; -} - -void SimulatorClient::findResources(ResourceFindCallback callback) -{ - if (!callback) - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - - typedef OCStackResult (*FindResource)(const std::string &, const std::string &, - OCConnectivityType, OC::FindCallback); - - invokeocplatform(static_cast(OC::OCPlatform::findResource), "", - OC_MULTICAST_DISCOVERY_URI, - CT_DEFAULT, - static_cast(std::bind(&SimulatorClient::onResourceFound, this, - std::placeholders::_1, callback))); -} - -void SimulatorClient::findResources(const std::string &resourceType, - ResourceFindCallback callback) -{ - if (resourceType.empty()) - throw InvalidArgsException(SIMULATOR_INVALID_TYPE, "resource type is empty!"); - - if (!callback) - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - - std::ostringstream query; - query << OC_MULTICAST_DISCOVERY_URI << "?rt=" << resourceType; - - typedef OCStackResult (*FindResource)(const std::string &, const std::string &, - OCConnectivityType, OC::FindCallback); - - invokeocplatform(static_cast(OC::OCPlatform::findResource), "", query.str(), - CT_DEFAULT, - static_cast(std::bind(&SimulatorClient::onResourceFound, - this, std::placeholders::_1, callback))); -} - -void SimulatorClient::onResourceFound(std::shared_ptr ocResource, - ResourceFindCallback callback) -{ - if (!ocResource) - { - OC_LOG(ERROR, TAG, "Invalid OCResource !"); - return; - } - - // Construct SimulatorRemoteResource - SimulatorRemoteResourceSP simulatorResource = - std::make_shared(ocResource); - if (!simulatorResource) - { - OC_LOG(ERROR, TAG, "Failed to create simulator remote resource !"); - return; - } - - OC_LOG(DEBUG, TAG, "Invoking resource found client callback !"); - callback(simulatorResource); -} - - diff --git a/service/simulator/src/client-controller/simulator_client.h b/service/simulator/src/client-controller/simulator_client.h deleted file mode 100644 index ed669b3..0000000 --- a/service/simulator/src/client-controller/simulator_client.h +++ /dev/null @@ -1,87 +0,0 @@ -/****************************************************************** - * - * Copyright 2015 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -/** - * @file simulator_client.h - * - * @brief This file provides a class for realizing simulator client functionality. - * - */ - -#ifndef SIMULATOR_CLIENT_H_ -#define SIMULATOR_CLIENT_H_ - -#include "simulator_client_types.h" -#include "simulator_remote_resource.h" -#include "simulator_exceptions.h" - -/** - * @class SimulatorClient - * @brief This class provides a set of functions for discovering the resources over the network. - */ -class SimulatorClient -{ - public: - - /** - * API for getting singleton instance of SimulatorClient class. - * - * @return Singleton instance of SimulatorClient class. - * - */ - static SimulatorClient *getInstance(void); - - /** - * API for discovering all type of resources. - * Discovered resources will be notified through the callback set using @callback parameter. - * - * @param callback - Method of type @ResourceFindCallback through which discoverd resources - * will be notified. - * - * NOTE: API throws @InvalidArgsException and @SimulatorException. - */ - void findResources(ResourceFindCallback callback); - - /** - * API for discovering resources of a particular resource type. - * Discovered resources will be notified through the callback set using @callback parameter. - * - * @param resourceType - Type of resource to be searched for - * @param callback - Method of type @ResourceFindCallback through which discoverd resources - * will be notified. - * - * NOTE: API throws @InvalidArgsException and @SimulatorException. - */ - void findResources(const std::string &resourceType, ResourceFindCallback callback); - - private: - SimulatorClient() = default; - ~SimulatorClient() = default; - SimulatorClient(const SimulatorClient &) = delete; - SimulatorClient &operator=(const SimulatorClient &) = delete; - SimulatorClient(const SimulatorClient &&) = delete; - SimulatorClient &operator=(const SimulatorClient && ) = delete; - - void onResourceFound(std::shared_ptr resource, - ResourceFindCallback callback); -}; - -#endif - diff --git a/service/simulator/src/client-controller/attribute_generator.cpp b/service/simulator/src/client/attribute_generator.cpp similarity index 52% rename from service/simulator/src/client-controller/attribute_generator.cpp rename to service/simulator/src/client/attribute_generator.cpp index 03abd64..14ce23f 100644 --- a/service/simulator/src/client-controller/attribute_generator.cpp +++ b/service/simulator/src/client/attribute_generator.cpp @@ -21,42 +21,31 @@ #include "attribute_generator.h" AttributeGenerator::AttributeGenerator(const SimulatorResourceModel::Attribute &attribute) - : m_name(attribute.getName()), - m_min(INT_MIN), - m_max(INT_MAX), - m_rangeIndex(-1), - m_allowedValueIndex(0), - m_hasRange(false), - m_hasAllowedValue(false) + : m_attribute(attribute), + m_curIntValue(INT_MIN), + m_valueSetIndex(0) { - if (attribute.getValueType() == - SimulatorResourceModel::Attribute::ValueType::INTEGER) + if (m_attribute.getProperty().type() == SimulatorResourceModel::AttributeProperty::Type::RANGE) { - attribute.getRange(m_min, m_max); - if (INT_MIN != m_min && INT_MAX != m_max) - { - m_hasRange = true; - m_rangeIndex = m_min; - } + m_curIntValue = m_attribute.getProperty().min(); } - else + else if (m_attribute.getProperty().type() == + SimulatorResourceModel::AttributeProperty::Type::VALUE_SET) { - m_allowedValues = attribute.getAllowedValues(); - if (0 != m_allowedValues.size()) - { - m_hasAllowedValue = true; - } + m_supportedValues = m_attribute.getProperty().valueSet(); } } bool AttributeGenerator::hasNext() { - if (m_hasRange && m_rangeIndex <= m_max) + if (m_attribute.getProperty().type() == SimulatorResourceModel::AttributeProperty::Type::RANGE + && m_curIntValue <= m_attribute.getProperty().max()) { return true; } - - if (m_hasAllowedValue && m_allowedValueIndex < m_allowedValues.size()) + else if (m_attribute.getProperty().type() == + SimulatorResourceModel::AttributeProperty::Type::VALUE_SET + && m_valueSetIndex <= m_supportedValues.size() - 1) { return true; } @@ -66,34 +55,40 @@ bool AttributeGenerator::hasNext() bool AttributeGenerator::next(SimulatorResourceModel::Attribute &attribute) { - attribute.setName(m_name); + if (!hasNext()) + return false; - if (m_hasRange) + attribute.setName(m_attribute.getName()); + if (m_attribute.getProperty().type() == SimulatorResourceModel::AttributeProperty::Type::RANGE + && m_curIntValue <= m_attribute.getProperty().max()) { - attribute.setValue(m_rangeIndex++); - return true; + attribute.setValue(m_curIntValue++); } - else if (m_hasAllowedValue) + else if (m_attribute.getProperty().type() == + SimulatorResourceModel::AttributeProperty::Type::VALUE_SET + && m_valueSetIndex <= m_supportedValues.size() - 1) { - attribute.setValue(m_allowedValues[m_allowedValueIndex++]); - return true; + attribute.setValue(m_supportedValues[m_valueSetIndex++]); } - return false; + return true; } SimulatorResourceModel::Attribute AttributeGenerator::current() { SimulatorResourceModel::Attribute attribute; + attribute.setName(m_attribute.getName()); - attribute.setName(m_name); - if (m_hasRange) + if (m_attribute.getProperty().type() == SimulatorResourceModel::AttributeProperty::Type::RANGE + && m_curIntValue <= m_attribute.getProperty().max()) { - attribute.setValue(m_rangeIndex); + attribute.setValue(m_curIntValue); } - else if (m_hasAllowedValue) + else if (m_attribute.getProperty().type() == + SimulatorResourceModel::AttributeProperty::Type::VALUE_SET + && m_valueSetIndex <= m_supportedValues.size() - 1) { - attribute.setValue(m_allowedValues[m_allowedValueIndex]); + attribute.setValue(m_supportedValues[m_valueSetIndex]); } return attribute; @@ -101,23 +96,18 @@ SimulatorResourceModel::Attribute AttributeGenerator::current() void AttributeGenerator::reset() { - if (m_hasRange) - { - m_rangeIndex = m_min; - } - else if (m_hasAllowedValue) - { - m_allowedValueIndex = 0; - } + m_curIntValue = m_attribute.getProperty().min(); + m_valueSetIndex = 0; } AttributeCombinationGen::AttributeCombinationGen( - const std::vector &attributes) + const std::vector &attributes) { for (auto &attr : attributes) { AttributeGenerator attrGen(attr); m_attrGenList.push_back(attr); + m_resModel.add(attr); } m_index = -1; @@ -135,10 +125,10 @@ bool AttributeCombinationGen::next(SimulatorResourceModel &resModel) // This block will execute for only first time if (-1 == m_index) { - for (int index = 0; index < m_attrGenList.size(); index++) + for (size_t index = 0; index < m_attrGenList.size(); index++) { // Add the attribute on resource model - addAttributeToModel(index); + updateAttributeInModel(index); } m_index = m_attrGenList.size() - 1; @@ -149,7 +139,7 @@ bool AttributeCombinationGen::next(SimulatorResourceModel &resModel) // Get the next attribute from statck top element if (m_attrGenList[m_index].hasNext()) { - addAttributeToModel(m_index); + updateAttributeInModel(m_index); resModel = m_resModel; return true; } @@ -163,11 +153,11 @@ bool AttributeCombinationGen::next(SimulatorResourceModel &resModel) return false; m_attrGenList[index].reset(); - addAttributeToModel(index); + updateAttributeInModel(index); } else { - addAttributeToModel(index); + updateAttributeInModel(index); break; } } @@ -179,9 +169,9 @@ bool AttributeCombinationGen::next(SimulatorResourceModel &resModel) return false; } -void AttributeCombinationGen::addAttributeToModel(int index) +void AttributeCombinationGen::updateAttributeInModel(int index) { SimulatorResourceModel::Attribute attribute; - m_attrGenList[index].next(attribute); - m_resModel.addAttribute(attribute, true); + if (m_attrGenList[index].next(attribute)) + m_resModel.updateValue(attribute); } diff --git a/service/simulator/src/client-controller/attribute_generator.h b/service/simulator/src/client/attribute_generator.h similarity index 83% rename from service/simulator/src/client-controller/attribute_generator.h rename to service/simulator/src/client/attribute_generator.h index fab888f..7743bad 100644 --- a/service/simulator/src/client-controller/attribute_generator.h +++ b/service/simulator/src/client/attribute_generator.h @@ -35,14 +35,10 @@ class AttributeGenerator void reset(); private: - std::string m_name; - int m_min; - int m_max; - int m_rangeIndex; - int m_allowedValueIndex; - bool m_hasRange; - bool m_hasAllowedValue; - std::vector m_allowedValues; + SimulatorResourceModel::Attribute m_attribute; + int m_curIntValue; + size_t m_valueSetIndex; + std::vector m_supportedValues; }; class AttributeCombinationGen @@ -52,7 +48,7 @@ class AttributeCombinationGen bool next(SimulatorResourceModel &resModel); private: - void addAttributeToModel(int index); + void updateAttributeInModel(int index); std::mutex m_lock; std::vector m_attrGenList; diff --git a/service/simulator/src/client-controller/auto_request_gen.cpp b/service/simulator/src/client/auto_request_gen.cpp similarity index 100% rename from service/simulator/src/client-controller/auto_request_gen.cpp rename to service/simulator/src/client/auto_request_gen.cpp diff --git a/service/simulator/src/client-controller/auto_request_gen.h b/service/simulator/src/client/auto_request_gen.h similarity index 100% rename from service/simulator/src/client-controller/auto_request_gen.h rename to service/simulator/src/client/auto_request_gen.h diff --git a/service/simulator/src/client-controller/auto_request_gen_mngr.cpp b/service/simulator/src/client/auto_request_gen_mngr.cpp similarity index 99% rename from service/simulator/src/client-controller/auto_request_gen_mngr.cpp rename to service/simulator/src/client/auto_request_gen_mngr.cpp index 56adc4a..10aaf14 100644 --- a/service/simulator/src/client-controller/auto_request_gen_mngr.cpp +++ b/service/simulator/src/client/auto_request_gen_mngr.cpp @@ -206,7 +206,7 @@ bool AutoRequestGenMngr::isValid(int id) bool AutoRequestGenMngr::isInProgress(RequestType type) { std::lock_guard lock(m_lock); - for (auto & session : m_requestGenList) + for (auto &session : m_requestGenList) { if ((session.second)->type() == type) return true; diff --git a/service/simulator/src/client-controller/auto_request_gen_mngr.h b/service/simulator/src/client/auto_request_gen_mngr.h similarity index 100% rename from service/simulator/src/client-controller/auto_request_gen_mngr.h rename to service/simulator/src/client/auto_request_gen_mngr.h diff --git a/service/simulator/src/client-controller/get_request_generator.cpp b/service/simulator/src/client/get_request_generator.cpp similarity index 100% rename from service/simulator/src/client-controller/get_request_generator.cpp rename to service/simulator/src/client/get_request_generator.cpp diff --git a/service/simulator/src/client-controller/get_request_generator.h b/service/simulator/src/client/get_request_generator.h similarity index 100% rename from service/simulator/src/client-controller/get_request_generator.h rename to service/simulator/src/client/get_request_generator.h diff --git a/service/simulator/src/client-controller/post_request_generator.cpp b/service/simulator/src/client/post_request_generator.cpp similarity index 93% rename from service/simulator/src/client-controller/post_request_generator.cpp rename to service/simulator/src/client/post_request_generator.cpp index b8c8ebb..a8c397d 100644 --- a/service/simulator/src/client-controller/post_request_generator.cpp +++ b/service/simulator/src/client/post_request_generator.cpp @@ -94,19 +94,19 @@ void POSTRequestGenerator::SendAllRequests() // Get the next possible queryParameter std::map queryParam = m_queryParamGen.next(); - for (auto & attributeGen : attributeGenList) + for (auto &attributeGen : attributeGenList) { while (attributeGen.hasNext()) { SimulatorResourceModelSP repModel(new SimulatorResourceModel); SimulatorResourceModel::Attribute attribute; if (true == attributeGen.next(attribute)) - repModel->addAttribute(attribute); + repModel->add(attribute); // Send the request m_requestSender->sendRequest(queryParam, repModel, - std::bind(&POSTRequestGenerator::onResponseReceived, - this, std::placeholders::_1, std::placeholders::_2), true); + std::bind(&POSTRequestGenerator::onResponseReceived, + this, std::placeholders::_1, std::placeholders::_2), true); m_requestCnt++; } diff --git a/service/simulator/src/client-controller/post_request_generator.h b/service/simulator/src/client/post_request_generator.h similarity index 100% rename from service/simulator/src/client-controller/post_request_generator.h rename to service/simulator/src/client/post_request_generator.h diff --git a/service/simulator/src/client-controller/put_request_generator.cpp b/service/simulator/src/client/put_request_generator.cpp similarity index 95% rename from service/simulator/src/client-controller/put_request_generator.cpp rename to service/simulator/src/client/put_request_generator.cpp index 56bee77..d54a52d 100644 --- a/service/simulator/src/client-controller/put_request_generator.cpp +++ b/service/simulator/src/client/put_request_generator.cpp @@ -109,8 +109,8 @@ void PUTRequestGenerator::SendAllRequests() // Send the request m_requestSender->sendRequest(queryParam, repModel, - std::bind(&PUTRequestGenerator::onResponseReceived, this, - std::placeholders::_1, std::placeholders::_2), true); + std::bind(&PUTRequestGenerator::onResponseReceived, this, + std::placeholders::_1, std::placeholders::_2), true); m_requestCnt++; } diff --git a/service/simulator/src/client-controller/put_request_generator.h b/service/simulator/src/client/put_request_generator.h similarity index 100% rename from service/simulator/src/client-controller/put_request_generator.h rename to service/simulator/src/client/put_request_generator.h diff --git a/service/simulator/src/client-controller/query_param_generator.cpp b/service/simulator/src/client/query_param_generator.cpp similarity index 100% rename from service/simulator/src/client-controller/query_param_generator.cpp rename to service/simulator/src/client/query_param_generator.cpp diff --git a/service/simulator/src/client-controller/query_param_generator.h b/service/simulator/src/client/query_param_generator.h similarity index 100% rename from service/simulator/src/client-controller/query_param_generator.h rename to service/simulator/src/client/query_param_generator.h diff --git a/service/simulator/src/client-controller/request_list.h b/service/simulator/src/client/request_list.h similarity index 100% rename from service/simulator/src/client-controller/request_list.h rename to service/simulator/src/client/request_list.h diff --git a/service/simulator/src/client-controller/request_sender.cpp b/service/simulator/src/client/request_sender.cpp similarity index 80% rename from service/simulator/src/client-controller/request_sender.cpp rename to service/simulator/src/client/request_sender.cpp index 4e5ba75..b577a00 100644 --- a/service/simulator/src/client-controller/request_sender.cpp +++ b/service/simulator/src/client/request_sender.cpp @@ -42,15 +42,15 @@ void RequestSender::sendRequest(const std::string &interfaceType, } void RequestSender::sendRequest(const std::map &queryParam, - SimulatorResourceModelSP repModel, + SimulatorResourceModelSP resourceModel, ResponseCallback responseCb, bool verifyResponse) { - sendRequest(std::string(), queryParam, repModel, responseCb, verifyResponse); + sendRequest(std::string(), queryParam, resourceModel, responseCb, verifyResponse); } void RequestSender::sendRequest(const std::string &interfaceType, const std::map &queryParam, - SimulatorResourceModelSP repModel, + SimulatorResourceModelSP resourceModel, ResponseCallback responseCb, bool verifyResponse) { // Add query paramter "if" if interfaceType is not empty @@ -62,13 +62,13 @@ void RequestSender::sendRequest(const std::string &interfaceType, RequestDetailSP requestDetail(new RequestDetail); requestDetail->type = m_type; requestDetail->queryParam = queryParamCpy; - requestDetail->body = repModel; + requestDetail->body = resourceModel; requestDetail->verifyResponse = verifyResponse; requestDetail->responseCb = responseCb; int requestId = m_requestList.add(requestDetail); - OCStackResult ocResult = send(queryParamCpy, repModel, std::bind( + OCStackResult ocResult = send(queryParamCpy, resourceModel, std::bind( &RequestSender::onResponseReceived, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, requestId)); if (OC_STACK_OK != ocResult) @@ -87,14 +87,12 @@ void RequestSender::setRequestModel(const RequestModelSP &requestModel) void RequestSender::onResponseReceived(const OC::HeaderOptions &headerOptions, const OC::OCRepresentation &rep, const int errorCode, int requestId) { - SIM_LOG(ILogger::INFO, "Response recieved..." << "\n" << getPayloadString(rep)); + SIM_LOG(ILogger::INFO, "Response received..." << "\n" << getPayloadString(rep)); // Ignore the response recieved for invalid requests RequestDetailSP request = m_requestList.remove(requestId); if (!request) - { return; - } // Validate the response as per the schema given by RAML ValidationStatus validationStatus {false, SIMULATOR_ERROR}; @@ -105,17 +103,19 @@ void RequestSender::onResponseReceived(const OC::HeaderOptions &headerOptions, validationStatus.isVerified = true; } - SimulatorResourceModelSP repModel = SimulatorResourceModel::create(rep); - request->responseCb(static_cast(errorCode), repModel); + SimulatorResourceModelSP resourceModel = std::make_shared( + SimulatorResourceModel::build(rep)); + request->responseCb(static_cast(errorCode), resourceModel); } GETRequestSender::GETRequestSender(std::shared_ptr &ocResource) : RequestSender(RequestType::RQ_TYPE_GET, ocResource) {} OCStackResult GETRequestSender::send(OC::QueryParamsMap &queryParams, - SimulatorResourceModelSP &repModel, OC::GetCallback callback) + SimulatorResourceModelSP &resourceModel, OC::GetCallback callback) { - SIM_LOG(ILogger::INFO, "Sending GET request..." << "\n" << getRequestString(queryParams)); + SIM_LOG(ILogger::INFO, "Sending GET request..." << "\n**Payload Details**\n" << getRequestString( + queryParams)); return m_ocResource->get(queryParams, callback); } @@ -124,15 +124,14 @@ PUTRequestSender::PUTRequestSender(std::shared_ptr &ocResource) : RequestSender(RequestType::RQ_TYPE_PUT, ocResource) {} OCStackResult PUTRequestSender::send(OC::QueryParamsMap &queryParams, - SimulatorResourceModelSP &repModel, OC::GetCallback callback) + SimulatorResourceModelSP &resourceModel, OC::GetCallback callback) { OC::OCRepresentation ocRep; - if (repModel) - { - ocRep = repModel->getOCRepresentation(); - } + if (resourceModel) + ocRep = resourceModel->getOCRepresentation(); - SIM_LOG(ILogger::INFO, "Sending PUT request..." << "\n" << getRequestString(queryParams, ocRep)); + SIM_LOG(ILogger::INFO, "Sending PUT request..." << "\n**Payload Details**\n" << getRequestString( + queryParams, ocRep)); return m_ocResource->put(ocRep, queryParams, callback); } @@ -140,12 +139,13 @@ POSTRequestSender::POSTRequestSender(std::shared_ptr &ocResource : RequestSender(RequestType::RQ_TYPE_POST, ocResource) {} OCStackResult POSTRequestSender::send(OC::QueryParamsMap &queryParams, - SimulatorResourceModelSP &repModel, OC::GetCallback callback) + SimulatorResourceModelSP &resourceModel, OC::GetCallback callback) { OC::OCRepresentation ocRep; - if (repModel) - ocRep = repModel->getOCRepresentation(); + if (resourceModel) + ocRep = resourceModel->getOCRepresentation(); - SIM_LOG(ILogger::INFO, "Sending POST request..." << "\n" << getRequestString(queryParams, ocRep)); + SIM_LOG(ILogger::INFO, "Sending POST request..." << "\n**Payload Details**\n" << getRequestString( + queryParams, ocRep)); return m_ocResource->post(ocRep, queryParams, callback); } diff --git a/service/simulator/src/client-controller/request_sender.h b/service/simulator/src/client/request_sender.h similarity index 87% rename from service/simulator/src/client-controller/request_sender.h rename to service/simulator/src/client/request_sender.h index 46457e9..fa6de91 100644 --- a/service/simulator/src/client-controller/request_sender.h +++ b/service/simulator/src/client/request_sender.h @@ -44,19 +44,19 @@ class RequestSender ResponseCallback responseCb, bool verifyResponse = false); void sendRequest(const std::map &queryParam, - SimulatorResourceModelSP repModel, + SimulatorResourceModelSP resourceModel, ResponseCallback responseCb, bool verifyResponse = false); void sendRequest(const std::string &interfaceType, const std::map &queryParam, - SimulatorResourceModelSP repModel, + SimulatorResourceModelSP resourceModel, ResponseCallback responseCb, bool verifyResponse = false); void setRequestModel(const RequestModelSP &requestModel); protected: virtual OCStackResult send(OC::QueryParamsMap &queryParams, - SimulatorResourceModelSP &repModel, OC::GetCallback callback) = 0; + SimulatorResourceModelSP &resourceModel, OC::GetCallback callback) = 0; void onResponseReceived(const OC::HeaderOptions &headerOptions, const OC::OCRepresentation &rep, const int errorCode, int requestId); @@ -84,7 +84,7 @@ class GETRequestSender : public RequestSender GETRequestSender(std::shared_ptr &ocResource); OCStackResult send(OC::QueryParamsMap &queryParams, - SimulatorResourceModelSP &repModel, OC::GetCallback callback); + SimulatorResourceModelSP &resourceModel, OC::GetCallback callback); }; class PUTRequestSender : public RequestSender @@ -93,7 +93,7 @@ class PUTRequestSender : public RequestSender PUTRequestSender(std::shared_ptr &ocResource); OCStackResult send(OC::QueryParamsMap &queryParams, - SimulatorResourceModelSP &repModel, OC::GetCallback callback); + SimulatorResourceModelSP &resourceModel, OC::GetCallback callback); }; class POSTRequestSender : public RequestSender @@ -102,7 +102,7 @@ class POSTRequestSender : public RequestSender POSTRequestSender(std::shared_ptr &ocResource); OCStackResult send(OC::QueryParamsMap &queryParams, - SimulatorResourceModelSP &repModel, OC::GetCallback callback); + SimulatorResourceModelSP &resourceModel, OC::GetCallback callback); }; typedef std::shared_ptr RequestSenderSP; diff --git a/service/simulator/src/client-controller/simulator_remote_resource_impl.cpp b/service/simulator/src/client/simulator_remote_resource_impl.cpp similarity index 76% rename from service/simulator/src/client-controller/simulator_remote_resource_impl.cpp rename to service/simulator/src/client/simulator_remote_resource_impl.cpp index 178dccb..336c3ba 100644 --- a/service/simulator/src/client-controller/simulator_remote_resource_impl.cpp +++ b/service/simulator/src/client/simulator_remote_resource_impl.cpp @@ -21,6 +21,8 @@ #include "simulator_remote_resource_impl.h" #include "request_model_builder.h" #include "simulator_exceptions.h" +#include "simulator_utils.h" +#include "simulator_logger.h" #include "logger.h" #define TAG "SIMULATOR_REMOTE_RESOURCE" @@ -75,41 +77,37 @@ bool SimulatorRemoteResourceImpl::isObservable() const void SimulatorRemoteResourceImpl::observe(ObserveType type, ObserveNotificationCallback callback) { - if (!callback) - { - OC_LOG(ERROR, TAG, "Invalid callback!"); - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - } + VALIDATE_CALLBACK(callback) - std::lock_guard lock(m_observeMutex); + std::lock_guard lock(m_observeLock); if (m_observeState) { - OC_LOG(WARNING, TAG, "Resource already in observe state !"); throw SimulatorException(SIMULATOR_ERROR, "Resource is already being observed!"); } - OC::ObserveCallback observeCallback = [this, callback](const OC::HeaderOptions & headerOptions, - const OC::OCRepresentation & rep, const int errorCode, - const int sequenceNum) + OC::ObserveCallback observeCallback = std::bind( + [](const OC::HeaderOptions & headerOptions, const OC::OCRepresentation & ocRep, + const int errorCode, const int sqNum, std::string id, ObserveNotificationCallback callback) { - // Convert OCRepresentation to SimulatorResourceModel - SimulatorResourceModelSP repModel = SimulatorResourceModel::create(rep); - callback(m_id, static_cast(errorCode), repModel, sequenceNum); - }; + SIM_LOG(ILogger::INFO, "Observe response received..." << "\n" << getPayloadString(ocRep)); + + SimulatorResourceModelSP resourceModel( + new SimulatorResourceModel(SimulatorResourceModel::build(ocRep))); + callback(id, static_cast(errorCode), resourceModel, sqNum); + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, + m_id, callback); OC::ObserveType observeType = OC::ObserveType::Observe; if (type == ObserveType::OBSERVE_ALL) - { observeType = OC::ObserveType::ObserveAll; - } try { OCStackResult ocResult = m_ocResource->observe(observeType, OC::QueryParamsMap(), observeCallback); if (OC_STACK_OK != ocResult) - { throw SimulatorException(static_cast(ocResult), OC::OCException::reason(ocResult)); - } + + SIM_LOG(ILogger::INFO, "OBSERVE request sent"); } catch (OC::OCException &e) { @@ -125,16 +123,16 @@ void SimulatorRemoteResourceImpl::cancelObserve() { OCStackResult ocResult = m_ocResource->cancelObserve(OC::QualityOfService::HighQos); if (OC_STACK_OK != ocResult) - { throw SimulatorException(static_cast(ocResult), OC::OCException::reason(ocResult)); - } + + SIM_LOG(ILogger::INFO, "OBSERVE CANCEL request sent"); } catch (OC::OCException &e) { throw SimulatorException(static_cast(e.code()), e.reason()); } - std::lock_guard lock(m_observeMutex); + std::lock_guard lock(m_observeLock); m_observeState = false; } @@ -142,11 +140,7 @@ void SimulatorRemoteResourceImpl::get(const std::string &interfaceType, const std::map &queryParams, ResponseCallback callback) { - if (!callback) - { - OC_LOG(ERROR, TAG, "Invalid callback!"); - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - } + VALIDATE_CALLBACK(callback) if (!m_getRequestSender) { @@ -163,11 +157,7 @@ void SimulatorRemoteResourceImpl::get(const std::string &interfaceType, void SimulatorRemoteResourceImpl::get(const std::map &queryParams, ResponseCallback callback) { - if (!callback) - { - OC_LOG(ERROR, TAG, "Invalid callback!"); - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - } + VALIDATE_CALLBACK(callback) if (!m_getRequestSender) { @@ -183,14 +173,10 @@ void SimulatorRemoteResourceImpl::get(const std::map & void SimulatorRemoteResourceImpl::put(const std::string &interfaceType, const std::map &queryParams, - SimulatorResourceModelSP representation, + SimulatorResourceModelSP resourceModel, ResponseCallback callback) { - if (!callback) - { - OC_LOG(ERROR, TAG, "Invalid callback!"); - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - } + VALIDATE_CALLBACK(callback) if (!m_putRequestSender) { @@ -199,20 +185,16 @@ void SimulatorRemoteResourceImpl::put(const std::string &interfaceType, } m_putRequestSender->sendRequest(interfaceType, queryParams, - representation, std::bind( + resourceModel, std::bind( &SimulatorRemoteResourceImpl::onResponseReceived, this, std::placeholders::_1, std::placeholders::_2, callback)); } void SimulatorRemoteResourceImpl::put(const std::map &queryParams, - SimulatorResourceModelSP representation, + SimulatorResourceModelSP resourceModel, ResponseCallback callback) { - if (!callback) - { - OC_LOG(ERROR, TAG, "Invalid callback!"); - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - } + VALIDATE_CALLBACK(callback) if (!m_putRequestSender) { @@ -221,21 +203,17 @@ void SimulatorRemoteResourceImpl::put(const std::map & } m_putRequestSender->sendRequest(std::string(), queryParams, - representation, std::bind( + resourceModel, std::bind( &SimulatorRemoteResourceImpl::onResponseReceived, this, std::placeholders::_1, std::placeholders::_2, callback)); } void SimulatorRemoteResourceImpl::post(const std::string &interfaceType, const std::map &queryParams, - SimulatorResourceModelSP representation, + SimulatorResourceModelSP resourceModel, ResponseCallback callback) { - if (!callback) - { - OC_LOG(ERROR, TAG, "Invalid callback!"); - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - } + VALIDATE_CALLBACK(callback) if (!m_postRequestSender) { @@ -244,20 +222,16 @@ void SimulatorRemoteResourceImpl::post(const std::string &interfaceType, } m_postRequestSender->sendRequest(interfaceType, queryParams, - representation, std::bind( + resourceModel, std::bind( &SimulatorRemoteResourceImpl::onResponseReceived, this, std::placeholders::_1, std::placeholders::_2, callback)); } void SimulatorRemoteResourceImpl::post(const std::map &queryParams, - SimulatorResourceModelSP representation, + SimulatorResourceModelSP resourceModel, ResponseCallback callback) { - if (!callback) - { - OC_LOG(ERROR, TAG, "Invalid callback!"); - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - } + VALIDATE_CALLBACK(callback) if (!m_postRequestSender) { @@ -266,7 +240,7 @@ void SimulatorRemoteResourceImpl::post(const std::map } m_postRequestSender->sendRequest(std::string(), queryParams, - representation, std::bind( + resourceModel, std::bind( &SimulatorRemoteResourceImpl::onResponseReceived, this, std::placeholders::_1, std::placeholders::_2, callback)); } @@ -274,11 +248,7 @@ void SimulatorRemoteResourceImpl::post(const std::map int SimulatorRemoteResourceImpl::startVerification(RequestType type, StateCallback callback) { - if (!callback) - { - OC_LOG(ERROR, TAG, "Invalid callback!"); - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - } + VALIDATE_CALLBACK(callback) if (!m_autoRequestGenMngr) { @@ -302,8 +272,8 @@ int SimulatorRemoteResourceImpl::startVerification(RequestType type, if (m_getRequestSender) { return m_autoRequestGenMngr->startOnGET(m_getRequestSender, - m_requestModelList[RequestType::RQ_TYPE_GET]->getQueryParams(), - localCallback); + m_requestModelList[RequestType::RQ_TYPE_GET]->getQueryParams(), + localCallback); } break; @@ -311,19 +281,19 @@ int SimulatorRemoteResourceImpl::startVerification(RequestType type, if (m_putRequestSender) { return m_autoRequestGenMngr->startOnPUT(m_putRequestSender, - m_requestModelList[RequestType::RQ_TYPE_PUT]->getQueryParams(), - m_requestModelList[RequestType::RQ_TYPE_PUT]->getRepSchema(), - localCallback); + m_requestModelList[RequestType::RQ_TYPE_PUT]->getQueryParams(), + m_requestModelList[RequestType::RQ_TYPE_PUT]->getRepSchema(), + localCallback); } break; case RequestType::RQ_TYPE_POST: if (m_postRequestSender) { - return m_autoRequestGenMngr->startOnPOST(m_putRequestSender, - m_requestModelList[RequestType::RQ_TYPE_POST]->getQueryParams(), - m_requestModelList[RequestType::RQ_TYPE_POST]->getRepSchema(), - localCallback); + return m_autoRequestGenMngr->startOnPOST(m_postRequestSender, + m_requestModelList[RequestType::RQ_TYPE_POST]->getQueryParams(), + m_requestModelList[RequestType::RQ_TYPE_POST]->getRepSchema(), + localCallback); } break; @@ -352,18 +322,28 @@ void SimulatorRemoteResourceImpl::stopVerification(int id) m_autoRequestGenMngr->stop(id); } -void SimulatorRemoteResourceImpl::configure(const std::string &path) +SimulatorResourceModelSP SimulatorRemoteResourceImpl::configure(const std::string &path) { - if (path.empty()) - { - OC_LOG(ERROR, TAG, "Invalid path given for configuration!"); - throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Empty path string!"); - } + VALIDATE_INPUT(path.empty(), "Path is empty!") std::shared_ptr ramlParser = std::make_shared(path); RAML::RamlPtr raml = ramlParser->getRamlPtr(); configure(raml); + + if (m_requestModelList.empty()) + throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "RAML file is invalid for the resource!"); + + for (auto &model : m_requestModelList) + { + SimulatorResourceModelSP schema = (model.second)->getRepSchema(); + if (schema) + { + return std::make_shared(*(schema.get())); + } + } + + return std::make_shared(); } void SimulatorRemoteResourceImpl::configure(std::shared_ptr &raml) @@ -394,10 +374,9 @@ void SimulatorRemoteResourceImpl::configure(std::shared_ptr &raml) } void SimulatorRemoteResourceImpl::onResponseReceived(SimulatorResult result, - SimulatorResourceModelSP repModel, - ResponseCallback clientCallback) + SimulatorResourceModelSP resourceModel, ResponseCallback clientCallback) { - clientCallback(m_id, result, repModel); + clientCallback(m_id, result, resourceModel); } SimulatorConnectivityType SimulatorRemoteResourceImpl::convertConnectivityType( @@ -423,4 +402,4 @@ SimulatorConnectivityType SimulatorRemoteResourceImpl::convertConnectivityType( default: return SIMULATOR_CT_DEFAULT; } -} \ No newline at end of file +} diff --git a/service/simulator/src/client-controller/simulator_remote_resource_impl.h b/service/simulator/src/client/simulator_remote_resource_impl.h similarity index 90% rename from service/simulator/src/client-controller/simulator_remote_resource_impl.h rename to service/simulator/src/client/simulator_remote_resource_impl.h index bd64e98..9948ea3 100644 --- a/service/simulator/src/client-controller/simulator_remote_resource_impl.h +++ b/service/simulator/src/client/simulator_remote_resource_impl.h @@ -59,35 +59,35 @@ class SimulatorRemoteResourceImpl : public SimulatorRemoteResource ResponseCallback callback); void put(const std::map &queryParams, - SimulatorResourceModelSP representation, + SimulatorResourceModelSP resourceModel, ResponseCallback callback); void put(const std::string &interfaceType, const std::map &queryParams, - SimulatorResourceModelSP representation, + SimulatorResourceModelSP resourceModel, ResponseCallback callback); void post(const std::map &queryParams, - SimulatorResourceModelSP representation, + SimulatorResourceModelSP resourceModel, ResponseCallback callback); void post(const std::string &interfaceType, const std::map &queryParams, - SimulatorResourceModelSP representation, + SimulatorResourceModelSP resourceModel, ResponseCallback callback); int startVerification(RequestType type, StateCallback callback); void stopVerification(int id); - void configure(const std::string &path); + SimulatorResourceModelSP configure(const std::string &path); private: void configure(std::shared_ptr &raml); - void onResponseReceived(SimulatorResult result, SimulatorResourceModelSP repModel, + void onResponseReceived(SimulatorResult result, SimulatorResourceModelSP resourceModel, ResponseCallback clientCallback); SimulatorConnectivityType convertConnectivityType(OCConnectivityType type) const; std::string m_id; - std::mutex m_observeMutex; + std::mutex m_observeLock; bool m_observeState; GETRequestSenderSP m_getRequestSender; PUTRequestSenderSP m_putRequestSender; diff --git a/service/simulator/src/common/request_model_builder.cpp b/service/simulator/src/common/request_model_builder.cpp index 54006c3..b181433 100755 --- a/service/simulator/src/common/request_model_builder.cpp +++ b/service/simulator/src/common/request_model_builder.cpp @@ -34,14 +34,14 @@ std::map RequestModelBuilder::build(const std::stri return modelList; } - for (auto & resource : m_raml->getResources()) + for (auto &resource : m_raml->getResources()) { // Pick the resource based on the resource uri. if (std::string::npos == uri.find((resource.second)->getResourceUri())) continue; - // Construcut Request and Response Model from RAML::Action - for (auto & action : (resource.second)->getActions()) + // Construct Request and Response Model from RAML::Action + for (auto &action : (resource.second)->getActions()) { RequestModelSP requestModel = createRequestModel(action.second); if (requestModel) @@ -71,9 +71,9 @@ RequestModelSP RequestModelBuilder::createRequestModel(const RAML::ActionPtr &ac RequestModelSP requestModel(new RequestModel(getRequestType(actionType))); // Get the allowed query parameters of the request - for (auto & qpEntry : action->getQueryParameters()) + for (auto &qpEntry : action->getQueryParameters()) { - for (auto & value : (qpEntry.second)->getEnumeration()) + for (auto &value : (qpEntry.second)->getEnumeration()) { requestModel->addQueryParam(qpEntry.first, value); } @@ -84,7 +84,7 @@ RequestModelSP RequestModelBuilder::createRequestModel(const RAML::ActionPtr &ac requestModel->setRepSchema(repSchema); // Corresponsing responses - for (auto & responseEntry : action->getResponses()) + for (auto &responseEntry : action->getResponses()) { std::string codeStr = responseEntry.first; int code = boost::lexical_cast(codeStr); @@ -115,6 +115,7 @@ SimulatorResourceModelSP RequestModelBuilder::createRepSchema(const RAML::Reques { return nullptr; } + RAML::SchemaPtr schema = rep->getSchema(); if (!schema) { @@ -126,7 +127,7 @@ SimulatorResourceModelSP RequestModelBuilder::createRepSchema(const RAML::Reques return nullptr; SimulatorResourceModelSP repSchema = std::make_shared(); - for (auto & propertyEntry : properties->getProperties()) + for (auto &propertyEntry : properties->getProperties()) { std::string propName = propertyEntry.second->getName(); if ("rt" == propName || "resourceType" == propName || "if" == propName @@ -139,34 +140,29 @@ SimulatorResourceModelSP RequestModelBuilder::createRepSchema(const RAML::Reques case 0: // Integer { // Add the attribute with value - repSchema->addAttribute(propertyEntry.second->getName(), propertyEntry.second->getValue()); + repSchema->add(propertyEntry.second->getName(), propertyEntry.second->getValue()); - // Set the range - double min, max; - int multipleof; - propertyEntry.second->getRange(min, max, multipleof); - repSchema->setRange(propertyEntry.second->getName(), min, max); + // Convert supported values + std::vector allowedValues = propertyEntry.second->getAllowedValuesInt(); + if (allowedValues.size() > 0) + { + SimulatorResourceModel::AttributeProperty attrProp(allowedValues); + repSchema->setAttributeProperty(propName, attrProp); + } } break; case 1: // Double { // Add the attribute with value - repSchema->addAttribute(propertyEntry.second->getName(), propertyEntry.second->getValue()); + repSchema->add(propertyEntry.second->getName(), propertyEntry.second->getValue()); - std::vector propValues = - propertyEntry.second->getAllowedValues(); - - // TODO: Use RAML function once available - if (0 < propertyEntry.second->getAllowedValuesSize()) + // Convert suppoted values + std::vector allowedValues = propertyEntry.second->getAllowedValuesDouble(); + if (allowedValues.size() > 0) { - std::vector allowedValues; - for (auto & propValue : propValues) - { - double value = boost::lexical_cast (propValue); - allowedValues.push_back(value); - } - repSchema->setAllowedValues(propertyEntry.second->getName(), allowedValues); + SimulatorResourceModel::AttributeProperty attrProp(allowedValues); + repSchema->setAttributeProperty(propName, attrProp); } } break; @@ -174,33 +170,43 @@ SimulatorResourceModelSP RequestModelBuilder::createRepSchema(const RAML::Reques case 2: // Boolean { // Add the attribute with value - repSchema->addAttribute(propertyEntry.second->getName(), propertyEntry.second->getValue()); + repSchema->add(propertyEntry.second->getName(), propertyEntry.second->getValue()); + // Convert supported values + std::vector allowedValues = propertyEntry.second->getAllowedValuesBool(); + if (allowedValues.size() > 0) + { + SimulatorResourceModel::AttributeProperty attrProp(allowedValues); + repSchema->setAttributeProperty(propName, attrProp); + } } break; case 3: // String { // Add the attribute with value - repSchema->addAttribute(propertyEntry.second->getName(), - propertyEntry.second->getValue()); + repSchema->add(propertyEntry.second->getName(), + propertyEntry.second->getValue()); - std::vector propValues = - propertyEntry.second->getAllowedValues(); - - // TODO: Use RAML function once available - if (0 < propertyEntry.second->getAllowedValuesSize()) + // Convert suppored values + std::vector allowedValues = propertyEntry.second->getAllowedValuesString(); + if (allowedValues.size() > 0) { - std::vector allowedValues; - for (auto & propValue : propValues) - { - std::string value = boost::lexical_cast (propValue); - allowedValues.push_back(value); - } - repSchema->setAllowedValues(propertyEntry.second->getName(), allowedValues); + SimulatorResourceModel::AttributeProperty attrProp(allowedValues); + repSchema->setAttributeProperty(propName, attrProp); } } break; } + + // Set the range property if its present + double min, max; + int multipleof; + propertyEntry.second->getRange(min, max, multipleof); + if (min != INT_MIN && max != INT_MAX) + { + SimulatorResourceModel::AttributeProperty attrProp(min, max); + repSchema->setAttributeProperty(propName, attrProp); + } } return repSchema; @@ -210,8 +216,6 @@ RequestType RequestModelBuilder::getRequestType(RAML::ActionType actionType) { switch (actionType) { - case RAML::ActionType::GET: - return RequestType::RQ_TYPE_GET; case RAML::ActionType::PUT: return RequestType::RQ_TYPE_PUT; case RAML::ActionType::POST: @@ -219,5 +223,7 @@ RequestType RequestModelBuilder::getRequestType(RAML::ActionType actionType) case RAML::ActionType::DELETE: return RequestType::RQ_TYPE_DELETE; } + + return RequestType::RQ_TYPE_GET; } diff --git a/service/simulator/src/common/response_model.cpp b/service/simulator/src/common/response_model.cpp index 8398a18..91349f0 100644 --- a/service/simulator/src/common/response_model.cpp +++ b/service/simulator/src/common/response_model.cpp @@ -27,98 +27,10 @@ void ResponseModel::setRepSchema(SimulatorResourceModelSP &repSchema) m_repSchema = repSchema; } -SimulatorResult ResponseModel::verifyResponse(const OC::OCRepresentation &rep) +SimulatorResult ResponseModel::verifyResponse(const OC::OCRepresentation &ocRep) { - for (auto & ocAttribute : rep) - { - SimulatorResourceModel::Attribute attribute; - if (false == m_repSchema->getAttribute(ocAttribute.attrname(), attribute)) - { - return SIMULATOR_UKNOWN_PROPERTY; - } - - switch (attribute.getValueType()) - { - case SimulatorResourceModel::Attribute::ValueType::INTEGER : // Integer - { - SimulatorResult result = validateAttributeInteger(attribute, ocAttribute); - if (SIMULATOR_OK != result) - { - return result; - } - } - break; - - case SimulatorResourceModel::Attribute::ValueType::DOUBLE : // Double - { - SimulatorResult result = validateAttributeDouble(attribute, ocAttribute); - if (SIMULATOR_OK != result) - { - return result; - } - } - break; - - case SimulatorResourceModel::Attribute::ValueType::STRING : // String - { - SimulatorResult result = validateAttributeString(attribute, ocAttribute); - if (SIMULATOR_OK != result) - { - return result; - } - } - break; - } - } - - return SIMULATOR_OK; -} - -SimulatorResult ResponseModel::validateAttributeInteger( - SimulatorResourceModel::Attribute &attrSchema, - const OC::OCRepresentation::AttributeItem &ocAttribute) -{ - // Check the value type - if (OC::AttributeType::Integer != ocAttribute.type()) - { - return SIMULATOR_TYPE_MISMATCH; - } - - // Check value if it is in range - int min, max, value; - attrSchema.getRange(min, max); - value = ocAttribute.getValue(); - if (value < min || value > max) - { - return SIMULATOR_BAD_VALUE; - } - - return SIMULATOR_OK; -} - -SimulatorResult ResponseModel::validateAttributeDouble( - SimulatorResourceModel::Attribute &attrSchema, - const OC::OCRepresentation::AttributeItem &ocAttribute) -{ - // Check the value type - if (OC::AttributeType::Double != ocAttribute.type()) - { - return SIMULATOR_TYPE_MISMATCH; - } - - return SIMULATOR_OK; -} - -SimulatorResult ResponseModel::validateAttributeString( - SimulatorResourceModel::Attribute &attrSchema, - const OC::OCRepresentation::AttributeItem &ocAttribute) -{ - // Check the value type - if (OC::AttributeType::String != ocAttribute.type()) - { - return SIMULATOR_TYPE_MISMATCH; - } - - // TODO: Check the allowed values - return SIMULATOR_OK; + SimulatorResourceModel resModel = SimulatorResourceModel::build(ocRep); + if (m_repSchema->match(resModel)) + return SIMULATOR_OK; + return SIMULATOR_ERROR; } \ No newline at end of file diff --git a/service/simulator/src/common/response_model.h b/service/simulator/src/common/response_model.h index 77cb2bb..f52626e 100644 --- a/service/simulator/src/common/response_model.h +++ b/service/simulator/src/common/response_model.h @@ -30,18 +30,11 @@ class ResponseModel public: friend class RequestModelBuilder; - SimulatorResult verifyResponse(const OC::OCRepresentation &rep); + SimulatorResult verifyResponse(const OC::OCRepresentation &ocRep); private: ResponseModel(int code); void setRepSchema(SimulatorResourceModelSP &repSchema); - SimulatorResult validateAttributeInteger(SimulatorResourceModel::Attribute &attrSchema, - const OC::OCRepresentation::AttributeItem &ocAttribute); - SimulatorResult validateAttributeDouble(SimulatorResourceModel::Attribute &attrSchema, - const OC::OCRepresentation::AttributeItem &ocAttribute); - SimulatorResult validateAttributeString(SimulatorResourceModel::Attribute &attrSchema, - const OC::OCRepresentation::AttributeItem &ocAttribute); - int m_code; SimulatorResourceModelSP m_repSchema; }; diff --git a/service/simulator/src/common/simulator_resource_model.cpp b/service/simulator/src/common/simulator_resource_model.cpp index 2a1a67d..02df295 100644 --- a/service/simulator/src/common/simulator_resource_model.cpp +++ b/service/simulator/src/common/simulator_resource_model.cpp @@ -21,375 +21,999 @@ #include "simulator_resource_model.h" #include "simulator_exceptions.h" #include "logger.h" -#include "OCPlatform.h" -#include + #include +#include + +#define TAG "SIM_RESOURCE_MODEL" template -struct TypeConverter -{ - constexpr static SimulatorResourceModel::Attribute::ValueType type = - SimulatorResourceModel::Attribute::ValueType::UNKNOWN; -}; +struct TypeConverter {}; template <> struct TypeConverter { - constexpr static SimulatorResourceModel::Attribute::ValueType type = - SimulatorResourceModel::Attribute::ValueType::INTEGER; + constexpr static SimulatorResourceModel::ValueType type = + SimulatorResourceModel::ValueType::INTEGER; }; template <> struct TypeConverter { - constexpr static SimulatorResourceModel::Attribute::ValueType type = - SimulatorResourceModel::Attribute::ValueType::DOUBLE; + constexpr static SimulatorResourceModel::ValueType type = + SimulatorResourceModel::ValueType::DOUBLE; }; template <> struct TypeConverter { - constexpr static SimulatorResourceModel::Attribute::ValueType type = - SimulatorResourceModel::Attribute::ValueType::BOOLEAN; + constexpr static SimulatorResourceModel::ValueType type = + SimulatorResourceModel::ValueType::BOOLEAN; }; template <> struct TypeConverter { - constexpr static SimulatorResourceModel::Attribute::ValueType type = - SimulatorResourceModel::Attribute::ValueType::STRING; + constexpr static SimulatorResourceModel::ValueType type = + SimulatorResourceModel::ValueType::STRING; }; -class attribute_type_visitor : public boost::static_visitor< - SimulatorResourceModel::Attribute::ValueType> +template <> +struct TypeConverter +{ + constexpr static SimulatorResourceModel::ValueType type = + SimulatorResourceModel::ValueType::RESOURCE_MODEL; +}; + +template +struct TypeDetails +{ + constexpr static SimulatorResourceModel::ValueType type = + TypeConverter::type; + constexpr static SimulatorResourceModel::ValueType baseType = + TypeConverter::type; + constexpr static int depth = 0; +}; + +template +struct TypeDetails> +{ + constexpr static SimulatorResourceModel::ValueType type = + SimulatorResourceModel::ValueType::VECTOR; + constexpr static SimulatorResourceModel::ValueType baseType = + TypeDetails::baseType; + constexpr static int depth = 1 + TypeDetails::depth; +}; + +class AttributeTypeVisitor : public boost::static_visitor<> { public: + AttributeTypeVisitor() : m_type(SimulatorResourceModel::ValueType::UNKNOWN), + m_baseType(SimulatorResourceModel::ValueType::UNKNOWN), m_depth(0) {} + template - result_type operator ()(const T &) + void operator ()(const T &) { - return TypeConverter::type; + m_type = TypeDetails::type; + m_baseType = TypeDetails::baseType; + m_depth = TypeDetails::depth; } + + SimulatorResourceModel::ValueType m_type; + SimulatorResourceModel::ValueType m_baseType; + int m_depth; }; -class to_string_visitor : public boost::static_visitor +class OCRepresentationBuilder { public: - template - result_type operator ()(const T &value) + class ValueConverter : public boost::static_visitor<> { - try - { - return boost::lexical_cast(value); - } - catch (const boost::bad_lexical_cast &e) + public: + ValueConverter(OC::OCRepresentation &rep, const std::string &key) + : m_rep(rep), m_key(key) {} + + template + void operator ()(const T &value) + { + m_rep.setValue(m_key, value); + } + + void operator ()(const SimulatorResourceModel &value) + { + OC::OCRepresentation ocRep; + for (auto &element : value.getValues()) + { + ValueConverter visitor(ocRep, element.first); + boost::apply_visitor(visitor, element.second); + } + + m_rep.setValue(m_key, ocRep); + } + + template + void operator ()(const std::vector &values) + { + m_rep.setValue(m_key, values); + } + + void operator ()(const std::vector &values) + { + std::vector ocRepArray; + for (size_t i = 0; i < values.size(); i++) + { + for (auto &element : values[i].getValues()) + { + ValueConverter visitor(ocRepArray[i], element.first); + boost::apply_visitor(visitor, element.second); + } + } + + m_rep.setValue(m_key, ocRepArray); + } + + template + void operator ()(const std::vector> &values) + { + m_rep.setValue(m_key, values); + } + + void operator ()(const std::vector> &values) + { + std::vector> ocRepArray; + for (size_t i = 0; i < values.size(); i++) + { + for (size_t j = 0; j < values[i].size(); j++) + { + for (auto &element : values[i][j].getValues()) + { + ValueConverter visitor(ocRepArray[i][j], element.first); + boost::apply_visitor(visitor, element.second); + } + } + } + + m_rep.setValue(m_key, ocRepArray); + } + + template + void operator ()(const std::vector>> &values) + { + m_rep.setValue(m_key, values); + } + + void operator ()(const std::vector>> &values) + { + std::vector>> ocRepArray; + for (size_t i = 0; i < values.size(); i++) + { + for (size_t j = 0; j < values[i].size(); j++) + { + for (size_t k = 0; j < values[i][j].size(); k++) + { + for (auto &element : values[i][j][k].getValues()) + { + ValueConverter visitor(ocRepArray[i][j][k], element.first); + boost::apply_visitor(visitor, element.second); + } + } + } + } + + m_rep.setValue(m_key, ocRepArray); + } + + private: + OC::OCRepresentation &m_rep; + std::string m_key; + }; + + OC::OCRepresentation build(SimulatorResourceModel &model) + { + OC::OCRepresentation ocRep; + for (auto &element : model.getValues()) { - return ""; + ValueConverter visitor(ocRep, element.first); + boost::apply_visitor(visitor, element.second); } + + return std::move(ocRep); } }; -class add_to_representation : public boost::static_visitor<> +// TODO: Class is very heavy, revisit again to clean +class SimulatorResourceModelBuilder { public: - add_to_representation(OC::OCRepresentation &rep, const std::string &key) - : m_rep(rep), m_key(key) {} + SimulatorResourceModel build(const OC::OCRepresentation &ocRep) + { + SimulatorResourceModel resModel; + handleRepresentationType(resModel, ocRep); + return std::move(resModel); + } - template - void operator ()(const T &value) + private: + void handleRepresentationType(SimulatorResourceModel &resModel, + const OC::OCRepresentation &ocRep) + { + for (auto &ocAttribute : ocRep) + { + if (OC::AttributeType::Integer == ocAttribute.type()) + { + resModel.add(ocAttribute.attrname(), ocAttribute.getValue()); + } + else if (OC::AttributeType::Double == ocAttribute.type()) + { + resModel.add(ocAttribute.attrname(), ocAttribute.getValue()); + } + else if (OC::AttributeType::Boolean == ocAttribute.type()) + { + resModel.add(ocAttribute.attrname(), ocAttribute.getValue()); + } + else if (OC::AttributeType::String == ocAttribute.type()) + { + resModel.add(ocAttribute.attrname(), ocAttribute.getValue()); + } + else if (OC::AttributeType::OCRepresentation == ocAttribute.type()) + { + SimulatorResourceModel subResModel; + OC::OCRepresentation ocSubRep = ocAttribute.getValue(); + handleRepresentationType(subResModel, ocSubRep); + resModel.add(ocAttribute.attrname(), subResModel); + } + else if (OC::AttributeType::Vector == ocAttribute.type()) + { + handleVectorType(resModel, ocAttribute); + } + } + } + + void handleVectorType(SimulatorResourceModel &resModel, + const OC::OCRepresentation::AttributeItem &ocAttribute) { - m_rep.setValue(m_key, value); + if (1 == ocAttribute.depth()) + { + handleVectorTypeDepth1(resModel, ocAttribute); + } + else if (2 == ocAttribute.depth()) + { + handleVectorTypeDepth2(resModel, ocAttribute); + } + else if (3 == ocAttribute.depth()) + { + handleVectorTypeDepth3(resModel, ocAttribute); + } } - OC::OCRepresentation &&getRep() + void handleVectorTypeDepth1(SimulatorResourceModel &resModel, + const OC::OCRepresentation::AttributeItem &ocAttribute) { - return std::move(m_rep); + if (OC::AttributeType::Integer == ocAttribute.base_type()) + { + resModel.add(ocAttribute.attrname(), ocAttribute.getValue>()); + } + else if (OC::AttributeType::Double == ocAttribute.base_type()) + { + resModel.add(ocAttribute.attrname(), ocAttribute.getValue>()); + } + else if (OC::AttributeType::Boolean == ocAttribute.base_type()) + { + resModel.add(ocAttribute.attrname(), ocAttribute.getValue>()); + } + else if (OC::AttributeType::String == ocAttribute.base_type()) + { + resModel.add(ocAttribute.attrname(), ocAttribute.getValue>()); + } + else if (OC::AttributeType::OCRepresentation == ocAttribute.base_type()) + { + std::vector subResModelArray; + std::vector ocSubRepArray = + ocAttribute.getValue>(); + + for (size_t i = 0; i < ocSubRepArray.size(); i++) + { + handleRepresentationType(subResModelArray[i], ocSubRepArray[i]); + } + + resModel.add>(ocAttribute.attrname(), subResModelArray); + } } - private: - OC::OCRepresentation m_rep; - std::string m_key; + void handleVectorTypeDepth2(SimulatorResourceModel &resModel, + const OC::OCRepresentation::AttributeItem &ocAttribute) + { + if (OC::AttributeType::Integer == ocAttribute.base_type()) + { + resModel.add(ocAttribute.attrname(), ocAttribute.getValue>>()); + } + else if (OC::AttributeType::Double == ocAttribute.base_type()) + { + resModel.add(ocAttribute.attrname(), ocAttribute.getValue>>()); + } + else if (OC::AttributeType::Boolean == ocAttribute.base_type()) + { + resModel.add(ocAttribute.attrname(), ocAttribute.getValue>>()); + } + else if (OC::AttributeType::String == ocAttribute.base_type()) + { + resModel.add(ocAttribute.attrname(), ocAttribute.getValue>>()); + } + else if (OC::AttributeType::OCRepresentation == ocAttribute.base_type()) + { + std::vector> subResModelArray; + std::vector> ocSubRepArray = + ocAttribute.getValue>>(); + + for (size_t i = 0; i < ocSubRepArray.size(); i++) + { + for (size_t j = 0; j < ocSubRepArray[i].size(); j++) + { + handleRepresentationType(subResModelArray[i][j], ocSubRepArray[i][j]); + } + } + + resModel.add>>( + ocAttribute.attrname(), subResModelArray); + } + } + + void handleVectorTypeDepth3(SimulatorResourceModel &resModel, + const OC::OCRepresentation::AttributeItem &ocAttribute) + { + if (OC::AttributeType::Integer == ocAttribute.base_type()) + { + resModel.add(ocAttribute.attrname(), + ocAttribute.getValue>>>()); + } + else if (OC::AttributeType::Double == ocAttribute.base_type()) + { + resModel.add(ocAttribute.attrname(), + ocAttribute.getValue>>>()); + } + else if (OC::AttributeType::Boolean == ocAttribute.base_type()) + { + resModel.add(ocAttribute.attrname(), + ocAttribute.getValue>>>()); + } + else if (OC::AttributeType::String == ocAttribute.base_type()) + { + resModel.add(ocAttribute.attrname(), + ocAttribute.getValue>>>()); + } + else if (OC::AttributeType::OCRepresentation == ocAttribute.base_type()) + { + std::vector>> subResModelArray; + std::vector>> ocSubRepArray = + ocAttribute.getValue>>>(); + + for (size_t i = 0; i < ocSubRepArray.size(); i++) + { + for (size_t j = 0; j < ocSubRepArray[i].size(); j++) + { + for (size_t k = 0; k < ocSubRepArray[i].size(); k++) + { + handleRepresentationType(subResModelArray[i][j][k], ocSubRepArray[i][j][k]); + } + } + } + + resModel.add>>>( + ocAttribute.attrname(), subResModelArray); + } + } }; -class range_validation : public boost::static_visitor +class RangeValidater : public boost::static_visitor { public: - range_validation (SimulatorResourceModel::Attribute &attrItem) - : m_attrItem(attrItem) {} + RangeValidater(SimulatorResourceModel::AttributeProperty &property) : + m_property(property) {} - bool operator ()(int &value) + bool operator ()(const int &value) { - int min, max; - m_attrItem.getRange(min, max); - if (value >= min && value <= max) + if (checkIntRange(value) || checkSupportedValueSet(value)) return true; return false; } - bool operator ()(double &value) + bool operator ()(const double &value) { - std::vector values - = m_attrItem.getAllowedValues(); - if(0 == values.size()) + return checkSupportedValueSet(value); + } + + bool operator ()(const std::string &value) + { + int len = value.length(); + if (checkIntRange(len) || checkSupportedValueSet(value)) return true; - for (SimulatorResourceModel::Attribute::ValueVariant & val : values) - { - SimulatorResourceModel::Attribute::ValueVariant vVal = value; - if (val == vVal) - return true; - } return false; } - bool operator ()(bool &value) + template + bool operator ()(const T &) { return true; } - bool operator ()(std::string &value) + private: + inline bool isValidProperty() { - std::vector values - = m_attrItem.getAllowedValues(); - if(0 == values.size()) + if (SimulatorResourceModel::AttributeProperty::Type::UNKNOWN != + m_property.type()) return true; - for (SimulatorResourceModel::Attribute::ValueVariant & vVal : values) + return false; + } + + bool checkIntRange(const int &value) + { + if (SimulatorResourceModel::AttributeProperty::Type::RANGE == + m_property.type()) { - std::string val = boost::get(vVal); - if (val == value) + if (value >= m_property.min() && value <= m_property.max()) return true; } return false; } - private: - SimulatorResourceModel::Attribute &m_attrItem; + template + bool checkSupportedValueSet(const T &value) + { + if (SimulatorResourceModel::AttributeProperty::Type::VALUE_SET == + m_property.type()) + { + for (auto &element : m_property.valueSet()) + { + T allowedValue = boost::get(element); + if (allowedValue == value) + return true; + } + } + + return false; + } + + SimulatorResourceModel::AttributeProperty &m_property; }; -SimulatorResourceModel::Attribute::ValueVariant -&SimulatorResourceModel::Attribute::AllowedValues::at(unsigned int index) +class ToStringConverter { - return m_values.at(index); + public: + class ValueVisitor : public boost::static_visitor + { + public: + + // Single basic type value conversion to string + template + std::string operator ()(const T &value) + { + try + { + return boost::lexical_cast(value); + } + catch (const boost::bad_lexical_cast &e) + { + return "CONVERSION_FAILED!"; + } + } + + // SimulatorResourceModel conversion to string + std::string operator ()(const SimulatorResourceModel &value) + { + std::ostringstream out; + out << "{ "; + for (auto &element : value.getValues()) + { + out << "\"" << element.first << "\" : "; + + ValueVisitor visitor; + out << boost::apply_visitor(visitor, element.second); + + out << ", "; + } + out << "}"; + return out.str(); + } + + template + std::string operator ()(const std::vector &values) + { + std::ostringstream out; + out << "[ "; + + for (size_t i = 0; i < values.size(); i++) + { + out << operator ()(values[i]); + out << " "; + } + + out << "]"; + return out.str(); + } + + template + std::string operator ()(const std::vector> &values) + { + std::ostringstream out; + out << "[ "; + + for (size_t i = 0; i < values.size(); i++) + { + out << operator ()(values[i]); + out << " "; + } + + out << "]"; + return out.str(); + } + + template + std::string operator ()(const std::vector>> &values) + { + std::ostringstream out; + out << "[ "; + + for (size_t i = 0; i < values.size(); i++) + { + out << operator ()(values[i]); + out << " "; + } + + out << "]"; + return out.str(); + } + }; + + std::string getStringRepresentation(const SimulatorResourceModel &resModel) + { + ValueVisitor visitor; + SimulatorResourceModel::ValueVariant value = resModel; + return boost::apply_visitor(visitor, value); + } + + std::string getStringRepresentation(const SimulatorResourceModel::ValueVariant &value) + { + ValueVisitor visitor; + return boost::apply_visitor(visitor, value); + } +}; + +SimulatorResourceModel::TypeInfo::TypeInfo( + SimulatorResourceModel::ValueType type = SimulatorResourceModel::ValueType::UNKNOWN, + SimulatorResourceModel::ValueType baseType = SimulatorResourceModel::ValueType::UNKNOWN, + int depth = 0) + : m_type (type), m_baseType(baseType), m_depth(depth) {} + +SimulatorResourceModel::ValueType SimulatorResourceModel::TypeInfo::type() const +{ + return m_type; +} + +SimulatorResourceModel::ValueType SimulatorResourceModel::TypeInfo::baseType() const +{ + return m_baseType; } -int SimulatorResourceModel::Attribute::AllowedValues::size() const +int SimulatorResourceModel::TypeInfo::depth() const { - return m_values.size(); + return m_depth; +} + +bool SimulatorResourceModel::TypeInfo::operator==( + const SimulatorResourceModel::TypeInfo &rhs ) const +{ + if (m_type == rhs.type() && m_baseType == rhs.baseType() + && m_depth == rhs.depth()) + return true; + return false; } -std::vector SimulatorResourceModel::Attribute::AllowedValues::toString() const +bool SimulatorResourceModel::TypeInfo::operator!=( + const SimulatorResourceModel::TypeInfo &rhs ) const { - std::vector values; + if (m_type != rhs.type() || m_baseType != rhs.baseType() + || m_depth != rhs.depth()) + return true; + return false; +} - for (auto & value : m_values) +std::string SimulatorResourceModel::AttributeProperty::valueSetToString() const +{ + std::ostringstream out; + out << "[ "; + for (auto &value : m_valueSet) { - to_string_visitor visitor; - values.push_back(boost::apply_visitor(visitor, value)); + out << ToStringConverter().getStringRepresentation(value); + out << ", "; } - return values; + out << "]"; + return out.str(); } -std::vector -SimulatorResourceModel::Attribute::AllowedValues::getValues() const +SimulatorResourceModel::AttributeProperty::AttributeProperty() + : m_type(SimulatorResourceModel::AttributeProperty::Type::UNKNOWN), + m_min(INT_MIN), + m_max(INT_MAX) {} + +SimulatorResourceModel::AttributeProperty::AttributeProperty(int min, int max) + : m_type(SimulatorResourceModel::AttributeProperty::Type::RANGE), + m_min(min), + m_max(max) {} + +SimulatorResourceModel::AttributeProperty::AttributeProperty( + const std::vector &valueSet) + : m_type(SimulatorResourceModel::AttributeProperty::Type::VALUE_SET), + m_min(INT_MIN), + m_max(INT_MAX), + m_valueSet(valueSet.begin(), valueSet.end()) {} + +SimulatorResourceModel::AttributeProperty::AttributeProperty( + const std::vector &valueSet) + : m_type(SimulatorResourceModel::AttributeProperty::Type::VALUE_SET), + m_min(INT_MIN), + m_max(INT_MAX), + m_valueSet(valueSet.begin(), valueSet.end()) {} + +SimulatorResourceModel::AttributeProperty::AttributeProperty( + const std::vector &valueSet) + : m_type(SimulatorResourceModel::AttributeProperty::Type::VALUE_SET), + m_min(INT_MIN), + m_max(INT_MAX), + m_valueSet(valueSet.begin(), valueSet.end()) {} + +SimulatorResourceModel::AttributeProperty::AttributeProperty( + const std::vector &valueSet) + : m_type(SimulatorResourceModel::AttributeProperty::Type::VALUE_SET), + m_min(INT_MIN), + m_max(INT_MAX), + m_valueSet(valueSet.begin(), valueSet.end()) {} + +SimulatorResourceModel::AttributeProperty::AttributeProperty( + const std::vector &valueSet) + : m_type(SimulatorResourceModel::AttributeProperty::Type::VALUE_SET), + m_min(INT_MIN), + m_max(INT_MAX), + m_valueSet(valueSet.begin(), valueSet.end()) {} + +SimulatorResourceModel::AttributeProperty::Type +SimulatorResourceModel::AttributeProperty::type() const +{ + return m_type; +} + +int SimulatorResourceModel::AttributeProperty::min() const { - return m_values; + return m_min; } -std::string SimulatorResourceModel::Attribute::getName(void) const +int SimulatorResourceModel::AttributeProperty::max() const { - return m_name; + return m_max; } -void SimulatorResourceModel::Attribute::setName(const std::string &name) +int SimulatorResourceModel::AttributeProperty::valueSetSize() const { - m_name = name; + return m_valueSet.size(); } -void SimulatorResourceModel::Attribute::getRange(int &min, int &max) const +std::vector +SimulatorResourceModel::AttributeProperty::valueSet() const { - min = m_min; - max = m_max; + return m_valueSet; } -void SimulatorResourceModel::Attribute::setRange(const int &min, const int &max) +std::string SimulatorResourceModel::Attribute::getName() const { - m_min = min; - m_max = max; + return m_name; } -int SimulatorResourceModel::Attribute::getAllowedValuesSize() const +SimulatorResourceModel::TypeInfo SimulatorResourceModel::Attribute::getType() const { - return m_allowedValues.size(); + if (m_value) + { + AttributeTypeVisitor typeVisitor; + boost::apply_visitor(typeVisitor, *(m_value.get())); + SimulatorResourceModel::TypeInfo typeInfo(typeVisitor.m_type, typeVisitor.m_baseType, + typeVisitor.m_depth); + return typeInfo; + } + + return SimulatorResourceModel::TypeInfo(); } -void SimulatorResourceModel::Attribute::setFromAllowedValue(unsigned int index) +const SimulatorResourceModel::AttributeProperty & +SimulatorResourceModel::Attribute::getProperty() const { - m_value = m_allowedValues.at(index); + return m_property; } -SimulatorResourceModel::Attribute::ValueType SimulatorResourceModel::Attribute::getValueType() const +SimulatorResourceModel::AttributeProperty &SimulatorResourceModel::Attribute::getProperty() { - attribute_type_visitor typeVisitor; - return boost::apply_visitor(typeVisitor, m_value); + return m_property; } -std::string SimulatorResourceModel::Attribute::valueToString() const +void SimulatorResourceModel::Attribute::setName(const std::string &name) { - to_string_visitor visitor; - return boost::apply_visitor(visitor, m_value); + m_name = name; } -std::vector SimulatorResourceModel::Attribute::allowedValuesToString() const +void SimulatorResourceModel::Attribute::setProperty( + const SimulatorResourceModel::AttributeProperty &property) { - return m_allowedValues.toString(); + m_property = property; } -void SimulatorResourceModel::Attribute::addValuetoRepresentation(OC::OCRepresentation &rep, - const std::string &key) const +std::string SimulatorResourceModel::Attribute::toString() const { - add_to_representation visitor(rep, key); - boost::apply_visitor(visitor, m_value); - rep = visitor.getRep(); + return ToStringConverter().getStringRepresentation(*m_value); } -bool SimulatorResourceModel::Attribute::compare(SimulatorResourceModel::Attribute &attribute) +bool SimulatorResourceModel::add(const SimulatorResourceModel::Attribute &attribute) { - // Check the value types - if (m_value.which() != attribute.getValue().which()) - { + if (attribute.getName().empty()) return false; + + if (m_attributes.end() == m_attributes.find(attribute.getName())) + { + m_attributes[attribute.getName()] = attribute.getValue(); + if (SimulatorResourceModel::AttributeProperty::Type::UNKNOWN != + attribute.getProperty().type()) + { + m_attrProperties[attribute.getName()] = attribute.getProperty(); + } + return true; } - // Check the value in allowed range - range_validation visitor(*this); - return boost::apply_visitor(visitor, attribute.getValue()); + return false; +} + +bool SimulatorResourceModel::updateValue(const SimulatorResourceModel::Attribute &attribute, + bool overwrite) +{ + return setAttributeValue(attribute.getName(), attribute.getValue(), false, overwrite); } -std::vector -SimulatorResourceModel::Attribute::getAllowedValues() const +bool SimulatorResourceModel::containsAttribute(const std::string &key) { - return m_allowedValues.getValues(); + if (m_attributes.end() != m_attributes.find(key)) + return true; + return false; } -bool SimulatorResourceModel::getAttribute(const std::string &attrName, Attribute &value) +bool SimulatorResourceModel::setAttributeProperty(const std::string &key, + const SimulatorResourceModel::AttributeProperty &property) { - if (m_attributes.end() != m_attributes.find(attrName)) + if (!key.empty() && m_attributes.end() != m_attributes.find(key)) { - value = m_attributes[attrName]; + m_attrProperties[key] = property; return true; } return false; } -std::map SimulatorResourceModel::getAttributes() -const +bool SimulatorResourceModel::getAttributeProperty(const std::string &key, + SimulatorResourceModel::AttributeProperty &property) { - return m_attributes; + if (m_attrProperties.end() != m_attrProperties.find(key)) + { + property = m_attrProperties[key]; + return true; + } + + return false; } -void SimulatorResourceModel::addAttribute(const SimulatorResourceModel::Attribute &attribute, bool overwrite) +int SimulatorResourceModel::size() const { - if (!attribute.getName().empty() && - (m_attributes.end() == m_attributes.find(attribute.getName()) || overwrite)) + return m_attributes.size(); +} + +SimulatorResourceModel::TypeInfo SimulatorResourceModel::getType(const std::string &key) +{ + if (m_attributes.end() != m_attributes.find(key)) { - m_attributes[attribute.getName()] = attribute; + return getTypeInfo(m_attributes.find(key)->second); } + + return SimulatorResourceModel::TypeInfo(); } -void SimulatorResourceModel::setRange(const std::string &attrName, const int min, const int max) +SimulatorResourceModel::TypeInfo SimulatorResourceModel::getTypeInfo(const ValueVariant &value) +const { - if (m_attributes.end() != m_attributes.find(attrName)) - m_attributes[attrName].setRange(min, max); + AttributeTypeVisitor typeVisitor; + boost::apply_visitor(typeVisitor, value); + SimulatorResourceModel::TypeInfo typeInfo(typeVisitor.m_type, typeVisitor.m_baseType, + typeVisitor.m_depth); + return typeInfo; } -void SimulatorResourceModel::setUpdateInterval(const std::string &attrName, int interval) +std::map SimulatorResourceModel::getValues() +const { - if (m_attributes.end() != m_attributes.find(attrName)) - m_attributes[attrName].setUpdateFrequencyTime(interval); + return m_attributes; } -void SimulatorResourceModel::updateAttributeFromAllowedValues(const std::string &attrName, - unsigned int index) +std::map SimulatorResourceModel::getAttributes() { - if (m_attributes.end() != m_attributes.find(attrName)) - m_attributes[attrName].setFromAllowedValue(index); + std::map attributes; + for (auto &element : m_attributes) + { + SimulatorResourceModel::Attribute attribute(element.first); + attribute.setValue(element.second); + + if (m_attrProperties.end() != m_attrProperties.find(element.first)) + attribute.setProperty(m_attrProperties[element.first]); + + attributes[element.first] = attribute; + } + + return attributes; } -void SimulatorResourceModel::removeAttribute(const std::string &attrName) +bool SimulatorResourceModel::getAttribute(const std::string &key, + SimulatorResourceModel::Attribute &attribute) { - if (attrName.empty() || m_attributes.end() == m_attributes.find(attrName)) - { - OC_LOG(ERROR, TAG, "Attribute name is empty or not found in model!"); - throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Attribute not found in model!"); - } + if (m_attributes.end() != m_attributes.find(key)) + { + attribute.setName(m_attributes.find(key)->first); + attribute.setValue(m_attributes.find(key)->second); + + if (m_attrProperties.end() != m_attrProperties.find(key)) + attribute.setProperty(m_attrProperties[key]); + + return true; + } - m_attributes.erase(attrName); - return; + return false; } -OC::OCRepresentation SimulatorResourceModel::getOCRepresentation() const +bool SimulatorResourceModel::removeAttribute(const std::string &key) { - OC::OCRepresentation rep; - for (auto & attribute : m_attributes) + if (m_attributes.end() == m_attributes.find(key)) { - (attribute.second).addValuetoRepresentation(rep, attribute.first); + return false; } - return rep; + m_attributes.erase(m_attributes.find(key)); + return true; } bool SimulatorResourceModel::update(OC::OCRepresentation &ocRep) { - if (0 == ocRep.size()) - return true; + SimulatorResourceModel resModel = SimulatorResourceModel::build(ocRep); + return update(resModel); +} - // Convert OCRepresentation to SimulatorResourceModel - SimulatorResourceModelSP resModel = create(ocRep); +OC::OCRepresentation SimulatorResourceModel::getOCRepresentation() +{ + OCRepresentationBuilder ocRepBuilder; + return ocRepBuilder.build(*this); +} - return update(resModel); +SimulatorResourceModel SimulatorResourceModel::build(const OC::OCRepresentation &ocRep) +{ + SimulatorResourceModelBuilder resModelBuilder; + return resModelBuilder.build(ocRep); } -bool SimulatorResourceModel::update(SimulatorResourceModelSP &repModel) +bool SimulatorResourceModel::update(SimulatorResourceModel &resModel) { - std::map attributes = repModel->getAttributes(); - for (auto & attributeItem : attributes) + if (false == match(resModel)) { - // Check the attribute presence - SimulatorResourceModel::Attribute attribute; - if (false == getAttribute((attributeItem.second).getName(), attribute)) + return false; + } + + for (auto &element : resModel.getValues()) + { + if (m_attributes.end() != m_attributes.find(element.first)) { - return false; + m_attributes[element.first] = element.second; } + } - // Check the validity of the value to be set - if (false == attribute.compare(attributeItem.second)) + return true; +} + +bool SimulatorResourceModel::setAttributeValue(const std::string &key, + const ValueVariant &newValue, bool create, bool overwrite) +{ + if (key.empty()) + { + OC_LOG(ERROR, TAG, "Invalid key!"); + throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Attribute name is empty!"); + } + + /* + * Add new entry to attributes map table if key doest not exist, + * othewise check the value update policy before setting value. + */ + if (m_attributes.end() == m_attributes.find(key) && create) + { + m_attributes[key] = newValue; + } + else + { + if (true == match(key, newValue)) + { + m_attributes[key] = newValue; + } + else if (overwrite) + { + m_attributes[key] = newValue; + m_attrProperties.erase(m_attrProperties.find(key)); + } + else { return false; } - m_attributes[(attributeItem.second).getName()].setValue((attributeItem.second).getValue()); } return true; } -SimulatorResourceModelSP SimulatorResourceModel::create(const OC::OCRepresentation &ocRep) +bool SimulatorResourceModel::match(const std::string &key, + const SimulatorResourceModel::ValueVariant &newValue) +{ + if (m_attributes.end() != m_attributes.find(key)) + { + // Check the type of values + if (getTypeInfo(m_attributes[key]) != getTypeInfo(newValue)) + { + return false; + } + + // Check the value based on attribute property + SimulatorResourceModel::AttributeProperty prop; + if (getAttributeProperty(key, prop) + && SimulatorResourceModel::AttributeProperty::Type::UNKNOWN != prop.type()) + { + RangeValidater rangeValidater(prop); + return boost::apply_visitor(rangeValidater, newValue); + } + + return true; + } + + return false; +} + +bool SimulatorResourceModel::match(const SimulatorResourceModel &resModel, bool strict) { - SimulatorResourceModelSP resModel(new SimulatorResourceModel); - for (auto & attributeItem : ocRep) + for (auto &element : resModel.getValues()) { - SimulatorResourceModel::Attribute attribute; - if (attributeItem.type() == OC::AttributeType::Integer) - attribute.setValue(attributeItem.getValue()); - if (attributeItem.type() == OC::AttributeType::Double) - attribute.setValue(attributeItem.getValue()); - if (attributeItem.type() == OC::AttributeType::String) - attribute.setValue(attributeItem.getValue()); - if (attributeItem.type() == OC::AttributeType::Boolean) - attribute.setValue(attributeItem.getValue()); - - attribute.setName(attributeItem.attrname()); - resModel->m_attributes[attributeItem.attrname()] = attribute; + // Attribute presence check + if (m_attributes.end() == m_attributes.find(element.first) && !strict) + { + continue; + } + else if (strict) + { + return false; + } + + // Attribute value type check + if (getTypeInfo(m_attributes[element.first]) != getTypeInfo(element.second)) + { + return false; + } + + SimulatorResourceModel::AttributeProperty prop; + if (getAttributeProperty(element.first, prop)) + { + RangeValidater rangeValidater(prop); + if (false == boost::apply_visitor(rangeValidater, element.second)) + { + return false; + } + } } - return resModel; + + return true; } +std::string SimulatorResourceModel::toString() const +{ + return ToStringConverter().getStringRepresentation(*this); +} diff --git a/service/simulator/src/common/simulator_utils.cpp b/service/simulator/src/common/simulator_utils.cpp index 08ca59f..d8cfe90 100644 --- a/service/simulator/src/common/simulator_utils.cpp +++ b/service/simulator/src/common/simulator_utils.cpp @@ -23,39 +23,132 @@ std::string getPayloadString(const OC::OCRepresentation &rep) { - std::ostringstream data; OCRepPayload *payload = rep.getPayload(); if (!payload) { - return "Payload: No payload"; + return "Empty payload"; } + std::ostringstream data; + std::ostringstream dummy; - // URI - data << "URI: " << payload->uri << std::endl; + std::string payloadType; + OCStringLL *types; + OCStringLL *interfaces; + OCRepPayloadValue *values; - // Attributes - data << "Attributes:" << std::endl; - OCRepPayloadValue *values = payload->values; - while (NULL != values) + // Iterate the payload list + while (payload) { - data << values->name << ":" << rep.getValueToString(values->name) << std::endl; - values = values->next; + // Payload type + payloadType = getPayloadTypeString(payload->base.type); + if (!payloadType.empty()) + data << "Payload type: " << payloadType << std::endl; + + // URI + if (NULL != payload->uri && strlen(payload->uri) > 0) + data << "URI: " << payload->uri << std::endl; + + // Types + types = payload->types; + while (types) + { + if (NULL != types->value && strlen(types->value) > 0) + { + dummy << types->value; + if (types->next) + dummy << ", "; + } + types = types->next; + } + if (!dummy.str().empty()) + { + data << "Types: " << dummy.str() << std::endl; + dummy.str(""); + } + + // Interfaces + interfaces = payload->interfaces; + while (interfaces) + { + if (NULL != interfaces->value && strlen(interfaces->value) > 0) + { + dummy << interfaces->value; + if (interfaces->next) + dummy << ", "; + } + interfaces = interfaces->next; + } + if (!dummy.str().empty()) + { + data << "Interfaces: " << dummy.str() << std::endl; + dummy.str(""); + } + + // Values + values = payload->values; + while (values) + { + dummy << "\t" << values->name << ":" << rep.getValueToString(values->name) << std::endl; + values = values->next; + } + if (!dummy.str().empty()) + { + data << "Values:-" << std::endl; + data << dummy.str(); + dummy.str(""); + } + payload = payload->next; + if (payload) + data << "----------------" << std::endl; } return data.str(); } +std::string getPayloadTypeString(OCPayloadType type) +{ + std::string typeStr; + switch (type) + { + case PAYLOAD_TYPE_INVALID: + typeStr = "PAYLOAD_TYPE_INVALID"; + break; + case PAYLOAD_TYPE_DISCOVERY: + typeStr = "PAYLOAD_TYPE_DISCOVERY"; + break; + case PAYLOAD_TYPE_DEVICE: + typeStr = "PAYLOAD_TYPE_DEVICE"; + break; + case PAYLOAD_TYPE_PLATFORM: + typeStr = "PAYLOAD_TYPE_PLATFORM"; + break; + case PAYLOAD_TYPE_REPRESENTATION: + typeStr = "PAYLOAD_TYPE_REPRESENTATION"; + break; + case PAYLOAD_TYPE_SECURITY: + typeStr = "PAYLOAD_TYPE_SECURITY"; + break; + case PAYLOAD_TYPE_PRESENCE: + typeStr = "PAYLOAD_TYPE_PRESENCE"; + break; + } + return typeStr; +} + std::string getRequestString(const std::map &queryParams, const OC::OCRepresentation &rep) { std::ostringstream data; - data << "qp: "; + std::ostringstream dummy; if (queryParams.size() > 0) { - for (auto & qp : queryParams) - data << qp.second << ","; + for (auto &qp : queryParams) + dummy << qp.second << ","; + } + if (!dummy.str().empty()) + { + data << "qp: " << dummy.str() << std::endl; } - data << getPayloadString(rep); return data.str(); } @@ -63,13 +156,16 @@ std::string getRequestString(const std::map &queryPara std::string getRequestString(const std::map &queryParams) { std::ostringstream data; - data << "qp: "; + std::ostringstream dummy; if (queryParams.size() > 0) { - for (auto & qp : queryParams) - data << qp.second << ","; + for (auto &qp : queryParams) + dummy << qp.second << ","; + } + if (!dummy.str().empty()) + { + data << "qp: " << dummy.str() << std::endl; } - data << "Payload: No payload"; return data.str(); } \ No newline at end of file diff --git a/service/simulator/src/common/simulator_utils.h b/service/simulator/src/common/simulator_utils.h index 23dd47f..c6fb66e 100644 --- a/service/simulator/src/common/simulator_utils.h +++ b/service/simulator/src/common/simulator_utils.h @@ -34,7 +34,7 @@ #include /** - * Utilities for Invokation of OC platfrom level APIs. + * Utilities for Invocation of OC platfrom level APIs. */ template typename std::enable_if()(std::declval()...))>::value>::type @@ -62,8 +62,13 @@ namespace OC } std::string getPayloadString(const OC::OCRepresentation &); +std::string getPayloadTypeString(OCPayloadType type); std::string getRequestString(const std::map &queryParams, const OC::OCRepresentation &rep); std::string getRequestString(const std::map &queryParams); + +#define VALIDATE_INPUT(CONDITION, MSG) if (CONDITION) {throw InvalidArgsException(SIMULATOR_INVALID_PARAM, MSG);} +#define VALIDATE_CALLBACK(CALLBACK) if (!CALLBACK){throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");} + #endif \ No newline at end of file diff --git a/service/simulator/src/service-provider/resource_update_automation.cpp b/service/simulator/src/server/resource_update_automation.cpp similarity index 58% rename from service/simulator/src/service-provider/resource_update_automation.cpp rename to service/simulator/src/server/resource_update_automation.cpp index f2f2bc0..1fbc607 100644 --- a/service/simulator/src/service-provider/resource_update_automation.cpp +++ b/service/simulator/src/server/resource_update_automation.cpp @@ -19,7 +19,7 @@ ******************************************************************/ #include "resource_update_automation.h" -#include "simulator_resource_server_impl.h" +#include "simulator_single_resource_impl.h" #include "attribute_generator.h" #include "simulator_exceptions.h" #include "simulator_logger.h" @@ -30,36 +30,27 @@ #define SLEEP_FOR(X) if (X > 0) std::this_thread::sleep_for(std::chrono::milliseconds(X)); -AttributeUpdateAutomation::AttributeUpdateAutomation(int id, SimulatorResourceServer *resource, - const std::string &attrName, AutomationType type, int interval, +AttributeUpdateAutomation::AttributeUpdateAutomation(int id, SimulatorSingleResource *resource, + const SimulatorResourceModel::Attribute &attribute, AutomationType type, int interval, updateCompleteCallback callback, std::function finishedCallback) : m_resource(resource), - m_attrName(attrName), m_type(type), m_id(id), m_stopRequested(false), m_updateInterval(interval), + m_attributeGen(attribute), m_callback(callback), m_finishedCallback(finishedCallback), - m_thread(nullptr) {} - -void AttributeUpdateAutomation::start() + m_thread(nullptr) { - // Check the validity of attribute - SimulatorResourceModel resModel = m_resource->getModel(); - if (false == resModel.getAttribute(m_attrName, m_attribute)) - { - OC_LOG_V(ERROR, ATAG, "Attribute:%s not present in resource!", m_attrName.c_str()); - throw SimulatorException(SIMULATOR_ERROR, "Attribute is not present in resource!"); - } - if (m_updateInterval < 0) { - m_updateInterval = m_attribute.getUpdateFrequencyTime(); - if (0 > m_updateInterval) - m_updateInterval = 0; + m_updateInterval = 0; } +} +void AttributeUpdateAutomation::start() +{ m_thread = new std::thread(&AttributeUpdateAutomation::updateAttribute, this); } @@ -72,20 +63,37 @@ void AttributeUpdateAutomation::stop() void AttributeUpdateAutomation::updateAttribute() { + SimulatorSingleResourceImpl *resourceImpl = + dynamic_cast(m_resource); + + if (!resourceImpl) + return; + do { try { - setAttributeValue(); + SimulatorResourceModel::Attribute attribute; + while (!m_stopRequested && true == m_attributeGen.next(attribute)) + { + if (false == m_resource->updateAttributeValue(attribute)) + { + OC_LOG_V(ERROR, TAG, "Failed to update the attribute![%s]", attribute.getName()); + continue; + } + resourceImpl->notifyApp(); + + SLEEP_FOR(m_updateInterval); + } + + m_attributeGen.reset(); } catch (SimulatorException &e) { break; } - if (m_stopRequested) - break; } - while (AutomationType::RECURRENT == m_type); + while (!m_stopRequested && AutomationType::RECURRENT == m_type); if (!m_stopRequested) { @@ -93,7 +101,7 @@ void AttributeUpdateAutomation::updateAttribute() SIM_LOG(ILogger::INFO, "Automation of " << m_attrName << " attribute is completed."); } - // Notify application + // Notify application through callback if (m_callback) m_callback(m_resource->getURI(), m_id); @@ -101,43 +109,7 @@ void AttributeUpdateAutomation::updateAttribute() m_finishedCallback(m_id); } -void AttributeUpdateAutomation::setAttributeValue() -{ - SimulatorResourceServerImpl *resourceImpl = - dynamic_cast(m_resource); - if (!resourceImpl) - return; - - if (SimulatorResourceModel::Attribute::ValueType::INTEGER == - m_attribute.getValueType()) // For integer type values - { - int min; - int max; - - m_attribute.getRange(min, max); - for (int value = min; value <= max; value++) - { - if (m_stopRequested) - break; - resourceImpl->updateAttributeValue(m_attribute.getName(), value); - resourceImpl->notifyApp(); - SLEEP_FOR(m_updateInterval); - } - } - else - { - for (int index = 0; index < m_attribute.getAllowedValuesSize(); index++) - { - if (m_stopRequested) - break; - resourceImpl->updateFromAllowedValues(m_attribute.getName(), index); - resourceImpl->notifyApp(); - SLEEP_FOR(m_updateInterval); - } - } -} - -ResourceUpdateAutomation::ResourceUpdateAutomation(int id, SimulatorResourceServer *resource, +ResourceUpdateAutomation::ResourceUpdateAutomation(int id, SimulatorSingleResource *resource, AutomationType type, int interval, updateCompleteCallback callback, std::function finishedCallback) : m_resource(resource), @@ -151,19 +123,18 @@ ResourceUpdateAutomation::ResourceUpdateAutomation(int id, SimulatorResourceServ void ResourceUpdateAutomation::start() { - SimulatorResourceModel resModel = m_resource->getModel(); - std::map attributesTable = - resModel.getAttributes(); - if (0 == attributesTable.size()) + std::vector attributes; + for (auto &attributeEntry : m_resource->getResourceModel().getAttributes()) + { + attributes.push_back(attributeEntry.second); + } + + if (0 == attributes.size()) { OC_LOG(ERROR, RTAG, "Resource has zero attributes!"); throw SimulatorException(SIMULATOR_ERROR, "Resource has zero attributes!"); } - std::vector attributes; - for (auto &attributeEntry : attributesTable) - attributes.push_back(attributeEntry.second); - m_thread = new std::thread(&ResourceUpdateAutomation::updateAttributes, this, attributes); } @@ -175,23 +146,30 @@ void ResourceUpdateAutomation::stop() } void ResourceUpdateAutomation::updateAttributes( - std::vector attributes) + std::vector attributes) { - SimulatorResourceServerImpl *resourceImpl = - dynamic_cast(m_resource); + SimulatorSingleResourceImpl *resourceImpl = + dynamic_cast(m_resource); + + if (!resourceImpl) + return; - AttributeCombinationGen attrCombGen(attributes); - SimulatorResourceModel resModel; - while (!m_stopRequested && attrCombGen.next(resModel)) + do { - for (auto &attributeEntry : resModel.getAttributes()) + AttributeCombinationGen attrCombGen(attributes); + SimulatorResourceModel resModel; + while (!m_stopRequested && attrCombGen.next(resModel)) { - resourceImpl->updateAttributeValue(attributeEntry.first, attributeEntry.second.getValue()); - } + for (auto &attributeEntry : resModel.getAttributes()) + { + resourceImpl->updateAttributeValue(attributeEntry.second); + } - resourceImpl->notifyApp(); - SLEEP_FOR(m_updateInterval); + resourceImpl->notifyApp(); + SLEEP_FOR(m_updateInterval); + } } + while (!m_stopRequested && AutomationType::RECURRENT == m_type); // Notify application if (m_callback) diff --git a/service/simulator/src/service-provider/resource_update_automation.h b/service/simulator/src/server/resource_update_automation.h similarity index 81% rename from service/simulator/src/service-provider/resource_update_automation.h rename to service/simulator/src/server/resource_update_automation.h index 6ae1f0e..a3dc6d1 100644 --- a/service/simulator/src/service-provider/resource_update_automation.h +++ b/service/simulator/src/server/resource_update_automation.h @@ -21,14 +21,16 @@ #ifndef RESOURCE_UPDATE_AUTOMATION_H_ #define RESOURCE_UPDATE_AUTOMATION_H_ -#include "simulator_resource_server.h" +#include "simulator_single_resource.h" +#include "attribute_generator.h" #include class AttributeUpdateAutomation { public: - AttributeUpdateAutomation(int id, SimulatorResourceServer *resource, - const std::string &attrName, AutomationType type, int interval, + AttributeUpdateAutomation(int id, SimulatorSingleResource *resource, + const SimulatorResourceModel::Attribute &attribute, + AutomationType type, int interval, updateCompleteCallback callback, std::function finishedCallback); @@ -38,15 +40,14 @@ class AttributeUpdateAutomation private: void updateAttribute(); - void setAttributeValue(); - SimulatorResourceServer *m_resource; + SimulatorSingleResource *m_resource; std::string m_attrName; AutomationType m_type; int m_id; bool m_stopRequested; int m_updateInterval; - SimulatorResourceModel::Attribute m_attribute; + AttributeGenerator m_attributeGen; updateCompleteCallback m_callback; std::function m_finishedCallback; std::thread *m_thread; @@ -57,7 +58,7 @@ typedef std::shared_ptr AttributeUpdateAutomationSP; class ResourceUpdateAutomation { public: - ResourceUpdateAutomation(int id, SimulatorResourceServer *resource, + ResourceUpdateAutomation(int id, SimulatorSingleResource *resource, AutomationType type, int interval, updateCompleteCallback callback, std::function finishedCallback); @@ -69,7 +70,7 @@ class ResourceUpdateAutomation private: void updateAttributes(std::vector attributes); - SimulatorResourceServer *m_resource; + SimulatorSingleResource *m_resource; AutomationType m_type; int m_id; bool m_stopRequested; diff --git a/service/simulator/src/service-provider/resource_update_automation_mngr.cpp b/service/simulator/src/server/resource_update_automation_mngr.cpp similarity index 86% rename from service/simulator/src/service-provider/resource_update_automation_mngr.cpp rename to service/simulator/src/server/resource_update_automation_mngr.cpp index 94eb2c5..06cb53b 100644 --- a/service/simulator/src/service-provider/resource_update_automation_mngr.cpp +++ b/service/simulator/src/server/resource_update_automation_mngr.cpp @@ -28,7 +28,7 @@ UpdateAutomationMngr::UpdateAutomationMngr() : m_id(0) {} -int UpdateAutomationMngr::startResourceAutomation(SimulatorResourceServer *resource, +int UpdateAutomationMngr::startResourceAutomation(SimulatorSingleResource *resource, AutomationType type, int interval, updateCompleteCallback callback) { if (!callback) @@ -51,7 +51,7 @@ int UpdateAutomationMngr::startResourceAutomation(SimulatorResourceServer *resou return m_id++; } -int UpdateAutomationMngr::startAttributeAutomation(SimulatorResourceServer *resource, +int UpdateAutomationMngr::startAttributeAutomation(SimulatorSingleResource *resource, const std::string &attrName, AutomationType type, int interval, updateCompleteCallback callback) { @@ -61,8 +61,16 @@ int UpdateAutomationMngr::startAttributeAutomation(SimulatorResourceServer *reso throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); } + // Check the validity of attribute + SimulatorResourceModel::Attribute attribute; + if (false == resource->getAttribute(attrName, attribute)) + { + OC_LOG_V(ERROR, ATAG, "Attribute:%s not present in resource!", m_attrName.c_str()); + throw SimulatorException(SIMULATOR_ERROR, "Attribute is not present in resource!"); + } + AttributeUpdateAutomationSP attributeAutomation(new AttributeUpdateAutomation( - m_id, resource, attrName, type, interval, callback, + m_id, resource, attribute, type, interval, callback, std::bind(&UpdateAutomationMngr::automationCompleted, this, std::placeholders::_1))); std::lock_guard lock(m_lock); @@ -82,7 +90,7 @@ std::vector UpdateAutomationMngr::getResourceAutomationIds() { std::vector ids; std::lock_guard lock(m_lock); - for (auto & automation : m_resourceUpdationList) + for (auto &automation : m_resourceUpdationList) ids.push_back(automation.first); return ids; @@ -92,7 +100,7 @@ std::vector UpdateAutomationMngr::getAttributeAutomationIds() { std::vector ids; std::lock_guard lock(m_lock); - for (auto & automation : m_attrUpdationList) + for (auto &automation : m_attrUpdationList) ids.push_back(automation.first); return ids; @@ -113,9 +121,6 @@ void UpdateAutomationMngr::stop(int id) m_attrUpdationList.erase(m_attrUpdationList.find(id)); return; } - - //Throw SimulatorException - throw SimulatorException(SIMULATOR_ERROR, "No automation is currently in progress for the given automation Id!"); } void UpdateAutomationMngr::stopAll() diff --git a/service/simulator/src/service-provider/resource_update_automation_mngr.h b/service/simulator/src/server/resource_update_automation_mngr.h similarity index 90% rename from service/simulator/src/service-provider/resource_update_automation_mngr.h rename to service/simulator/src/server/resource_update_automation_mngr.h index 985d79c..68227fd 100644 --- a/service/simulator/src/service-provider/resource_update_automation_mngr.h +++ b/service/simulator/src/server/resource_update_automation_mngr.h @@ -21,7 +21,7 @@ #ifndef RESOURCE_UPDATE_AUTOMATION_MNGR_H_ #define RESOURCE_UPDATE_AUTOMATION_MNGR_H_ -#include "simulator_resource_server.h" +#include "simulator_single_resource.h" #include "resource_update_automation.h" class UpdateAutomationMngr @@ -29,10 +29,10 @@ class UpdateAutomationMngr public: UpdateAutomationMngr(); - int startResourceAutomation(SimulatorResourceServer *resource, + int startResourceAutomation(SimulatorSingleResource *resource, AutomationType type, int interval, updateCompleteCallback callback); - int startAttributeAutomation(SimulatorResourceServer *resource, + int startAttributeAutomation(SimulatorSingleResource *resource, const std::string &attrName, AutomationType type, int interval, updateCompleteCallback callback); diff --git a/service/simulator/src/server/simulator_collection_resource_impl.cpp b/service/simulator/src/server/simulator_collection_resource_impl.cpp new file mode 100644 index 0000000..f46f0aa --- /dev/null +++ b/service/simulator/src/server/simulator_collection_resource_impl.cpp @@ -0,0 +1,499 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +#include "simulator_collection_resource_impl.h" +#include "simulator_utils.h" +#include "simulator_logger.h" +#include "logger.h" + +#define TAG "SIM_COLLECTION_RESOURCE" + +SimulatorCollectionResourceImpl::SimulatorCollectionResourceImpl() + : m_type(SimulatorResource::Type::COLLECTION_RESOURCE), + m_interfaces {OC::DEFAULT_INTERFACE, OC::LINK_INTERFACE}, + m_resourceHandle(NULL) +{ + m_property = static_cast(OC_DISCOVERABLE | OC_OBSERVABLE); +} + +std::string SimulatorCollectionResourceImpl::getName() const +{ + return m_name; +} + +SimulatorResource::Type SimulatorCollectionResourceImpl::getType() const +{ + return m_type; +} + +std::string SimulatorCollectionResourceImpl::getURI() const +{ + return m_uri; +} + +std::string SimulatorCollectionResourceImpl::getResourceType() const +{ + return m_resourceType; +} + +std::vector SimulatorCollectionResourceImpl::getInterface() const +{ + return m_interfaces; +} + +void SimulatorCollectionResourceImpl::setName(const std::string &name) +{ + VALIDATE_INPUT(name.empty(), "Name is empty!") + + std::lock_guard lock(m_objectLock); + if (m_resourceHandle) + { + throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED, + "Name can not be set when collection is started!"); + } + + m_name = name; +} + +void SimulatorCollectionResourceImpl::setURI(const std::string &uri) +{ + VALIDATE_INPUT(uri.empty(), "Uri is empty!") + + std::lock_guard lock(m_objectLock); + if (m_resourceHandle) + { + throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED, + "URI can not be set when collection is started!"); + } + + m_uri = uri; +} + +void SimulatorCollectionResourceImpl::setResourceType(const std::string &resourceType) +{ + VALIDATE_INPUT(resourceType.empty(), "Resource type is empty!") + + std::lock_guard lock(m_objectLock); + if (m_resourceHandle) + { + throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED, + "Resource type can not be set when collection is started!"); + } + + m_resourceType = resourceType; +} + +void SimulatorCollectionResourceImpl::addInterface(std::string interfaceType) +{ + VALIDATE_INPUT(interfaceType.empty(), "Interface type is empty!") + + if (interfaceType == OC::GROUP_INTERFACE) + { + throw NoSupportException("Collection resource does not support this interface type!"); + } + + std::lock_guard lock(m_objectLock); + if (m_resourceHandle) + { + throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED, + "Interface type can not be set when resource is started!"); + } + + auto found = std::find(m_interfaces.begin(), m_interfaces.end(), interfaceType); + if (found != m_interfaces.end()) + m_interfaces.push_back(interfaceType); +} + +void SimulatorCollectionResourceImpl::setObservable(bool state) +{ + std::lock_guard lock(m_objectLock); + if (m_resourceHandle) + { + throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED, + "Observation state can not be changed when resource is started!"); + } + + if (true == state) + m_property = static_cast(m_property | OC_OBSERVABLE); + else + m_property = static_cast(m_property ^ OC_OBSERVABLE); +} + +void SimulatorCollectionResourceImpl::setObserverCallback(ObserverCallback callback) +{ + VALIDATE_CALLBACK(callback) + m_observeCallback = callback; +} + +bool SimulatorCollectionResourceImpl::isObservable() +{ + return (m_property & OC_OBSERVABLE); +} + +bool SimulatorCollectionResourceImpl::isStarted() +{ + return (nullptr != m_resourceHandle); +} + +void SimulatorCollectionResourceImpl::start() +{ + std::lock_guard lock(m_objectLock); + if (m_resourceHandle) + { + throw SimulatorException(SIMULATOR_ERROR, "Collection already registered!"); + } + + if (m_uri.empty() || m_resourceType.empty()) + { + throw SimulatorException(SIMULATOR_ERROR, "Found incomplete data to start resource!"); + } + + typedef OCStackResult (*RegisterResource)(OCResourceHandle &, std::string &, const std::string &, + const std::string &, OC::EntityHandler, uint8_t); + + invokeocplatform(static_cast(OC::OCPlatform::registerResource), + m_resourceHandle, m_uri, m_resourceType, m_interfaces[0], + std::bind(&SimulatorCollectionResourceImpl::handleRequests, + this, std::placeholders::_1), m_property); + + for (size_t index = 1; m_interfaces.size() > 1 && index < m_interfaces.size(); index++) + { + typedef OCStackResult (*bindInterfaceToResource)(const OCResourceHandle &, + const std::string &); + + try + { + invokeocplatform(static_cast( + OC::OCPlatform::bindInterfaceToResource), m_resourceHandle, + m_interfaces[index]); + } + catch (SimulatorException &e) + { + stop(); + throw; + } + } +} + +void SimulatorCollectionResourceImpl::stop() +{ + std::lock_guard lock(m_objectLock); + if (!m_resourceHandle) + return; + + typedef OCStackResult (*UnregisterResource)(const OCResourceHandle &); + + invokeocplatform(static_cast(OC::OCPlatform::unregisterResource), + m_resourceHandle); + + m_resourceHandle = nullptr; +} + +std::vector SimulatorCollectionResourceImpl::getObserversList() +{ + return m_observersList; +} + +void SimulatorCollectionResourceImpl::notify(int id) +{ + std::lock_guard lock(m_objectLock); + if (!m_resourceHandle) + return; + + OC::ObservationIds observers {static_cast(id)}; + sendNotification(observers); +} + +void SimulatorCollectionResourceImpl::notifyAll() +{ + std::lock_guard lock(m_objectLock); + if (!m_resourceHandle) + return; + + if (!m_observersList.size()) + return; + + OC::ObservationIds observers; + for (auto &observer : m_observersList) + observers.push_back(observer.id); + sendNotification(observers); +} + +std::vector SimulatorCollectionResourceImpl::getSupportedResources() +{ + return m_supportedTypes; +} + +void SimulatorCollectionResourceImpl::addChildResource(SimulatorResourceSP &resource) +{ + VALIDATE_INPUT(!resource, "Invalid child resource!") + + std::lock_guard lock(m_childResourcesLock); + if (m_childResources.end() != m_childResources.find(resource->getURI())) + { + throw SimulatorException(SIMULATOR_ERROR, "Child resource with same URI is already exisit!"); + } + + m_childResources[resource->getURI()] = resource; +} + +void SimulatorCollectionResourceImpl::removeChildResource(SimulatorResourceSP &resource) +{ + VALIDATE_INPUT(!resource, "Invalid child resource!") + + std::lock_guard lock(m_childResourcesLock); + if (m_childResources.end() == m_childResources.find(resource->getURI())) + { + throw SimulatorException(SIMULATOR_ERROR, "Child resource not found in collection!"); + } + + m_childResources.erase(m_childResources.find(resource->getURI())); +} + +void SimulatorCollectionResourceImpl::removeChildResource(const std::string &uri) +{ + VALIDATE_INPUT(uri.empty(), "Uri is empty!") + + std::lock_guard lock(m_childResourcesLock); + if (m_childResources.end() == m_childResources.find(uri)) + { + throw SimulatorException(SIMULATOR_ERROR, "Child resource not found in collection!"); + } + + m_childResources.erase(m_childResources.find(uri)); +} + +std::vector SimulatorCollectionResourceImpl::getChildResources() +{ + std::lock_guard lock(m_childResourcesLock); + + std::vector result; + for (auto &entry : m_childResources) + result.push_back(entry.second); + + return result; +} + +OCEntityHandlerResult SimulatorCollectionResourceImpl::handleRequests( + std::shared_ptr request) +{ + if (!request) + return OC_EH_ERROR; + + if (OC::RequestHandlerFlag::RequestFlag & request->getRequestHandlerFlag()) + { + { + OC::OCRepresentation rep = request->getResourceRepresentation(); + std::string payload = getPayloadString(rep); + SIM_LOG(ILogger::INFO, "[" << m_name << "] " << request->getRequestType() + << " request received. \n**Payload details**\n" << payload) + } + + // Handover the request to appropriate interface handler + std::string interfaceType(OC::DEFAULT_INTERFACE); + OC::QueryParamsMap queryParams = request->getQueryParameters(); + if (queryParams.end() != queryParams.find("if")) + interfaceType = queryParams["if"]; + + std::shared_ptr response; + if (interfaceType == OC::DEFAULT_INTERFACE) + { + response = requestOnBaseLineInterface(request); + } + else if (interfaceType == OC::LINK_INTERFACE) + { + response = requestOnLinkListInterface(request); + } + else if (interfaceType == OC::BATCH_INTERFACE) + { + response = requestOnBatchInterface(request); + } + + // Send response if the request handled by resource + if (response) + { + if (OC_STACK_OK != OC::OCPlatform::sendResponse(response)) + return OC_EH_ERROR; + } + else + { + SIM_LOG(ILogger::ERROR, "[" << m_name << "] " << "Unsupported request received!") + return OC_EH_ERROR; + } + } + + if (OC::RequestHandlerFlag::ObserverFlag & request->getRequestHandlerFlag()) + { + if (!isObservable()) + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE request received") + SIM_LOG(ILogger::INFO, "[" << m_uri << "] Sending error as resource is in unobservable state!") + return OC_EH_ERROR; + } + + OC::ObservationInfo observationInfo = request->getObservationInfo(); + if (OC::ObserveAction::ObserveRegister == observationInfo.action) + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE REGISTER request received"); + + ObserverInfo info {observationInfo.obsId, observationInfo.address, observationInfo.port}; + m_observersList.push_back(info); + + if (m_observeCallback) + m_observeCallback(m_uri, ObservationStatus::REGISTER, info); + } + else if (OC::ObserveAction::ObserveUnregister == observationInfo.action) + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE UNREGISTER request received"); + + ObserverInfo info; + for (auto iter = m_observersList.begin(); iter != m_observersList.end(); iter++) + { + if ((info = *iter), info.id == observationInfo.obsId) + { + m_observersList.erase(iter); + break; + } + } + + if (m_observeCallback) + m_observeCallback(m_uri, ObservationStatus::UNREGISTER, info); + } + } + + return OC_EH_OK; +} + +std::shared_ptr SimulatorCollectionResourceImpl::requestOnBaseLineInterface( + std::shared_ptr request) +{ + std::shared_ptr response; + if ("GET" == request->getRequestType()) + { + // Construct the representation + OC::OCRepresentation ocRep = prepareRepresentation(); + response = std::make_shared(); + response->setErrorCode(200); + response->setResponseResult(OC_EH_OK); + response->setResourceRepresentation(ocRep); + std::string resPayload = getPayloadString(ocRep); + SIM_LOG(ILogger::INFO, "[" << m_uri << + "] Sending response for GET request. \n**Payload details**" << resPayload) + } + + // TODO: Handle PUT, POST and DELETE requests + + if (response) + { + response->setRequestHandle(request->getRequestHandle()); + response->setResourceHandle(request->getResourceHandle()); + } + + return response; +} + +std::shared_ptr SimulatorCollectionResourceImpl::requestOnLinkListInterface( + std::shared_ptr request) +{ + std::lock_guard lock(m_childResourcesLock); + std::shared_ptr response; + if ("GET" == request->getRequestType()) + { + // Construct the representation + OC::OCRepresentation ocRep; + std::vector links; + int index = 0; + for (auto &entry : m_childResources) + { + links[index].setValue("href", entry.second->getURI()); + links[index].setValue("rt", entry.second->getResourceType()); + links[index].setValue("if", entry.second->getInterface()[0]); + } + + ocRep.setValue("links", links); + + response = std::make_shared(); + response->setRequestHandle(request->getRequestHandle()); + response->setResourceHandle(request->getResourceHandle()); + response->setErrorCode(200); + response->setResponseResult(OC_EH_OK); + response->setResourceRepresentation(ocRep); + std::string resPayload = getPayloadString(ocRep); + SIM_LOG(ILogger::INFO, "[" << m_uri << + "] Sending response for GET request. \n**Payload details**" << resPayload) + } + + return nullptr; +} + +std::shared_ptr SimulatorCollectionResourceImpl::requestOnBatchInterface( + std::shared_ptr) +{ + // TODO: Handle this interface + return nullptr; +} + +void SimulatorCollectionResourceImpl::sendNotification(OC::ObservationIds &observers) +{ + std::lock_guard lock(m_objectLock); + std::shared_ptr response(new OC::OCResourceResponse()); + response->setErrorCode(200); + response->setResponseResult(OC_EH_OK); + response->setResourceRepresentation(prepareRepresentation(), OC::DEFAULT_INTERFACE); + + typedef OCStackResult (*NotifyListOfObservers)(OCResourceHandle, OC::ObservationIds &, + const std::shared_ptr); + + invokeocplatform(static_cast(OC::OCPlatform::notifyListOfObservers), + m_resourceHandle, observers, response); +} + +OC::OCRepresentation SimulatorCollectionResourceImpl::prepareRepresentation() +{ + OC::OCRepresentation ocRep; + + ocRep.setValue("n", getName()); + ocRep.setResourceTypes({m_resourceType}); + ocRep.setResourceInterfaces(m_interfaces); + + // Add "rts" attribute + std::ostringstream supportedTypes; + for (auto &type : m_supportedTypes) + { + if (!supportedTypes.str().empty()) + supportedTypes << " ,"; + supportedTypes << type; + } + ocRep.setValue("rts", supportedTypes.str()); + + // Add "links" attribute + std::vector links; + int index = 0; + for (auto &entry : m_childResources) + { + links[index].setValue("href", entry.second->getURI()); + links[index].setValue("rt", entry.second->getResourceType()); + links[index].setValue("if", entry.second->getInterface()[0]); + } + + ocRep.setValue("links", links); + + return ocRep; +} \ No newline at end of file diff --git a/service/simulator/src/server/simulator_collection_resource_impl.h b/service/simulator/src/server/simulator_collection_resource_impl.h new file mode 100644 index 0000000..ab8f347 --- /dev/null +++ b/service/simulator/src/server/simulator_collection_resource_impl.h @@ -0,0 +1,87 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +#ifndef SIMULATOR_COLLECTION_RESOURCE_IMPL_H_ +#define SIMULATOR_COLLECTION_RESOURCE_IMPL_H_ + +#include "simulator_collection_resource.h" + +class SimulatorResourceFactory; +class SimulatorCollectionResourceImpl : public SimulatorCollectionResource +{ + public: + friend class SimulatorResourceFactory; + + std::string getName() const; + SimulatorResource::Type getType() const; + std::string getURI() const; + std::string getResourceType() const; + std::vector getInterface() const; + void setName(const std::string &name); + void setURI(const std::string &uri); + void setResourceType(const std::string &resourceType); + void addInterface(std::string interfaceType); + void setObservable(bool state); + void setObserverCallback(ObserverCallback callback); + bool isObservable(); + bool isStarted(); + void start(); + void stop(); + std::vector getObserversList(); + void notify(int id); + void notifyAll(); + + std::vector getSupportedResources(); + void addChildResource(SimulatorResourceSP &resource); + void removeChildResource(SimulatorResourceSP &resource); + void removeChildResource(const std::string &uri); + std::vector getChildResources(); + + private: + SimulatorCollectionResourceImpl(); + + OCEntityHandlerResult handleRequests(std::shared_ptr request); + std::shared_ptr requestOnBaseLineInterface( + std::shared_ptr request); + std::shared_ptr requestOnLinkListInterface( + std::shared_ptr request); + std::shared_ptr requestOnBatchInterface( + std::shared_ptr request); + void sendNotification(OC::ObservationIds &observers); + OC::OCRepresentation prepareRepresentation(); + + SimulatorResource::Type m_type; + std::string m_name; + std::string m_uri; + std::string m_resourceType; + std::vector m_interfaces; + + std::recursive_mutex m_objectLock; + std::mutex m_childResourcesLock; + std::map m_childResources; + std::vector m_supportedTypes; + std::vector m_observersList; + ObserverCallback m_observeCallback; + + OCResourceProperty m_property; + OCResourceHandle m_resourceHandle; +}; + +#endif diff --git a/service/simulator/src/server/simulator_resource_factory.cpp b/service/simulator/src/server/simulator_resource_factory.cpp new file mode 100644 index 0000000..90d2a6d --- /dev/null +++ b/service/simulator/src/server/simulator_resource_factory.cpp @@ -0,0 +1,312 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +#include "simulator_resource_factory.h" +#include "simulator_single_resource_impl.h" +#include "simulator_collection_resource_impl.h" +#include "RamlParser.h" +#include "simulator_logger.h" +#include "logger.h" + +#define TAG "SIM_RESOURCE_FACTORY" + +SimulatorResourceFactory *SimulatorResourceFactory::getInstance() +{ + static SimulatorResourceFactory s_instance; + return &s_instance; +} + +std::shared_ptr SimulatorResourceFactory::createResource( + const std::string &configPath) +{ + // Parse the RAML file + std::shared_ptr ramlParser = std::make_shared(configPath); + RAML::RamlPtr raml = ramlParser->getRamlPtr(); + + // Get the first resource model from RAML + RAML::RamlResourcePtr ramlResource; + if (0 == raml->getResources().size() + || nullptr == (ramlResource = raml->getResources().begin()->second)) + { + OC_LOG(ERROR, TAG, "Zero resources detected from RAML!"); + return nullptr; + } + + return buildResource(ramlResource); +} + +std::vector > SimulatorResourceFactory::createResource( + const std::string &configPath, unsigned int count) +{ + std::vector> resources; + + // Parse the RAML file + std::shared_ptr ramlParser = std::make_shared(configPath); + RAML::RamlPtr raml = ramlParser->getRamlPtr(); + + // Get the first resource model from RAML + RAML::RamlResourcePtr ramlResource; + if (0 == raml->getResources().size() + || nullptr == (ramlResource = raml->getResources().begin()->second)) + { + OC_LOG(ERROR, TAG, "Zero resources detected from RAML!"); + return resources; + } + + while (count--) + { + std::shared_ptr resource = buildResource(ramlResource); + if (!resource) + { + OC_LOG(ERROR, TAG, "Failed to create resource!"); + return resources; + } + + resources.push_back(resource); + } + + return resources; +} + +std::shared_ptr SimulatorResourceFactory::createSingleResource( + const std::string &name, const std::string &uri, const std::string &resourceType) +{ + SimulatorSingleResourceImpl *simpleResource = new SimulatorSingleResourceImpl(); + simpleResource->setName(name); + simpleResource->setURI(uri); + simpleResource->setResourceType(resourceType); + return std::shared_ptr(simpleResource); +} + +std::shared_ptr SimulatorResourceFactory::createCollectionResource( + const std::string &name, const std::string &uri, const std::string &resourceType) +{ + SimulatorCollectionResourceImpl *collectionResource = new SimulatorCollectionResourceImpl(); + collectionResource->setName(name); + collectionResource->setURI(uri); + collectionResource->setResourceType(resourceType); + return std::shared_ptr(collectionResource); +} + +std::shared_ptr SimulatorResourceFactory::buildResource( + std::shared_ptr ramlResource) +{ + std::string name; + std::string uri; + std::string resourceType; + std::string interfaceType; + + name = ramlResource->getDisplayName(); + uri = ramlResource->getResourceUri(); + + // Get the resource representation schema from GET response body + RAML::ActionPtr action = ramlResource->getAction(RAML::ActionType::GET); + if (!action) + { + OC_LOG(ERROR, TAG, "Resource does not possess the GET request!"); + return nullptr; + } + + RAML::ResponsePtr getResponse = action->getResponse("200"); + if (!getResponse) + { + OC_LOG(ERROR, TAG, "Resource does not provide valid GET response!"); + return nullptr; + } + + RAML::RequestResponseBodyPtr responseBody = getResponse->getResponseBody("application/json"); + if (!responseBody) + { + OC_LOG(ERROR, TAG, "GET response is not of type \"application/json\" "); + return nullptr; + } + + // Iterate throgh all resource property and extract information needed for simulating resource + RAML::JsonSchemaPtr resourceProperties = responseBody->getSchema()->getProperties(); + SimulatorResourceModel resModel; + for ( auto &propertyElement : resourceProperties->getProperties()) + { + if (!propertyElement.second) + continue; + + std::string propName = propertyElement.second->getName(); + + // Resource type + if ("rt" == propName || "resourceType" == propName) + { + resourceType = propertyElement.second->getValueString(); + continue; + } + + // Interface type + if ("if" == propName) + { + interfaceType = propertyElement.second->getValueString(); + continue; + } + + // Other Standard properties which should not be part of resource model + if ("p" == propName || "n" == propName || "id" == propName) + { + continue; + } + + // Build representation attribute + SimulatorResourceModel::Attribute attribute(propName); + switch (propertyElement.second->getValueType()) + { + case 0: // Integer + { + attribute.setValue(propertyElement.second->getValue()); + + // Convert suppoted values + std::vector allowedValues = propertyElement.second->getAllowedValuesInt(); + if (allowedValues.size() > 0) + { + SimulatorResourceModel::AttributeProperty attrProp(allowedValues); + attribute.setProperty(attrProp); + } + } + break; + + case 1: // Double + { + attribute.setValue(propertyElement.second->getValue()); + + // Convert suppoted values + std::vector allowedValues = propertyElement.second->getAllowedValuesDouble(); + if (allowedValues.size() > 0) + { + SimulatorResourceModel::AttributeProperty attrProp(allowedValues); + attribute.setProperty(attrProp); + } + } + break; + + case 2: // Boolean + { + attribute.setValue(propertyElement.second->getValue()); + + std::vector allowedValues = {true, false}; + SimulatorResourceModel::AttributeProperty attrProp(allowedValues); + attribute.setProperty(attrProp); + } + break; + + case 3: // String + { + attribute.setValue(propertyElement.second->getValue()); + + // Convert suppoted values + std::vector allowedValues = propertyElement.second->getAllowedValuesString(); + if (allowedValues.size() > 0) + { + SimulatorResourceModel::AttributeProperty attrProp(allowedValues); + attribute.setProperty(attrProp); + } + } + break; + } + + // Set the range property if its present + double min, max; + int multipleof; + propertyElement.second->getRange(min, max, multipleof); + if (min != INT_MIN && max != INT_MAX) + { + SimulatorResourceModel::AttributeProperty attrProp(min, max); + attribute.setProperty(attrProp); + } + + // Add the attribute to resource model + resModel.add(attribute); + } + + // Create simple/collection resource + std::shared_ptr simResource; + if (interfaceType == "oic.if.ll" + || resModel.containsAttribute("links") || resModel.containsAttribute("rts")) + { + try + { + std::shared_ptr collectionRes( + new SimulatorCollectionResourceImpl()); + + collectionRes->setName(name); + collectionRes->setResourceType(resourceType); + if (ResourceURIFactory::getInstance()->isUnique(uri)) + collectionRes->setURI(uri); + else + collectionRes->setURI(ResourceURIFactory::getInstance()->constructURI(uri)); + + simResource = std::dynamic_pointer_cast(collectionRes); + } + catch (InvalidArgsException &e) {} + } + else + { + try + { + std::shared_ptr singleRes( + new SimulatorSingleResourceImpl()); + + singleRes->setName(name); + singleRes->setResourceType(resourceType); + if (ResourceURIFactory::getInstance()->isUnique(uri)) + singleRes->setURI(uri); + else + singleRes->setURI(ResourceURIFactory::getInstance()->constructURI(uri)); + + singleRes->setResourceModel(resModel); + simResource = std::dynamic_pointer_cast(singleRes); + } + catch (InvalidArgsException &e) {} + } + + return simResource; +} + +ResourceURIFactory *ResourceURIFactory::getInstance() +{ + static ResourceURIFactory s_instance; + return &s_instance; +} + +ResourceURIFactory::ResourceURIFactory() + : m_id(0) {} + +std::string ResourceURIFactory::constructURI(const std::string &uri) +{ + std::ostringstream os; + os << uri; + if (!uri.empty() && '/' != uri[uri.length() - 1]) + os << '/'; + os << m_id++; + return os.str(); +} + +bool ResourceURIFactory::isUnique(const std::string &uri) +{ + if (m_uriList.end() == m_uriList.find(uri)) + return true; + else + return false; +} + diff --git a/service/simulator/src/server/simulator_resource_factory.h b/service/simulator/src/server/simulator_resource_factory.h new file mode 100644 index 0000000..0ab3a01 --- /dev/null +++ b/service/simulator/src/server/simulator_resource_factory.h @@ -0,0 +1,137 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +#ifndef SIMULATOR_RESOURCE_FACTORY_H_ +#define SIMULATOR_RESOURCE_FACTORY_H_ + +#include "simulator_single_resource.h" +#include "simulator_collection_resource.h" + +namespace RAML +{ + class RamlResource; +} + +class SimulatorResourceFactory +{ + public: + /** + * API for getting singleton instance of SimulatorClient class. + * + * @return Singleton instance of SimulatorClient class. + * + */ + static SimulatorResourceFactory *getInstance(); + + /** + * API to create resource based on the given RAML file. + * + * @param configPath - RAML file path. + * + * @return SimulatorResource shared object created using RAML file. + */ + std::shared_ptr createResource(const std::string &configPath); + + /** + * API to create resource based on the given RAML file. + * + * @param configPath - RAML file path. + * + * @return SimulatorResource shared object created using RAML file. + */ + std::vector > createResource( + const std::string &configPath, unsigned int count); + + /** + * API to create simple resource. + * + * @param name - Name of resource. + * @param uri - URI of resource. + * @param resourceType - ResourceType of resource. + * + * @return SimulatorSimpleResource. + */ + std::shared_ptr createSingleResource( + const std::string &name, const std::string &uri, const std::string &resourceType); + + /** + * API to create collection resource. + * + * @param name - Name of collection resource. + * @param uri - URI of resource. + * @param resourceType - ResourceType of collection resource. + * + * @return SimulatorCollectionResource. + */ + std::shared_ptr createCollectionResource( + const std::string &name, const std::string &uri, const std::string &resourceType); + + private: + std::shared_ptr buildResource( + std::shared_ptr ramlResource); + + SimulatorResourceFactory() = default; + SimulatorResourceFactory(const SimulatorResourceFactory &) = delete; + SimulatorResourceFactory &operator=(const SimulatorResourceFactory &) = delete; + SimulatorResourceFactory(SimulatorResourceFactory &&) = delete; + SimulatorResourceFactory &operator=(SimulatorResourceFactory && ) = delete; +}; + +class ResourceURIFactory +{ + public: + /** + * API for getting singleton instance of SimulatorClient class. + * + * @return Singleton instance of SimulatorClient class. + * + */ + static ResourceURIFactory *getInstance(); + + /** + * API to construct unique URI from the given base @uri. + * + * @param uri - Base uri to be used to construct unique uri. + * + * @return Unique uri. + */ + std::string constructURI(const std::string &uri); + + /** + * API to check the uri is unique or not. + * + * @param uri - uri to be checked for its uniqueness. + * + * @return true if uri is unique, otherwise false. + */ + bool isUnique(const std::string &uri); + + private: + ResourceURIFactory(); + ResourceURIFactory(const ResourceURIFactory &) = delete; + ResourceURIFactory &operator=(const ResourceURIFactory &) = delete; + ResourceURIFactory(ResourceURIFactory &&) = delete; + ResourceURIFactory &operator=(ResourceURIFactory && ) = delete; + + unsigned int m_id; + std::map m_uriList; +}; + +#endif diff --git a/service/simulator/src/server/simulator_single_resource_impl.cpp b/service/simulator/src/server/simulator_single_resource_impl.cpp new file mode 100644 index 0000000..e41eac3 --- /dev/null +++ b/service/simulator/src/server/simulator_single_resource_impl.cpp @@ -0,0 +1,541 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +#include "simulator_single_resource_impl.h" +#include "simulator_utils.h" +#include "simulator_logger.h" +#include "logger.h" + +#define TAG "SIM_SINGLE_RESOURCE" + +SimulatorSingleResourceImpl::SimulatorSingleResourceImpl() + : m_type(SimulatorResource::Type::SINGLE_RESOURCE), + m_interfaces {OC::DEFAULT_INTERFACE}, + m_resourceHandle(NULL) +{ + m_property = static_cast(OC_DISCOVERABLE | OC_OBSERVABLE); +} + +std::string SimulatorSingleResourceImpl::getName() const +{ + return m_name; +} + +SimulatorResource::Type SimulatorSingleResourceImpl::getType() const +{ + return m_type; +} + +std::string SimulatorSingleResourceImpl::getURI() const +{ + return m_uri; +} + +std::string SimulatorSingleResourceImpl::getResourceType() const +{ + return m_resourceType; +} + +std::vector SimulatorSingleResourceImpl::getInterface() const +{ + return m_interfaces; +} + +void SimulatorSingleResourceImpl::setName(const std::string &name) +{ + VALIDATE_INPUT(name.empty(), "Name is empty!") + + std::lock_guard lock(m_objectLock); + if (m_resourceHandle) + { + throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED, + "Name can not be set when resource is started!"); + } + + m_name = name; +} + +void SimulatorSingleResourceImpl::setURI(const std::string &uri) +{ + VALIDATE_INPUT(uri.empty(), "Uri is empty!") + + std::lock_guard lock(m_objectLock); + if (m_resourceHandle) + { + throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED, + "URI can not be set when resource is started!"); + } + + m_uri = uri; +} + +void SimulatorSingleResourceImpl::setResourceType(const std::string &resourceType) +{ + VALIDATE_INPUT(resourceType.empty(), "Resource type is empty!") + + std::lock_guard lock(m_objectLock); + if (m_resourceHandle) + { + throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED, + "Resource type can not be set when resource is started!"); + } + + m_resourceType = resourceType; +} + +void SimulatorSingleResourceImpl::addInterface(std::string interfaceType) +{ + VALIDATE_INPUT(interfaceType.empty(), "Interface type is empty!") + + if (interfaceType == OC::LINK_INTERFACE + || interfaceType == OC::BATCH_INTERFACE + || interfaceType == OC::GROUP_INTERFACE) + { + throw NoSupportException("Single type resource does not support this interface!"); + } + + std::lock_guard lock(m_objectLock); + if (m_resourceHandle) + { + throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED, + "Interface type can not be set when resource is started!"); + } + + auto found = std::find(m_interfaces.begin(), m_interfaces.end(), interfaceType); + if (found != m_interfaces.end()) + m_interfaces.push_back(interfaceType); +} + +void SimulatorSingleResourceImpl::setObservable(bool state) +{ + std::lock_guard lock(m_objectLock); + if (m_resourceHandle) + { + throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED, + "Observation state can not be changed when resource is started!"); + } + + if (true == state) + m_property = static_cast(m_property | OC_OBSERVABLE); + else + m_property = static_cast(m_property ^ OC_OBSERVABLE); +} + +void SimulatorSingleResourceImpl::setObserverCallback(ObserverCallback callback) +{ + VALIDATE_CALLBACK(callback) + m_observeCallback = callback; +} + +bool SimulatorSingleResourceImpl::isObservable() +{ + return (m_property & OC_OBSERVABLE); +} + +bool SimulatorSingleResourceImpl::isStarted() +{ + return (nullptr != m_resourceHandle); +} + +void SimulatorSingleResourceImpl::start() +{ + std::lock_guard lock(m_objectLock); + if (m_resourceHandle) + { + throw SimulatorException(SIMULATOR_ERROR, "Resource already registered!"); + } + + if (m_uri.empty() || m_resourceType.empty()) + { + throw SimulatorException(SIMULATOR_ERROR, "Found incomplete data to start resource!"); + } + + typedef OCStackResult (*RegisterResource)(OCResourceHandle &, std::string &, const std::string &, + const std::string &, OC::EntityHandler, uint8_t); + + invokeocplatform(static_cast(OC::OCPlatform::registerResource), + m_resourceHandle, m_uri, m_resourceType, m_interfaces[0], + std::bind(&SimulatorSingleResourceImpl::handleRequests, + this, std::placeholders::_1), m_property); + + for (size_t index = 1; m_interfaces.size() > 1 && index < m_interfaces.size(); index++) + { + typedef OCStackResult (*bindInterfaceToResource)(const OCResourceHandle &, + const std::string &); + + try + { + invokeocplatform(static_cast( + OC::OCPlatform::bindInterfaceToResource), m_resourceHandle, + m_interfaces[index]); + } + catch (SimulatorException &e) + { + stop(); + throw; + } + } +} + +void SimulatorSingleResourceImpl::stop() +{ + std::lock_guard lock(m_objectLock); + if (!m_resourceHandle) + return; + + typedef OCStackResult (*UnregisterResource)(const OCResourceHandle &); + + invokeocplatform(static_cast(OC::OCPlatform::unregisterResource), + m_resourceHandle); + + m_resourceHandle = nullptr; +} + +std::vector SimulatorSingleResourceImpl::getObserversList() +{ + return m_observersList; +} + +void SimulatorSingleResourceImpl::notify(int id) +{ + std::lock_guard lock(m_objectLock); + if (!m_resourceHandle) + return; + + std::shared_ptr resourceResponse = + {std::make_shared()}; + + resourceResponse->setErrorCode(200); + resourceResponse->setResponseResult(OC_EH_OK); + resourceResponse->setResourceRepresentation(m_resModel.getOCRepresentation(), + OC::DEFAULT_INTERFACE); + + OC::ObservationIds observers; + observers.push_back(id); + + typedef OCStackResult (*NotifyListOfObservers)(OCResourceHandle, OC::ObservationIds &, + const std::shared_ptr); + + invokeocplatform(static_cast(OC::OCPlatform::notifyListOfObservers), + m_resourceHandle, observers, resourceResponse); +} + +void SimulatorSingleResourceImpl::notifyAll() +{ + std::lock_guard lock(m_objectLock); + if (!m_resourceHandle) + return; + + if (!m_observersList.size()) + return; + + std::shared_ptr resourceResponse = + {std::make_shared()}; + + resourceResponse->setErrorCode(200); + resourceResponse->setResponseResult(OC_EH_OK); + resourceResponse->setResourceRepresentation(m_resModel.getOCRepresentation(), + OC::DEFAULT_INTERFACE); + + OC::ObservationIds observers; + for (auto &observer : m_observersList) + observers.push_back(observer.id); + + typedef OCStackResult (*NotifyListOfObservers)(OCResourceHandle, OC::ObservationIds &, + const std::shared_ptr); + + invokeocplatform(static_cast(OC::OCPlatform::notifyListOfObservers), + m_resourceHandle, observers, resourceResponse); +} + +bool SimulatorSingleResourceImpl::getAttribute(const std::string &attrName, + SimulatorResourceModel::Attribute &attribute) +{ + VALIDATE_INPUT(attrName.empty(), "Attribute name is empty!") + + std::lock_guard lock(m_modelLock); + return m_resModel.getAttribute(attrName, attribute); +} + +void SimulatorSingleResourceImpl::addAttribute(const SimulatorResourceModel::Attribute &attribute, + bool notify) +{ + std::lock_guard lock(m_modelLock); + if (m_resModel.containsAttribute(attribute.getName())) + throw SimulatorException(SIMULATOR_ERROR, "Attribute exist with same name!"); + + if (!m_resModel.add(attribute)) + throw SimulatorException(SIMULATOR_ERROR, "Failed to add attribute!"); + + if (notify && isStarted()) + notifyAll(); +} + +bool SimulatorSingleResourceImpl::getAttributeProperty(const std::string &attrName, + SimulatorResourceModel::AttributeProperty &property) +{ + VALIDATE_INPUT(attrName.empty(), "Attribute name is empty!") + + std::lock_guard lock(m_modelLock); + return m_resModel.getAttributeProperty(attrName, property); +} + +bool SimulatorSingleResourceImpl::setAttributeProperty(const std::string &attrName, + const SimulatorResourceModel::AttributeProperty &property) +{ + VALIDATE_INPUT(attrName.empty(), "Attribute name is empty!") + + std::lock_guard lock(m_modelLock); + return m_resModel.setAttributeProperty(attrName, property); +} + +bool SimulatorSingleResourceImpl::updateAttributeValue( + const SimulatorResourceModel::Attribute &attribute, + bool notify) +{ + std::lock_guard lock(m_modelLock); + if (m_resModel.updateValue(attribute)) + { + if (notify && isStarted()) + notifyAll(); + return true; + } + + return false; +} + +bool SimulatorSingleResourceImpl::removeAttribute(const std::string &attrName, bool notify) +{ + VALIDATE_INPUT(attrName.empty(), "Attribute name is empty!") + + std::lock_guard lock(m_modelLock); + if (m_resModel.removeAttribute(attrName)) + { + if (notify && isStarted()) + notifyAll(); + return true; + } + + return false; +} + +SimulatorResourceModel SimulatorSingleResourceImpl::getResourceModel() +{ + std::lock_guard lock(m_modelLock); + return m_resModel; +} + +void SimulatorSingleResourceImpl::setModelChangeCallback(ResourceModelChangedCallback callback) +{ + VALIDATE_CALLBACK(callback) + m_modelCallback = callback; +} + +int SimulatorSingleResourceImpl::startResourceUpdation(AutomationType type, + int updateInterval, updateCompleteCallback callback) +{ + VALIDATE_CALLBACK(callback) + + std::lock_guard lock(m_objectLock); + if (!m_resourceHandle) + throw SimulatorException(SIMULATOR_NO_RESOURCE, "Resource is not registered!"); + + return m_updateAutomationMgr.startResourceAutomation(this, type, updateInterval, callback); +} + +int SimulatorSingleResourceImpl::startAttributeUpdation(const std::string &attrName, + AutomationType type, int updateInterval, updateCompleteCallback callback) +{ + VALIDATE_CALLBACK(callback) + + std::lock_guard lock(m_objectLock); + if (!m_resourceHandle) + throw SimulatorException(SIMULATOR_NO_RESOURCE, "Resource is not registered!"); + + return m_updateAutomationMgr.startAttributeAutomation(this, attrName, type, + updateInterval, callback); +} + +std::vector SimulatorSingleResourceImpl::getResourceUpdationIds() +{ + return m_updateAutomationMgr.getResourceAutomationIds(); +} + +std::vector SimulatorSingleResourceImpl::getAttributeUpdationIds() +{ + return m_updateAutomationMgr.getAttributeAutomationIds(); +} + +void SimulatorSingleResourceImpl::stopUpdation(const int id) +{ + m_updateAutomationMgr.stop(id); +} + +void SimulatorSingleResourceImpl::setResourceModel(const SimulatorResourceModel &resModel) +{ + std::lock_guard lock(m_modelLock); + m_resModel = resModel; +} + +void SimulatorSingleResourceImpl::notifyApp() +{ + if (m_modelCallback) + { + SimulatorResourceModel resModel = m_resModel; + m_modelCallback(m_uri, resModel); + } +} + +OCEntityHandlerResult SimulatorSingleResourceImpl::handleRequests( + std::shared_ptr request) +{ + OCEntityHandlerResult errCode = OC_EH_ERROR; + if (!request) + return OC_EH_ERROR; + + if (OC::RequestHandlerFlag::RequestFlag & request->getRequestHandlerFlag()) + { + { + OC::OCRepresentation rep = request->getResourceRepresentation(); + std::string payload = getPayloadString(rep); + SIM_LOG(ILogger::INFO, "[" << m_name << "] " << request->getRequestType() + << " request received. \n**Payload details**\n" << payload) + } + + // Handover the request to appropriate interface handler + std::string interfaceType(OC::DEFAULT_INTERFACE); + OC::QueryParamsMap queryParams = request->getQueryParameters(); + if (queryParams.end() != queryParams.find("if")) + interfaceType = queryParams["if"]; + + std::shared_ptr response; + if (interfaceType == OC::DEFAULT_INTERFACE) + { + response = requestOnBaseLineInterface(request); + } + + // Send response if the request handled by resource + if (response) + { + if (OC_STACK_OK != OC::OCPlatform::sendResponse(response)) + return OC_EH_ERROR; + } + else + { + SIM_LOG(ILogger::ERROR, "[" << m_name << "] " << "Unsupported request received!") + return OC_EH_ERROR; + } + } + + if (OC::RequestHandlerFlag::ObserverFlag & request->getRequestHandlerFlag()) + { + if (false == isObservable()) + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE request received") + SIM_LOG(ILogger::INFO, "[" << m_uri << "] Sending error as resource is in unobservable state") + return OC_EH_ERROR; + } + + OC::ObservationInfo observationInfo = request->getObservationInfo(); + if (OC::ObserveAction::ObserveRegister == observationInfo.action) + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE REGISTER request received"); + + ObserverInfo info {observationInfo.obsId, observationInfo.address, observationInfo.port}; + m_observersList.push_back(info); + + if (m_observeCallback) + m_observeCallback(m_uri, ObservationStatus::REGISTER, info); + } + else if (OC::ObserveAction::ObserveUnregister == observationInfo.action) + { + SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE UNREGISTER request received"); + + ObserverInfo info; + for (auto iter = m_observersList.begin(); iter != m_observersList.end(); iter++) + { + if ((info = *iter), info.id == observationInfo.obsId) + { + m_observersList.erase(iter); + break; + } + } + + if (m_observeCallback) + m_observeCallback(m_uri, ObservationStatus::UNREGISTER, info); + } + errCode = OC_EH_OK; + } + + return errCode; +} + +std::shared_ptr SimulatorSingleResourceImpl::requestOnBaseLineInterface( + std::shared_ptr request) +{ + std::shared_ptr response; + if ("GET" == request->getRequestType()) + { + response = std::make_shared(); + response->setErrorCode(200); + response->setResponseResult(OC_EH_OK); + response->setResourceRepresentation(m_resModel.getOCRepresentation()); + std::string resPayload = getPayloadString(m_resModel.getOCRepresentation()); + SIM_LOG(ILogger::INFO, "[" << m_uri << + "] Sending response for GET request. \n**Payload details**" << resPayload) + } + else if ("PUT" == request->getRequestType() + || "POST" == request->getRequestType()) + { + OC::OCRepresentation requestRep = request->getResourceRepresentation(); + if (true == m_resModel.update(requestRep)) + { + notifyAll(); + notifyApp(); + + response = std::make_shared(); + response->setErrorCode(200); + response->setResponseResult(OC_EH_OK); + response->setResourceRepresentation(m_resModel.getOCRepresentation()); + std::string resPayload = getPayloadString(m_resModel.getOCRepresentation()); + SIM_LOG(ILogger::INFO, "[" << m_uri << + "] Sending response for " << request->getRequestType() << " request. \n**Payload details**" << + resPayload) + } + else + { + response = std::make_shared(); + response->setErrorCode(400); + response->setResponseResult(OC_EH_ERROR); + } + } + else if ("DELETE" == request->getRequestType()) + { + // TODO: Handle this request + } + + if (response) + { + response->setRequestHandle(request->getRequestHandle()); + response->setResourceHandle(request->getResourceHandle()); + } + + return response; +} diff --git a/service/simulator/src/server/simulator_single_resource_impl.h b/service/simulator/src/server/simulator_single_resource_impl.h new file mode 100644 index 0000000..73e3d7c --- /dev/null +++ b/service/simulator/src/server/simulator_single_resource_impl.h @@ -0,0 +1,101 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +#ifndef SIMULATOR_SINGLE_RESOURCE_IMPL_H_ +#define SIMULATOR_SINGLE_RESOURCE_IMPL_H_ + +#include "simulator_single_resource.h" +#include "resource_update_automation_mngr.h" + +class SimulatorResourceFactory; +class SimulatorSingleResourceImpl : public SimulatorSingleResource +{ + public: + friend class SimulatorResourceFactory; + + std::string getName() const; + SimulatorResource::Type getType() const; + std::string getURI() const; + std::string getResourceType() const; + std::vector getInterface() const; + void setName(const std::string &name); + void setURI(const std::string &uri); + void setResourceType(const std::string &resourceType); + void addInterface(std::string interfaceType); + void setObservable(bool state); + void setObserverCallback(ObserverCallback callback); + bool isObservable(); + bool isStarted(); + void start(); + void stop(); + std::vector getObserversList(); + void notify(int id); + void notifyAll(); + + bool getAttribute(const std::string &attrName, + SimulatorResourceModel::Attribute &attribute); + void addAttribute(const SimulatorResourceModel::Attribute &attribute, bool notify = true); + bool getAttributeProperty(const std::string &attrName, + SimulatorResourceModel::AttributeProperty &property); + bool setAttributeProperty(const std::string &attrName, + const SimulatorResourceModel::AttributeProperty &property); + bool updateAttributeValue(const SimulatorResourceModel::Attribute &attribute, + bool notify = true); + bool removeAttribute(const std::string &attrName, bool notify = true); + SimulatorResourceModel getResourceModel(); + void setModelChangeCallback(ResourceModelChangedCallback callback); + int startResourceUpdation(AutomationType type, int updateInterval, + updateCompleteCallback callback); + int startAttributeUpdation(const std::string &attrName, AutomationType type, + int updateInterval, updateCompleteCallback callback); + std::vector getResourceUpdationIds(); + std::vector getAttributeUpdationIds(); + void stopUpdation(const int id); + void setResourceModel(const SimulatorResourceModel &resModel); + void notifyApp(); + + private: + SimulatorSingleResourceImpl(); + OCEntityHandlerResult handleRequests(std::shared_ptr request); + std::shared_ptr requestOnBaseLineInterface( + std::shared_ptr request); + void resourceModified(); + + SimulatorResource::Type m_type; + std::string m_name; + std::string m_uri; + std::string m_resourceType; + std::vector m_interfaces; + + std::recursive_mutex m_objectLock; + std::mutex m_modelLock; + SimulatorResourceModel m_resModel; + ResourceModelChangedCallback m_modelCallback; + ObserverCallback m_observeCallback; + UpdateAutomationMngr m_updateAutomationMgr; + std::vector m_observersList; + + OCResourceProperty m_property; + OCResourceHandle m_resourceHandle; +}; + +typedef std::shared_ptr SimulatorSingleResourceImplSP; + +#endif diff --git a/service/simulator/src/service-provider/resource_manager.cpp b/service/simulator/src/service-provider/resource_manager.cpp deleted file mode 100644 index 54c5e8b..0000000 --- a/service/simulator/src/service-provider/resource_manager.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/****************************************************************** - * - * Copyright 2015 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -#include "resource_manager.h" -#include "simulator_logger.h" -#include "logger.h" - -#define TAG "RESOURCE_MANAGER" - -ResourceManager *ResourceManager::getInstance() -{ - static ResourceManager s_instance; - return &s_instance; -} - -SimulatorResourceServerSP ResourceManager::createResource(const std::string &configPath, - SimulatorResourceServer::ResourceModelChangedCB callback) -{ - OC_LOG_V(INFO, "Create resource request : config=%s", configPath.c_str()); - - // Input validation - if (configPath.empty()) - { - OC_LOG(ERROR, TAG, "Invalid config file path!"); - throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Invalid RAML file path!"); - } - - if (!callback) - { - OC_LOG(ERROR, TAG, "Invalid callback!"); - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - } - - return buildResource(configPath, callback); -} - -std::vector ResourceManager::createResource( - const std::string &configPath, unsigned short count, - SimulatorResourceServer::ResourceModelChangedCB callback) -{ - OC_LOG_V(INFO, "Create multiple resource request : config=%s, count=%d", configPath.c_str(), - count); - - // Input validation - if (configPath.empty()) - { - OC_LOG(ERROR, TAG, "Invalid config file path!"); - throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Invalid RAML file path!"); - } - - if (0 == count) - { - OC_LOG(ERROR, TAG, "Invalid count value!"); - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid count value!"); - } - - if (!callback) - { - OC_LOG(ERROR, TAG, "Invalid callback!"); - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - } - - std::vector resourceList; - - // Create resources - for (unsigned short i = 0; i < count; i++) - { - OC_LOG_V(INFO, TAG, "Creating resource [%d]", i + 1); - SIM_LOG(ILogger::INFO, "Creating resource [" << i + 1 << "]"); - - SimulatorResourceServerSP resource = buildResource(configPath, callback); - if (!resource) - { - break; - } - - resourceList.push_back(resource); - } - - SIM_LOG(ILogger::INFO, "[" << resourceList.size() << " out of " << count << - "] resource(s) created successfully."); - - return resourceList; -} - -std::vector ResourceManager::getResources( - const std::string &resourceType) -{ - std::lock_guard lock(m_lock); - - std::vector resourceList; - for (auto resourceTableEntry : m_resources) - { - if (!resourceType.empty() && resourceType.compare(resourceTableEntry.first)) - continue; - - for (auto resourceEntry : resourceTableEntry.second) - { - resourceList.push_back(resourceEntry.second); - } - } - - return resourceList; -} - -void ResourceManager::deleteResource(const SimulatorResourceServerSP &resource) -{ - if (!resource) - { - OC_LOG(ERROR, TAG, "Invalid resource object!"); - throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Invalid resource object!"); - } - - std::lock_guard lock(m_lock); - auto resourceTableEntry = m_resources.find(resource->getResourceType()); - if (m_resources.end() != resourceTableEntry) - { - auto resourceEntry = resourceTableEntry->second.find(resource->getURI()); - if (resourceTableEntry->second.end() != resourceEntry) - { - SimulatorResourceServerImplSP resourceImpl = - std::dynamic_pointer_cast(resource); - resourceImpl->stop(); - resourceTableEntry->second.erase(resourceEntry); - SIM_LOG(ILogger::INFO, "Resource (" << resource->getURI() << - ") deleted successfully."); - } - } -} - -void ResourceManager::deleteResources(const std::string &resourceType) -{ - std::lock_guard lock(m_lock); - for (auto & resourceTableEntry : m_resources) - { - if (!resourceType.empty() && resourceType.compare(resourceTableEntry.first)) - continue; - - for (auto & resourceEntry : resourceTableEntry.second) - { - SimulatorResourceServerSP resource = resourceEntry.second; - SimulatorResourceServerImplSP resourceImpl = - std::dynamic_pointer_cast(resource); - resourceImpl->stop(); - SIM_LOG(ILogger::INFO, "Resource (" << resource->getURI() << - ") deleted successfully."); - } - - // Erase the entry for resource type from resources list - m_resources.erase(resourceTableEntry.first); - } -} - -/** - * This method does not validate the input given, thus Caller of this method must validate - * the inputs before invoking this private method. - */ -SimulatorResourceServerSP ResourceManager::buildResource(const std::string &configPath, - SimulatorResourceServer::ResourceModelChangedCB callback) -{ - // Create resource based on the RAML file. - SimulatorResourceServerImplSP resourceImpl = m_resourceCreator.createResource(configPath); - if (!resourceImpl) - { - OC_LOG(ERROR, TAG, "Failed to create resource!"); - throw SimulatorException(SIMULATOR_ERROR, "Failed to create resource!"); - } - - resourceImpl->setModelChangeCallback(callback); - resourceImpl->start(); - - // Add the resource to resource list table - std::lock_guard lock(m_lock); - SimulatorResourceServerSP resource = - std::dynamic_pointer_cast(resourceImpl); - m_resources[resourceImpl->getResourceType()].insert( - std::pair(resourceImpl->getURI(), resourceImpl)); - - SIM_LOG(ILogger::INFO, "Created an OIC resource of type [" << - resourceImpl->getResourceType() << "]"); - return resourceImpl; -} - -/** - * This method appends a unique key to the given URI to make the URI unique in simulator. - * Example: If input is "/a/light", then the output will be "/a/light/simulator/0" for the first resource - * and "/a/light/simulator/1" for the second resource and so on. - */ -std::string ResourceManager::constructURI(const std::string &uri) -{ - std::ostringstream os; - os << uri; - if (!uri.empty() && '/' != uri[uri.length() - 1]) - os << '/'; - os << "simulator/" << m_id++; - return os.str(); -} - diff --git a/service/simulator/src/service-provider/resource_manager.h b/service/simulator/src/service-provider/resource_manager.h deleted file mode 100644 index ddb63f3..0000000 --- a/service/simulator/src/service-provider/resource_manager.h +++ /dev/null @@ -1,119 +0,0 @@ -/****************************************************************** - * - * Copyright 2015 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -/** - * @file resource_manager.h - * - * @brief This file provides APIs for simulated resource management. - */ - -#ifndef RESOURCE_MANAGER_H_ -#define RESOURCE_MANAGER_H_ - -#include "simulator_resource_server_impl.h" -#include "simulator_resource_creator.h" -#include "simulator_error_codes.h" - -/** - * @class ResourceManager - * @brief This class provides a set of APIs for managing the simulated resource(s). - */ -class ResourceManager -{ - public: - /** - * This method is to create/obtain the singleton instance of ResourceManager. - */ - static ResourceManager *getInstance(void); - - /** - * This method is for simulating/creating a resource based on the input data provided from - * RAML file. - * - * @param configPath - RAML configuration file path. - * @param callback - Callback method for receiving notifications when resource model changes. - * - * @return SimulatorResourceServer shared object representing simulated/created resource. - */ - SimulatorResourceServerSP createResource(const std::string &configPath, - SimulatorResourceServer::ResourceModelChangedCB callback); - - /** - * This method is for creating multiple resources of same type based on the input data - * provided from RAML file. - * - * @param configPath - RAML configuration file path. - * @param count - Number of resource to be created. - * @param callback - Callback method for receiving notifications when resource model changes. - * - * @return vector of SimulatorResourceServer shared objects representing simulated/created - * resources. - */ - std::vector createResource(const std::string &configPath, - unsigned short count, SimulatorResourceServer::ResourceModelChangedCB callback); - - /** - * This method is for obtaining a list of created resources. - * - * @param resourceType - Resource type. Empty value will fetch all resources. - * Default value is empty string. - * - * @return vector of SimulatorResourceServer shared objects representing simulated/created - */ - std::vector getResources(const std::string &resourceType = ""); - - /** - * This method is for deleting/unregistering resource. - * - * @param resource - SimulatorResourceServer shared object. - * - */ - void deleteResource(const SimulatorResourceServerSP &resource); - - /** - * This method is for deleting multiple resources based on resource type. - * - * @param resourceType - Resource type. Empty value will delete all the resources. - * Default value is empty string. - * - */ - void deleteResources(const std::string &resourceType = ""); - - private: - ResourceManager(): m_id(0) {} - ~ResourceManager() = default; - ResourceManager(const ResourceManager &) = delete; - ResourceManager &operator=(const ResourceManager &) = delete; - ResourceManager(const ResourceManager &&) = delete; - ResourceManager &operator=(const ResourceManager && ) = delete; - - SimulatorResourceServerSP buildResource(const std::string &configPath, - SimulatorResourceServer::ResourceModelChangedCB callback); - std::string constructURI(const std::string &uri); - - /*Member variables*/ - int m_id; - SimulatorResourceCreator m_resourceCreator; - std::recursive_mutex m_lock; - std::map> m_resources; -}; - -#endif - diff --git a/service/simulator/src/service-provider/simulator_resource_creator.cpp b/service/simulator/src/service-provider/simulator_resource_creator.cpp deleted file mode 100755 index c6ff567..0000000 --- a/service/simulator/src/service-provider/simulator_resource_creator.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/****************************************************************** - * - * Copyright 2015 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -#include "simulator_resource_creator.h" -#include "simulator_logger.h" -#include -#include "logger.h" - -#define TAG "SIM_RESOURCE_CREATOR" - -unsigned int SimulatorResourceCreator::s_id; -SimulatorResourceServerImplSP SimulatorResourceCreator::createResource( - const std::string &configPath) -{ - RAML::RamlPtr raml; - - try - { - std::shared_ptr ramlParser = std::make_shared(configPath); - raml = ramlParser->getRamlPtr(); - } - catch (RAML::RamlException &e) - { - OC_LOG_V(ERROR, TAG, "RAML Exception occured! [%s]", e.what()); - throw; - } - - std::map ramlResources = raml->getResources(); - RAML::RamlResourcePtr ramlResource; - if (0 == ramlResources.size() || (ramlResource = ramlResources.begin()->second) == nullptr) - { - OC_LOG(ERROR, TAG, "Zero resources detected from RAML!"); - return nullptr; - } - - if (ramlResource) - { - SimulatorResourceServerImplSP simResource(new SimulatorResourceServerImpl()); - simResource->setName(ramlResource->getDisplayName()); - simResource->setURI(ramlResource->getResourceUri()); - - // Get the resource representation schema from GET response body - RAML::ActionPtr action = ramlResource->getAction(RAML::ActionType::GET); - if (!action) - { - OC_LOG(ERROR, TAG, "Failed to create resource representation schema as it does not" - "posess the GET request!"); - return nullptr; - } - - RAML::ResponsePtr getResponse = action->getResponse("200"); - if (!getResponse) - { - OC_LOG(ERROR, TAG, "Resource does not provide valid GET response!"); - return nullptr; - } - - RAML::RequestResponseBodyPtr responseBody = getResponse->getResponseBody("application/json"); - if (responseBody) - { - RAML::JsonSchemaPtr resourceProperties = responseBody->getSchema()->getProperties(); - for ( auto & propertyElement : resourceProperties->getProperties()) - { - if (!propertyElement.second) - continue; - - std::string propName = propertyElement.second->getName(); - if ("rt" == propName || "resourceType" == propName) - { - simResource->setResourceType(propertyElement.second->getValueString()); - continue; - } - else if ("if" == propName) - { - simResource->setInterfaceType(propertyElement.second->getValueString()); - continue; - } - else if ("p" == propName || "n" == propName || "id" == propName) - { - continue; - } - - // Build representation attribute - SimulatorResourceModel::Attribute attribute(propName); - switch (propertyElement.second->getValueType()) - { - case 0: // Integer - attribute.setValue(propertyElement.second->getValue()); - break; - - case 1: // Double - attribute.setValue(propertyElement.second->getValue()); - break; - - case 2: // Boolean - attribute.setValue(propertyElement.second->getValue()); - break; - - case 3: // String - attribute.setValue(propertyElement.second->getValue()); - break; - } - - // Set range/supported values set - double min = 0, max = 0; - int multipleof = 0; - propertyElement.second->getRange(min, max, multipleof); - attribute.setRange(min, max); - - if (propertyElement.second->getAllowedValuesSize() > 0) - attribute.setAllowedValues(propertyElement.second->getAllowedValues()); - - simResource->addAttribute(attribute); - } - } - - simResource->setURI(constructURI(simResource->getURI())); - return simResource; - } - - return nullptr; -} - -/** - * This method appends a unique key to the given URI to make the URI unique in simulator. - * Example: If input is "/a/light", then the output will be "/a/light/simulator/0" for the first resource - * and "/a/light/simulator/1" for the second resource and so on. - */ -std::string SimulatorResourceCreator::constructURI(const std::string &uri) -{ - std::ostringstream os; - os << uri; - if (!uri.empty() && '/' != uri[uri.length() - 1]) - os << '/'; - os << "simulator/" << s_id++; - return os.str(); -} - diff --git a/service/simulator/src/service-provider/simulator_resource_server.cpp b/service/simulator/src/service-provider/simulator_resource_server.cpp deleted file mode 100644 index a4ae6a7..0000000 --- a/service/simulator/src/service-provider/simulator_resource_server.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/****************************************************************** - * - * Copyright 2015 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -#include "simulator_resource_server.h" - -SimulatorResourceServer::SimulatorResourceServer() -{ -} - -std::string SimulatorResourceServer::getURI() const -{ - return m_uri; -} - -std::string SimulatorResourceServer::getResourceType() const -{ - return m_resourceType; -} - -std::string SimulatorResourceServer::getInterfaceType() const -{ - return m_interfaceType; -} - -std::string SimulatorResourceServer::getName() const -{ - return m_name; -} - -void SimulatorResourceServer::addAttribute(SimulatorResourceModel::Attribute &attribute) -{ - m_resModel.addAttribute(attribute); -} - -void SimulatorResourceServer::setRange(const std::string &attrName, const int min, const int max) -{ - m_resModel.setRange(attrName, min, max); -} - -SimulatorResourceModel SimulatorResourceServer::getModel() const -{ - return m_resModel; -} - -void SimulatorResourceServer::updateFromAllowedValues(const std::string &attrName, - unsigned int index) -{ - m_resModel.updateAttributeFromAllowedValues(attrName, index); - - // Notify all the subscribers - notifyAll(); -} - -void SimulatorResourceServer::removeAttribute(const std::string &attrName) -{ - m_resModel.removeAttribute(attrName); -} - diff --git a/service/simulator/src/service-provider/simulator_resource_server_impl.cpp b/service/simulator/src/service-provider/simulator_resource_server_impl.cpp deleted file mode 100644 index 4f3b042..0000000 --- a/service/simulator/src/service-provider/simulator_resource_server_impl.cpp +++ /dev/null @@ -1,438 +0,0 @@ -/****************************************************************** - * - * Copyright 2015 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -#include "simulator_resource_server_impl.h" -#include "simulator_utils.h" -#include "simulator_logger.h" -#include "logger.h" - -#define TAG "SIM_RESOURCE_SERVER" - -SimulatorResourceServerImpl::SimulatorResourceServerImpl() - : m_resourceHandle(NULL) -{ - m_property = static_cast(OC_DISCOVERABLE | OC_OBSERVABLE); - m_interfaceType.assign(OC::DEFAULT_INTERFACE); -} - -bool SimulatorResourceServerImpl::isObservable() const -{ - return (m_property & OC_OBSERVABLE); -} - -void SimulatorResourceServerImpl::setURI(const std::string &uri) -{ - m_uri = uri; -} - -void SimulatorResourceServerImpl::setResourceType(const std::string &resourceType) -{ - m_resourceType = resourceType; -} - -void SimulatorResourceServerImpl::setInterfaceType(const std::string &interfaceType) -{ - m_interfaceType = interfaceType; -} - -void SimulatorResourceServerImpl::setName(const std::string &name) -{ - m_name = name; -} - -void SimulatorResourceServerImpl::setObservable(bool state) -{ - if (true == state) - m_property = static_cast(m_property | OC_OBSERVABLE); - else - m_property = static_cast(m_property ^ OC_OBSERVABLE); -} - -int SimulatorResourceServerImpl::startUpdateAutomation(AutomationType type, - int updateInterval, updateCompleteCallback callback) -{ - if (!callback) - { - OC_LOG(ERROR, TAG, "Invalid callback!"); - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - } - - if (!m_resourceHandle) - { - OC_LOG(ERROR, TAG, "Invalid resource!"); - throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!"); - } - - return m_updateAutomationMgr.startResourceAutomation(this, type, updateInterval, callback); -} - -int SimulatorResourceServerImpl::startUpdateAutomation(const std::string &attrName, - AutomationType type, int updateInterval, - updateCompleteCallback callback) -{ - if (!callback) - { - OC_LOG(ERROR, TAG, "Invalid callback!"); - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); - } - - if (!m_resourceHandle) - { - OC_LOG(ERROR, TAG, "Invalid resource!"); - throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!"); - } - - return m_updateAutomationMgr.startAttributeAutomation(this, attrName, type, updateInterval, callback); -} - -std::vector SimulatorResourceServerImpl::getResourceAutomationIds() -{ - return m_updateAutomationMgr.getResourceAutomationIds(); -} - -std::vector SimulatorResourceServerImpl::getAttributeAutomationIds() -{ - return m_updateAutomationMgr.getAttributeAutomationIds(); -} - -void SimulatorResourceServerImpl::stopUpdateAutomation(const int id) -{ - m_updateAutomationMgr.stop(id); -} - -void SimulatorResourceServerImpl::setModelChangeCallback(ResourceModelChangedCB callback) -{ - m_callback = callback; -} - -void SimulatorResourceServerImpl::setObserverCallback(ObserverCB callback) -{ - m_observeCallback = callback; -} - -std::vector SimulatorResourceServerImpl::getObserversList() -{ - return m_observersList; -} - -void SimulatorResourceServerImpl::notify(uint8_t id) -{ - if (!m_resourceHandle) - { - OC_LOG(ERROR, TAG, "Invalid resource!"); - throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!"); - } - - std::shared_ptr resourceResponse = - {std::make_shared()}; - - resourceResponse->setErrorCode(200); - resourceResponse->setResponseResult(OC_EH_OK); - resourceResponse->setResourceRepresentation(getOCRepresentation(), OC::DEFAULT_INTERFACE); - - OC::ObservationIds observers; - observers.push_back(id); - - SIM_LOG(ILogger::INFO, "[" << m_uri << "] Sending notification to observer with id " << id); - - typedef OCStackResult (*NotifyListOfObservers)(OCResourceHandle, OC::ObservationIds &, - const std::shared_ptr); - - invokeocplatform(static_cast(OC::OCPlatform::notifyListOfObservers), - m_resourceHandle, - observers, - resourceResponse); -} - -void SimulatorResourceServerImpl::notifyAll() -{ - if (!m_resourceHandle) - { - OC_LOG(ERROR, TAG, "Invalid resource!"); - throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!"); - } - - if (!m_observersList.size()) - { - OC_LOG(ERROR, TAG, "Observers list is empty!"); - return; - } - - std::shared_ptr resourceResponse = - {std::make_shared()}; - - resourceResponse->setErrorCode(200); - resourceResponse->setResponseResult(OC_EH_OK); - resourceResponse->setResourceRepresentation(getOCRepresentation(), OC::DEFAULT_INTERFACE); - - OC::ObservationIds observers; - for (auto & observer : m_observersList) - observers.push_back(observer.id); - - SIM_LOG(ILogger::INFO, "[" << m_uri << "] Sending notification to all observers"); - - typedef OCStackResult (*NotifyListOfObservers)(OCResourceHandle, OC::ObservationIds &, - const std::shared_ptr); - - invokeocplatform(static_cast(OC::OCPlatform::notifyListOfObservers), - m_resourceHandle, - observers, - resourceResponse); -} - -void SimulatorResourceServerImpl::start() -{ - if (m_uri.empty() || m_resourceType.empty() || - m_interfaceType.empty() || m_name.empty() || !m_callback) - { - OC_LOG(ERROR, TAG, "Invalid data found to register the resource!"); - throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Invalid data found to register the resource!"); - } - - if (m_resourceHandle) - { - OC_LOG(ERROR, TAG, "Resource already registered!"); - throw SimulatorException(SIMULATOR_ERROR, "Resource already registered!"); - } - - typedef OCStackResult (*RegisterResource)(OCResourceHandle &, std::string &, const std::string &, - const std::string &, OC::EntityHandler, uint8_t); - - invokeocplatform(static_cast(OC::OCPlatform::registerResource), - m_resourceHandle, m_uri, m_resourceType, m_interfaceType, - std::bind(&SimulatorResourceServerImpl::entityHandler, - this, std::placeholders::_1), m_property); -} - -void SimulatorResourceServerImpl::stop() -{ - if (!m_resourceHandle) - { - OC_LOG(ERROR, TAG, "Invalid resource!"); - throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!"); - } - - typedef OCStackResult (*UnregisterResource)(const OCResourceHandle &); - - invokeocplatform(static_cast(OC::OCPlatform::unregisterResource), - m_resourceHandle); - - m_resourceHandle = nullptr; -} - -void SimulatorResourceServerImpl::notifyApp() -{ - // Notify the application callback - if (m_callback) - { - m_callback(m_uri, m_resModel); - } -} - -OC::OCRepresentation SimulatorResourceServerImpl::getOCRepresentation() -{ - return m_resModel.getOCRepresentation(); -} - -bool SimulatorResourceServerImpl::modifyResourceModel(OC::OCRepresentation &ocRep) -{ - bool status = m_resModel.update(ocRep); - if (true == status) - { - resourceModified(); - } - return status; -} - -void SimulatorResourceServerImpl::resourceModified() -{ - if (!m_resourceHandle) - { - return; - } - - // Notify all the subscribers - notifyAll(); - - // Notify the application callback - if (m_callback) - { - m_callback(m_uri, m_resModel); - } -} - -OCEntityHandlerResult SimulatorResourceServerImpl::entityHandler( - std::shared_ptr - request) -{ - OCEntityHandlerResult errCode = OC_EH_ERROR; - if (!request) - { - return OC_EH_ERROR; - } - - if (OC::RequestHandlerFlag::RequestFlag & request->getRequestHandlerFlag()) - { - auto response = std::make_shared(); - response->setRequestHandle(request->getRequestHandle()); - response->setResourceHandle(request->getResourceHandle()); - - if ("GET" == request->getRequestType()) - { - OC::OCRepresentation rep = request->getResourceRepresentation(); - std::string payload = getPayloadString(rep); - SIM_LOG(ILogger::INFO, "[" << m_uri << - "] GET request received. \n**Payload details**" << payload) - - response->setErrorCode(200); - response->setResponseResult(OC_EH_OK); - response->setResourceRepresentation(getOCRepresentation()); - - if (OC_STACK_OK == OC::OCPlatform::sendResponse(response)) - { - errCode = OC_EH_OK; - } - } - else if ("PUT" == request->getRequestType()) - { - OC::OCRepresentation rep = request->getResourceRepresentation(); - std::string payload = getPayloadString(rep); - SIM_LOG(ILogger::INFO, "[" << m_uri << - "] PUT request received. \n**Payload details**" << payload) - - if (true == modifyResourceModel(rep)) - { - response->setErrorCode(200); - response->setResponseResult(OC_EH_OK); - response->setResourceRepresentation(getOCRepresentation()); - } - else - { - response->setErrorCode(400); - response->setResponseResult(OC_EH_ERROR); - } - - if (OC_STACK_OK == OC::OCPlatform::sendResponse(response)) - { - errCode = OC_EH_OK; - } - } - else if ("POST" == request->getRequestType()) - { - OC::OCRepresentation rep = request->getResourceRepresentation(); - std::string payload = getPayloadString(rep); - SIM_LOG(ILogger::INFO, "[" << m_uri << - "] POST request received. \n**Payload details**" << payload) - - if (true == modifyResourceModel(rep)) - { - response->setErrorCode(200); - response->setResponseResult(OC_EH_OK); - response->setResourceRepresentation(getOCRepresentation()); - } - else - { - response->setErrorCode(400); - response->setResponseResult(OC_EH_ERROR); - } - - if (OC_STACK_OK == OC::OCPlatform::sendResponse(response)) - { - errCode = OC_EH_OK; - } - } - else if ("DELETE" == request->getRequestType()) - { - OC::OCRepresentation rep = request->getResourceRepresentation(); - std::string payload = getPayloadString(rep); - SIM_LOG(ILogger::INFO, "[" << m_uri << - "] DELETE request received. \n**Payload details**" << payload) - - // DELETE request handling not supported right now - response->setErrorCode(400); - response->setResponseResult(OC_EH_ERROR); - if (OC_STACK_OK == OC::OCPlatform::sendResponse(response)) - { - errCode = OC_EH_OK; - } - } - else - { - OC::OCRepresentation rep = request->getResourceRepresentation(); - std::string payload = getPayloadString(rep); - SIM_LOG(ILogger::INFO, "[" << m_uri << - "] UNKNOWN type request received. \n**Payload details**" << payload) - - response->setResponseResult(OC_EH_ERROR); - if (OC_STACK_OK == OC::OCPlatform::sendResponse(response)) - { - errCode = OC_EH_ERROR; - } - } - } - - if (OC::RequestHandlerFlag::ObserverFlag & request->getRequestHandlerFlag()) - { - if (false == isObservable()) - { - SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE request received") - SIM_LOG(ILogger::INFO, "[" << m_uri << "] Sending error as resource is in unobservable state") - return OC_EH_ERROR; - } - - OC::ObservationInfo observationInfo = request->getObservationInfo(); - if (OC::ObserveAction::ObserveRegister == observationInfo.action) - { - SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE REGISTER request received"); - - ObserverInfo info {observationInfo.obsId, observationInfo.address, observationInfo.port}; - m_observersList.push_back(info); - - //Inform about addition of observer - if (m_observeCallback) - { - m_observeCallback(m_uri, ObservationStatus::OBSERVE_REGISTER, info); - } - } - else if (OC::ObserveAction::ObserveUnregister == observationInfo.action) - { - SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE UNREGISTER request received"); - - ObserverInfo info; - for (auto iter = m_observersList.begin(); iter != m_observersList.end(); iter++) - { - if ((info = *iter), info.id == observationInfo.obsId) - { - m_observersList.erase(iter); - break; - } - } - - // Inform about cancellation of observer - if (m_observeCallback) - { - m_observeCallback(m_uri, ObservationStatus::OBSERVE_UNREGISTER, info); - } - } - errCode = OC_EH_OK; - } - - return errCode; -} diff --git a/service/simulator/src/service-provider/simulator_resource_server_impl.h b/service/simulator/src/service-provider/simulator_resource_server_impl.h deleted file mode 100644 index 010865c..0000000 --- a/service/simulator/src/service-provider/simulator_resource_server_impl.h +++ /dev/null @@ -1,89 +0,0 @@ -/****************************************************************** - * - * Copyright 2015 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -#ifndef SIMULATOR_RESOURCE_SERVER_IMPL_H_ -#define SIMULATOR_RESOURCE_SERVER_IMPL_H_ - -#include "simulator_resource_server.h" -#include "resource_update_automation_mngr.h" - -class SimulatorResourceServerImpl : public SimulatorResourceServer -{ - public: - SimulatorResourceServerImpl(); - - void setURI(const std::string &uri); - - void setResourceType(const std::string &resourceType); - - void setInterfaceType(const std::string &interfaceType); - - void setName(const std::string &name); - - void setObservable(bool state); - - bool isObservable() const; - - int startUpdateAutomation(AutomationType type, int updateInterval, - updateCompleteCallback callback); - - int startUpdateAutomation(const std::string &attrName, AutomationType type, - int updateInterval, updateCompleteCallback callback); - - std::vector getResourceAutomationIds(); - - std::vector getAttributeAutomationIds(); - - void stopUpdateAutomation(const int id); - - void setModelChangeCallback(ResourceModelChangedCB callback); - - void setObserverCallback(ObserverCB callback); - - std::vector getObserversList(); - - void notify(uint8_t id); - - void notifyAll(); - - void start(); - - void stop(); - - void notifyApp(); - - private: - OC::OCRepresentation getOCRepresentation(); - bool modifyResourceModel(OC::OCRepresentation &ocRep); - OCEntityHandlerResult entityHandler(std::shared_ptr request); - void resourceModified(); - - ResourceModelChangedCB m_callback; - ObserverCB m_observeCallback; - UpdateAutomationMngr m_updateAutomationMgr; - std::vector m_observersList; - - OCResourceProperty m_property; - OCResourceHandle m_resourceHandle; -}; - -typedef std::shared_ptr SimulatorResourceServerImplSP; - -#endif diff --git a/service/simulator/src/simulator_manager.cpp b/service/simulator/src/simulator_manager.cpp index 38e5269..18ca709 100644 --- a/service/simulator/src/simulator_manager.cpp +++ b/service/simulator/src/simulator_manager.cpp @@ -19,8 +19,8 @@ ******************************************************************/ #include "simulator_manager.h" -#include "resource_manager.h" -#include "simulator_client.h" +#include "simulator_resource_factory.h" +#include "simulator_remote_resource_impl.h" #include "simulator_utils.h" SimulatorManager *SimulatorManager::getInstance() @@ -43,54 +43,94 @@ SimulatorManager::SimulatorManager() OC::OCPlatform::Configure(conf); } -std::shared_ptr SimulatorManager::createResource( - const std::string &configPath, - SimulatorResourceServer::ResourceModelChangedCB callback) +std::shared_ptr SimulatorManager::createResource( + const std::string &configPath) { - return ResourceManager::getInstance()->createResource(configPath, callback); -} + VALIDATE_INPUT(configPath.empty(), "Empty path!") -std::vector> SimulatorManager::createResource( - const std::string &configPath, unsigned short count, - SimulatorResourceServer::ResourceModelChangedCB callback) -{ - return ResourceManager::getInstance()->createResource(configPath, count, callback); + return SimulatorResourceFactory::getInstance()->createResource(configPath); } -std::vector> SimulatorManager::getResources( - const std::string &resourceType) +std::vector> SimulatorManager::createResource( + const std::string &configPath, unsigned int count) { - return ResourceManager::getInstance()->getResources(resourceType); + VALIDATE_INPUT(configPath.empty(), "Empty path!") + VALIDATE_INPUT(!count, "Count is zero!") + + return SimulatorResourceFactory::getInstance()->createResource(configPath, count); } -void SimulatorManager::deleteResource( - const std::shared_ptr &resource) +std::shared_ptr SimulatorManager::createSingleResource( + const std::string &name, const std::string &uri, const std::string &resourceType) { - ResourceManager::getInstance()->deleteResource(resource); + VALIDATE_INPUT(name.empty(), "Empty resource name!") + VALIDATE_INPUT(resourceType.empty(), "Empty resource type!") + + return SimulatorResourceFactory::getInstance()->createSingleResource(name, uri, resourceType); } -void SimulatorManager::deleteResource(const std::string &resourceType) +std::shared_ptr SimulatorManager::createCollectionResource( + const std::string &name, const std::string &uri, const std::string &resourceType) { - ResourceManager::getInstance()->deleteResources(resourceType); + VALIDATE_INPUT(name.empty(), "Empty resource name!") + VALIDATE_INPUT(resourceType.empty(), "Empty resource type!") + + return SimulatorResourceFactory::getInstance()->createCollectionResource(name, uri, resourceType); } void SimulatorManager::findResource(ResourceFindCallback callback) { - SimulatorClient::getInstance()->findResources(callback); + VALIDATE_CALLBACK(callback) + + OC::FindCallback findCallback = std::bind( + [](std::shared_ptr ocResource, ResourceFindCallback callback) + { + if (!ocResource) + return; + + SimulatorRemoteResourceSP simulatorResource(new SimulatorRemoteResourceImpl(ocResource)); + callback(simulatorResource); + }, std::placeholders::_1, callback); + + typedef OCStackResult (*FindResource)(const std::string &, const std::string &, + OCConnectivityType, OC::FindCallback); + + invokeocplatform(static_cast(OC::OCPlatform::findResource), "", + OC_MULTICAST_DISCOVERY_URI, CT_DEFAULT, findCallback); } void SimulatorManager::findResource(const std::string &resourceType, - ResourceFindCallback callback) + ResourceFindCallback callback) { - SimulatorClient::getInstance()->findResources(resourceType, callback); + VALIDATE_INPUT(resourceType.empty(), "Empty resource type!") + VALIDATE_CALLBACK(callback) + + OC::FindCallback findCallback = std::bind( + [](std::shared_ptr ocResource, ResourceFindCallback callback) + { + if (!ocResource) + return; + + SimulatorRemoteResourceSP simulatorResource(new SimulatorRemoteResourceImpl(ocResource)); + callback(simulatorResource); + }, std::placeholders::_1, callback); + + std::ostringstream query; + query << OC_MULTICAST_DISCOVERY_URI << "?rt=" << resourceType; + + typedef OCStackResult (*FindResource)(const std::string &, const std::string &, + OCConnectivityType, OC::FindCallback); + + invokeocplatform(static_cast(OC::OCPlatform::findResource), "", query.str(), + CT_DEFAULT, findCallback); } void SimulatorManager::getDeviceInfo(DeviceInfoCallback callback) { - if (!callback) - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); + VALIDATE_CALLBACK(callback) - OC::FindDeviceCallback deviceCallback = [this, callback](const OC::OCRepresentation & rep) + OC::FindDeviceCallback deviceCallback = std::bind( + [](const OC::OCRepresentation & rep, DeviceInfoCallback callback) { std::string deviceName = rep.getValue("n"); std::string deviceID = rep.getValue("di"); @@ -99,7 +139,7 @@ void SimulatorManager::getDeviceInfo(DeviceInfoCallback callback) DeviceInfo deviceInfo(deviceName, deviceID, deviceSpecVersion, deviceDMV); callback(deviceInfo); - }; + }, std::placeholders::_1, callback); std::ostringstream uri; uri << OC_MULTICAST_PREFIX << OC_RSRVD_DEVICE_URI; @@ -108,16 +148,12 @@ void SimulatorManager::getDeviceInfo(DeviceInfoCallback callback) OCConnectivityType, OC::FindDeviceCallback); invokeocplatform(static_cast(OC::OCPlatform::getDeviceInfo), "", - uri.str(), - CT_DEFAULT, - deviceCallback); + uri.str(), CT_DEFAULT, deviceCallback); } void SimulatorManager::setDeviceInfo(const std::string &deviceName) { - if (deviceName.empty()) - throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Device name is empty!"); - + VALIDATE_INPUT(deviceName.empty(), "Empty resource type!") typedef OCStackResult (*RegisterDeviceInfo)(const OCDeviceInfo); @@ -129,10 +165,10 @@ void SimulatorManager::setDeviceInfo(const std::string &deviceName) void SimulatorManager::getPlatformInfo(PlatformInfoCallback callback) { - if (!callback) - throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!"); + VALIDATE_CALLBACK(callback) - OC::FindPlatformCallback platformCallback = [this, callback](const OC::OCRepresentation & rep) + OC::FindPlatformCallback platformCallback = std::bind( + [](const OC::OCRepresentation & rep, PlatformInfoCallback callback) { PlatformInfo platformInfo; platformInfo.setPlatformID(rep.getValue("pi")); @@ -148,7 +184,7 @@ void SimulatorManager::getPlatformInfo(PlatformInfoCallback callback) platformInfo.setSystemTime(rep.getValue("st")); callback(platformInfo); - }; + }, std::placeholders::_1, callback); std::ostringstream uri; uri << OC_MULTICAST_PREFIX << OC_RSRVD_PLATFORM_URI; @@ -157,9 +193,7 @@ void SimulatorManager::getPlatformInfo(PlatformInfoCallback callback) OCConnectivityType, OC::FindPlatformCallback); invokeocplatform(static_cast(OC::OCPlatform::getPlatformInfo), "", - uri.str(), - CT_DEFAULT, - platformCallback); + uri.str(), CT_DEFAULT, platformCallback); } void SimulatorManager::setPlatformInfo(PlatformInfo &platformInfo)