Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • sw/armarx/robot-api
  • uwkce_singer/robot-api
  • untcg_hofmann/robot-api
  • ulqba_korosakov/RobotAPI
4 results
Show changes
Commits on Source (28)
Showing
with 523 additions and 122 deletions
......@@ -99,6 +99,11 @@ module armarx
string hint;
};
exception FluxioException
{
string reason;
};
sequence<dto::FluxioIdentificator> FluxioIdentificatorList;
struct FluxioSkillStatusUpdate
......@@ -240,25 +245,25 @@ module armarx
//****************************//
optional(3) string
executeFluxioSkill(string skillId); // executes a fluxio skill
executeFluxioSkill(string skillId) throws dto::FluxioException; // executes a fluxio skill
void
abortFluxioSkill(string executionId); // aborts a fluxio skill
abortFluxioSkill(string executionId) throws dto::FluxioException ; // aborts a fluxio skill
dto::FluxioSkillList
getSkillList(); // returns skills of all providers
getSkillList() throws dto::FluxioException; // returns skills of all providers
optional(4) dto::FluxioSkill
getSkill(string id); // returns a single skill
getSkill(string id) throws dto::FluxioException; // returns a single skill
bool
updateSkill(string userId, dto::FluxioSkill skill); // updates an existing skill
updateSkill(string userId, dto::FluxioSkill skill) throws dto::FluxioException; // updates an existing skill
bool
getSkillMutex(string skillId, string userId); // request a mutex for a skill
getSkillMutex(string skillId, string userId) throws dto::FluxioException; // request a mutex for a skill
void
deleteSkillMutex(string skillId, string userId); // release a mutex for a skill
deleteSkillMutex(string skillId, string userId) throws dto::FluxioException; // release a mutex for a skill
optional(5) dto::FluxioIdentificatorList
deleteSkill(string skillId, string userId, bool dryRun); // removes a skill
......@@ -268,31 +273,31 @@ module armarx
removeSkillParameter(string skillId, string parameterId, string userId); // removes a parameter from a skill
dto::FluxioProfileList
getProfileList(); // returns all profiles
getProfileList() throws dto::FluxioException; // returns all profiles
optional(6) dto::FluxioProfile
getProfile(string id); // returns a single profile
getProfile(string id) throws dto::FluxioException; // returns a single profile
dto::FluxioProfile
createProfile(dto::FluxioProfile profile); // creates a new profile
createProfile(dto::FluxioProfile profile) throws dto::FluxioException; // creates a new profile
void
updateProfile(dto::FluxioProfile profile); // updates an existing profile
updateProfile(dto::FluxioProfile profile) throws dto::FluxioException; // updates an existing profile
dto::FluxioProviderList
getProviderList(); // returns all providers
getProviderList() throws dto::FluxioException; // returns all providers
optional(7) dto::FluxioProvider
getProvider(string id); // returns a single provider
getProvider(string id) throws dto::FluxioException; // returns a single provider
optional(8) dto::FluxioSkillList
getSkillsOfProvider(string id); // returns all skills of a provider
getSkillsOfProvider(string id) throws dto::FluxioException; // returns all skills of a provider
optional(9) dto::FluxioSkill
addSkillToProvider(string userId, string providerId, dto::FluxioSkill skill); // adds a new skill to a provider
addSkillToProvider(string userId, string providerId, dto::FluxioSkill skill) throws dto::FluxioException; // adds a new skill to a provider
optional(10) dto::FluxioSkillStatusUpdateList
getFluxioSkillExecutionStatus(string executionId); // returns the status of a fluxio execution
getFluxioSkillExecutionStatus(string executionId) throws dto::FluxioException; // returns the status of a fluxio execution
};
}
}
......
......@@ -19,6 +19,8 @@ armarx_add_library(
executor/FluxioNativeExecutor.cpp
executor/FluxioCompositeExecutor.cpp
executor/FluxioMergerExecutor.cpp
error/FluxioException.cpp
error/FluxioErrorMessages.cpp
SkillID.cpp
ProviderID.cpp
ProviderInfo.cpp
......@@ -41,8 +43,12 @@ armarx_add_library(
FluxioParameterNode.cpp
FluxioSubSkillNode.cpp
FluxioSkillStatusUpdate.cpp
FluxioResult.cpp
HEADERS
error/FluxioException.h
error/Exception.h
error/FluxioErrorMessages.h
FluxioResult.h
executor/FluxioExecutor.h
executor/FluxioNativeExecutor.h
executor/FluxioCompositeExecutor.h
......
#include <stdexcept>
#include <memory>
namespace armarx
{
namespace skills
{
template <typename T, typename E = std::exception>
class Result
{
private:
const bool success;
const std::shared_ptr<const T> result;
const std::shared_ptr<const E> error;
public:
Result(const T& res) : success(true), result(std::make_shared<const T>(res)), error(nullptr)
{
}
Result(const E& err) : success(false), result(nullptr), error(std::make_shared<const E>(err))
{
}
bool isSuccess() const
{
return success;
}
T getResult() const
{
if (!success)
{
throw std::logic_error("Result is not successful");
}
return *result;
}
E getError() const
{
if (success)
{
throw std::logic_error("Result does not contain an error");
}
return *error;
}
};
}
}
......@@ -20,18 +20,14 @@
* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
* GNU General Public License
*/
#pragma once
// STD/STL
#include <map>
#include <string>
#include <vector>
// ArmarX
#include <ArmarXCore/core/exceptions/Exception.h>
#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
namespace armarx::skills::error
{
/**
......@@ -41,13 +37,11 @@ namespace armarx::skills::error
{
public:
SkillException() = delete;
SkillException(const std::string& prettymethod, const std::string& reason) :
LocalException(prettymethod + ": " + reason + ".")
{
}
};
/**
* @brief Indicates that a skill was not found, e.g., by the skill manager.
*/
......@@ -55,35 +49,29 @@ namespace armarx::skills::error
{
public:
SkillNotFoundException() = delete;
SkillNotFoundException(const std::string& prettymethod, const std::string& reason) :
SkillException(prettymethod, reason)
{
}
};
class SkillAbortedException : public SkillException
{
public:
SkillAbortedException() = delete;
SkillAbortedException(const std::string& prettymethod, const std::string& reason) :
SkillException(prettymethod, reason)
{
}
};
class SkillFailedException : public SkillException
{
public:
SkillFailedException() = delete;
SkillFailedException(const std::string& prettymethod, const std::string& reason) :
SkillException(prettymethod, reason)
{
}
};
/**
* @brief The NotImplementedYetException class
*/
......@@ -91,10 +79,9 @@ namespace armarx::skills::error
{
public:
NotImplementedYetException() = delete;
NotImplementedYetException(const std::string& prettymethod) :
SkillException(prettymethod, "This method is not yet implemented!")
{
}
};
} // namespace armarx::skills::error
} // namespace armarx::skills::error
\ No newline at end of file
#include "FluxioErrorMessages.h"
#include <string>
namespace armarx::skills::error
{
std::string formatString(const std::string& format, const std::vector<std::string>& args) {
std::string formatted = format;
size_t pos = 0;
size_t argIndex = 0;
while ((pos = formatted.find("%s", pos)) != std::string::npos && argIndex < args.size()) {
formatted.replace(pos, 2, args[argIndex]);
pos += args[argIndex].length();
++argIndex;
}
return formatted;
}
std::string createErrorMessage(ErrorCode code, const std::vector<std::basic_string<char>>& args) {
switch (code) {
case ErrorCode::ExecutionNotFound:
return formatString("Execution with ID '%s' not found.", args);
case ErrorCode::ExecutorNotFound:
return formatString("Executor with ID '%s' not found.", args);
case ErrorCode::RunnerNotFound:
return formatString("Error while getting execution runner for fluxio skill with id '%s'", args);
case ErrorCode::ConverterError:
return formatString("Skill with ID '%s' could not be converted.", args);
case ErrorCode::NotFluxioCompExecutor:
return formatString("Executor with ID '%s' is not a FluxioCompositeExecutor.", args);
case ErrorCode::SkillNotFound:
return formatString("Skill with ID '%s' not found.", args);
case ErrorCode::ProfileNotFound:
return formatString("Profile with ID '%s' not found.", args);
case ErrorCode::ProviderNotFound:
return formatString("Provider with ID '%s' not found.", args);
case ErrorCode::SkillDescNotFound:
return formatString("Skill description for Skill with ID '%s' not found. Abort executing.", args);
case ErrorCode::GenericMutexError:
return formatString("Mutex for Skill with ID '%s' could not be aquired", args);
case ErrorCode::UserHasNoMutexError:
return formatString("Mutex for Skill with ID '%s' could not be removed because the user does not hold the mutex.", args);
case ErrorCode::AddSkillError:
return formatString("Skill with ID: '%s' could not be added to provider with ID: '%s'.", args);
case ErrorCode::TestError:
return formatString("This is a test Error with Argument: '%s'", args);
case ErrorCode::ProviderAlreadyExists:
return formatString("Provider with ID '%s' already exists.", args);
default:
return "Unknown error.";
}
}
} // namespace armarx::skills::error
\ No newline at end of file
#include <string>
#include <vector>
namespace armarx::skills::error
{
enum class ErrorCode {
ExecutionNotFound,
ExecutorNotFound,
RunnerNotFound,
SkillNotFound,
SkillDescNotFound,
NotFluxioCompExecutor,
ProfileNotFound,
ProviderNotFound,
GenericMutexError,
UserHasNoMutexError,
AddSkillError,
ProviderAlreadyExists,
ConverterError,
TestError
};
std::string formatString(const std::string& format, const std::vector<std::string>& args);
std::string createErrorMessage(ErrorCode code, const std::vector<std::basic_string<char>>& args);
} // namespace armarx::skills::error
\ No newline at end of file
#pragma once
// STD/STL
#include <list>
#include <map>
#include <optional>
#include <sstream>
#include <string>
#include <vector>
// ArmarX
#include <ArmarXCore/core/exceptions/Exception.h>
#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
#include <RobotAPI/interface/skills/SkillManagerInterface.h>
namespace armarx::skills::error
{
/**
* @brief A base class for skill exceptions. All skill exceptions inherit from this class
*/
class FluxioException : public armarx::LocalException
{
private:
std::string prettymethod;
std::list<std::string> contextList;
public:
std::string
format(const std::list<std::string>& contextList) const
{
std::string message = "1: " + prettymethod + '\n';
int tmp = 2;
for (const auto& s : contextList)
{
message += (std::to_string(tmp) + ": " + s + '\n');
tmp++;
}
return message;
}
FluxioException() = delete;
FluxioException(const std::string& pretty, std::list<std::string> contextList = {}) :
prettymethod(pretty), contextList(contextList)
{
}
void
addToContext(const std::optional<std::string>& contextItem = std::nullopt, std::optional<std::string> className = std::nullopt, std::optional<std::string> methodName = std::nullopt, std::optional<int> line = std::nullopt)
{
std::ostringstream oss;
if (className.has_value() && methodName.has_value() && line.has_value()) {
oss << "From class " << className.value() << " in method " << methodName.value() << " in line " << line.value();
if (contextItem.has_value()) {
oss << "\n" << contextItem.value();
}
} else if (contextItem.has_value()) {
oss << contextItem.value();
}
contextList.push_back(oss.str());
}
static FluxioException
Create(const std::string& pretty, const std::string& className, const char* function, int line)
{
FluxioException error(pretty);
error.addToContext(std::nullopt, className, function, line);
return error;
}
skills::manager::dto::FluxioException
toManagerIce() const
{
skills::manager::dto::FluxioException ret;
ret.reason = format(contextList);
return ret;
}
};
} // namespace armarx::skills::error
......@@ -84,4 +84,4 @@ namespace armarx::skills
const armarx::Duration pollingFrequency = armarx::Duration::MilliSeconds(250);
};
} // namespace armarx::skills
} // namespace armarx::skills
\ No newline at end of file
......@@ -34,6 +34,8 @@
#include "RobotAPI/libraries/skills/core/FluxioSkill.h"
#include "RobotAPI/libraries/skills/core/FluxioSubSkillNode.h"
#include "RobotAPI/libraries/skills/core/FluxioValue.h"
#include "RobotAPI/libraries/skills/core/error/FluxioErrorMessages.h"
#include "RobotAPI/libraries/skills/core/error/FluxioException.h"
#include "RobotAPI/libraries/skills/core/executor/FluxioCompositeExecutor.h"
#include "RobotAPI/libraries/skills/core/executor/FluxioExecutor.h"
#include "RobotAPI/libraries/skills/core/executor/FluxioMergerExecutor.h"
......@@ -634,20 +636,28 @@ namespace armarx::plugins
//** Fluxio related methods **//
//****************************//
std::experimental::observer_ptr<skills::FluxioExecutor>
skills::Result<std::experimental::observer_ptr<skills::FluxioExecutor>,
skills::error::FluxioException>
SkillManagerComponentPlugin::executeFluxioSkill(const std::string& skillId,
const std::string& executorName)
{
const auto& skill = getSkill(skillId);
if (skill == nullptr)
const auto& result = getSkill(skillId);
if (!result.isSuccess())
{
ARMARX_WARNING << "Skill with id '" << skillId << "' not found.";
return nullptr;
return {skills::error::FluxioException::Create(
skills::error::createErrorMessage(skills::error::ErrorCode::SkillNotFound,
{skillId}),
"SkillManagerComponentPlugin",
__FUNCTION__,
__LINE__)};
}
const auto& skill = result.getResult(); // TODO: nullptr check
const std::string& executionId = IceUtil::generateUUID();
std::experimental::observer_ptr<skills::FluxioExecutor> executorPtr = nullptr;
if (!skill->native)
{
// currently empty parameters
......@@ -655,7 +665,7 @@ namespace armarx::plugins
const auto& executeFluxioSkillFunc =
[this](const std::string& skillId, const std::string& executorName)
{ return this->executeFluxioSkill(skillId, executorName); };
{ return this->executeFluxioSkill(skillId, executorName).getResult(); };
const auto& abortFluxioSkill = [this](const std::string& executionId)
{ this->abortFluxioSkill(executionId); };
......@@ -700,14 +710,20 @@ namespace armarx::plugins
{
skills::SkillID sID = skills::SkillID{
.providerId = skills::ProviderID{.providerName = skill->skillProviderPtr->name},
.skillName = skill->name};
.skillName = skill->skillProviderPtr->name};
auto skillDescr = getSkillDescription(sID);
if (!skillDescr.has_value())
{
ARMARX_WARNING << "Skill description for skill with id '" << skillId
<< "' not found. Aborting execution.";
return nullptr;
return {skills::error::FluxioException::Create(
skills::error::createErrorMessage(skills::error::ErrorCode::SkillDescNotFound,
{skillId}),
"SkillManagerComponentPlugin",
__FUNCTION__,
__LINE__)};
}
const auto& abortSkillFunc = [this](const skills::SkillExecutionID& executionId)
......@@ -729,6 +745,7 @@ namespace armarx::plugins
std::move(abortSkillFunc),
std::move(executeSkillAsyncFunc),
std::move(getSkillExecutionStatusFunc));
fluxioDC.fluxioExecutors[executionId]->run(executorName,
skillDescr->rootProfileDefaults);
executorPtr =
......@@ -740,7 +757,7 @@ namespace armarx::plugins
.detach();
}
return executorPtr;
return {executorPtr};
}
void
......@@ -751,15 +768,22 @@ namespace armarx::plugins
if (executorIt == fluxioDC.fluxioExecutors.end())
{
ARMARX_WARNING << "Execution with id '" << executionId << "' not found.";
l.unlock();
return;
throw skills::error::FluxioException::Create(
skills::error::createErrorMessage(skills::error::ErrorCode::ExecutionNotFound,
{executionId}),
"SkillManagerComponentPlugin",
__FUNCTION__,
__LINE__)
.toManagerIce();
}
l.unlock();
executorIt->second->abort();
}
std::optional<std::vector<skills::FluxioSkillStatusUpdate>>
skills::Result<std::vector<skills::FluxioSkillStatusUpdate>, skills::error::FluxioException>
SkillManagerComponentPlugin::getFluxioSkillExecutionStatus(const std::string& executionId)
{
std::shared_lock l(fluxioDC.fluxioExecutorsMutex);
......@@ -767,12 +791,18 @@ namespace armarx::plugins
if (executorIt == fluxioDC.fluxioExecutors.end())
{
ARMARX_WARNING << "Execution with id '" << executionId << "' not found.";
l.unlock();
return std::nullopt;
return {skills::error::FluxioException::Create(
skills::error::createErrorMessage(skills::error::ErrorCode::ExecutionNotFound,
{executionId}),
"SkillManagerComponentPlugin",
__FUNCTION__,
__LINE__)};
}
l.unlock();
return executorIt->second->getStatusUpdate();
return {executorIt->second->getStatusUpdate().value()};
}
/**
......@@ -825,7 +855,8 @@ namespace armarx::plugins
return generator(str);
}
std::vector<std::experimental::observer_ptr<const skills::FluxioSkill>>
skills::Result<std::vector<std::experimental::observer_ptr<const skills::FluxioSkill>>,
skills::error::FluxioException>
SkillManagerComponentPlugin::getSkillList()
{
std::map<skills::SkillID, skills::SkillDescription> skillDescriptions =
......@@ -865,8 +896,8 @@ namespace armarx::plugins
}
else
{
const auto p = addFluxioProvider(skillId.providerId->providerName);
if (p == nullptr)
const auto& res = addFluxioProvider(skillId.providerId->providerName);
if (!res.isSuccess())
{
ARMARX_WARNING << "Failed to add provider with name '"
<< skillId.providerId->providerName << "'. Skill: '" << s.name
......@@ -874,6 +905,7 @@ namespace armarx::plugins
providersLock.unlock();
continue;
}
const auto p = res.getResult(); // TODO: nullptr check
s.skillProviderPtr = p;
}
providersLock.unlock();
......@@ -957,10 +989,12 @@ namespace armarx::plugins
skillsLock.unlock();
}
return convertMapValuesToObserverVector(fluxioDC.skills);
return {convertMapValuesToObserverVector(fluxioDC.skills)};
}
std::experimental::observer_ptr<const skills::FluxioSkill>
skills::Result<std::experimental::observer_ptr<const skills::FluxioSkill>,
skills::error::FluxioException>
SkillManagerComponentPlugin::getSkill(const std::string& id)
{
std::shared_lock l(fluxioDC.skillsMutex);
......@@ -969,13 +1003,18 @@ namespace armarx::plugins
{
ARMARX_WARNING << "Skill with id '" << id << "' not found.";
l.unlock();
return nullptr;
return {skills::error::FluxioException::Create(
skills::error::createErrorMessage(skills::error::ErrorCode::SkillNotFound, {id}),
"SkillManagerComponentPlugin",
__FUNCTION__,
__LINE__)};
}
l.unlock();
return std::experimental::make_observer(&skillsEntry->second);
return {std::experimental::make_observer(&skillsEntry->second)};
}
// TODO: Outsource to a helper function or a separate class
std::optional<std::vector<std::experimental::observer_ptr<const skills::FluxioSkill>>>
SkillManagerComponentPlugin::deleteSkill(const std::string& skillId,
const std::string& userId,
......@@ -998,7 +1037,16 @@ namespace armarx::plugins
return std::nullopt;
}
if (!getSkillMutex(skillId, userId))
const auto& skillMutexResult = getSkillMutex(skillId, userId);
if (!skillMutexResult.isSuccess())
{
ARMARX_WARNING << "User '" << userId << "' needs to acquire the mutex for skill '"
<< skillId << "' in order to delete it.";
return std::nullopt;
}
if (!skillMutexResult.getResult())
{
ARMARX_WARNING << "User '" << userId << "' needs to acquire the mutex for skill '"
<< skillId << "' in order to delete it.";
......@@ -1055,7 +1103,16 @@ namespace armarx::plugins
bool mutexesAquired = true;
for (const auto& affectedSkill : affectedSkills)
{
if (!getSkillMutex(affectedSkill->id, userId))
const auto& affectedMutexResult = getSkillMutex(affectedSkill->id, userId);
if (!affectedMutexResult.isSuccess())
{
mutexesAquired = false;
ARMARX_WARNING << "Someone else is editing the skill '" << affectedSkill->name
<< "(" << affectedSkill->id << ")' right now.";
}
if (!affectedMutexResult.getResult())
{
mutexesAquired = false;
ARMARX_WARNING << "Someone else is editing the skill '" << affectedSkill->name
......@@ -1093,11 +1150,10 @@ namespace armarx::plugins
{
return ret;
}
return std::nullopt;
}
bool
skills::Result<bool, skills::error::FluxioException>
SkillManagerComponentPlugin::getSkillMutex(const std::string& skillId,
const std::string& userId)
{
......@@ -1119,16 +1175,17 @@ namespace armarx::plugins
// TODO: check if mutex is held by user
}
std::vector<std::experimental::observer_ptr<const skills::FluxioProfile>>
skills::Result<std::vector<std::experimental::observer_ptr<const skills::FluxioProfile>>,
skills::error::FluxioException>
SkillManagerComponentPlugin::getProfileList()
{
std::shared_lock l(fluxioDC.profilesMutex);
const auto& ret = convertMapValuesToObserverVector(fluxioDC.profiles);
l.unlock();
return ret;
return {ret};
}
std::optional<skills::FluxioProfile>
skills::Result<skills::FluxioProfile, skills::error::FluxioException>
SkillManagerComponentPlugin::getProfile(const std::string& id)
{
std::shared_lock l(fluxioDC.profilesMutex);
......@@ -1137,14 +1194,18 @@ namespace armarx::plugins
if (profilesEntry == fluxioDC.profiles.end())
{
l.unlock();
return std::nullopt;
return {skills::error::FluxioException::Create(
skills::error::createErrorMessage(skills::error::ErrorCode::ProfileNotFound, {id}),
"SkillManagerComponentPlugin",
__FUNCTION__,
__LINE__)};
}
l.unlock();
return profilesEntry->second;
return {profilesEntry->second};
}
skills::FluxioProfile
skills::Result<skills::FluxioProfile, skills::error::FluxioException>
SkillManagerComponentPlugin::createProfile(const skills::FluxioProfile& profile)
{
std::string id = IceUtil::generateUUID();
......@@ -1155,7 +1216,7 @@ namespace armarx::plugins
const auto& ret = fluxioDC.profiles[id];
l.unlock();
return ret;
return {ret};
}
void
......@@ -1163,7 +1224,7 @@ namespace armarx::plugins
{
auto oldProfile = getProfile(profile.id);
if (oldProfile.has_value() && oldProfile->id == profile.id)
if (oldProfile.isSuccess() && oldProfile.getResult().id == profile.id)
{
std::unique_lock l(fluxioDC.profilesMutex);
fluxioDC.profiles[profile.id].name = profile.name;
......@@ -1171,9 +1232,14 @@ namespace armarx::plugins
fluxioDC.profiles[profile.id].parentPtr = profile.parentPtr;
l.unlock();
}
else
{
//TODO: Do we throw the error here?
}
}
std::experimental::observer_ptr<const skills::FluxioProvider>
skills::Result<std::experimental::observer_ptr<const skills::FluxioProvider>,
skills::error::FluxioException>
SkillManagerComponentPlugin::addFluxioProvider(const std::string& name)
{
const std::string& providerId = boost::uuids::to_string(createUuidWithString(name));
......@@ -1182,9 +1248,8 @@ namespace armarx::plugins
if (fluxioDC.providers.find(providerId) != fluxioDC.providers.end())
{
ARMARX_WARNING << "Provider with name '" << name << "' already exists.";
return std::experimental::make_observer(&fluxioDC.providers[providerId]);
l.unlock();
return nullptr;
return {std::experimental::make_observer(&fluxioDC.providers[providerId])};
}
skills::FluxioProvider p;
......@@ -1195,10 +1260,11 @@ namespace armarx::plugins
const auto& ret = std::experimental::make_observer(&fluxioDC.providers[p.id]);
l.unlock();
return ret;
return {ret};
}
std::vector<std::experimental::observer_ptr<const skills::FluxioProvider>>
skills::Result<std::vector<std::experimental::observer_ptr<const skills::FluxioProvider>>,
skills::error::FluxioException>
SkillManagerComponentPlugin::getProviderList()
{
for (const auto& [providerID, providerPrx] : skillProviderMap)
......@@ -1218,10 +1284,10 @@ namespace armarx::plugins
addFluxioProvider(providerID.providerName);
}
return convertMapValuesToObserverVector(fluxioDC.providers);
return {convertMapValuesToObserverVector(fluxioDC.providers)};
}
std::optional<skills::FluxioProvider>
skills::Result<skills::FluxioProvider, skills::error::FluxioException>
SkillManagerComponentPlugin::getProvider(const std::string& id)
{
getProviderList();
......@@ -1232,14 +1298,19 @@ namespace armarx::plugins
if (providersEntry != fluxioDC.providers.end())
{
l.unlock();
return providersEntry->second;
return {providersEntry->second};
}
l.unlock();
return std::nullopt;
return {skills::error::FluxioException::Create(
skills::error::createErrorMessage(skills::error::ErrorCode::ProfileNotFound, {id}),
"SkillManagerComponentPlugin",
__FUNCTION__,
__LINE__)};
}
std::optional<std::vector<std::experimental::observer_ptr<const skills::FluxioSkill>>>
skills::Result<std::vector<std::experimental::observer_ptr<const skills::FluxioSkill>>,
skills::error::FluxioException>
SkillManagerComponentPlugin::getSkillsOfProvider(const std::string& id)
{
getProviderList();
......@@ -1250,11 +1321,24 @@ namespace armarx::plugins
if (providersEntry == fluxioDC.providers.end())
{
l.unlock();
return std::nullopt;
return {skills::error::FluxioException::Create(
skills::error::createErrorMessage(skills::error::ErrorCode::ProviderNotFound, {id}),
"SkillManagerComponentPlugin",
__FUNCTION__,
__LINE__)};
}
l.unlock();
auto allSkills = getSkillList();
auto res = getSkillList();
if (!res.isSuccess())
{
auto e = res.getError();
e.addToContext(std::nullopt, "SkillManagerComponentPlugin", __FUNCTION__, __LINE__);
return {e};
}
auto allSkills = res.getResult();
allSkills.erase(std::remove_if(allSkills.begin(),
allSkills.end(),
......@@ -1262,10 +1346,11 @@ namespace armarx::plugins
{ return skillPtr->skillProviderPtr->id != id; }),
allSkills.end());
return allSkills;
return {allSkills};
}
std::experimental::observer_ptr<const skills::FluxioSkill>
skills::Result<std::experimental::observer_ptr<const skills::FluxioSkill>,
skills::error::FluxioException>
SkillManagerComponentPlugin::addSkillToProvider(const std::string& userId,
const std::string& providerId,
skills::FluxioSkill&& skill)
......@@ -1276,7 +1361,12 @@ namespace armarx::plugins
{
ARMARX_WARNING << "Provider with id '" << providerId << "' not found.";
l.unlock();
return nullptr;
return {skills::error::FluxioException::Create(
skills::error::createErrorMessage(skills::error::ErrorCode::ProviderNotFound,
{providerId}),
"SkillManagerComponentPlugin",
__FUNCTION__,
__LINE__)};
}
l.unlock();
......@@ -1347,10 +1437,10 @@ namespace armarx::plugins
// set mutex
setEditFluxioSkillMutex(true, userId, skill.id);
return ret;
return {ret};
}
bool // TODO: add armarx info messages
bool
SkillManagerComponentPlugin::setEditFluxioSkillMutex(bool aquireMutex,
const std::string& userId,
const std::string& skillId)
......@@ -1387,7 +1477,13 @@ namespace armarx::plugins
}
// mutex could not be aquired
return false;
throw skills::error::FluxioException::Create(
skills::error::createErrorMessage(skills::error::ErrorCode::GenericMutexError,
{skillId}),
"SkillManagerComponentPlugin",
__FUNCTION__,
__LINE__)
.toManagerIce();
}
// remove mutex
......@@ -1397,6 +1493,7 @@ namespace armarx::plugins
return true;
}
// check if the user holds the mutex, as only the user that holds the mutex can release it
if (std::get<0>(fluxioDC.skillMutexMap[skillId]) == userId)
{
......@@ -1405,6 +1502,12 @@ namespace armarx::plugins
}
// mutex could not be removed
return false;
throw skills::error::FluxioException::Create(
skills::error::createErrorMessage(skills::error::ErrorCode::UserHasNoMutexError,
{skillId}),
"SkillManagerComponentPlugin",
__FUNCTION__,
__LINE__)
.toManagerIce();
}
} // namespace armarx::plugins
......@@ -13,12 +13,14 @@
#include <ArmarXCore/core/time/DateTime.h>
#include "RobotAPI/libraries/skills/core/FluxioSkillStatusUpdate.h"
#include "RobotAPI/libraries/skills/core/error/FluxioException.h"
#include <RobotAPI/interface/skills/SkillManagerInterface.h>
#include <RobotAPI/libraries/skills/core/FluxioEdge.h>
#include <RobotAPI/libraries/skills/core/FluxioNode.h>
#include <RobotAPI/libraries/skills/core/FluxioParameter.h>
#include <RobotAPI/libraries/skills/core/FluxioProfile.h>
#include <RobotAPI/libraries/skills/core/FluxioProvider.h>
#include <RobotAPI/libraries/skills/core/FluxioResult.h>
#include <RobotAPI/libraries/skills/core/FluxioSkill.h>
#include <RobotAPI/libraries/skills/core/FluxioValue.h>
#include <RobotAPI/libraries/skills/core/ProviderID.h>
......@@ -77,22 +79,28 @@ namespace armarx::plugins
//** Fluxio related methods **//
//****************************//
std::experimental::observer_ptr<skills::FluxioExecutor>
skills::Result<std::experimental::observer_ptr<skills::FluxioExecutor>,
skills::error::FluxioException>
executeFluxioSkill(const std::string& skillId, const std::string& executorName);
void abortFluxioSkill(const std::string& executionId);
std::optional<std::vector<skills::FluxioSkillStatusUpdate>>
skills::Result<std::vector<skills::FluxioSkillStatusUpdate>, skills::error::FluxioException>
getFluxioSkillExecutionStatus(const std::string& executionId);
std::vector<std::experimental::observer_ptr<const skills::FluxioSkill>> getSkillList();
skills::Result<std::vector<std::experimental::observer_ptr<const skills::FluxioSkill>>,
skills::error::FluxioException>
getSkillList();
std::experimental::observer_ptr<const skills::FluxioSkill> getSkill(const std::string& id);
skills::Result<std::experimental::observer_ptr<const skills::FluxioSkill>,
skills::error::FluxioException>
getSkill(const std::string& id);
std::optional<std::vector<std::experimental::observer_ptr<const skills::FluxioSkill>>>
deleteSkill(const std::string& skillId, const std::string& userId, bool dryRun);
bool getSkillMutex(const std::string& skillId, const std::string& userId);
skills::Result<bool, skills::error::FluxioException>
getSkillMutex(const std::string& skillId, const std::string& userId);
void deleteSkillMutex(const std::string& skillId, const std::string& userId);
......@@ -100,26 +108,35 @@ namespace armarx::plugins
const std::string& skillId,
const std::string& parameterId);
std::vector<std::experimental::observer_ptr<const skills::FluxioProfile>> getProfileList();
skills::Result<std::vector<std::experimental::observer_ptr<const skills::FluxioProfile>>,
skills::error::FluxioException>
getProfileList();
std::optional<skills::FluxioProfile> getProfile(const std::string& id);
skills::Result<skills::FluxioProfile, skills::error::FluxioException>
getProfile(const std::string& id);
skills::FluxioProfile createProfile(const skills::FluxioProfile& profile);
skills::Result<skills::FluxioProfile, skills::error::FluxioException>
createProfile(const skills::FluxioProfile& profile);
void updateProfile(const skills::FluxioProfile& profile);
std::vector<std::experimental::observer_ptr<const skills::FluxioProvider>>
skills::Result<std::vector<std::experimental::observer_ptr<const skills::FluxioProvider>>,
skills::error::FluxioException>
getProviderList();
std::experimental::observer_ptr<const skills::FluxioProvider>
addFluxioProvider(const std::string& name);
skills::Result<skills::FluxioProvider, skills::error::FluxioException>
getProvider(const std::string& id);
std::optional<skills::FluxioProvider> getProvider(const std::string& id);
skills::Result<std::experimental::observer_ptr<const skills::FluxioProvider>,
skills::error::FluxioException>
addFluxioProvider(const std::string& name);
std::optional<std::vector<std::experimental::observer_ptr<const skills::FluxioSkill>>>
skills::Result<std::vector<std::experimental::observer_ptr<const skills::FluxioSkill>>,
skills::error::FluxioException>
getSkillsOfProvider(const std::string& id);
std::experimental::observer_ptr<const skills::FluxioSkill>
skills::Result<std::experimental::observer_ptr<const skills::FluxioSkill>,
skills::error::FluxioException>
addSkillToProvider(const std::string& userId,
const std::string& providerId,
skills::FluxioSkill&& skill);
......
#include "SkillManagerComponentPluginUser.h"
#include <mutex>
#include <optional>
#include <string>
#include <Ice/Exception.h>
#include <Ice/OutputStream.h>
#include <IceUtil/Exception.h>
#include <IceUtil/Optional.h>
#include <ArmarXCore/core/exceptions/LocalException.h>
#include <ArmarXCore/core/logging/Logging.h>
#include "RobotAPI/libraries/skills/core/FluxioProfile.h"
#include "RobotAPI/libraries/skills/core/FluxioProvider.h"
#include "RobotAPI/libraries/skills/core/FluxioSkill.h"
#include "RobotAPI/libraries/skills/core/error/FluxioErrorMessages.h"
#include "RobotAPI/libraries/skills/core/error/FluxioException.h"
#include "RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h"
#include <RobotAPI/interface/skills/SkillManagerInterface.h>
namespace armarx
......@@ -164,12 +173,14 @@ namespace armarx
const Ice::Current& current)
{
const auto& res = this->plugin->executeFluxioSkill(skillId, "Fluxio");
if (res == nullptr)
if (!res.isSuccess())
{
return {};
auto e = res.getError();
e.addToContext(std::nullopt, "SkillManagerComponentPluginUser", __FUNCTION__, __LINE__);
throw e.toManagerIce();
}
return res->id;
return res.getResult()->id; // TODO: nullptr check
}
void
......@@ -184,15 +195,18 @@ namespace armarx
const Ice::Current& current)
{
auto l = this->plugin->getFluxioSkillExecutionStatus(executionId);
if (!l.has_value())
if (!l.isSuccess())
{
ARMARX_WARNING << "Error getting FluxioSkillExecutionStatus";
return {};
auto e = l.getError();
e.addToContext(std::nullopt, "SkillManagerComponentPluginUser", __FUNCTION__, __LINE__);
throw e.toManagerIce();
}
skills::manager::dto::FluxioSkillStatusUpdateList ret;
for (const auto& s : l.value())
for (const auto& s : l.getResult())
{
ret.push_back(s.toManagerIce());
}
......@@ -207,7 +221,14 @@ namespace armarx
auto l = this->plugin->getSkillList();
for (const auto& s : l)
if (!l.isSuccess())
{
auto e = l.getError();
e.addToContext(std::nullopt, "SkillManagerComponentPluginUser", __FUNCTION__, __LINE__);
throw e.toManagerIce();
}
for (const auto& s : l.getResult())
{
if (s == nullptr)
{
......@@ -232,8 +253,15 @@ namespace armarx
IceUtil::Optional<skills::manager::dto::FluxioSkill>
SkillManagerComponentPluginUser::getSkill(const std::string& id, const Ice::Current& current)
{
auto skill = this->plugin->getSkill(id);
auto result = this->plugin->getSkill(id);
if (!result.isSuccess())
{
auto e = result.getError();
e.addToContext(std::nullopt, "SkillManagerComponentPluginUser", __FUNCTION__, __LINE__);
throw e.toManagerIce();
}
const auto& skill = result.getResult();
if (skill == nullptr)
{
return {};
......@@ -271,11 +299,19 @@ namespace armarx
}
// Check if the user has the mutex for the skill
if (!this->plugin->getSkillMutex(skill.id, userId))
auto res = this->plugin->getSkillMutex(skill.id, userId);
if (!res.isSuccess())
{
ARMARX_WARNING << "SkillManagerComponentPluginUser::updateSkill: User " << userId
<< " does not have the mutex for skill with id " << skill.id;
return false;
<< "User does not have Mutex for this Skill" << skill.id;
auto error = res.getError();
error.addToContext(skills::error::createErrorMessage(
skills::error::ErrorCode::UserHasNoMutexError, {skill.id}),
"SkillManagerComponentPluginUser",
__FUNCTION__,
__LINE__);
throw error.toManagerIce();
}
const bool ret = s->second.updateFromIce(skill, providersMap, profilesMap, skillsMap);
......@@ -314,7 +350,7 @@ namespace armarx
const std::string& userId,
const Ice::Current& current)
{
return this->plugin->getSkillMutex(skillId, userId);
return this->plugin->getSkillMutex(skillId, userId).getResult(); //
}
void
......@@ -341,7 +377,7 @@ namespace armarx
auto l = this->plugin->getProfileList();
for (const auto& p : l)
for (const auto& p : l.getResult())
{
if (p == nullptr)
{
......@@ -359,12 +395,13 @@ namespace armarx
{
auto profile = this->plugin->getProfile(id);
if (!profile.has_value())
if (!profile.isSuccess())
{
return {};
auto e = profile.getError();
e.addToContext(std::nullopt, "SkillManagerComponentPluginUser", __FUNCTION__, __LINE__);
throw e.toManagerIce();
}
return profile->toManagerIce();
return profile.getResult().toManagerIce();
}
skills::manager::dto::FluxioProfile
......@@ -377,6 +414,7 @@ namespace armarx
l.unlock();
auto ret = this->plugin->createProfile(skills::FluxioProfile::FromIce(profile, profilesMap))
.getResult()
.toManagerIce();
return ret;
}
......@@ -399,8 +437,14 @@ namespace armarx
skills::manager::dto::FluxioProviderList ret;
auto l = this->plugin->getProviderList();
if (!l.isSuccess())
{
auto e = l.getError();
e.addToContext(std::nullopt, "SkillManagerComponentPluginUser", __FUNCTION__, __LINE__);
throw e.toManagerIce();
}
for (const auto& p : l)
for (const auto& p : l.getResult())
{
if (p == nullptr)
{
......@@ -418,12 +462,13 @@ namespace armarx
{
auto provider = this->plugin->getProvider(id);
if (!provider.has_value())
if (provider.isSuccess())
{
return {};
auto e = provider.getError();
e.addToContext(std::nullopt, "SkillManagerComponentPluginUser", __FUNCTION__, __LINE__);
throw e.toManagerIce();
}
return provider->toManagerIce();
return provider.getResult().toManagerIce();
}
IceUtil::Optional<skills::manager::dto::FluxioSkillList>
......@@ -434,12 +479,15 @@ namespace armarx
auto l = this->plugin->getSkillsOfProvider(id);
if (!l.has_value())
if (!l.isSuccess())
{
return {};
auto error = l.getError();
error.addToContext(
std::nullopt, "SkillManagerComponentPluginUser", __FUNCTION__, __LINE__);
throw error.toManagerIce();
}
for (const auto& s : l.value())
for (const auto& s : l.getResult())
{
if (s == nullptr)
{
......@@ -483,7 +531,14 @@ namespace armarx
if (skillBO == nullptr)
{
ARMARX_WARNING << "Skill with id " << skill.id << " could not be converted";
return {};
throw skills::error::FluxioException::Create(
skills::error::createErrorMessage(skills::error::ErrorCode::ConverterError,
{skill.id}),
"SkillManagerComponentPluginUser",
__FUNCTION__,
__LINE__)
.toManagerIce();
}
skillsLock.unlock();
......@@ -491,8 +546,24 @@ namespace armarx
providersLock.unlock();
auto& skillReleased = *skillBO.release();
const auto s =
const auto res =
this->plugin->addSkillToProvider(userId, providerId, std::move(skillReleased));
if (!res.isSuccess())
{
ARMARX_WARNING << "Skill with id " << skill.id
<< " could not be added to provider with id " << providerId;
auto error = res.getError();
error.addToContext(
(skills::error::createErrorMessage(skills::error::ErrorCode::AddSkillError,
{skill.id, providerId})),
"SkillManagerComponentPluginUser",
__FUNCTION__,
__LINE__);
throw error.toManagerIce();
}
const auto& s = res.getResult();
if (s == nullptr)
{
......
#pragma once
#include <Ice/Current.h>
#include <RobotAPI/interface/skills/SkillManagerInterface.h>
#include "SkillManagerComponentPlugin.h"
......