Owner Keys and Consumer UUIDs
by Devan Goodwin
Began the process of switching to use owner keys in the owner resource
URLs and got to thinking, instead of making two entities behave
differently (in having both a numeric database ID + a possibly
externally generated string ID), why don't we make consumer URLs use
the objects ID instead of UUID.
All our resources would then behave almost identically. This would
cleanup a problem I mailed about last week related to HATEOAS ID
serialization. The consumer UUID and owner key would still remain in
the database and JSON, just not be used as the "ID" as far as our REST
API is concerned.
The only downside I can think of is clients (which store the UUID
locally) would now have to do an initial call to lookup their consumer
ID, but this could easily be done by a client library transparently,
and could be cached if desired. Additionally if we're going down the
HATEOAS path, the impact on integrating apps and clients should be
minimal as hopefully, they won't need to be assuming URL paths.
Thoughts?
Cheers,
Devan
--
Devan Goodwin <dgoodwin(a)rm-rf.ca>
http://rm-rf.ca
13 years, 7 months
HATEOAS Patch
by Devan Goodwin
Attached is a work in progress patch for HATEOAS support.
In terms of what it does, I think it's exactly what we want. We have
one custom serializer which we register for all our linkable types.
This serializer can check the context it's in. If serializing a root
object, we want to just proceed with normal serialization. (more on
this later) If serializing within another object, we want to manually
output our JSON with just an 'href'. Not added yet but we'll do
exactly the same if within a collection, and there is a context for
this as well.
As far as making it happen it got a little messy. I had to dig way
into Jackson internals and the end result was creation of our own
SerializerProvider and SerializerFactory sub-classes. These are both
configured on the ObjectMapper, and then once in the serializer it
assumes the provider configured is our's and casts it. (if you tried
to use our custom serializer in an object mapper that didn't use our
serializer provider and factory, this would error out fast, but not a
problem generally as far as I've seen) Worst of all, there is a 30-odd
line method copied in our SerializerFactory that comes straight from
it's grandparent class in Jackson.
All of the above is done so we can register customer serializer, and
then within that serializer, have a method call available to us which
circumvents the custom serializers registered and just moves on to use
the default. (thus preventing infinite recursion with our serializer)
I tried everything I could come up with to manually create the default
object serializer but it's a BeanSerailizer in Jackson and it's
creation is non-trivial.
So while this code doesn't thrill me, it's isolated and not something
that can spread throughout the code base, and the end result JSON
appears to be spot on for what we want. If in the future it were to
become unmaintainable or break, we could work out another solution, or
do custom serializers for all our objects, and just keep the JSON
consistent. As such I think it's worth proceeding with this, provided
there are no hidden gremlins.
Still to do:
- Possibly serialize ID along with href. (watch out for consumer.uuid
and soon, owner.key.)
- Linkify collections. (just need to check for context in CandlepinSerializer)
- Expand to more model classes. (certs, subscriptions, possibly a couple others)
- Add top level links to resources.
- Fix *everything*, cuke/rspec, RHSM, etc.
Still a bit of work to be done to finish it off, particularly in the
last step. This patch has been pushed to the hateros2 branch.
There is possibility here for a patch submission to Jackson I think.
This solution isn't it, but I think a new annotation that would
automagically do most of the above might be.
Cheers,
Devan
--
Devan Goodwin <dgoodwin(a)rm-rf.ca>
http://rm-rf.ca
13 years, 7 months
Randomness in Testing
by Justin Harris
All,
I have seen some use of random number/name generation used in tests
recently and want to discuss it further here. I am
going to go out on a limb and give the opinion that this is not a good
thing, and sets a
bad precedent. I think that the real value of tests is that they are an
easily repeatable, consistent assessment of where
the code is at a certain point in time. Tests really start to lose their
value when two runs of the same test on the same
code base can result in two different outcomes. I know that for things
like name generation this probably won't happen,
but as I said it is starting down a slippery slope, and IMHO we should
avoid it if possible.
Note that there is nothing wrong with *arbitrary* values, or values
determined at random and hard coded into tests - let's
just be sure that they are the same on subsequent runs of the same test.
Thoughts?
- Justin
13 years, 7 months
Re: HATEOAS Patch
by Justin Harris
----- "Devan Goodwin" <dgoodwin(a)rm-rf.ca> wrote:
> On Wed, Aug 18, 2010 at 9:57 AM, Devan Goodwin <dgoodwin(a)rm-rf.ca>
> wrote:
> > Still to do:
> > - Possibly serialize ID along with href. (watch out for
> consumer.uuid
> > and soon, owner.key.)
>
> Do we want this HATEOAS form of an object to contain "id" and "href"
> both? My concern with the ID is that if you serialize a consumer, you
> have an "id" which is a numeric database ID, but the "uuid" is the
> actual ID we use in all URLs. It seems all kinds of wrong to return
> "id" = "uuid" when the HATEOAS serialization kicks in, and then "id"
> =
> int when you follow that link.
>
> Perhaps consumer.id needs to go away?
Yeah this is a good point - if consumer uuid truly is unique, then it seems
to me that it is an appropriate primary key in the db as well.
>
> We were talking about making owner.key the URL identifier for owners
> as well, should that also become owner.id and behave just like
> consumer UUIDs?
+1 for this as well. But in both of these scenarios I think that it will involve
a little more error messaging with the client, because in both of these scenarios the
client can provide the primary key, which can easily mean collisions. Not a big deal to
handle, but it does mean that the client should be able to display an error message saying
that the provided (uuid/key) is in use and a different one should be provided.
>
>
> --
> Devan Goodwin <dgoodwin(a)rm-rf.ca>
> http://rm-rf.ca
> _______________________________________________
> candlepin mailing list
> candlepin(a)lists.fedorahosted.org
> https://fedorahosted.org/mailman/listinfo/candlepin
13 years, 8 months
Re: HATEOAS Patch
by Justin Harris
----- "Bryan Kearney" <bkearney(a)redhat.com> wrote:
> On 08/18/2010 11:21 AM, James Bowes wrote:
> > On Wed, Aug 18, 2010 at 11:18:12AM -0400, Jesus M. Rodriguez wrote:
> >> -----BEGIN PGP SIGNED MESSAGE-----
> >> Hash: SHA1
> >>
> >> On 08/18/2010 09:56 AM, Justin Harris wrote:
> >>> Maybe we established this a while back, but does this mean that
> JSON is our
> >>> only supported format?
> >>
> >> I thought that was the case when we changed to jackson.
> >
> > jackson still uses the same xml annotations, so technically they
> both
> > work. though i doubt anyone has confirmed that in a while.
> >
>
> Sorry.. Justin.. any issues with this?
No issues from me. I just wanted to throw it out there in case anyone was
under a different impression. It seems that a most of our resources indicate
that they support xml as well (in @Produces and @Consumes annotations) - so at
a minimum we should probably clean those up if we really are dropping xml.
>
> -- bk
>
> _______________________________________________
> candlepin mailing list
> candlepin(a)lists.fedorahosted.org
> https://fedorahosted.org/mailman/listinfo/candlepin
13 years, 8 months