3 === How to Write a SB Neutron Consumer
5 In Lithium, there will be two options for SB Neutron Consumers:
7 * Using the legacy I*Aware interfaces
8 * Listening for changes via the Neutron YANG model
10 === How to use the legacy I*Aware interfaces
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
20 .Table I*Aware Methods
22 |Create |Update |Delete
33 ==== The semantics of the can*() methods
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.
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.
47 ==== The semantics of the neutron*() methods
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.
59 ==== How to register your consumer with the Neutron Service
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:
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));
121 === How to use the Neutron YANG model
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
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.
133 protected abstract T toMd(S neutronObject);
134 protected abstract T toMd(String uuid);
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.
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.
149 As an example, one of the toMD code for Neutron Networks is
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());
159 if (network.getShared() != null) {
160 networkBuilder.setShared(network.getShared());
162 if (network.getStatus() != null) {
163 networkBuilder.setStatus(network.getStatus());
165 if (network.getSubnets() != null) {
166 List<Uuid> subnets = new ArrayList<Uuid>();
167 for( String subnet : network.getSubnets()) {
168 subnets.add(toUuid(subnet));
170 networkBuilder.setSubnets(subnets);
172 if (network.getTenantID() != null) {
173 networkBuilder.setTenantId(toUuid(network.getTenantID()));
175 if (network.getNetworkUUID() != null) {
176 networkBuilder.setUuid(toUuid(network.getNetworkUUID()));
178 logger.warn("Attempting to write neutron network without UUID");
180 return networkBuilder.build();