9632cdfbd331701dda5563f00108a47a5493a40b
[docs.git] / manuals / developer-guide / src / main / asciidoc / neutron / neutron.adoc
1 == Neutron Northbound
2
3 === How to Write a SB Neutron Consumer
4
5 In Lithium, there will be two options for SB Neutron Consumers:
6
7 * Using the legacy I*Aware interfaces
8 * Listening for changes via the Neutron YANG model
9
10 === How to use the legacy I*Aware interfaces
11
12 For each neutron data object, there is an I*Aware interface defined to allow
13 southbound providers that don't want to use the MD-SAL to register with the
14 Neutron service to be made aware of potential operations on that type of
15 object.  For each modification operation (create, update and delete), the
16 I*Aware interface defines a pair of calls (The general template
17 is shown in the following table, please see javadoc of the specific interface
18 for specific details)
19
20 .Table I*Aware Methods
21 |===
22 |Create |Update |Delete
23
24 |canCreate*()
25 |canUpdate*()
26 |canDelete*()
27
28 |neutron*Created()
29 |neutron*Updated()
30 |neutron*Deleted()
31 |===
32
33 ==== The semantics of the can*() methods
34
35 Each of the can*() methods gives a southbound provider a vote on whether a
36 proposed change is acceptable or not. A southbound provider that implements
37 a particular can*() method is expected to return an HTTP response code as
38 its "vote" - values between 200 and 299 are a "yes" vote, other values are
39 a "no" vote.  The neutron white board pattern is an all or nothing affair:
40 if any one southbound provider votes no on a change, that change is rejected.
41
42 For the canCreate*() method, the southbound provider recieves the proposed
43 object.  In the case of canDelete*(), the southbound provider recieves the
44 current object that will be removed.  Lastly, the canUpdate*() method passed
45 the current object and the proposed delta.
46
47 ==== The semantics of the neutron*() methods
48
49 Once all southbound providers vote yes for a particular change, the neutron
50 service transcribes the change into its caches/MD-SAL models and then calls
51 the appropriate neutron*() method on each registered southbound provider.
52 At this point, the southbound provider is expected to meet the request as
53 best they can and when they can, taking responsibility for any errors that
54 might be incurred (there is no back signalling of errors).  For these calls,
55 the modified object is provided in all cases, except for the neutron*Deleted()
56 method.  This passes an instance of the deleted object that will be garbage
57 collected once all the southbound providers are finished with it.
58
59 ==== How to register your consumer with the Neutron Service
60
61 A southbound provider that wants to register with the neutron service
62 via a particular I*Aware interface must first implement that interface.
63 Then, in the init class of its Activator method, it should add the name of
64 the implemented I*Aware class as an interface that is managed, along with
65 the class that implements the interface as the implementation via the
66 setInterface method.  The following example from the Neutron test dummy
67 provider shows it is registering for *all* I*Aware interfaces:
68
69 [source,java]
70 ----
71     @Override
72     public void init(BundleContext context, DependencyManager manager) throws Exception {
73        manager.add(createComponent().setInterface(new String[] {
74            INeutronFirewallAware.class.getName()}, null)
75            .setImplementation(NeutronFirewallDummyProvider.class));
76        manager.add(createComponent().setInterface(new String[] {
77            INeutronFirewallPolicyAware.class.getName()}, null)
78            .setImplementation(NeutronFirewallPolicyDummyProvider.class));
79        manager.add(createComponent().setInterface(new String[] {
80            INeutronFirewallRuleAware.class.getName()}, null)
81            .setImplementation(NeutronFirewallRuleDummyProvider.class));
82        manager.add(createComponent().setInterface(new String[] {
83            INeutronFloatingIPAware.class.getName()}, null)
84            .setImplementation(NeutronFloatingIPDummyProvider.class));
85        manager.add(createComponent().setInterface(new String[] {
86            INeutronLoadBalancerAware.class.getName()}, null)
87            .setImplementation(NeutronLoadBalancerDummyProvider.class));
88        manager.add(createComponent().setInterface(new String[] {
89            INeutronLoadBalancerHealthMonitorAware.class.getName()}, null)
90            .setImplementation(NeutronLoadBalancerHealthMonitorDummyProvider.class));
91        manager.add(createComponent().setInterface(new String[] {
92            INeutronLoadBalancerListenerAware.class.getName()}, null)
93            .setImplementation(NeutronLoadBalancerListenerDummyProvider.class));
94        manager.add(createComponent().setInterface(new String[] {
95            INeutronLoadBalancerPoolAware.class.getName()}, null)
96            .setImplementation(NeutronLoadBalancerPoolDummyProvider.class));
97        manager.add(createComponent().setInterface(new String[] {
98            INeutronLoadBalancerPoolMemberAware.class.getName()}, null)
99            .setImplementation(NeutronLoadBalancerPoolMemberDummyProvider.class));
100        manager.add(createComponent().setInterface(new String[] {
101            INeutronNetworkAware.class.getName()}, null)
102            .setImplementation(NeutronNetworkDummyProvider.class));
103        manager.add(createComponent().setInterface(new String[] {
104            INeutronPortAware.class.getName()}, null)
105            .setImplementation(NeutronPortDummyProvider.class));
106        manager.add(createComponent().setInterface(new String[] {
107            INeutronRouterAware.class.getName()}, null)
108            .setImplementation(NeutronRouterDummyProvider.class));
109        manager.add(createComponent().setInterface(new String[] {
110            INeutronSecurityGroupAware.class.getName()}, null)
111            .setImplementation(NeutronSecurityGroupDummyProvider.class));
112        manager.add(createComponent().setInterface(new String[] {
113            INeutronSecurityRuleAware.class.getName()}, null)
114            .setImplementation(NeutronSecurityRuleDummyProvider.class));
115        manager.add(createComponent().setInterface(new String[] {
116            INeutronSubnetAware.class.getName()}, null)
117            .setImplementation(NeutronSubnetDummyProvider.class));
118     }
119 ----
120
121 === How to use the Neutron YANG model
122
123 For each neutron data object, there is an Neutron*Interface defined within
124 the transcriber artifact that will write that object to the MD-SAL
125 configurational datastore. +
126 All Neutron*Interface extend AbstractNeutronInterface, in which two methods
127 are defined: +
128
129 * one takes the neutron object as input, and will create a data object from it. +
130 * one takes an uuid as input, and will create a data object containing the uuid.
131
132 ----
133 protected abstract T toMd(S neutronObject);
134 protected abstract T toMd(String uuid);
135 ----
136
137 In addition the AbstractNeutronInterface class provides several other
138 helper methods (addMd, updateMd, removeMd), which handle the actual
139 writing to the configuration datastore.
140
141 ==== The semantics of the toMD() methods
142 Each of the Neutron YANG models defines structures containing data.
143 Further each YANG-modeled structures has it own builder.
144 A particular toMD() method instantiates an instance of the correct
145 builder, fills in the properties of the builder from the corresponding
146 values of the Neutron object and then creates the YANG-modeled structures
147 via the build() method.
148
149 As an example, one of the toMD code for Neutron Networks is
150 presented below:
151
152 ----
153     protected Network toMd(NeutronNetwork network) {
154         NetworkBuilder networkBuilder = new NetworkBuilder();
155         networkBuilder.setAdminStateUp(network.getAdminStateUp());
156         if (network.getNetworkName() != null) {
157             networkBuilder.setName(network.getNetworkName());
158         }
159         if (network.getShared() != null) {
160             networkBuilder.setShared(network.getShared());
161         }
162         if (network.getStatus() != null) {
163             networkBuilder.setStatus(network.getStatus());
164         }
165         if (network.getSubnets() != null) {
166             List<Uuid> subnets = new ArrayList<Uuid>();
167             for( String subnet : network.getSubnets()) {
168                 subnets.add(toUuid(subnet));
169             }
170             networkBuilder.setSubnets(subnets);
171         }
172         if (network.getTenantID() != null) {
173             networkBuilder.setTenantId(toUuid(network.getTenantID()));
174         }
175         if (network.getNetworkUUID() != null) {
176             networkBuilder.setUuid(toUuid(network.getNetworkUUID()));
177         } else {
178             logger.warn("Attempting to write neutron network without UUID");
179         }
180         return networkBuilder.build();
181     }
182 ----