Skip to content

Commit f892461

Browse files
inocybe-jenkinsGerrit Code Review
authored andcommitted
Merge "Core Developer's Guide"
2 parents d2840c0 + ae7b5a1 commit f892461

40 files changed

+2090
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
== API design principles and patterns contributed by southbound plugins
2+
3+
This section is intended to define common design patterns supporting extensions contributed by southbound plugins, which could be used in the SAL or or used in modelling any abstract extensible APIs.
4+
5+
NOTE: Wire protocol specific information (serialization, serialization constants , TLV identifiers, bit masks, field ordering) should not be part of the SAL. Also, APIs (interfaces, classes) should support extensibility using subclassing or other extension patterns. This allows for abstract APIs and also for concrete APIs to coexist in the SAL and to use common infrastructure.
6+
7+
=== Extensible enumeration pattern
8+
9+
This pattern is suitable for modelling or defining APIs for the enumeration of immutable data or types, which for example could represent ether type, protocol type, and others. The workflow for API definition is simple:
10+
11+
. Define a simple interface with the needed functionality.
12+
13+
. Declare an enum implementing the interface where the enum constants represent the known values.
14+
15+
. (optional) Include a factory method mapping from names to objects implementing the interface.
16+
17+
For more information, see the following links:
18+
19+
** http://jtechies.blogspot.com/2012/07/item-34-emulate-extensible-enums-with.html
20+
21+
** http://blogs.oracle.com/darcy/entry/enums_and_mixins
22+
23+
=== Type-value pairs pattern
24+
25+
This pattern is suitable for modelling or defining APIs for extensible set of fields, where the values could be of different types. The requirements for type-value pairs are: Extensible and Type safety.
26+
27+
==== Common antipatterns
28+
29+
This pattern is to replace the following constructs:
30+
31+
32+
* Simple untyped approach to properties (pros: extensible, cons: does not provide semantics and type safety):
33+
34+
[literal]
35+
// Ommited for clarity...
36+
HashMap<String,Object> properties;
37+
38+
39+
* More refined approach using the enumeration to define a set of supported field types (pros: provides semantics, cons: not extensible).
40+
41+
[literal]
42+
enum Type {
43+
TYPE1(String.class),
44+
TYPE2(Boolean.class),
45+
private Class<?> valueType; // This line is optional.
46+
// ommited for clarity...
47+
}
48+
class Field {
49+
Type type;
50+
Object value;
51+
// ommited for clarity...
52+
}
53+
54+
55+
=== Actual pattern
56+
57+
We can model this by using the abstract class and the generics to define value type and set of subclasses representing various types of fields. The instances of this class represents actual type-value pair, where class represents type and value is represented by object in the instance.
58+
59+
[literal]
60+
abstract class Field<V> {
61+
private V value;
62+
public Field(V value) {
63+
this.value = value;
64+
}
65+
...
66+
}
67+
class Type1Field extends Field<String> {
68+
public Type1Field(String value){super(value);}
69+
}
70+
class Type2Field extends Field<Boolean> {
71+
public Type2Field(Boolean value){super(value);}
72+
}
73+
74+
The abstract class does not have to only define fields or values, but could also define additional methods (concrete or abstract) which could provide additional semantic about the field type. This example shows only one value field, but it is possible to have multiple fields. It is possible to model common part of API also as an interface and leave all the implementation to the super types. Map, which should store one instance of the field is: Map<Class<? extends Field<?>>,Field<?>>. It is possible to provide simpler facade on top of this map.
75+
76+
=== Extension interface pattern
77+
78+
The following Java design allows an object to be extended without changing its interface to clients. The object can implement additional extension interfaces. Clients can ask the object for extension interfaces that it implements.
79+
80+
81+
In the interface present in the SAL models general approach or abstraction, the client code (applications) could ask for extension interface (which could be used to model protocol specific functionality, interfaces, data) by querying for the extension. Extension is identified by Java interface (the client code using extension must be compiled against this interface).
82+
83+
84+
This pattern could be also used as an replacement for the field pattern. We have defined a set of fields provided by extension as separate class or interface, the values could be queried by using the extension class.
85+
The strong point of this pattern is that the client code needs to be aware of the extension and its contract (be compiled against the base interface and also extension) in order to use the extension. The code which was not compiled against extension is not affected by introducing new extensions.
86+
87+
*Synopsis: Original pattern*
88+
89+
[literal]
90+
public interface A {
91+
// Ommited for clarity...
92+
<T> T getExtension(Class<T> extensionType)
93+
}
94+
95+
*Synopsis: Updated pattern*
96+
[literal]
97+
public interface Extensible<P> {
98+
// Ommited for clarity...
99+
<T extends Extension<P>> T getExtension(Class<T> extensionType)
100+
}
101+
public interface Extension<T> {
102+
}
103+
104+
Where:
105+
106+
* Extensible is interface which is to be implemented by classes which provides extension support
107+
108+
* P - generic argument, usually interface / class which implements
109+
110+
* Extension is marker interface (for type-safety reasons) which marks interfaces / classes which are extensions
111+
112+
* T - generic argument, pointing to the class / interface to which this extension is associated.
113+
114+
=== Usage example
115+
116+
[literal]
117+
ublic class Node extends Extensible<Node> {
118+
// contents ommited
119+
// the instatiated version of extension interface isExtension method is
120+
@Override
121+
<T extends Extension<Node> T getExtension(Class<T> extensionType) {
122+
// contents ommited
123+
}
124+
}
125+
public class OpenflowNode extends Extension<Node> {
126+
// contents ommited
127+
}
128+
Node node = provider.getNode(); // sample call returning node
129+
OpenflowNode ofNode = node.getExtension(OpenflowNode.class);
130+
if(ofNode != null) {
131+
// do openflow specific stuff
132+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
== OpenDaylight controller library descriptions
2+
3+
Shared functions and methods are compiled and bundled into libraries. This page describes client libraries.
4+
5+
=== C client library
6+
7+
The C module generates the source code for the ANSI-C-compatible data structures and (de)serialization functions that can be used in conjunction with http://xmlsoft.org/[libxml2] to (de)serialize the REST resources as they are represented as XML data.
8+
9+
10+
The generated C source code depends on the http://xmlsoft.org/html/libxml-xmlreader.html[XML Reader API] and the http://xmlsoft.org/html/libxml-xmlwriter.html[XML Writer API] as well as the <time.h>, <string.h>, and <stdlib.h> C standard libraries.
11+
12+
13+
=== REST XML example
14+
15+
[literal]
16+
#include <full.c>
17+
//...
18+
xmlTextReaderPtr reader = ...; //set up the reader to the url.
19+
full_ns0_edgeProps *response_element = ...;
20+
response_element = xml_read_full_ns0_edgeProps(reader);
21+
//handle the response as needed...
22+
//free the full_ns0_edgeProps
23+
free_full_ns0_edgeProps(response_element);
24+
25+
26+
=== .NET client library
27+
28+
The .NET client-side library defines the classes that can be (de)serialized to/from XML. This is useful for accessing the REST endpoints that are published by this application.
29+
30+
==== REST example
31+
32+
[literal]
33+
//read a resource from a REST url
34+
Uri uri = new Uri(...);
35+
XmlSerializer s = new XmlSerializer(
36+
typeof( EdgeProps )
37+
);
38+
//Create the request object
39+
WebRequest req = WebRequest.Create(uri);
40+
WebResponse resp = req.GetResponse();
41+
Stream stream = resp.GetResponseStream();
42+
TextReader r = new StreamReader( stream );
43+
EdgeProps order = (EdgeProps) s.Deserialize( r );
44+
//handle the result as needed...
45+
46+
This bundle contains C# source code.
47+
48+
=== Java client library
49+
50+
The Java client-side library is used to access the Web service API for this application.
51+
The JAX-WS client-side library is used to provide the set of Java objects that can be serialized to/from XML using https://jaxb.dev.java.net/[JAXB]. This is useful for accessing the REST endpoints that are published by this application.
52+
53+
54+
==== REST example (Raw JAXB)
55+
56+
[literal]
57+
java.net.URL url = new java.net.URL(baseURL + "/{containerName}");
58+
JAXBContext context = JAXBContext.newInstance( EdgeProps.class );
59+
java.net.URLConnection connection = url.openConnection();
60+
connection.connect();
61+
Unmarshaller unmarshaller = context.createUnmarshaller();
62+
EdgeProps result = (EdgeProps) unmarshaller.unmarshal( connection.getInputStream() );
63+
//handle the result as needed...
64+
65+
66+
==== REST example (Jersey client)
67+
68+
[literal]
69+
</nowiki>
70+
com.sun.jersey.api.client.Client client = com.sun.jersey.api.client.Client.create();
71+
EdgeProps result = client.resource(baseUrl + "/{containerName}")
72+
.get(EdgeProps.class);
73+
//handle the result as needed...
74+
</nowiki>
75+
76+
=== Java JSON client library
77+
78+
The Java client-side library is used to provide the set of Java objects that can be serialized to/from JSON using Jackson. This is useful for accessing the JSON REST endpoints that are published by this application.
79+
80+
==== REST example (Raw Jackson)
81+
82+
83+
[literal]
84+
java.net.URL url = new java.net.URL(baseURL + "/{containerName}");
85+
ObjectMapper mapper = new ObjectMapper();
86+
java.net.URLConnection connection = url.openConnection();
87+
connection.connect();
88+
EdgeProps result = (EdgeProps) mapper.readValue( connection.getInputStream(), EdgeProps.class );
89+
//handle the result as needed...
90+
91+
92+
=== Objective C Client library
93+
94+
The Objective C module generates the source code for the Objective C classes and (de)serialization functions that can be used in conjunction with http://xmlsoft.org/[libxml2] to (de)serialize the REST resources as they are represented as XML data.
95+
96+
97+
The generated Objective C source code depends on the http://xmlsoft.org/html/libxml-xmlreader.html[XML Reader API] and the http://xmlsoft.org/html/libxml-xmlwriter.html[XML Writer API] as well as the base OpenStep foundation classes.
98+
99+
==== REST XML example
100+
101+
[literal]
102+
#import <full.h>
103+
//...
104+
FULLNS0EdgeProps *responseElement;
105+
NSData *responseData; //data holding the XML from the response.
106+
NSURL *baseURL = ...; //the base url including the host and subpath.
107+
NSURL *url = [NSURL URLWithString: @"/{containerName}" relativeToURL: baseURL];
108+
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
109+
NSURLResponse *response = nil;
110+
NSError *error = NULL;
111+
[request setHTTPMethod: @"GET"];
112+
//this example uses a synchronous request,
113+
//but you'll probably want to use an asynchronous call
114+
responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
115+
FULLNS0EdgeProps *responseElement = [FULLNS0EdgeProps readFromXML: responseData];
116+
[responseElement retain];
117+
//handle the response as needed...
118+
119+
120+
121+
122+
123+

0 commit comments

Comments
 (0)