05-09-2018 02:03 PM - edited 03-01-2019 04:09 AM
Hi
I'm trying to write a stacked service. In that there are 2 service models A and B.
I'd like to add data to Service A and Service B in the same session.
However, Service B has a dependency on Service A.
That is, an object in Service B needs to make sure that an object in Service A exists.
Im using python to process Service B. During that, how can I access the uncommitted data for Service A?
Any example will be appreciated?
I already tried to access the /ncs:services/Service_A/data. But since the changes are uncommitted, I can't find it there.
Thanks
Kiran
Solved! Go to Solution.
05-18-2018 11:33 AM
Kiran,
Generally speaking:
First of all this will be bad approach for scalability as the number of interfaces/uuid increases and you are looping through the entire, potentially large, list...
Secondly, from a NSO-specific implementation perspective, looping such as this should never be done within the service create code, since during this entire period the transaction lock will be held during this entire period. You want to minimized the processing done in the create code. It is better to gather all needed information prior to entering the service create code - invoking a Reactive Fastmap approach if needed.
Now to your code:
'root' is provided in the service create - why re-determine it here?
def cb_create(self, tctx, root, service, proplist):
Where does the 't' (transaction) variable get created? are you starting a second transaction within the create() transaction?
-Larry
05-10-2018 12:27 PM
I also tried to access root.service.my_service{}. But even there, I only see committed data.
So the question is how do we access uncommitted service data in python?
05-10-2018 09:23 PM
Hi Kiran,
If you are creating a stacked service, would not service A create service B?. If you are using stacked services, the uncommitted data should be available within the context of FASTMAP?
-Dan
05-17-2018 12:06 PM
Hi Dan
Sorry, I meant to say the Stacked service(C) calls Services A and B. And A and B have a dependency as above.
How do I access the data via FASTMAP? Can you give an example?
Thanks
Kiran
05-17-2018 01:02 PM
Kiran,
The description of the overall task you are trying to achieve, and perhaps a few more detail, may help here.
If service B is dependent on service A, then I would create Service A (perhaps from service C, but I don't see it's value from what is presented here) do your dependency check on Service A items, then create service B from Service A.
-Larry
05-17-2018 01:27 PM
I wanted to avoid boring you all with details:)
Service A: Creates a Network. It generates a UUID in its python script.
This needs to run from Service C as well as stand alone.
Service B: Creates a Subnet. It needs to make sure a Network from Service A is available and the Network's UUID. This needs to run from Service C as well as Stand alone. When running stand-alone, it will browse the committed cdb tree for a Network. While running from Service C, it needs to make sure that a network has been provisioned and get its UUID before proceeding.
Service C: Create a Network through A and then create a Subnet through B and commit everything in one transaction.
I was thinking that Service B can access uncommitted Service A and access the UUID for proceeding.
Hope that clarifies it?
05-18-2018 07:51 AM
Kiran,
You should be able to access the data from ServiceA from ServiceB - provided that you save the desired data to from ServiceA:
Example in ServiceA we create a UUID somehow (I just simply multiply 2 values I pass in from ServiceC) and save the uuid to CDB:
ServiceC - create ServiceA and then ServiceB:
ServiceA Create:
@Service.create
def cb_create(self, tctx, root, service, proplist):
self.log.info('Service create(service=', service._path, ')')
base = service.uuid_base
mult = service.uuid_mult
service.uuid = base * mult # save uuid to ServiceA instance data
On ServiceB Read the ServiceA uuid:
@Service.create
def cb_create(self, tctx, root, service, proplist):
self.log.info('Service create(service=', service._path, ')')
srva = root.services.srvA[service.name] # get srvA instance... you need to know (or determine) ServiceA instance
# identifier - here the same instance id used for SrvA and SrvB
# so service.name can be used to identify the SrvA instance.
service.uuid_from_a = srva.uuid # read uuid data from SrvA
self.log.info('uuid_from_a: ', service.uuid_from_a)
05-18-2018 10:29 AM
Hi Larry
I tested this exact approach. But root.services.srvA{} does not contain the uncommitted data..
Looks like a bug.. Can you test it in your environment too and confirm?
Thanks
Kiran
05-18-2018 10:59 AM
Works fine, tested it before I posted it here.
When you say "root.services.srvA{} does not contain the uncommitted data" are you using that exact syntax? or are you using "root.services.srvA[<srvA instanceid>]" with the specific instance identifier for the SrvA instance created?
Simple stacked service create run:
admin@ncs% set services srvC test1 uuid-base 1000 uuid-mult 9
[ok][2018-05-18 13:50:19]
[edit]
admin@ncs% commit dry-run
cli {
local-node {
data services {
+ srvA test1 {
+ uuid-base 1000;
+ uuid-mult 9;
+ }
+ srvB test1 {
+ }
+ srvC test1 {
+ uuid-base 1000;
+ uuid-mult 9;
+ }
}
}
}
admin@ncs% show services srvA
srvA test1 {
uuid-base 1000;
uuid-mult 9;
}
[ok][2018-05-18 13:52:03]
[edit]
admin@ncs% run show services srvA
services srvA test1
uuid 9000
[ok][2018-05-18 13:52:06]
[edit]
admin@ncs% show services srvB
srvB test1;
[ok][2018-05-18 13:52:12]
[edit]
admin@ncs% run show services srvB
services srvB test1
uuid_from_a 9000
[ok][2018-05-18 13:52:18]
05-18-2018 11:07 AM
Here is the code that I use on the Subnet Service to search for a Network Service which has been provisioned(but un-committed). I use the network-name to search all entries and once found, copy the UUID:
To answer your question, I don't use the exact NetworkService identifier, but walk through all the entries in Network services.
Let me know if that can be a problem?
if found_network_id == False:
root = ncs.maagic.get_root(t)
self.log.info('Root',(dir(root)))
self.log.info('Services',dir(root.services.vts_network_v1))
netuuids = root.services.vts_network_v1__vts_network_v1
#with t.cursor('/ncs:services/vts-network-v1:vts-network-v1') as netuuids:
for eachuuid in netuuids:
self.log.info('each network uuid: ', eachuuid.name)
name = eachuuid.name #str(eachuuid).strip('{}')
self.log.info('Network name: ', name)
self.log.info('Network subnet.network_name: ', subnet.network_name)
if name == subnet.network_name:
self.log.info('found services network-id: ', name)
npath = '/ncs:services/vts-network-v1:vts-network-v1{name}/id'
net_id = t.get_elem(npath)
found_network_id = True
self.log.info('Network ID ', net_id)
vars.add('network-id', str(net_id).strip('{}'))
break
05-18-2018 11:33 AM
Kiran,
Generally speaking:
First of all this will be bad approach for scalability as the number of interfaces/uuid increases and you are looping through the entire, potentially large, list...
Secondly, from a NSO-specific implementation perspective, looping such as this should never be done within the service create code, since during this entire period the transaction lock will be held during this entire period. You want to minimized the processing done in the create code. It is better to gather all needed information prior to entering the service create code - invoking a Reactive Fastmap approach if needed.
Now to your code:
'root' is provided in the service create - why re-determine it here?
def cb_create(self, tctx, root, service, proplist):
Where does the 't' (transaction) variable get created? are you starting a second transaction within the create() transaction?
-Larry
05-18-2018 11:48 AM
You are correct. The mistake was I was creating another transaction(t) to access the data and was missing the data from the _create transaction.
Now that I removed the creation of new transaction, I can now access the uncommitted data.
Thanks for all the help!
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide