Skip to content
Snippets Groups Projects
Commit eb4d058e authored by Raphael Defosseux's avatar Raphael Defosseux
Browse files

Merge branch 'refactor_sm_policy' into 'develop'

Refactor of SM Policy classes

See merge request !10
parents c1b20094 59d9fc0e
No related branches found
No related tags found
1 merge request!10Refactor of SM Policy classes
Pipeline #33301 passed
Showing
with 185 additions and 230 deletions
......@@ -53,12 +53,12 @@ using namespace oai::pcf::model;
using namespace std;
extern pcf_smpc* pcf_smpc_inst;
extern pcf_config pcf_cfg;
//------------------------------------------------------------------------------
pcf_smpc::pcf_smpc(
std::shared_ptr<oai::pcf::app::sm_policy::policy_storage> policy_storage) {
const std::shared_ptr<oai::pcf::app::sm_policy::policy_storage>&
policy_storage) {
m_policy_storage = policy_storage;
std::function<void(const std::shared_ptr<policy_decision>& decision)> f =
......@@ -85,19 +85,17 @@ status_code pcf_smpc::create_sm_policy_handler(
return status_code::CONTEXT_DENIED;
}
std::shared_ptr<SmPolicyDecision> decision_ptr;
association_id = std::to_string(m_association_id_generator.get_uid());
status_code res = chosen_decision->decide(context, decision_ptr);
individual_sm_association assoc(context, *chosen_decision, association_id);
status_code res = assoc.decide_policy(decision);
if (res != status_code::CREATED) {
problem_details = fmt::format(
"SM Policy request from SUPI {}: Invalid policy decision provisioned",
context.getSupi());
} else {
association_id = std::to_string(m_association_id_generator.get_uid());
individual_sm_association assoc(context, decision_ptr, association_id);
std::unique_lock lock_assocations(m_associations_mutex);
m_associations.insert(std::make_pair(association_id, assoc));
......@@ -105,18 +103,16 @@ status_code pcf_smpc::create_sm_policy_handler(
"Created Policy Decision for SUPI {} with ID {}", context.getSupi(),
association_id));
}
decision = *decision_ptr;
return res;
}
//------------------------------------------------------------------------------
sm_policy::status_code pcf_smpc::delete_sm_policy_handler(
std::string id, const SmPolicyDeleteData& delete_data,
const std::string& id, const SmPolicyDeleteData& delete_data,
std::string& problem_details) {
// TODO for now, just delete, ignore the delete_data
std::unique_lock lock_associations(m_associations_mutex);
std::unordered_map<std::string, individual_sm_association>::const_iterator
iter = m_associations.find(id);
auto iter = m_associations.find(id);
if (iter == m_associations.end()) {
problem_details =
fmt::format("Could not delete policy association: ID {} not found", id);
......@@ -132,11 +128,10 @@ sm_policy::status_code pcf_smpc::delete_sm_policy_handler(
//------------------------------------------------------------------------------
sm_policy::status_code pcf_smpc::get_sm_policy_handler(
std::string id, oai::pcf::model::SmPolicyControl& control,
const std::string& id, oai::pcf::model::SmPolicyControl& control,
std::string& problem_details) {
std::shared_lock lock_associations(m_associations_mutex);
std::unordered_map<std::string, individual_sm_association>::const_iterator
iter = m_associations.find(id);
auto iter = m_associations.find(id);
if (iter == m_associations.end()) {
problem_details = fmt::format(
"Could not retrieve policy association: ID {} not found", id);
......@@ -144,7 +139,7 @@ sm_policy::status_code pcf_smpc::get_sm_policy_handler(
return status_code::NOT_FOUND;
}
control.setContext(iter->second.get_sm_policy_context_data());
control.setPolicy(*(iter->second.get_sm_policy_decision()));
control.setPolicy(iter->second.get_sm_policy_decision_dto());
Logger::pcf_app().info(
fmt::format("Retrieved policy association with ID {}", id));
......@@ -154,11 +149,10 @@ sm_policy::status_code pcf_smpc::get_sm_policy_handler(
//------------------------------------------------------------------------------
sm_policy::status_code pcf_smpc::update_sm_policy_handler(
std::string id, const SmPolicyUpdateContextData& update_context,
const std::string& id, const SmPolicyUpdateContextData& update_context,
SmPolicyDecision& decision, std::string& problem_details) {
std::unique_lock lock_associations(m_associations_mutex);
std::unordered_map<std::string, individual_sm_association>::iterator iter =
m_associations.find(id);
auto iter = m_associations.find(id);
if (iter == m_associations.end()) {
problem_details =
......@@ -167,38 +161,10 @@ sm_policy::status_code pcf_smpc::update_sm_policy_handler(
return status_code::NOT_FOUND;
}
std::shared_ptr<SmPolicyDecision> new_decision_ptr;
std::shared_ptr<SmPolicyDecision> orig_decision =
iter->second.get_sm_policy_decision();
SmPolicyContextData orig_context = iter->second.get_sm_policy_context_data();
// find the original decision to redecide
std::shared_ptr<policy_decision> chosen_decision =
m_policy_storage->find_policy(orig_context);
// this may happen when the policy has been updated/deleted in the meantime.
if (!chosen_decision) {
problem_details = fmt::format(
"SM policy update from SUPI {}: No policies found",
orig_context.getSupi());
Logger::pcf_app().info(problem_details);
return status_code::CONTEXT_DENIED;
}
SmPolicyDecision new_decision;
status_code res = chosen_decision->redecide(
orig_context, orig_decision, update_context, new_decision_ptr,
problem_details);
// we can release the locks here
// update the existing context and policy and receive a policy diff
// TODO in TS 23.512 Chapter 4.2.6 it is described that only the diff should
// be returned. here, we return the whole policy object.
individual_sm_association assoc(orig_context, new_decision_ptr, id);
iter->second = assoc;
// overwrite existing association
m_associations.insert(std::make_pair(id, assoc));
decision = *new_decision_ptr;
return res;
return iter->second.redecide_policy(
update_context, decision, problem_details);
}
//------------------------------------------------------------------------------
......
......@@ -54,7 +54,8 @@ namespace oai::pcf::app {
class pcf_smpc {
public:
explicit pcf_smpc(
std::shared_ptr<oai::pcf::app::sm_policy::policy_storage> policy_storage);
const std::shared_ptr<oai::pcf::app::sm_policy::policy_storage>&
policy_storage);
pcf_smpc(pcf_smpc const&) = delete;
void operator=(pcf_smpc const&) = delete;
......@@ -87,7 +88,8 @@ class pcf_smpc {
* @return sm_policy::status_code
*/
sm_policy::status_code delete_sm_policy_handler(
std::string id, const oai::pcf::model::SmPolicyDeleteData& delete_data,
const std::string& id,
const oai::pcf::model::SmPolicyDeleteData& delete_data,
std::string& problem_details);
/**
......@@ -102,7 +104,7 @@ class pcf_smpc {
* @return sm_policy::status_code
*/
sm_policy::status_code get_sm_policy_handler(
std::string id, oai::pcf::model::SmPolicyControl& control,
const std::string& id, oai::pcf::model::SmPolicyControl& control,
std::string& problem_details);
/**
......@@ -117,7 +119,7 @@ class pcf_smpc {
* @return sm_policy::status_code
*/
sm_policy::status_code update_sm_policy_handler(
std::string id,
const std::string& id,
const oai::pcf::model::SmPolicyUpdateContextData& update_context,
oai::pcf::model::SmPolicyDecision& decision,
std::string& problem_details);
......
......@@ -36,7 +36,7 @@ using namespace oai::pcf::app;
status_code dnn_policy_decision::decide(
const SmPolicyContextData& context,
std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision) const {
oai::pcf::model::SmPolicyDecision& decision) const {
if (context.getDnn() != m_dnn) {
return status_code::CONTEXT_DENIED;
}
......@@ -52,7 +52,7 @@ std::string dnn_policy_decision::get_dnn() const {
std::string dnn_policy_decision::to_string() const {
std::stringstream ss;
ss << "DNN: " << m_dnn << "\n";
ss << " -- " << *m_decision;
ss << " -- " << m_decision;
return ss.str();
}
......@@ -61,5 +61,3 @@ std::ostream& operator<<(
const oai::pcf::app::sm_policy::dnn_policy_decision& storage) {
return (os << storage.to_string());
}
dnn_policy_decision::~dnn_policy_decision() {}
\ No newline at end of file
......@@ -45,14 +45,12 @@ namespace oai::pcf::app::sm_policy {
class dnn_policy_decision : public oai::pcf::app::sm_policy::policy_decision {
public:
explicit dnn_policy_decision(
std::string dnn,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision)
const std::string& dnn, const oai::pcf::model::SmPolicyDecision& decision)
: policy_decision(decision) {
m_dnn = dnn;
m_decision = decision;
m_dnn = dnn;
}
virtual ~dnn_policy_decision();
~dnn_policy_decision() override = default;
/**
* @brief Decides based on context on a policy and the DNN information. In
......@@ -63,21 +61,20 @@ class dnn_policy_decision : public oai::pcf::app::sm_policy::policy_decision {
* @return oai::pcf::app::sm_policy::status_code CREATED in case of
* success
*/
oai::pcf::app::sm_policy::status_code decide(
[[nodiscard]] oai::pcf::app::sm_policy::status_code decide(
const oai::pcf::model::SmPolicyContextData& context,
std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision) const;
oai::pcf::model::SmPolicyDecision& decision) const override;
/**
* @brief Get the dnn object
*
* @return std::string
*/
std::string get_dnn() const;
[[nodiscard]] std::string get_dnn() const;
std::string to_string() const;
[[nodiscard]] std::string to_string() const override;
private:
std::shared_ptr<oai::pcf::model::SmPolicyDecision> m_decision;
std::string m_dnn;
};
} // namespace oai::pcf::app::sm_policy
......
......@@ -32,26 +32,29 @@
using namespace oai::pcf::model;
using namespace oai::pcf::app::sm_policy;
SmPolicyContextData individual_sm_association::get_sm_policy_context_data()
const {
const SmPolicyContextData&
individual_sm_association::get_sm_policy_context_data() const {
return m_context;
}
std::shared_ptr<oai::pcf::model::SmPolicyDecision>
individual_sm_association::get_sm_policy_decision() const {
return m_decision;
const SmPolicyDecision& individual_sm_association::get_sm_policy_decision_dto()
const {
return m_decision.get_sm_policy_decision();
}
void individual_sm_association::set_sm_policy_context_data(
SmPolicyContextData& context) {
m_context = context;
std::string individual_sm_association::get_id() const {
return m_id;
}
void individual_sm_association::set_sm_policy_decision(
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision) {
m_decision = decision;
oai::pcf::app::sm_policy::status_code
individual_sm_association::redecide_policy(
const SmPolicyUpdateContextData& update_data,
SmPolicyDecision& new_decision, std::string& problem_details) {
return m_decision.redecide(
m_context, update_data, new_decision, problem_details);
}
std::string individual_sm_association::get_id() const {
return m_id;
oai::pcf::app::sm_policy::status_code individual_sm_association::decide_policy(
oai::pcf::model::SmPolicyDecision& decision) {
return m_decision.decide(m_context, decision);
}
......@@ -32,6 +32,7 @@
#include "SmPolicyContextData.h"
#include "SmPolicyDecision.h"
#include "policy_decision.hpp"
#include <memory.h>
......@@ -40,30 +41,35 @@ namespace oai::pcf::app::sm_policy {
class individual_sm_association {
public:
explicit individual_sm_association(
oai::pcf::model::SmPolicyContextData context,
std::shared_ptr<oai::pcf::model::SmPolicyDecision> decision,
std::string id) {
m_decision = decision;
m_context = context;
m_id = id;
const oai::pcf::model::SmPolicyContextData& context,
const oai::pcf::app::sm_policy::policy_decision& decision,
const std::string& id)
: m_decision(decision) {
m_context = context;
m_id = id;
}
virtual ~individual_sm_association() = default;
oai::pcf::model::SmPolicyContextData get_sm_policy_context_data() const;
std::shared_ptr<oai::pcf::model::SmPolicyDecision> get_sm_policy_decision()
const;
[[nodiscard]] virtual const oai::pcf::model::SmPolicyContextData&
get_sm_policy_context_data() const;
void set_sm_policy_context_data(
oai::pcf::model::SmPolicyContextData& context);
void set_sm_policy_decision(
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision);
[[nodiscard]] virtual const oai::pcf::model::SmPolicyDecision&
get_sm_policy_decision_dto() const;
std::string get_id() const;
[[nodiscard]] virtual oai::pcf::app::sm_policy::status_code redecide_policy(
const oai::pcf::model::SmPolicyUpdateContextData& update_data,
oai::pcf::model::SmPolicyDecision& new_decision,
std::string& problem_details);
[[nodiscard]] virtual oai::pcf::app::sm_policy::status_code decide_policy(
oai::pcf::model::SmPolicyDecision& decision);
[[nodiscard]] virtual std::string get_id() const;
private:
oai::pcf::model::SmPolicyContextData m_context;
std::shared_ptr<oai::pcf::model::SmPolicyDecision> m_decision;
oai::pcf::app::sm_policy::policy_decision m_decision;
std::string m_id;
};
} // namespace oai::pcf::app::sm_policy
......
......@@ -39,17 +39,21 @@ using namespace oai::pcf::app;
typedef PolicyControlRequestTrigger_anyOf::ePolicyControlRequestTrigger_anyOf E;
status_code policy_decision::decide(
const SmPolicyContextData& context,
std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision) const {
const SmPolicyContextData& context, SmPolicyDecision& decision) const {
// default rule, so just reply with the decision
decision = m_decision;
return status_code::CREATED;
}
const SmPolicyDecision& policy_decision::get_sm_policy_decision() const {
return m_decision;
}
status_code policy_decision::handle_plmn_change(
SmPolicyContextData& orig_context, const SmPolicyUpdateContextData& update,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision,
std::string& problem_details) {
// TODO actually also change m_decision, method should not be static
if (update.servingNetworkIsSet()) {
orig_context.setServingNetwork(update.getServingNetwork());
return status_code::OK;
......@@ -60,8 +64,8 @@ status_code policy_decision::handle_plmn_change(
status_code policy_decision::handle_access_type_change(
SmPolicyContextData& orig_context, const SmPolicyUpdateContextData& update,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision,
std::string& problem_details) {
// TODO actually also change m_decision, method should not be static
if (update.accessTypeIsSet()) {
orig_context.setAccessType(update.getAccessType());
return status_code::OK;
......@@ -76,8 +80,8 @@ status_code policy_decision::handle_access_type_change(
status_code policy_decision::handle_ip_address_change(
SmPolicyContextData& orig_context, const SmPolicyUpdateContextData& update,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision,
std::string& problem_details) {
// TODO actually also change m_decision, method should not be static
problem_details = "";
status_code code = status_code::INVALID_PARAMETERS;
if (update.ipv4AddressIsSet()) {
......@@ -101,16 +105,17 @@ status_code policy_decision::handle_ip_address_change(
if (code != status_code::OK) {
std::string det = "IPv4 or IPv6 address needs to be specified";
problem_details =
problem_details != "" ? problem_details + " | " + det : det;
problem_details = !problem_details.empty() ?
problem_details.append(" | ").append(det) :
det;
}
return code;
}
status_code policy_decision::handle_rat_type_change(
SmPolicyContextData& orig_context, const SmPolicyUpdateContextData& update,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision,
std::string& problem_details) {
// TODO actually also change m_decision, method should not be static
status_code code = status_code::INVALID_PARAMETERS;
if (update.ratTypeIsSet()) {
orig_context.setRatType(update.getRatType());
......@@ -135,12 +140,9 @@ status_code policy_decision::handle_rat_type_change(
status_code policy_decision::redecide(
SmPolicyContextData& original_context,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& original_decision,
const SmPolicyUpdateContextData& update_data,
std::shared_ptr<oai::pcf::model::SmPolicyDecision>& new_decision,
oai::pcf::model::SmPolicyDecision& new_decision,
std::string& problem_details) {
new_decision = m_decision;
status_code status = status_code::OK;
// that is not very beautiful, but that is how the API is designed
// (TS 29.512 4.2.4.2)
......@@ -155,18 +157,18 @@ status_code policy_decision::redecide(
switch (it->getEnumValue()) {
case E::PLMN_CH:
status = handle_plmn_change(
original_context, update_data, new_decision, problem_details);
original_context, update_data, problem_details);
break;
case E::RES_MO_RE:
Logger::pcf_app().error("RES_MO_RE not supported");
break;
case E::AC_TY_CH:
status = handle_access_type_change(
original_context, update_data, new_decision, problem_details);
original_context, update_data, problem_details);
break;
case E::UE_IP_CH:
status = handle_ip_address_change(
original_context, update_data, new_decision, problem_details);
original_context, update_data, problem_details);
break;
case E::UE_MAC_CH:
Logger::pcf_app().error("UE_MAC_CH not supported");
......@@ -227,7 +229,7 @@ status_code policy_decision::redecide(
break;
case E::RAT_TY_CH:
status = handle_rat_type_change(
original_context, update_data, new_decision, problem_details);
original_context, update_data, problem_details);
break;
case E::REF_QOS_IND_CH:
Logger::pcf_app().error("REF_QOS_IND_CH not supported");
......@@ -264,12 +266,14 @@ status_code policy_decision::redecide(
}
}
}
new_decision = m_decision;
return status;
}
std::string policy_decision::to_string() const {
std::stringstream ss;
ss << *m_decision;
ss << m_decision;
return ss.str();
}
......@@ -278,5 +282,3 @@ std::ostream& operator<<(
const oai::pcf::app::sm_policy::policy_decision& storage) {
return (os << storage.to_string());
}
policy_decision::~policy_decision() {}
\ No newline at end of file
......@@ -38,17 +38,19 @@
namespace oai::pcf::app::sm_policy {
/**
* @brief Base class for policy decisions. All sub classes need to
* implement the decide function
* @brief Base class for policy decisions, also acts as default policy
*
*/
class policy_decision {
public:
explicit policy_decision(
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision) {
explicit policy_decision(const oai::pcf::model::SmPolicyDecision& decision) {
m_decision = decision;
}
policy_decision(const policy_decision& other) {
m_decision = other.m_decision;
}
/**
* @brief Decides based on context on a policy. In case the return code is !=
* CREATED, the decision reference may be undefined
......@@ -58,9 +60,9 @@ class policy_decision {
* @return oai::pcf::app::sm_policy::status_code CREATED in case of
* success
*/
virtual oai::pcf::app::sm_policy::status_code decide(
[[nodiscard]] virtual oai::pcf::app::sm_policy::status_code decide(
const oai::pcf::model::SmPolicyContextData& context,
std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision) const;
oai::pcf::model::SmPolicyDecision& decision) const;
/**
* @brief Redecides based on the original context, original decision and
......@@ -70,51 +72,48 @@ class policy_decision {
* @param original_context The context of the create request and/or
* previous update requests, is changed according to updated values in
* update_data
* @param original_decision input: The original decision
* @param update_data input: The data from the update
* @param decision_diff output: the new policy decision
* @param new_decision output: the diff to the old decision (TODO currently no
* diff, but whole object)
* @param problem_details output: Error information
* @return oai::pcf::app::sm_policy::status_code OK in case of successful
* update
*/
virtual oai::pcf::app::sm_policy::status_code redecide(
[[nodiscard]] virtual oai::pcf::app::sm_policy::status_code redecide(
oai::pcf::model::SmPolicyContextData& original_context,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>&
original_decision,
const oai::pcf::model::SmPolicyUpdateContextData& update_data,
std::shared_ptr<oai::pcf::model::SmPolicyDecision>& new_decision,
oai::pcf::model::SmPolicyDecision& new_decision,
std::string& problem_details);
virtual ~policy_decision();
virtual ~policy_decision() = default;
[[nodiscard]] virtual const oai::pcf::model::SmPolicyDecision&
get_sm_policy_decision() const;
std::string to_string() const;
[[nodiscard]] virtual std::string to_string() const;
protected:
oai::pcf::app::sm_policy::status_code handle_plmn_change(
oai::pcf::model::SmPolicyContextData& orig_context,
const oai::pcf::model::SmPolicyUpdateContextData& update,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision,
std::string& problem_details);
oai::pcf::app::sm_policy::status_code handle_access_type_change(
oai::pcf::model::SmPolicyContextData& orig_context,
const oai::pcf::model::SmPolicyUpdateContextData& update,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision,
std::string& problem_details);
oai::pcf::app::sm_policy::status_code handle_ip_address_change(
oai::pcf::model::SmPolicyContextData& orig_context,
const oai::pcf::model::SmPolicyUpdateContextData& update,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision,
std::string& problem_details);
oai::pcf::app::sm_policy::status_code handle_rat_type_change(
oai::pcf::model::SmPolicyContextData& orig_context,
const oai::pcf::model::SmPolicyUpdateContextData& update,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision,
std::string& problem_details);
private:
std::shared_ptr<oai::pcf::model::SmPolicyDecision> m_decision;
oai::pcf::model::SmPolicyDecision m_decision;
};
} // namespace oai::pcf::app::sm_policy
......
......@@ -46,19 +46,12 @@ using namespace boost::filesystem;
extern pcf_config pcf_cfg;
policy_provisioning_file::policy_provisioning_file(
const std::shared_ptr<oai::pcf::app::sm_policy::policy_storage>&
policy_storage) {
m_policy_storage = policy_storage;
}
bool policy_provisioning_file::read_all_policy_files() {
// first start at the traffic descriptions as they are referenced
std::vector<YAML::Node> traffic_controls;
std::vector<YAML::Node> pcc_rules;
std::vector<YAML::Node> policy_decisions;
// TODO die sind alle leeeeer
if (!read_all_files_in_dir(pcf_cfg.traffic_rules_path, traffic_controls)) {
Logger::pcf_app().warn("Could not load Traffic Control Description files");
}
......@@ -76,10 +69,10 @@ bool policy_provisioning_file::read_all_policy_files() {
convert_yaml_to_model<TrafficControlData>(traffic_controls);
auto pcc_rule_objects = convert_yaml_to_model<PccRule>(pcc_rules);
if (traffic_control_objects.size() == 0) {
if (traffic_control_objects.empty()) {
Logger::pcf_app().warn("No traffic control descriptions are loaded");
}
if (pcc_rule_objects.size() == 0) {
if (pcc_rule_objects.empty()) {
Logger::pcf_app().warn("No mandatory PCC rules are loaded");
return false;
}
......@@ -91,8 +84,6 @@ bool policy_provisioning_file::read_all_policy_files() {
}
for (auto pcc : pcc_rule_objects) {
pcc.second.setPccRuleId(pcc.first);
// TODO debug and see
// pcc_rule_objects[pcc.first] = pcc.second;
// check if traffic control data exists
auto reftc = pcc.second.getRefTcData();
......@@ -115,9 +106,9 @@ bool policy_provisioning_file::read_all_policy_files() {
// Now parse the decisions (manually as it is not a model)
for (auto node : policy_decisions) {
for (auto it = node.begin(); it != node.end(); ++it) {
std::shared_ptr<SmPolicyDecision> decision = decision_from_rules(
SmPolicyDecision decision = decision_from_rules(
it->second, pcc_rule_objects, traffic_control_objects);
if (!decision) {
if (!decision.pccRulesIsSet()) {
Logger::pcf_app().warn(
"Decision %s could not be parsed. It is ignored",
it->first.as<std::string>().c_str());
......@@ -128,17 +119,17 @@ bool policy_provisioning_file::read_all_policy_files() {
std::string supi = "imsi-" + it->second["supi_imsi"].as<std::string>();
m_policy_storage->insert_supi_decision(supi, decision);
} else if (it->second["dnn"]) {
std::string dnn = it->second["dnn"].as<std::string>();
auto dnn = it->second["dnn"].as<std::string>();
m_policy_storage->insert_dnn_decision(dnn, decision);
} else if (it->second["slice"]) {
Snssai snssai;
try {
std::string sd = it->second["slice"]["sd"].as<std::string>();
int sst = it->second["slice"]["sst"].as<int>();
auto sd = it->second["slice"]["sd"].as<std::string>();
int sst = it->second["slice"]["sst"].as<int>();
snssai.setSd(sd);
snssai.setSst(sst);
m_policy_storage->insert_slice_decision(snssai, decision);
} catch (YAML::Exception ex) {
} catch (YAML::Exception& ex) {
Logger::pcf_app().warn(
"Error while parsing slice decision: %s", ex.msg.c_str());
}
......@@ -157,11 +148,10 @@ bool policy_provisioning_file::read_all_policy_files() {
return true;
}
std::shared_ptr<SmPolicyDecision> policy_provisioning_file::decision_from_rules(
SmPolicyDecision policy_provisioning_file::decision_from_rules(
const YAML::Node& node, const std::map<std::string, PccRule>& pcc_rules,
const std::map<std::string, TrafficControlData>& traffic_control) {
std::shared_ptr<SmPolicyDecision> decision =
std::make_shared<SmPolicyDecision>();
SmPolicyDecision decision = {};
std::map<std::string, PccRule> used_rules;
......@@ -169,8 +159,8 @@ std::shared_ptr<SmPolicyDecision> policy_provisioning_file::decision_from_rules(
for (auto it = node["pcc_rules"].begin(); it != node["pcc_rules"].end();
++it) {
try {
std::string key = it->as<std::string>();
auto found = pcc_rules.find(key);
auto key = it->as<std::string>();
auto found = pcc_rules.find(key);
if (found == pcc_rules.end()) {
Logger::pcf_app().warn(
"You configured PCC rule %s in policy decision, but it does not "
......@@ -179,43 +169,43 @@ std::shared_ptr<SmPolicyDecision> policy_provisioning_file::decision_from_rules(
} else {
used_rules.insert(std::make_pair(key, found->second));
}
} catch (YAML::Exception ex) {
} catch (YAML::Exception& ex) {
Logger::pcf_app().error(
"Error while parsing decision: %s. Please check your file.",
ex.msg.c_str());
return nullptr;
return {};
}
}
} else {
Logger::pcf_app().warn("You did not set mandatory PCC rules for Decision");
return nullptr;
return {};
}
std::map<std::string, TrafficControlData> used_traffic_control;
// now add the TrafficControlDescriptions
for (auto rule : used_rules) {
for (auto traffic : rule.second.getRefTcData()) {
for (const auto& rule : used_rules) {
for (const auto& traffic : rule.second.getRefTcData()) {
auto found = traffic_control.find(traffic);
if (found != traffic_control.end()) {
used_traffic_control.insert(std::make_pair(traffic, found->second));
}
}
}
if (used_rules.size() > 0) {
decision->setPccRules(used_rules);
decision->setTraffContDecs(used_traffic_control);
if (!used_rules.empty()) {
decision.setPccRules(used_rules);
decision.setTraffContDecs(used_traffic_control);
return decision;
}
return nullptr;
return {};
}
void policy_provisioning_file::replace_json_string_with_int(nlohmann::json& j) {
for (auto elem : j.items()) {
for (const auto& elem : j.items()) {
if (elem.value().is_primitive()) {
try {
std::string e = elem.value();
int val = std::stoi(e);
j[elem.key()] = val; // replace with int
} catch (std::invalid_argument ex) {
} catch (std::invalid_argument& ex) {
}
} else {
replace_json_string_with_int(elem.value());
......@@ -229,7 +219,7 @@ std::map<std::string, T> policy_provisioning_file::convert_yaml_to_model(
std::map<std::string, T> objects_map;
// here we convert YAML to json so we can use the already existing JSON parser
// https://stackoverflow.com/questions/43902941/emitting-json-with-yaml-cpp
for (auto node : nodes) {
for (const auto& node : nodes) {
YAML::Emitter emitter;
emitter << YAML::DoubleQuoted << YAML::Flow << YAML::BeginSeq << node;
std::string json_string(emitter.c_str() + 1);
......@@ -237,7 +227,7 @@ std::map<std::string, T> policy_provisioning_file::convert_yaml_to_model(
// this is a bit hacky but the problem is that YAML emits ints as strings
replace_json_string_with_int(j);
for (auto elem : j.items()) {
for (const auto& elem : j.items()) {
T obj;
from_json(elem.value(), obj);
std::stringstream stream;
......@@ -271,16 +261,16 @@ bool policy_provisioning_file::read_all_files_in_dir(
}
}
for (auto path : filenames) {
for (const auto& path : filenames) {
YAML::Node node;
try {
node = YAML::LoadFile(path);
yaml_output.push_back(node);
} catch (YAML::BadFile ex) {
} catch (YAML::BadFile& ex) {
Logger::pcf_app().warn(
"Something went wrong while reading the YAML file: %s",
ex.msg.c_str());
}
}
return yaml_output.size() > 0;
return !yaml_output.empty();
}
\ No newline at end of file
......@@ -45,23 +45,25 @@ class policy_provisioning_file {
bool read_all_policy_files();
explicit policy_provisioning_file(
const std::shared_ptr<oai::pcf::app::sm_policy::policy_storage>&
policy_storage);
policy_storage) {
m_policy_storage = policy_storage;
}
private:
bool read_all_files_in_dir(
static bool read_all_files_in_dir(
const std::string& dir_path, std::vector<YAML::Node>& yaml_output);
std::shared_ptr<oai::pcf::model::SmPolicyDecision> decision_from_rules(
static oai::pcf::model::SmPolicyDecision decision_from_rules(
const YAML::Node& node,
const std::map<std::string, oai::pcf::model::PccRule>& pcc_rules,
const std::map<std::string, oai::pcf::model::TrafficControlData>&
traffic_control);
template<class T>
std::map<std::string, T> convert_yaml_to_model(
static std::map<std::string, T> convert_yaml_to_model(
const std::vector<YAML::Node>& nodes);
void replace_json_string_with_int(nlohmann::json& j);
static void replace_json_string_with_int(nlohmann::json& j);
std::shared_ptr<oai::pcf::app::sm_policy::policy_storage> m_policy_storage;
};
......
......@@ -35,10 +35,7 @@
using namespace oai::pcf::app::sm_policy;
using namespace oai::pcf::model;
policy_storage::policy_storage() {}
void policy_storage::set_default_decision(
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision) {
void policy_storage::set_default_decision(const SmPolicyDecision& decision) {
std::shared_ptr<policy_decision> desc =
std::make_shared<policy_decision>(decision);
......@@ -47,35 +44,38 @@ void policy_storage::set_default_decision(
}
void policy_storage::insert_supi_decision(
std::string supi, const std::shared_ptr<SmPolicyDecision>& decision) {
const std::string& supi, const SmPolicyDecision& decision) {
std::unique_lock supi_decision_lock(m_supi_policy_decisions_mutex);
std::shared_ptr<supi_policy_decision> desc =
std::make_shared<supi_policy_decision>(supi, decision);
m_supi_policy_decisions.insert(std::make_pair(supi, desc));
supi_decision_lock.unlock();
notify_subscribers(desc);
}
void policy_storage::insert_dnn_decision(
std::string dnn, const std::shared_ptr<SmPolicyDecision>& decision) {
const std::string& dnn, const SmPolicyDecision& decision) {
std::unique_lock dnn_decision_lock(m_dnn_policy_decisions_mutex);
std::shared_ptr<dnn_policy_decision> desc =
std::make_shared<dnn_policy_decision>(dnn, decision);
m_dnn_policy_decisions.insert(std::make_pair(dnn, desc));
dnn_decision_lock.unlock();
notify_subscribers(desc);
}
void policy_storage::insert_slice_decision(
Snssai slice, const std::shared_ptr<SmPolicyDecision>& decision) {
const Snssai& slice, const SmPolicyDecision& decision) {
std::unique_lock slice_decision_lock(m_slice_policy_decisions_mutex);
std::shared_ptr<slice_policy_decision> desc =
std::make_shared<slice_policy_decision>(slice, decision);
m_slice_policy_decisions.insert(std::make_pair(slice, desc));
slice_decision_lock.unlock();
notify_subscribers(desc);
}
/**
......@@ -140,7 +140,6 @@ std::shared_ptr<policy_decision> policy_storage::find_policy(
Logger::pcf_app().debug("%s Decide based on SUPI", msg_base.c_str());
return got_supi->second;
}
return res_ptr;
}
void policy_storage::notify_subscribers(
......@@ -160,7 +159,7 @@ std::string policy_storage::to_string() const {
std::stringstream ss;
std::string output = "";
std::string output;
ss << "Policy Storage: \n";
ss << " - Default Decision: \n";
......@@ -170,25 +169,25 @@ std::string policy_storage::to_string() const {
ss << " -- No Default Decision\n";
}
ss << " - Slice Decisions: \n";
if (m_slice_policy_decisions.size() > 0) {
for (auto slice_desc : m_slice_policy_decisions) {
if (!m_slice_policy_decisions.empty()) {
for (const auto& slice_desc : m_slice_policy_decisions) {
ss << " -- " << *slice_desc.second << "\n";
}
} else {
ss << " -- No Slice Decisions\n";
}
ss << " - DNN Decisions: \n";
if (m_dnn_policy_decisions.size() > 0) {
for (auto dnn_desc : m_dnn_policy_decisions) {
if (!m_dnn_policy_decisions.empty()) {
for (const auto& dnn_desc : m_dnn_policy_decisions) {
ss << " -- " << *dnn_desc.second << "\n";
}
} else {
ss << " -- No DNN Decisions\n";
}
if (m_supi_policy_decisions.size() > 0) {
if (!m_supi_policy_decisions.empty()) {
ss << " - SUPI Decisions: \n";
for (auto supi_desc : m_supi_policy_decisions) {
for (const auto& supi_desc : m_supi_policy_decisions) {
ss << " -- " << *supi_desc.second << "\n";
}
} else {
......
......@@ -78,25 +78,24 @@ class policy_storage {
mutable std::shared_mutex m_supi_policy_decisions_mutex;
public:
explicit policy_storage();
explicit policy_storage() = default;
policy_storage(policy_storage const&) = delete;
void operator=(policy_storage const&) = delete;
// TODO methods to update and delete policies
void insert_supi_decision(
std::string supi,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision);
const std::string& supi,
const oai::pcf::model::SmPolicyDecision& decision);
void insert_dnn_decision(
std::string dnn,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision);
const std::string& dnn,
const oai::pcf::model::SmPolicyDecision& decision);
void insert_slice_decision(
oai::pcf::model::Snssai,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision);
const oai::pcf::model::Snssai&,
const oai::pcf::model::SmPolicyDecision& decision);
void set_default_decision(
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision);
void set_default_decision(const oai::pcf::model::SmPolicyDecision& decision);
std::shared_ptr<policy_decision> find_policy(
const oai::pcf::model::SmPolicyContextData& context);
......
......@@ -36,7 +36,7 @@ using namespace oai::pcf::app;
status_code slice_policy_decision::decide(
const SmPolicyContextData& context,
std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision) const {
oai::pcf::model::SmPolicyDecision& decision) const {
if (context.getSliceInfo() != m_snssai) {
return status_code::CONTEXT_DENIED;
}
......@@ -53,7 +53,7 @@ std::string slice_policy_decision::to_string() const {
std::stringstream ss;
ss << "Slice: Sd: " << m_snssai.getSd()
<< " Sst: " << std::to_string(m_snssai.getSst()) << "\n";
ss << " -- " << *m_decision;
ss << " -- " << m_decision;
return ss.str();
}
......@@ -62,5 +62,3 @@ std::ostream& operator<<(
const oai::pcf::app::sm_policy::slice_policy_decision& storage) {
return (os << storage.to_string());
}
slice_policy_decision::~slice_policy_decision() {}
\ No newline at end of file
......@@ -44,14 +44,13 @@ namespace oai::pcf::app::sm_policy {
class slice_policy_decision : public oai::pcf::app::sm_policy::policy_decision {
public:
explicit slice_policy_decision(
oai::pcf::model::Snssai snssai,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision)
const oai::pcf::model::Snssai& snssai,
const oai::pcf::model::SmPolicyDecision& decision)
: policy_decision(decision) {
m_snssai = snssai;
m_decision = decision;
m_snssai = snssai;
}
virtual ~slice_policy_decision();
~slice_policy_decision() override = default;
/**
* @brief Decides based on context on a policy and the snssai information. In
......@@ -62,21 +61,20 @@ class slice_policy_decision : public oai::pcf::app::sm_policy::policy_decision {
* @return oai::pcf::app::sm_policy::status_code CREATED in case of
* success
*/
oai::pcf::app::sm_policy::status_code decide(
[[nodiscard]] oai::pcf::app::sm_policy::status_code decide(
const oai::pcf::model::SmPolicyContextData& context,
std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision) const;
oai::pcf::model::SmPolicyDecision& decision) const override;
/**
* @brief Get the snssai object
*
* @return oai::pcf::model::Snssai
*/
oai::pcf::model::Snssai get_snssai() const;
[[nodiscard]] oai::pcf::model::Snssai get_snssai() const;
std::string to_string() const;
[[nodiscard]] std::string to_string() const override;
private:
std::shared_ptr<oai::pcf::model::SmPolicyDecision> m_decision;
oai::pcf::model::Snssai m_snssai;
};
} // namespace oai::pcf::app::sm_policy
......
......@@ -36,7 +36,7 @@ using namespace oai::pcf::app;
status_code supi_policy_decision::decide(
const SmPolicyContextData& context,
std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision) const {
oai::pcf::model::SmPolicyDecision& decision) const {
if (context.getSupi() != m_supi) {
return status_code::CONTEXT_DENIED;
}
......@@ -52,7 +52,7 @@ std::string supi_policy_decision::get_supi() const {
std::string supi_policy_decision::to_string() const {
std::stringstream ss;
ss << "SUPI: " << m_supi << "\n";
ss << " -- " << *m_decision;
ss << " -- " << m_decision;
return ss.str();
}
......@@ -61,5 +61,3 @@ std::ostream& operator<<(
const oai::pcf::app::sm_policy::supi_policy_decision& storage) {
return (os << storage.to_string());
}
supi_policy_decision::~supi_policy_decision() {}
\ No newline at end of file
......@@ -45,14 +45,13 @@ namespace oai::pcf::app::sm_policy {
class supi_policy_decision : public oai::pcf::app::sm_policy::policy_decision {
public:
explicit supi_policy_decision(
std::string supi,
const std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision)
const std::string& supi,
const oai::pcf::model::SmPolicyDecision& decision)
: policy_decision(decision) {
m_supi = supi;
m_decision = decision;
m_supi = supi;
}
virtual ~supi_policy_decision();
~supi_policy_decision() override = default;
/**
* @brief Decides based on context on a policy and the DNN information. In
......@@ -63,21 +62,20 @@ class supi_policy_decision : public oai::pcf::app::sm_policy::policy_decision {
* @return oai::pcf::app::sm_policy::status_code CREATED in case of
* success
*/
oai::pcf::app::sm_policy::status_code decide(
[[nodiscard]] oai::pcf::app::sm_policy::status_code decide(
const oai::pcf::model::SmPolicyContextData& context,
std::shared_ptr<oai::pcf::model::SmPolicyDecision>& decision) const;
oai::pcf::model::SmPolicyDecision& decision) const override;
/**
* @brief Get the supi object
*
* @return std::string
*/
std::string get_supi() const;
[[nodiscard]] std::string get_supi() const;
std::string to_string() const;
[[nodiscard]] std::string to_string() const override;
private:
std::shared_ptr<oai::pcf::model::SmPolicyDecision> m_decision;
std::string m_supi;
};
} // namespace oai::pcf::app::sm_policy
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment