Skip to content

Commit

Permalink
Merge pull request #212 from rruckley/ServiceCategory-211
Browse files Browse the repository at this point in the history
TMF633: Implement Service category
  • Loading branch information
rruckley authored Jan 8, 2025
2 parents baf1031 + 5b60e74 commit 9b03e3a
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 25 deletions.
15 changes: 15 additions & 0 deletions examples/create_service_candidate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//! Create Service Candidate Example
use tmflib::tmf633::service_candidate::ServiceCandidate;
use tmflib::tmf633::service_category::{ServiceCategory,ServiceCategoryRef};
use tmflib::tmf633::service_specification::{ServiceSpecification,ServiceSpecificationRef};

fn main() {

let cat = ServiceCategory::new("A Service Category");
let spec = ServiceSpecification::new("A Service Specification");
let candidate = ServiceCandidate::new("A Service Candidate",ServiceSpecificationRef::from(spec))
.category(ServiceCategoryRef::from(cat));

dbg!(candidate);
}
1 change: 1 addition & 0 deletions src/tmf633/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
const MOD_PATH : &str = "serviceCatalogManagement/v4";

pub mod service_category;
pub mod service_specification;
pub mod service_candidate;
pub mod characteristic_specification;
51 changes: 36 additions & 15 deletions src/tmf633/service_candidate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,45 @@
use serde::{Deserialize, Serialize};
use std::convert::From;

use crate::{HasId,HasLastUpdate, HasName, LIB_PATH};
use crate::{HasId, HasLastUpdate, HasName, TimeStamp, LIB_PATH, Uri, TimePeriod,vec_insert};
use tmflib_derive::{HasId, HasLastUpdate, HasName};

use super::MOD_PATH;
use super::{service_specification::ServiceSpecificationRef, MOD_PATH,service_category::ServiceCategoryRef};
const CLASS_PATH : &str = "serviceCandidate";
const CANDIDATE_NEW_VERS : &str = "1.0";
const CANDIDATE_NEW_STATUS : &str = "new";

/// Service Candidate
#[derive(Clone, Debug, Default, Deserialize, HasId, HasLastUpdate, HasName, Serialize)]
pub struct ServiceCandidate {
id: Option<String>,
href: Option<String>,
href: Option<Uri>,
name: Option<String>,
last_update: Option<String>,
last_update: Option<TimeStamp>,
lifecycle_status: Option<String>,
valid_for: Option<TimePeriod>,
version: Option<String>,
// References
service_specification: ServiceSpecificationRef,
category : Option<Vec<ServiceCategoryRef>>,
}

impl ServiceCandidate {
/// Create new instance of Service Candidate
pub fn new(name : impl Into<String>) -> ServiceCandidate {
let mut sc = ServiceCandidate::create_with_time();
sc.name = Some(name.into());
sc
pub fn new(name : impl Into<String>, specification_ref : ServiceSpecificationRef) -> ServiceCandidate {
ServiceCandidate {
name: Some(name.into()),
lifecycle_status: Some(CANDIDATE_NEW_STATUS.into()),
version: Some(CANDIDATE_NEW_VERS.into()),
service_specification : specification_ref,
..ServiceCandidate::create_with_time()
}
}
}

impl From<String> for ServiceCandidate {
fn from(value: String) -> Self {
ServiceCandidate::new(value)
/// Add a category to this Service Candidate by passing in a Category reference
pub fn category(mut self, category : ServiceCategoryRef) -> ServiceCandidate {
vec_insert(&mut self.category, category);
self
}
}

Expand Down Expand Up @@ -58,7 +70,10 @@ mod test {
const CANDIDATE_NAME : &str = "CandidateName";
#[test]
fn test_servicecandidate_new() {
let candidate = ServiceCandidate::new(CANDIDATE_NAME);
// Since new() requires a specification, using deafult then setting name via set_name()
let mut candidate = ServiceCandidate::default();
candidate.generate_id();
candidate.set_name(CANDIDATE_NAME);

assert_eq!(candidate.get_name().as_str(),CANDIDATE_NAME);
assert_eq!(candidate.id.is_some(),true);
Expand All @@ -67,7 +82,10 @@ mod test {

#[test]
fn test_servicecandidate_from_string() {
let candidate = ServiceCandidate::from(CANDIDATE_NAME.to_string());
// Since new() requires a specification, using deafult then setting name via set_name()
let mut candidate = ServiceCandidate::default();
candidate.generate_id();
candidate.set_name(CANDIDATE_NAME);

assert_eq!(candidate.get_name().as_str(),CANDIDATE_NAME);
assert_eq!(candidate.id.is_some(),true);
Expand All @@ -76,7 +94,10 @@ mod test {

#[test]
fn test_candidateref_from_candidate() {
let candidate = ServiceCandidate::from(CANDIDATE_NAME.to_string());
// Since new() requires a specification, using deafult then setting name via set_name()
let mut candidate = ServiceCandidate::default();
candidate.generate_id();
candidate.set_name(CANDIDATE_NAME);

let candidate_ref = ServiceCandidateRef::from(candidate.clone());

Expand Down
126 changes: 126 additions & 0 deletions src/tmf633/service_category.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
//! Service Category Module

use serde::{Deserialize, Serialize};

use crate::{
HasId,
HasLastUpdate,
HasName,
HasDescription,
HasValidity,
TimeStamp,
TimePeriod,
LIB_PATH,
Uri,
};
use tmflib_derive::{HasId, HasLastUpdate, HasDescription, HasName, HasValidity};

use super::{service_candidate::ServiceCandidate, MOD_PATH};
const CLASS_PATH : &str = "serviceCategory";
const CAT_STATUS_NEW : &str = "new";
const CAT_VERS_NEW : &str = "1.0";

/// Service Category Reference
/// # Description
/// Reference to another service category in the catalog
#[derive(Clone,Default,Debug,Deserialize, Serialize)]
pub struct ServiceCategoryRef {
href: Uri,
id: String,
name: String,
version: Option<String>,
}

impl From<ServiceCategory> for ServiceCategoryRef {
fn from(value: ServiceCategory) -> Self {
ServiceCategoryRef {
href: value.get_href(),
id: value.get_id(),
name: value.get_name(),
version: value.version.clone(),
}
}
}

/// Service Category
/// # Desecription
/// Categorisation for services in a service catalog
#[derive(Clone, Debug, Default, Deserialize, HasId, HasName, HasDescription, HasLastUpdate, HasValidity, Serialize)]
pub struct ServiceCategory {
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
href: Option<Uri>,
#[serde(skip_serializing_if = "Option::is_none")]
id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
is_root: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
last_update: Option<TimeStamp>,
#[serde(skip_serializing_if = "Option::is_none")]
lifecycle_status: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
parent_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
valid_for: Option<TimePeriod>,
#[serde(skip_serializing_if = "Option::is_none")]
version: Option<String>,
// META
/// Base Type this type is derived from if creating sub-classes
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@baseType")]
pub base_type : Option<String>,
/// Schema Definition of the sub-class (if required)
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@schemaLocation")]
pub schema_location: Option<Uri>,
/// Name for this Type when sub-classing
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
pub r#type : Option<String>,
// References
#[serde(skip_serializing_if = "Option::is_none")]
category : Option<Vec<ServiceCategoryRef>>,
#[serde(skip_serializing_if = "Option::is_none")]
service_candidate: Option<Vec<ServiceCandidate>>,
}

impl ServiceCategory {
/// Create a new category instance
pub fn new(name : impl Into<String>) -> ServiceCategory {
ServiceCategory {
name: Some(name.into()),
lifecycle_status: Some(CAT_STATUS_NEW.into()),
version : Some(CAT_VERS_NEW.into()),
..ServiceCategory::create_with_time()
}
}
}

#[cfg(test)]
mod test {

use super::*;

const CAT_NAME : &str = "CAT_NAME";

#[test]
fn test_servicecategory_create() {
let category = ServiceCategory::new(CAT_NAME);

assert_eq!(category.get_name(),CAT_NAME.to_string());
}

#[test]
fn test_category_into_ref() {
let category = ServiceCategory::new(CAT_NAME);

let cat_ref : ServiceCategoryRef = category.into();

// name in ref should match input name of cat
assert_eq!(CAT_NAME.to_string(),cat_ref.name);
}
}
28 changes: 18 additions & 10 deletions src/tmf633/service_specification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use super::MOD_PATH;
use crate::LIB_PATH;

const CLASS_PATH : &str = "serviceSpecification";
const SPEC_NEW_VERSION : &str = "1.0";
const SPEC_NEW_STATUS : &str = "new";

use super::characteristic_specification::CharacteristicSpecification;

Expand Down Expand Up @@ -54,12 +56,18 @@ pub struct ServiceSpecification {
impl ServiceSpecification {
/// Create a new specification
pub fn new(name : impl Into<String>) -> ServiceSpecification {
let mut ss = ServiceSpecification::create_with_time();
ss.name = Some(name.into());
ss.spec_characteristics = Some(vec![]);
ss.is_bundle = Some(false);
ss.lifecycle_status = Some("New".to_string());
ss
// let mut ss = ServiceSpecification::create_with_time();
// ss.name = Some(name.into());
// ss.spec_characteristics = Some(vec![]);
// ss.is_bundle = Some(false);
// ss.lifecycle_status = Some("New".to_string());
// ss
ServiceSpecification {
name : Some(name.into()),
lifecycle_status : Some(SPEC_NEW_STATUS.into()),
version : Some(SPEC_NEW_VERSION.into()),
..ServiceSpecification::create_with_time()
}
}

/// Add a characteristic to this service specification
Expand Down Expand Up @@ -103,10 +111,10 @@ mod test {
let spec = ServiceSpecification::new(SPEC_NAME);

assert_eq!(spec.get_name().as_str(),SPEC_NAME);
assert_eq!(spec.is_bundle.is_some(),true);
assert_eq!(spec.is_bundle.unwrap(),false);
// assert_eq!(spec.is_bundle.is_some(),true);
// assert_eq!(spec.is_bundle.unwrap(),false);
assert_eq!(spec.lifecycle_status.is_some(),true);
assert_eq!(spec.lifecycle_status.unwrap().as_str(),"New");
assert_eq!(spec.lifecycle_status.unwrap().as_str(),SPEC_NEW_STATUS);
}

#[test]
Expand All @@ -118,6 +126,6 @@ mod test {
assert_eq!(spec.get_name(),spec_ref.name);
assert_eq!(spec.get_id(),spec_ref.id);
assert_eq!(spec.get_href(),spec_ref.href);
assert_eq!(spec_ref.version.is_none(),true);
assert_eq!(spec_ref.version.is_none(),false);
}
}

0 comments on commit 9b03e3a

Please sign in to comment.