Re: [jclouds-site] Domain classes, better builders blog post. (#124)
[jclouds-site-pull-requests #393](https://jclouds.ci.cloudbees.com/job/jclouds-site-pull-requests/393/) SUCCESS This pull request looks good --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54453827
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
to review your changes. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54454032
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Reopened #124. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#event-161122494
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
[jclouds-site-pull-requests #394](https://jclouds.ci.cloudbees.com/job/jclouds-site-pull-requests/394/) SUCCESS This pull request looks good --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54454709
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
to review your changes. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54454813
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Closed #124. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#event-161132054
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Reopened #124. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#event-161132059
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Go to http://306ae818722ae6b78b92-2e69301a260e5804fbad8c2752c99931.r57.cf5.rackcdn.com/ to review your changes. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54458152
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Alright, problems with the PR build script seem fixed now. This also seems good to merge. Should I merge it? Is there anything else that needs to be done? The front page has a link to the blog I think. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54461023
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Merge and publish! --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54484345
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
merged --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54491307
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Website deployed. It seems to not be completely broken so far. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54493351
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Closed #124. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#event-161253336
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
+host: % +}, +{ +databases: [ +{ +name: sampledb +} +], +host: %, +name: demouser +} +] +} +{% endhighlight %} + +To parse the response, jclouds uses [domain classes](https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/domain/User.java) to represent the JSON data returned by the service. The array of users is unwrapped into individual User domain objects. Conversely, when creating users, domain objects are transformed into a JSON request body. [minor] `User` instead of User? --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124/files#r17126220
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
+{ +databases: [ +{ +name: sampledb +} +], +host: %, +name: demouser +} +] +} +{% endhighlight %} + +To parse the response, jclouds uses [domain classes](https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/domain/User.java) to represent the JSON data returned by the service. The array of users is unwrapped into individual User domain objects. Conversely, when creating users, domain objects are transformed into a JSON request body. + +Because of the relative simplicity of user creation in trove, jclouds developers can use a create method in the features package without having to build an instance of the User class. For example, the developer might use a method such as [minor] Trove? And `User` again? --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124/files#r17126236
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
+} +] +} +{% endhighlight %} + +To parse the response, jclouds uses [domain classes](https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/domain/User.java) to represent the JSON data returned by the service. The array of users is unwrapped into individual User domain objects. Conversely, when creating users, domain objects are transformed into a JSON request body. + +Because of the relative simplicity of user creation in trove, jclouds developers can use a create method in the features package without having to build an instance of the User class. For example, the developer might use a method such as + +{% highlight Java %} +boolean create(String userName, String password, String databaseName); +{% endhighlight %} + +In this case, it was easy to add support for this call by using a [map binder](https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/binders/BindCreateUserToJson.java). + +However, some APIs send or receive significantly more complex JSON structures. Recent work on Neutron has shown that there are benefits to increased consistency among the domain classes and the OpenStack API calls that use them. [minor] Add link to Neutron? Extra PR for the API ;-) --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124/files#r17126250
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
+ +To parse the response, jclouds uses [domain classes](https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/domain/User.java) to represent the JSON data returned by the service. The array of users is unwrapped into individual User domain objects. Conversely, when creating users, domain objects are transformed into a JSON request body. + +Because of the relative simplicity of user creation in trove, jclouds developers can use a create method in the features package without having to build an instance of the User class. For example, the developer might use a method such as + +{% highlight Java %} +boolean create(String userName, String password, String databaseName); +{% endhighlight %} + +In this case, it was easy to add support for this call by using a [map binder](https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/binders/BindCreateUserToJson.java). + +However, some APIs send or receive significantly more complex JSON structures. Recent work on Neutron has shown that there are benefits to increased consistency among the domain classes and the OpenStack API calls that use them. + +Current implementations have the following two issues : + +1. Heavy use of map-binders and parsers to transform JSON. Map-binders use annotation-selected classes to map method data (such as the data in the create-user call above) to the JSON required by the service. The [parsers](https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/functions/ParseNetworkDetails.java) apply the reverse transformation: from JSON to domain objects. [minor] Too many spaces between use and annotation-selected --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124/files#r17126267
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
+Current implementations have the following two issues : + +1. Heavy use of map-binders and parsers to transform JSON. Map-binders use annotation-selected classes to map method data (such as the data in the create-user call above) to the JSON required by the service. The [parsers](https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/functions/ParseNetworkDetails.java) apply the reverse transformation: from JSON to domain objects. +2. Lack of consistent, concise, and user-friendly way to use domain objects in create/update/list methods. + +In addition to fixing these issues, jclouds wants to provide developers with some compiler checks and other syntactic sugar (fluent builders), while also supporting different updating, creating, or listing validation strategies. + +We want to + +1. Ensure object immutability. +2. Utilize the fluent builder pattern. +3. Ensure that create objects can only be used for create; update for update; and listed resources cannot be directly sent back to the service. +4. Reuse code and keep domain classes [DRY](http://en.wikipedia.org/wiki/Don't_repeat_yourself). +5. Allow using different validation strategies (for example, create vs update). + +We have been able to identify a pattern that addresses these issues. Here is some [sample code](https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Router.java). Include the relevant snippet of the sample code here? Or is it too long? --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124/files#r17126300
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
+1. Heavy use of map-binders and parsers to transform JSON. Map-binders use annotation-selected classes to map method data (such as the data in the create-user call above) to the JSON required by the service. The [parsers](https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/functions/ParseNetworkDetails.java) apply the reverse transformation: from JSON to domain objects. +2. Lack of consistent, concise, and user-friendly way to use domain objects in create/update/list methods. + +In addition to fixing these issues, jclouds wants to provide developers with some compiler checks and other syntactic sugar (fluent builders), while also supporting different updating, creating, or listing validation strategies. + +We want to + +1. Ensure object immutability. +2. Utilize the fluent builder pattern. +3. Ensure that create objects can only be used for create; update for update; and listed resources cannot be directly sent back to the service. +4. Reuse code and keep domain classes [DRY](http://en.wikipedia.org/wiki/Don't_repeat_yourself). +5. Allow using different validation strategies (for example, create vs update). + +We have been able to identify a pattern that addresses these issues. Here is some [sample code](https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Router.java). + +This approach reuses code by having [GSON](https://code.google.com/p/google-gson/) handle the domain objects directly, as much as possible, both for serialization and deserialization, thus eliminating map-binders and parsers in most cases. The domain classes annotate their member variables using the @Named (for serialization) and @ConstructorProperties (for deserialization) annotations. [minor] I think they refer to it as Gson? --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124/files#r17126331
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
+ +In addition to fixing these issues, jclouds wants to provide developers with some compiler checks and other syntactic sugar (fluent builders), while also supporting different updating, creating, or listing validation strategies. + +We want to + +1. Ensure object immutability. +2. Utilize the fluent builder pattern. +3. Ensure that create objects can only be used for create; update for update; and listed resources cannot be directly sent back to the service. +4. Reuse code and keep domain classes [DRY](http://en.wikipedia.org/wiki/Don't_repeat_yourself). +5. Allow using different validation strategies (for example, create vs update). + +We have been able to identify a pattern that addresses these issues. Here is some [sample code](https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Router.java). + +This approach reuses code by having [GSON](https://code.google.com/p/google-gson/) handle the domain objects directly, as much as possible, both for serialization and deserialization, thus eliminating map-binders and parsers in most cases. The domain classes annotate their member variables using the @Named (for serialization) and @ConstructorProperties (for deserialization) annotations. + +Many of the JSON attributes in Neutron are optional. GSON's jclouds configuration supports such optional values by using @Nullable and boxed types. An alternate supported method, more convoluted, implements OptionalT private member variables and getter return types. Code font for `@Nullable` and `OptionalT`? --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124/files#r17126365
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
+ +We want to + +1. Ensure object immutability. +2. Utilize the fluent builder pattern. +3. Ensure that create objects can only be used for create; update for update; and listed resources cannot be directly sent back to the service. +4. Reuse code and keep domain classes [DRY](http://en.wikipedia.org/wiki/Don't_repeat_yourself). +5. Allow using different validation strategies (for example, create vs update). + +We have been able to identify a pattern that addresses these issues. Here is some [sample code](https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Router.java). + +This approach reuses code by having [GSON](https://code.google.com/p/google-gson/) handle the domain objects directly, as much as possible, both for serialization and deserialization, thus eliminating map-binders and parsers in most cases. The domain classes annotate their member variables using the @Named (for serialization) and @ConstructorProperties (for deserialization) annotations. + +Many of the JSON attributes in Neutron are optional. GSON's jclouds configuration supports such optional values by using @Nullable and boxed types. An alternate supported method, more convoluted, implements OptionalT private member variables and getter return types. + +To ensure immutability, users have no access to a constructor or setters, and instead they must instantiate domain objects by using a slightly modified Builder pattern. The builder pattern also provides proper validation and user-friendliness. [minor] lowercase builder? --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124/files#r17126377
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
+Some [simpler classes](https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java) implement the regular fluent builder pattern. + +In [other cases](https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/NetworkApi.java), the same domain class has several different purposes, such as making sure users have different Network-subtype object instances for updating, creating, and listing networks: + +1. Listing networks returns a Network or a list of Networks. +2. Updating a network requires Network.UpdateOptions. +3. Creating a network requires Network.CreateOptions. + +CreateOptions and UpdateOptions extend Network and implement their own copy constructors, with custom validation, if needed. + +To instantiate these create or update-specific objects, developers have access to CreateBuilder and UpdateBuilder, which both extend the regular Network builder abstract class. The only code these special builders implement: the constructor (taking as parameters any required properties), a build() method returning the create or update object, and also self(). The self method is needed to make sure we can reuse most of the Builder code, but still be able to chain the fluent builder methods. + +This is how it all works out from the developer's perspective: + +{% highlight Java %} +Network.CreateOptions createNetwork = Network.createOptions(jclouds-wibble) Interesting example: here, the domain object subtypes are pretty visible. Is that the intention? Or so you see people calling the API call directly, without creating this intervening object and (thus) exposing this subtype? --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124/files#r17126468
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
+In this case, it was easy to add support for this call by using a [map binder](https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/binders/BindCreateUserToJson.java). + +However, some APIs send or receive significantly more complex JSON structures. Recent work on Neutron has shown that there are benefits to increased consistency among the domain classes and the OpenStack API calls that use them. + +Current implementations have the following two issues : + +1. Heavy use of map-binders and parsers to transform JSON. Map-binders use annotation-selected classes to map method data (such as the data in the create-user call above) to the JSON required by the service. The [parsers](https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/functions/ParseNetworkDetails.java) apply the reverse transformation: from JSON to domain objects. +2. Lack of consistent, concise, and user-friendly way to use domain objects in create/update/list methods. + +In addition to fixing these issues, jclouds wants to provide developers with some compiler checks and other syntactic sugar (fluent builders), while also supporting different updating, creating, or listing validation strategies. + +We want to + +1. Ensure object immutability. +2. Utilize the fluent builder pattern. +3. Ensure that create objects can only be used for create; update for update; and listed resources cannot be directly sent back to the service. This seems to be the most important part in terms of why we need CreateOptions/CreateRequest/whatever. Would it make sense to illustrate what the problem is here by extending the code sample below? --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124/files#r17126556
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Thanks, @zack-shoylev! Great to see more posts on the blog. Just a bunch of minor comments, many of them around code font (or not) for things like classes. I have no strong preference either way, but it would be good to be consistent with other blog posts... --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54508957
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Already deployed it :) but will consider adding some more to illustrate the create for create example. About fonts: I don't like using that much outside code blocks, but I see what you are saying with regards to consistency. Hmm. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54509614
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Already deployed it :) I noticed...but we can always apply a little edit here and there if we think that's merited ;-) --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54546199
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
to review your changes. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54330496
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
[jclouds-site-pull-requests #390](https://jclouds.ci.cloudbees.com/job/jclouds-site-pull-requests/390/) SUCCESS This pull request looks good --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54330214
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Reopened #124. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#event-160752549
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Closed #124. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#event-160752544
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
[jclouds-site-pull-requests #391](https://jclouds.ci.cloudbees.com/job/jclouds-site-pull-requests/391/) SUCCESS This pull request looks good --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54346770
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
to review your changes. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54346972
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
Reopened #124. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#event-160761654
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
[jclouds-site-pull-requests #392](https://jclouds.ci.cloudbees.com/job/jclouds-site-pull-requests/392/) SUCCESS This pull request looks good --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124#issuecomment-54349279
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
@@ -0,0 +1,119 @@ +--- +author: Zack Shoylev +comments: true +date: 2014-09-03 23:00:00+00:00 +layout: post +slug: better-builders-with-jclouds +title: Better Builders with jclouds! +--- + +# Better Builders with jclouds No need to repeat the title here. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124/files#r17072721
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
@@ -0,0 +1,119 @@ +--- +author: Zack Shoylev +comments: true +date: 2014-09-03 23:00:00+00:00 +layout: post +slug: better-builders-with-jclouds +title: Better Builders with jclouds! +--- + +# Better Builders with jclouds + +If you are a new [jclouds](https://developer.rackspace.com/sdks/java/) developer, or even if you are already developing jclouds support for any of the OpenStack or Rackspace APIs, you have likely seen the domain classes that are used throughout the the jclouds codebase. +These classes are used to represent OpenStack resources, particularly the JSON structures supported by OpenStack APIs. + Add a `!--more--` between these paragraphs. --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124/files#r17072775
Re: [jclouds-site] Domain classes, better builders blog post. (#124)
+name: sampledb +} +], +host: %, +name: demouser +} +] +} +{% endhighlight %} + +To parse the response, jclouds uses [domain classes](https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/domain/User.java) to represent the JSON data returned by the service. The array of users is unwrapped into individual User domain objects. Conversely, when creating users, domain objects are transformed into a JSON request body. + +Because of the relative simplicity of user creation in trove, jclouds developers can use a create method in the features package without having to build an instance of the User class. For example, the developer might use a method such as + +{% highlight Java %} +boolean create(String userName, String password, String databaseName); remove one space before String databaseName --- Reply to this email directly or view it on GitHub: https://github.com/jclouds/jclouds-site/pull/124/files#r17074065