Table of Contents |
---|
Table of Contents |
---|
Note | ||
---|---|---|
| ||
This wiki is under construction - this is an evolving POC |
Jira Legacy | ||||||
---|---|---|---|---|---|---|
|
Purpose: prototype a REST client on top of ONAP - specifically for VF-Module orchestration.
Analysis
vFirewall Demo Sequence of Events
...
Passwords in /testsuite/properties/integration_robot_properties.py
Variables
IAD region
...
...
Status (current/future) Flow
Before | After (REST extraction) |
---|---|
in demo.sh init (customer create, service model create) in vid deploy service model in vid create service instance in vid add vnf to service instance in demo.sh preload in vid vf-module creation in demo.sh appc | 2 AAI rest calls unchanged vid unchanged vid unchanged vid SDNC rest call MSO rest call unchanged robot |
Variables
IAD region
key | name | value |
---|---|---|
service | c54316d8-464e-4967-bece-8c2b2f458b66 | |
VNF | 6229cdee-10f6-4ec4-a5e0-0593154e6d83 | |
VfModule | 5a08199b-4161-4181-9b2d-da29f6df1410 |
...
Seq | Name | Source | Target | Actor | robot | REST write | REST read | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
create customer | robot | aai | ./demo.sh init | Executing robot tests at log level TRACE ============================================================================== OpenECOMP ETE ============================================================================== OpenECOMP ETE.Robot ============================================================================== OpenECOMP ETE.Robot.Testsuites ============================================================================== OpenECOMP ETE.Robot.Testsuites.Demo :: Executes the VNF Orchestration Test ... ============================================================================== Initialize Customer And Models | PASS | ------------------------------------------------------------------------------ OpenECOMP ETE.Robot.Testsuites.Demo :: Executes the VNF Orchestrat... | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== OpenECOMP ETE.Robot.Testsuites | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== OpenECOMP ETE.Robot | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== OpenECOMP ETE | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== Output: /share/logs/demo/InitDemo/output.xml Log: /share/logs/demo/InitDemo/log.html Report: /share/logs/demo/InitDemo/report.html | PUT https://{{aai_ip}}:8443/aai/v8/business/customers/customer/ONAP-User { "global-customer-id": "ONAP-User", | https://{{aai_ip}}:8443/aai/v8/business/customers/customer { "global-customer-id": "Demonstration","subscriber-name": "Demonstration", | create service model | robot | aai | ./demo.sh init | PUT aai/v8/service-design-and-creation/services { "service-id": "${UUID}", | https://{{aai_ip}}:8443/aai/v8/service-design-and-creation/models "model-name-version-id": "dcb40136-9cec-45be-b080-2a36b31c2f06", |
...
Seq | Name | Source | Target | Actor | REST write | REST read | ||||
---|---|---|---|---|---|---|---|---|---|---|
deploy service model | vid | aai | demo user | 9023f592-5c64-4a5b-9333-3287fdc9d304 | create service instance | vid | aai | demo user | Input: InstanceName=DemoInstance Output: however on a clean system - where the tenant target node in the graph db does not exist yet - we fail { | https://{{aai_ip}}:8443/aai/v8/business/customers/customer { "global-customer-id": "Demonstration","subscriber-name": "Demonstration", |
create service model | robot | aai | ./demo.sh init | PUT aai/v8/service-design-and-creation/services { "service-id": "${UUID}", | https://{{aai_ip}}:8443/aai/v8/service-design-and-creation/models "model-name-version-id": "dcb40136-9cec-45be-b080-2a36b31c2f06", |
Service Deployment
Seq | Name | Source | Target | Actor | REST write | REST read | REST delete |
---|---|---|---|---|---|---|---|
deploy service model | vid | aai | demo user | 9023f592-5c64-4a5b-9333-3287fdc9d304 | |||
create service instance | vid | aai | demo user | Input: InstanceName=DemoInstance Output: 07/27/17 12:10:39 HTTP Status: OK (200)
{
"request": {
"requestId": "96dcaa23-88cb-41ac-bf8c-e1e5bb423232",
"startTime": "Wed, 26 Jul 2017 16:10:26 GMT",
"requestScope": "service",
"requestType": "createInstance",
"requestDetails": {
"modelInfo": {
"modelCustomizationName": null,
"modelInvariantId": "43d59b70-8829-4a50-a3f7-d261b220ceef",
"modelType": "service",
"modelNameVersionId": "dcb40136-9cec-45be-b080-2a36b31c2f06",
"modelName": "vfservice",
"modelVersion": "1.0"
},
"requestInfo": {
"billingAccountNumber": null,
"callbackUrl": null,
"correlator": null,
"orderNumber": null,
"productFamilyId": null,
"orderVersion": null,
"source": "VID",
"instanceName": "DemoInstance",
"suppressRollback": false
},
"relatedInstanceList": null,
"subscriberInfo": {
"globalSubscriberId": "Demonstration",
"subscriberName": null
},
"cloudConfiguration": null,
"requestParameters": {
"subscriptionServiceType": "vFW",
"userParams": []
}
},
"instanceReferences": {
"serviceInstanceId": "cd2eb659-2463-461b-9c3b-3bf03619c167",
"serviceInstanceName": "DemoInstance",
"vnfInstanceId": null,
"vnfInstanceName": null,
"vfModuleInstanceId": null,
"vfModuleInstanceName": null,
"volumeGroupInstanceId": null,
"volumeGroupInstanceName": null,
"networkInstanceId": null,
"networkInstanceName": null
},
"requestStatus": {
"requestState": "COMPLETE",
"statusMessage": "Service Instance has been created successfully.",
"percentProgress": 100,
"finishTime": "Wed, 26 Jul 2017 16:10:31 GMT"
}
}
}
07/27/17 12:10:28 HTTP Status: Accepted (202)
{
"requestReferences": {
"instanceId": "cd2eb659-2463-461b-9c3b-3bf03619c167",
"requestId": "96dcaa23-88cb-41ac-bf8c-e1e5bb423232"
}
}
| https://{{aai_ip}}:8443/aai/v8/business/customers/customer/Demonstration/service-subscriptions/service-subscription/vFW https://{{aai_ip}}:8443/aai/v8/business/customers/customer/Demonstration/service-subscriptions/service-subscription/vFW/service-instances/ { "service-instance": [{ |
VNF Creation
Seq | http://{{mso_ip}}:8080/ecomp/mso/infra/serviceInstances/v2/cd2eb659-2463-461b-9c3b-3bf03619c167 { |
---|
VNF Creation
Seq | Name | Source | Target | Actor | REST write | REST read | REST delete |
---|---|---|---|---|---|---|---|
Add VNF to Service Instance | vid | sdc | demo user | 07/27/17 12:15:13 HTTP Status: OK (200) { "request": { "requestId": "e867be64-e725-4e29-8448-c9eceb51ce3c", "startTime": "Wed, 26 Jul 2017 16:15:02 GMT", "requestScope": "vnf", "requestType": "createInstance", "requestDetails": { "modelInfo": { "modelCustomizationName": "vsp 1", "modelInvariantId": "27036887-1053-48e8-a55e-3d2a7264a658", "modelType": "vnf", "modelNameVersionId": "b63a0b42-a151-460a-9bb2-ba469948622b", "modelName": "vsp", "modelVersion": "1.0" }, "requestInfo": { "billingAccountNumber": null, "callbackUrl": null, "correlator": null, "orderNumber": null, "productFamilyId": "03606d31-c2f3-483e-9882-6d050ab3610f", "orderVersion": null, "source": "VID", "instanceName": "DemoVNF", "suppressRollback": false }, "relatedInstanceList": [ { "relatedInstance": { "instanceName": null, "instanceId": "cd2eb659-2463-461b-9c3b-3bf03619c167", "modelInfo": { "modelCustomizationName": null, "modelInvariantId": "43d59b70-8829-4a50-a3f7-d261b220ceef", "modelType": "service", "modelNameVersionId": "dcb40136-9cec-45be-b080-2a36b31c2f06", "modelName": "vfservice", "modelVersion": "1.0" } } } ], "subscriberInfo": null, "cloudConfiguration": { "aicNodeClli": null, "tenantId": "1035021your_tenant_id", "lcpCloudRegionId": "DFW" }, "requestParameters": { "subscriptionServiceType": null, "userParams": [] } }, "instanceReferences": { "serviceInstanceId": "cd2eb659-2463-461b-9c3b-3bf03619c167", "serviceInstanceName": null, "vnfInstanceId": "110f0e9c-52f9-4b12-8bd8-fa2980e48454", "vnfInstanceName": "DemoVNF", "vfModuleInstanceId": null, "vfModuleInstanceName": null, "volumeGroupInstanceId": null, "volumeGroupInstanceName": null, "networkInstanceId": null, "networkInstanceName": null }, "requestStatus": { "requestState": "COMPLETE", "statusMessage": "Vnf has been created successfully.", "percentProgress": 100, "finishTime": "Wed, 26 Jul 2017 16:15:03 GMT" } } } 07/27/17 12:15:02 HTTP Status: Accepted (202) { "requestReferences": { "instanceId": "110f0e9c-52f9-4b12-8bd8-fa2980e48454", "requestId": "e867be64-e725-4e29-8448-c9eceb51ce3c" } } | |||
Seq | Name | Source | Target | Actor | robot | REST write | REST read |
preload vnf | robot | get VSPs http://{{sdc_ip}}:8080/onboarding-api/v1.0/vendor-software-products "name": "vsp", |
VfModule Preload
https://{{aai_ip}}:8443/aai/v8/network/generic-vnfs/generic-vnf/6229cdee-10f6-4ec4-a5e0-0593154e6d83 | DEL http://{{mso_ip}}:8080/ecomp/mso/infra/serviceInstances/v2/cd2eb659-2463-461b-9c3b-3bf03619c167/vnfs/42aa89af-cd4e-43d1-8b58-73e8f6b33097 | ||||||
VfModule Preload
Seq | Name | Source | Target | Actor | robot | REST write | REST read |
---|---|---|---|---|---|---|---|
preload vnf | robot | ./demo.sh preload <DemoVNF> <DemoModule> or http://sdnc:8843/login | Starting Xvfb on display :89 with res 1280x1024x24 Executing robot tests at log level TRACE ============================================================================== OpenECOMP ETE ============================================================================== OpenECOMP ETE.Robot ============================================================================== OpenECOMP ETE.Robot.Testsuites ============================================================================== OpenECOMP ETE.Robot.Testsuites.Demo :: Executes the VNF Orchestration Test ... ============================================================================== Preload VNF | PASS | ------------------------------------------------------------------------------ OpenECOMP ETE.Robot.Testsuites.Demo :: Executes the VNF Orchestrat... | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== OpenECOMP ETE.Robot.Testsuites | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== OpenECOMP ETE.Robot | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== OpenECOMP ETE | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== Output: /share/logs/demo/PreloadDemo/output.xml Log: /share/logs/demo/PreloadDemo/log.html Report: /share/logs/demo/PreloadDemo/report.html | http://{{sdnc_ip}}:8282/restconf/operations/VNF-API:preload-vnf-topology-operation where "service-type" = the root service instance id at top of vid page (do a get on - https://{{aai_ip}}:8443/aai/v8/business/customers/customer/Demonstration/service-subscriptions/service-subscription/vFW/service-instances/ Accept:application/json Content-Type:application/json X-TransactionId:0a3f6713-ba96-4971-a6f8-c2da85a3176e X-FromAppId:API client Authorization:Basic YWRtaW46S3A4Yko0U1hzek0wV1hsaGFrM2VIbGNzZTJnQXc4NHZhb0dHbUp2VXkyVQ== { "input": { "request-information": { "notification-url": "openecomp.org", "order-number": "1", "order-version": "1", "request-action": "PreloadVNFRequest", "request-id": "test" }, "sdnc-request-header": { "svc-action": "reserve", "svc-notification-url": "http:\/\/openecomp.org:8080\/adapters\/rest\/SDNCNotify", "svc-request-id": "test" }, "vnf-topology-information": { "vnf-assignments": { "availability-zones": [], "vnf-networks": [], "vnf-vms": [] }, "vnf-parameters": [{ { "vnf- "vnf-parameter-name": "vfw_private_ip_0", "vnf-parameter-value": "192.168.110.100" }, { "vnf-parameter-name": "vfw_private_ip_1", "vnf-parameter-value": "192.168.120.100" }, { "vnf-parameter-name": "vfw_private_ip_2", "vnf-parameter-value": "10.1.0.11" }, { "vnf-parameter-name": "vpg_name_0", "vnf-parameter-value": "demofwl01pgn" }, { "vnf-parameter-name": "demo_artifacts_version", "vnf-parameter-value": "1.0.0" }, { "vnf-parameter-name": "ecomp_private_net_cidr", "vnf-parameter-value": "10.0.0.0/8" }, { "vnf-parameter-name": "key_name", "vnf-parameter-value": "vfw_keydemo" }, { "vnf-parameter-name": "repo_url_artifacts", "vnf-parameter-value": "https://nexus.onap.org/content/groups/staging" }, { "vnf-parameter-name": "protected_private_net_id", "vnf-parameter-value": "demofwl_protected" }, { "vnf-parameter-name": "vpg_private_ip_0", "vnf-parameter-value": "192.168.110.200" }, { "vnf-parameter-name": "vpg_private_ip_1", "vnf-parameter-value": "10.1.0.12" }, { "vnf-parameter-name": "unprotected_private_net_cidr", "vnf-parameter-value": "192.168.110.0/24" }, { "vnf-parameter-name": "dcae_collector_ip", "vnf-parameter-value": "10.0.4.102" }, { "vnf-parameter-name": "repo_url_blob", "vnf-parameter-value": "https://nexus.onap.org/content/repositories/raw" }, { "vnf-parameter-name": "vsn_private_ip_0", "vnf-parameter-value": "192.168.120.250" }, { "vnf-parameter-name": "vsn_private_ip_1", "vnf-parameter-value": "10.1.0.13" }, { "vnf-parameter-name": "vsn_name_0", "vnf-parameter-value": "demofwl01snk" }, { "vnf-parameter-name": "vfw_name_0", "vnf-parameter-value": "demofwl01fwl" }, { "vnf-parameter-name": "pub_key", "vnf-parameter-value": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAqqnA9BAiMLtjOPSYBfhzLu4CiBolWoskDg4KVwhTJVTTeB6CqrQNcadlGXxOHhCYuNCKkUmIVF4WTOisVOJ75Z1c4OMoZLL85xVPKSIeH63kgVugwgPYQu55NbbWX+rsbUha3LnElDhNviMM3iTPbD5nnhKixNERAJMTLKXvZZZGqxW94bREknYPQTT2qrk3YRqwldncopp6Nkgv3AnSJz2gc9tjxnWF0poTQnQm/3D6hiJICrzKfAV0EaPN0KdtYjPhKrYoy6Qb/tKOVaaqsvwfKBJGrT9LfcA7D7M/yj292RT1XN63hI84WC383LsaPJ6eWdDTE6zUP1eGTWCoOw== rsa-key-20161026" }, { "vnf-parameter-name": "ecomp_private_net_id", "vnf-parameter-value": "oam_ecomp_LbMf" // wrong network oam_ecomp_QbZ1 will fail vfModule creation later (get it from an openstack server call) }, { "vnf-parameter-name": "dcae_collector_port", "vnf-parameter-value": "8080" }, { "vnf-parameter-name": "unprotected_private_net_id", "vnf-parameter-value": "demofwl_unprotected" }, { "vnf-parameter-name": "ecomp_private_subnet_id", "vnf-parameter-value": "oam_ecomp_LbMf" }, { "vnf-parameter-name": "protected_private_net_cidr", "vnf-parameter-value": "192.168.120.0/24" } ], "vnf-topology-identifier": { "generic-vnf-name": "DemoVNF", "generic-vnf-type": "service/vsp 1", "service-type": "c54316d8-464e-4967-bece-8c2b2f458b66", "vnf-name": "DemoModule", "vnf-type": "Vsp..base_vfw..module-0" } } }} output { "output": { see also Tutorial: Creating a Service Instance from a Design Model#PreloadFlow | http://{{sdnc_ip}}:8282/restconf/config/VNF-API:preload-vnfs { "preload-vnfs": { http://{{sdnc_ip}}:8282/restconf/config/VNF-API:preload-vnfs/vnf-preload-list/DemoModule/Vsp..base_vfw..module-0 {"vnf-preload-list": [{ | ||
VfModule Creation
Seq | Name | Source | Target | Actor | REST write | REST read | REST delete | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
create Vf module <DemoModule> | vid | demo user | Success without running VID! - workaround for Output: VfModuleID=5a08199b-4161-4181-9b2d-da29f6df1410 via OpenStack openstack server list 4be336b3-a31c-4be0-9261-0cb1cb51227d | demofwl01fwl | ACTIVE | oam_ecomp_LbMf=10.1.0.11; demofwl_unprotected=192.168.110.100; public=104.239.230.93, | || | | | 2001:4802:7803:104:be76:4eff:fe20:377b; demofwl_protected=192.168.120.100 |
Closed Loop
post call http://{{mso_ip}}:8080/ecomp/mso/infra/serviceInstances/v2/<id>/vnfs/<id>/vfModules inputs: serviceInstance id = c543... from relatedInstance:type=service vnf id = 6229.. from relatedInstance:type=vnf using https://{{ |
aai_ip}}: |
8443/ |
see JSON.parse(returnedData[i].event.commonEventHeader.eventId
["{\"event\":{\"measurementsForVfScalingFields\":{\"measurementInterval\":10,\"measurementsForVfScalingVersion\":1.1,\"vNicUsageArray\":[{\"multicastPacketsIn\":0,\"bytesIn\":14500,\"unicastPacketsIn\":0,\"multicastPacketsOut\":0,\"broadcastPacketsOut\":0,\"packetsOut\":0,\"bytesOut\":0,\"broadcastPacketsIn\":0,\"packetsIn\":500,\"unicastPacketsOut\":0,\"vNicIdentifier\":\"eth1\"}]},\"commonEventHeader\":{\"reportingEntityName\":\"demofwl01fwl\",\"startEpochMicrosec\":1500849487268085,\"lastEpochMicrosec\":1500849497268085,\"eventId\":\"43434\",\"sourceName\":\"Dummy VM name - No Metadata available\",\"sequence\":43434,\"priority\":\"Normal\",\"functionalRole\":\"vFirewall\",\"domain\":\"measurementsForVfScaling\",\"reportingEntityId\":\"No UUID available\",\"sourceId\":\"Dummy VM UUID - No Metadata available\",\"version\":1.2}}}",
http://{{collector_ip}}:3904/events/unauthenticated.TCA_EVENT_OUTPUT/group3/sub1?timeout=30000
API History
http://{{mso_ip}}:8080/ecomp/mso/infra/orchestrationRequests/v2/?filter=serviceInstanceId%3AEQUALS%3Ac54316d8-464e-4967-bece-8c2b2f458b66
http://{{mso_ip}}:8080/ecomp/mso/infra/orchestrationRequests/v2/?filter=vnfInstanceId%3AEQUALS%3A6229cdee-10f6-4ec4-a5e0-0593154e6d83
http://{{mso_ip}}:8080/ecomp/mso/infra/orchestrationRequests/v2/?filter=vfModuleInstanceId%3AEQUALS%3A5a08199b-4161-4181-9b2d-da29f6df1410
see also
http://{{sdc_ip}}:8080/sdc2/rest/v1/catalog/services/latestversion/notabstract/uidonly?internalComponentType=SERVICE
feeds
http://{{sdc_ip}}:8080/sdc2/rest/v1/catalog/services/378bc9b7-2b7d-4a4f-96d9-1c654c2242fa
Design Issues
DI 1: 20170712: AAI Cert required for HTTPS REST calls
Use postman for adhoc rest calls - but if you want to code up call chains or hammer an endpoint use Spring RestController or the Rest client in JAX-RS 2.0
Calls to AAI such as the following require both the authentication header and an imported certificate. When running Postman - because it is a Chrome app - this is a simple case of loading a REST url in the browser and importing the certificate after an authentication challenge (AAI:AAI). However for a java client like a JAX-RS 2.0 client we need the certificate in a keystore (the default or a specially defined one).
Below we import the cert into the default keystore. Where did I get the cert? by extracting it from Firefox - however it is in the code base - looking it up
...
obrienbiometrics:onap michaelobrien$ ls $JAVA_HOME/jre/lib/security/cacerts
/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/security/cacerts
sudo keytool -import -trustcacerts -alias aai -file /Users/michaelobrien/Dropbox/_amdocs/config/certs/aai/aaiapisimpledemoopenecomporg.cer -keystore $JAVA_HOME/jre/lib/security/cacerts
Running an https rest target using this certificate - if the cert is in a default keystore - you dont need to define it.
...
// require: cert, username, password, headers(X-FromAppId,Accept), Authenticator
public String run(boolean isSSL, String url, String port, String path) {
String record = null;
Client client = null;
WebTarget latestTarget = null;
WebTarget rootTarget = null;
if(isSSL) {
SslConfigurator sslConfig = SslConfigurator.newInstance();
SSLContext sslContext = sslConfig.createSSLContext();
HostnameVerifier verifier = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession sslSession) {
return true; // TODO: security breach
}};
client = ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(verifier).build();
client.register(new Authenticator("AAI","AAI"));
} else {
client = ClientBuilder.newClient();
}
rootTarget = client.target(url);
latestTarget = rootTarget.path(path);
try {
try { Thread.sleep(1); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); }
record = finalTarget.request()
.header("X-FromAppId", "AAI").header("Accept", "application/json")
.get(String.class);
...
DI 2: 20170712: Spring Boot Backend Framework
Instead of using a full Tomcat deployment server - we will use an embedded Jetty container.
...
pom.xml
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.3.RELEASE</version></parent>
<dependencies>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
<!-- avoid restarts --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId>
<!-- may not be required --><configuration><addResources>true</addResources> </configuration></plugin></plugins></build>
DI 3: 20170712: JAX-RS 2.0 API Framework
DI 4: 20170712: 3D Framework: Three js OpenGL 3D wrapper on Canvas
Di 5: 20170712: Javascript Timer Framework
DI 6: 20170712: Three js Listener
DI 7: 20170712: Three js Edges between Nodes
DI 8: 20170712: Three js Click Context
DI 9: 20170712: AJAX JAX-RS Channel
DI 10: 20170712: WebSocket Channel
DI 11: 20170712: React.js Framework
DI 12: 20170712: Three js Text
DI 13: 20170721: Demo Robot REST extraction
Reverse engineer the orchestration rest calls coming out of demo.sh
/testsuite/properties/demo.sh not /testsuite/docker/demo.sh
/testsuite/runtags.sh
/testsuite/resources/demo_preload.robot "Load Customer And Models"
"Create Customer For VNF Demo"
create_customer.robot (aai put /aai/v8//business/customers/customer/)
create_service.robot (aai put /aai/v8/service-design-and-creation/services
"Load Models" | Distribute Model | Model Distribution For Directory in model_test_template.robot | Distribute Model From ASDC in addc_interface.robot
(Add ASDC Catalog Service, Setup ASDC Catalog Resource, Get ASDC Catalog Resource,
Add ASDC Resource Instance, Get ASDC Catalog Service, Checkin ASDC Catalog Service,
Request Certify ASDC Catalog Service, Start Certify ASDC Catalog Service, Certify ASDC Catalog Service, Approve ASDC Catalog Service,
Distribute ASDC Catalog Service, Get ASDC Catalog Service, Check Catalog Service Distributed)
Preload VNF:demo.robot (
Preload User Model:demo_preload.robot (
Get Service Instance
Get Relationship Data
Get Persona Model Id
Login To VID GUI
Get Module Names from VID
Preload Vnf:sdngc_interface.robot(
Update Module Name
Preload Vnf Profile(
Login To SDNGC Admin GUI
goto sdnc:8843/mobility/getVnfProfile
click add_vnf_profile
inserts directly to the DB from the client (for now)
/sdnc-oam/admportal/mobility.js
router.post('/addVnfNetwork', csp.checkAuth, function(req,res){
var sql = "INSERT INTO VNF_NETWORKS (vnf_type,network_role) VALUES ("
+ "'" + req.body.nf_vnf_type + "'," + "'" + req.body.nf_network_role + "')";
tasks.push( function(callback) { dbRoutes.executeSQL(sql,req,res,callback); } );
)
Preload One Vnf Topology
)))
...
aai/v8/network/generic-vnfs get: "relatedInstance": { "instanceId": "6229cdee-10f6-4ec4-a5e0-0593154e6d83", from: {"generic-vnf": [{"vnf-id": "6229cdee-10f6-4ec4-a5e0-0593154e6d83" get: modelInvariantId": "7425ba97-e159-4c0f-87dd-3af3b439148b" from: "persona-model-id": "7425ba97-e159-4c0f-87dd-3af3b439148b" using https://{{aai_ip}}:8443/aai/v8/business/customers/customer/Demonstration/service-subscriptions/service-subscription/vFW/service-instances/ get: "instanceReferences": { "serviceInstanceId": "c54316d8-464e-4967-bece-8c2b2f458b66" from: { "service-instance": [{"service-instance-id": "c54316d8-464e-4967-bece-8c2b2f458b66", body : { "requestDetails": { however there is more to this than just a rest call - no heat stack means no vf instances yet http://{{mso_ip}}:8080/ecomp/mso/infra/serviceInstances/v2/cd2eb659-2463-461b-9c3b-3bf03619c167/vnfs/110f0e9c-52f9-4b12-8bd8-fa2980e48454/vfModules { however a call to the following - shows we need to get the right network name in the preload http://{{mso_ip}}:8080/ecomp/mso/infra/orchestrationRequests/v2/?filter=vnfInstanceId%3AEQUALS%3A110f0e9c-52f9-4b12-8bd8-fa2980e48454 "requestStatus": { retry after redoing preload with proper subnet name oam_ecomp_QbZ1 200 OK { "requestReferences": { | http://{{mso_ip}}:8080/ecomp/mso/infra/orchestrationRequests/v2/?filter=vfModuleInstanceId%3AEQUALS%3A5a08199b-4161-4181-9b2d-da29f6df1410 http://{{mso_ip}}:8080/ecomp/mso/infra/orchestrationRequests/v2/?filter=vnfInstanceId%3AEQUALS%3A110f0e9c-52f9-4b12-8bd8-fa2980e48454 http://{{mso_ip}}:8080/ecomp/mso/infra/orchestrationRequests/v2/?filter=vfModuleInstanceId%3AEQUALS%3Ad5508965-35c6-4720-a7f0-4b0e17f25c9d { "requestList": [{ "request": { | get ID via http://{{mso_ip}}:8080/ecomp/mso/infra/orchestrationRequests/v2/?filter=vfModuleInstanceId%3AEQUALS%3Ad5508965-35c6-4720-a7f0-4b0e17f25c9d { ... DEL to http://{{mso_ip}}:8080/ecomp/mso/infra/serviceInstances/v2/cd2eb659-2463-461b-9c3b-3bf03619c167/vnfs/110f0e9c-52f9-4b12-8bd8-fa2980e48454/vfModules/d5508965-35c6-4720-a7f0-4b0e17f25c9d fails - referencing an older preload { | |||||
Closed Loop
Seq | Name | Source | Target | Actor | Robot | REST write | REST read |
---|---|---|---|---|---|---|---|
appc | robot | ./demo.sh appc <DemoModule> | Starting Xvfb on display :89 with res 1280x1024x24 Executing robot tests at log level TRACE ============================================================================== OpenECOMP ETE ============================================================================== OpenECOMP ETE.Robot ============================================================================== OpenECOMP ETE.Robot.Testsuites ============================================================================== OpenECOMP ETE.Robot.Testsuites.Demo :: Executes the VNF Orchestration Test ... ============================================================================== Create APPC Mount Point | PASS | ------------------------------------------------------------------------------ OpenECOMP ETE.Robot.Testsuites.Demo :: Executes the VNF Orchestrat... | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== OpenECOMP ETE.Robot.Testsuites | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== OpenECOMP ETE.Robot | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== OpenECOMP ETE | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== Output: /share/logs/demo/APPCMountPointDemo/output.xml Log: /share/logs/demo/APPCMountPointDemo/log.html Report: /share/logs/demo/APPCMountPointDemo/report.html | ||||
DMaaP | http://{{collector_ip}}:3904/events/unauthenticated.SEC_MEASUREMENT_OUTPUT/group3/sub1?timeout=9000 see JSON.parse(returnedData[i].event.commonEventHeader.eventId ["{\"event\":{\"measurementsForVfScalingFields\":{\"measurementInterval\":10,\"measurementsForVfScalingVersion\":1.1,\"vNicUsageArray\":[{\"multicastPacketsIn\":0,\"bytesIn\":14500,\"unicastPacketsIn\":0,\"multicastPacketsOut\":0,\"broadcastPacketsOut\":0,\"packetsOut\":0,\"bytesOut\":0,\"broadcastPacketsIn\":0,\"packetsIn\":500,\"unicastPacketsOut\":0,\"vNicIdentifier\":\"eth1\"}]},\"commonEventHeader\":{\"reportingEntityName\":\"demofwl01fwl\",\"startEpochMicrosec\":1500849487268085,\"lastEpochMicrosec\":1500849497268085,\"eventId\":\"43434\",\"sourceName\":\"Dummy VM name - No Metadata available\",\"sequence\":43434,\"priority\":\"Normal\",\"functionalRole\":\"vFirewall\",\"domain\":\"measurementsForVfScaling\",\"reportingEntityId\":\"No UUID available\",\"sourceId\":\"Dummy VM UUID - No Metadata available\",\"version\":1.2}}}", | ||||||
DMaaP | http://{{collector_ip}}:3904/events/unauthenticated.TCA_EVENT_OUTPUT/group3/sub1?timeout=30000 [ "{\"closedLoopEventClient\":\"DCAE_INSTANCE_ID.dcae-tca\",\"policyVersion\":\"1.0.0.5\",\"policyName\":\"vFirewall\",\"policyScope\":\"resource=SampleResource,service=SampleService,type=SampleType,closedLoopControlName=SampleClosedLoop\",\"target_type\":\"VNF\",\"AAI\":{\"generic-vnf.vnf-id\":\"demofwl01fwl\"},\"closedLoopAlarmStart\":1501103790415551,\"closedLoopEventStatus\":\"ONSET\",\"closedLoopControlName\":\"CL-FRWL-LOW-TRAFFIC-SIG-d925ed73-8231-4d02-9545-db4e101f88f8\",\"version\":\"1.0.2\",\"target\":\"generic-vnf.vnf-id\",\"requestID\":\"05ac4b8f-b844-439f-a6d1-c2713356e102\",\"from\":\"DCAE\"}", "{\"closedLoopEventClient\":\"DCAE_INSTANCE_ID.dcae-tca\",\"policyVersion\":\"1.0.0.5\",\"policyName\":\"vFirewall\",\"policyScope\":\"resource=SampleResource,service=SampleService,type=SampleType,closedLoopControlName=SampleClosedLoop\",\"target_type\":\"VNF\",\"AAI\":{\"generic-vnf.vnf-id\":\"demofwl01fwl\"},\"closedLoopAlarmStart\":1501103870657180,\"closedLoopEventStatus\":\"ONSET\",\"closedLoopControlName\":\"CL-FRWL-LOW-TRAFFIC-SIG-d925ed73-8231-4d02-9545-db4e101f88f8\",\"version\":\"1.0.2\",\"target\":\"generic-vnf.vnf-id\",\"requestID\":\"cb65cec6-4058-42a2-9e19-8ef61fea1fbf\",\"from\":\"DCAE\"}", |
API History
http://{{mso_ip}}:8080/ecomp/mso/infra/orchestrationRequests/v2/?filter=serviceInstanceId%3AEQUALS%3Ac54316d8-464e-4967-bece-8c2b2f458b66
http://{{mso_ip}}:8080/ecomp/mso/infra/orchestrationRequests/v2/?filter=vnfInstanceId%3AEQUALS%3A6229cdee-10f6-4ec4-a5e0-0593154e6d83
http://{{mso_ip}}:8080/ecomp/mso/infra/orchestrationRequests/v2/?filter=vfModuleInstanceId%3AEQUALS%3A5a08199b-4161-4181-9b2d-da29f6df1410
see also
http://{{sdc_ip}}:8080/sdc2/rest/v1/catalog/services/latestversion/notabstract/uidonly?internalComponentType=SERVICE
feeds
http://{{sdc_ip}}:8080/sdc2/rest/v1/catalog/services/378bc9b7-2b7d-4a4f-96d9-1c654c2242fa
Design Issues
DI 1: 20170712: AAI Cert required for HTTPS REST calls
Use postman for adhoc rest calls - but if you want to code up call chains or hammer an endpoint use Spring RestController or the Rest client in JAX-RS 2.0
Calls to AAI such as the following require both the authentication header and an imported certificate. When running Postman - because it is a Chrome app - this is a simple case of loading a REST url in the browser and importing the certificate after an authentication challenge (AAI:AAI). However for a java client like a JAX-RS 2.0 client we need the certificate in a keystore (the default or a specially defined one).
Below we import the cert into the default keystore. Where did I get the cert? by extracting it from Firefox - however it is in the code base - looking it up
CURL commands need the certificate - see Verifying your ONAP Deployment#Postman/CurlRESTcalls
Note: we will need to replace the AAI Certificate before 1 Dec 2017 -
Jira Legacy | ||||||
---|---|---|---|---|---|---|
|
$ ls $JAVA_HOME/jre/lib/security/cacerts /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/security/cacerts sudo keytool -import -trustcacerts -alias aai -file /config/certs/aai/aaiapisimpledemoopenecomporg.cer -keystore $JAVA_HOME/jre/lib/security/cacerts on robot root@vm1-robot:~# keytool -list -keystore /usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/security/cacerts -v sudo scp aaiapisimpledemoopenecomporg.cer root@robot:/opt keytool -import -trustcacerts -alias aai -file aaiapisimpledemoopenecomporg.cer -keystore /usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/security/cacerts the aai keystore password does not work - I will use my own truststore "AAI_KEYSTORE_PASSWD_X": "OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0" |
---|
Installing the AAI certificate in your own keystore on the Robot VM
root@vm1-robot:/opt# keytool -import -trustcacerts -alias aai -file aaiapisimpledemoopenecomporg.cer -keystore /usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/security/cacerts Enter keystore password: // use our own keytool error: java.io.IOException: Keystore was tampered with, or password was incorrect root@vm1-robot:/opt# keytool -genkey -alias onap -keyalg RSA -keystore KeyStore.jks -keysize 2048 Enter keystore password: Is CN=Michael OBrien, OU=onap, O=onap, L=Unknown, ST=Unknown, C=Unknown correct? Enter key password for <onap> (RETURN if same as keystore password): Re-enter new password: // import cer root@vm1-robot:/opt# keytool -import -trustcacerts -alias aai -file aaiapisimpledemoopenecomporg.cer -keystore KeyStore.jks Enter keystore password: Owner: EMAILADDRESS=aai-host@api.simpledemo.openecomp.org, CN=aai.api.simpledemo.openecomp.org, OU=SimpleDemo, O=OpenECOMP, L=Bedminster, ST=NJ, C=US Issuer: EMAILADDRESS=simpledemo@openecomp.org, CN=OpenECOMP simpledemo Server CA X1, OU=simpledemo, O=OpenECOMP, L=Bedminster, ST=NJ, C=US Serial number: 83ca7c32dc9f7329 Valid from: Wed Nov 30 15:38:39 UTC 2016 until: Thu Nov 30 15:38:39 UTC 2017 Trust this certificate? [no]: yes Certificate was added to keystore |
---|
Running an https rest target using this certificate - if the cert is in a default keystore - you dont need to define it - otherwise set your own trust/keystore as below.
// require: cert, username, password, headers(X-FromAppId,Accept), Authenticator public String run(boolean isSSL, String url, String port, String path) { String record = null; // SslConfigurator sslConfig = SslConfigurator.newInstance(); SslConfigurator sslConfig =SslConfigurator.newInstance() .trustStoreFile("/opt/KeyStore.jks") .trustStorePassword("changeme")//"changeit") .keyStoreFile("/opt/KeyStore.jks") .keyPassword("changeme");//"changeit"); SSLContext sslContext = sslConfig.createSSLContext(); client = ClientBuilder.newClient(); |
---|
public class Authenticator implements ClientRequestFilter { |
---|
Creating a custom keystore on the robot VM
DI 2: 20170712: Spring Boot Backend Framework
Instead of using a full Tomcat deployment server - we will use an embedded Jetty container.
pom.xml <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.3.RELEASE</version></parent> <dependencies> <!-- avoid restarts --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency> <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId> |
---|
DI 3: 20170712: JAX-RS 2.0 API Framework
DI 4: 20170712: 3D Framework: Three js OpenGL 3D wrapper on Canvas
changing state
scene.getObjectByName(arrowToFlash).line.material.color.set(flashOnColor); scene.getObjectByName(arrowToFlash).cone.material.color.set(flashOnColor); aDmaap.material.color.set(flashOnColor); aFirewall.material.color.set(flashOnColor); |
---|
Di 5: 20170712: Javascript Timer Framework
DI 6: 20170712: Three js Listener
DI 7: 20170712: Three js Edges between Nodes
var vmFromNames = ["generator", "firewall", "service-firewall", "firewall", "appc", "policy","policy"]; var vmToNames = ["firewall", "sink", "firewall", "dmaap", "generator", "dmaap", "appc"]; var edgeColors = [ colorRed, colorRed, colorGreen, colorRed, colorRed, colorBlue, colorBlue]; for(var vm=0; vm<vmFromNames.length; vm++) { threejsFlashStates[vmNames[vm]] = 0; var startObject = scene.getObjectByName(vmFromNames[vm]); var endObject = scene.getObjectByName(vmToNames[vm]); var startPoint = new THREE.Vector3(startObject.position.x, startObject.position.y, startObject.position.z); var endPoint = new THREE.Vector3(endObject.position.x, endObject.position.y, endObject.position.z); var direction = new THREE.Vector3().subVectors(endPoint, startPoint).normalize(); var arrow = new THREE.ArrowHelper(direction, startPoint, startPoint.distanceTo(endPoint), edgeColors[vm] ); arrow.line.material.linewidth = 4; // no effect on windows var vName = "edge-" + vmFromNames[vm] + "-" + vmToNames[vm]; console.log(vName); arrow.name = vName; group.add(arrow); } |
---|
DI 8: 20170712: Three js Click Context
DI 9: 20170712: AJAX JAX-RS Channel
Example: getCustomer() from AAI
AJAX client
function getCustomer() { $.ajax({url: "/api", data: { action: 'customer-read' }, success: function( data ) { var returnedData = JSON.parse(data.content); console.log(returnedData); document.getElementById('config-customer-value').bgColor='#c0ff30' $( "#config-customer-value" ).html( "<strong>" + returnedData['global-customer-id'] + "</strong>" ); }}); } |
---|
JAX-RS NBI
@Controller @RequestMapping("/api") publicclassApiController{ @RequestMapping(method=RequestMethod.GET) public@ResponseBodyApiprocess(@RequestParam(value="action",required=true,defaultValue="undefined")String action){ content = client.run(true,Configuration.get(Configuration.DC,"aai-ip"),"8443","aai/v8/business/customers/customer","AAI","AAI","AAI"); |
---|
JAX-RS SBI
record = rootTarget.request() .header("X-FromAppId", appId).header("Accept","application/json") .get(String.class); |
---|
DI 10: 20170712: WebSocket Channel
DI 11: 20170712: React.js Framework
DI 12: 20170712: Three js Text
DI 13: 20170721: Demo Robot REST extraction
Reverse engineer the orchestration rest calls coming out of demo.sh
/testsuite/properties/demo.sh not /testsuite/docker/demo.sh /testsuite/runtags.sh /testsuite/resources/demo_preload.robot "Load Customer And Models" "Create Customer For VNF Demo" create_customer.robot (aai put /aai/v8//business/customers/customer/) create_service.robot (aai put /aai/v8/service-design-and-creation/services "Load Models" | Distribute Model | Model Distribution For Directory in model_test_template.robot | Distribute Model From ASDC in addc_interface.robot (Add ASDC Catalog Service, Setup ASDC Catalog Resource, Get ASDC Catalog Resource, Add ASDC Resource Instance, Get ASDC Catalog Service, Checkin ASDC Catalog Service, Request Certify ASDC Catalog Service, Start Certify ASDC Catalog Service, Certify ASDC Catalog Service, Approve ASDC Catalog Service, Distribute ASDC Catalog Service, Get ASDC Catalog Service, Check Catalog Service Distributed) Preload VNF:demo.robot ( Preload User Model:demo_preload.robot ( Get Service Instance Get Relationship Data Get Persona Model Id Login To VID GUI Get Module Names from VID Preload Vnf:sdngc_interface.robot( Update Module Name Preload Vnf Profile( Login To SDNGC Admin GUI goto sdnc:8843/mobility/getVnfProfile click add_vnf_profile inserts directly to the DB from the client (for now) /sdnc-oam/admportal/mobility.js router.post('/addVnfNetwork', csp.checkAuth, function(req,res){ ) Preload One Vnf Topology ))) |
---|
DI 20: 20170721: Rest API Chaining
DI 21: 20170727: Parse VF-Module IPs from endpoint after VF-Module creation
DI 22: 20170728: Determine Healthcheck for vFW VMs are ready for appc Closed-Loop
The box should be ready for DMaaP TCA events - not just up with a 200.
Check port 667 on the sink vm.
DI 23: 20170728: Add granular Policy healthcheck for PDBD/PAP/PDP
http://{{policy_ip}}:6969/healthcheck Content-Type:application/json |
---|
DI 24: 20170728: Add TCA topic event capture between Policy and APPC
DI 25: 20170806: Add jcloud API to query VMs via Nova
http://jclouds.apache.org/guides/openstack/
DI 26: 20170806: Add docker ps parse calls to get docker health
ssh root@aai1 -o StrictHostKeyChecking=no 'docker ps'
will return results to calling server.
Notes
The MSO Rest post workaround to avoid VID for VF-Module creation fixes Jira Legacy server System Jira serverId 4733707d-2057-3a0f-ae5e-4fd8aff50176 key VID-19