cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1307
Views
0
Helpful
11
Replies

Access uncommitted service data in python

koushik331
Level 1
Level 1

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

1 Accepted Solution

Accepted Solutions

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

View solution in original post

11 Replies 11

koushik331
Level 1
Level 1

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?

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

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

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

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?

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)

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

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]

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

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

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!