Hello Guys,

This is another update to the proof of concept, and today we are doing big improvements to cover other parts of the representation that we did not cover yet: fetching data from Hawkular, and turning that into entities/views.

First, let's look at fetching data from Hawkular's Inventory:

# Create Client
client = Hawkular::Client.new(
  entrypoint: 'http://localhost:8080',
  credentials: { username: 'jdoe', password: 'password' },
  options: { tenant: 'hawkular' }
)

# Get all feeds available on the server
feeds = client.inventory.list_feeds

# Get all resources
feeds.map do |feed|
 # We get the resources for the feed
 resources = client.inventory.list_resources_for_feed(feed, true)
 # Then we make them presentable
 HawkularResourceCollection.new(resources).prepare
end
The first new thing here is HawkularResourceCollection, which does the following:

Gets the raw representation of the properties defined by Hawkular
This is necessary because we want to use everything the server gives us, not only what the gem decides to expose.
Creates the entities by mapping the data (we will cover that soon).
Merge other resource properties for the servers.
This last step is a little more complicated: there are two kinds of resources that we get from the inventory: servers (like WildFly Servers) and what I call resources: java runtime, operating systems, and so on. We need some properties on the server that are exposed from the runtime/os, like immutability controls, so we merge those to all the servers on the feed.

To map the data to the entities, we use EntityMapper, a class that does exactly this mapping. Besides that, it does name transformation for properties, feed extracting, unescaping of paths, and returning a hash. When we need to persist anything, this is the data that we generate for the field, so persisting and fetching data from the db can looks like this:

# Getting data from the db, raw_hash being our json field to save the response
server = MiddlewareServer.last
entity = Entity.constantize(server.raw_hash)

# And persisting an entity to the db
server.update(raw_hash: entity.data)
The generated hash is then fed to Entity.constantize, which returns the entities we will use to render.

So, we have the data, and we have the entities. I have a standalone setup running, generated by hawkinit, and the response contains the following:

A WildFly Server
The Java Runtime
The Operating System
Which will use the following entities/views to render (refer to old emails/README.md for more on this):




Well, that's it. If you download the code at the github repo, you can see this in action, by just running the server and visiting ./ It will list everything hawkular found running, in pretty pretty json using the defined views.

On Wed, Jul 19, 2017 at 12:59 PM, Caina Costa <cacosta@redhat.com> wrote:
So, an update:

I implemented support of json and yaml schemas to generate views dynamically. A schema looks like this:

{
        "summary": [
                {"name": "id"},
                {"name": "active", "alias": "is_active"},
                {"name": "full_name", "alias": "name"}
        ],
        "foo": {"name": "foo"}
}

Which is functionally equivalent (it actually generates a view dynamically with the same ruby code) to this:

pane :summary do
  field :id
  field :active, :is_active
  field :full_name, :mario
end

field :foo

And this is how it could be used to generate the views from data:

render json: View.from_json(unparsed_json).new(entity)
render json: View.from_yaml(unparsed_yaml).new(entity)
render json: View.from_hash(data_as_hash).new(entity)

Since those methods generate classes, they can be used to inherit new views, or even doing something like this:

class EAPServerView < View.from_json(:code_to_get_from_hawkular)
end

Also, another important thing is that methods defined inside a view are used for the rendering, so attribute transformation can done in the view, instead of the entity if necessary, like this:

entity = OpenStruct.new(foo: :bar)
class MyView < View
  field :foo

  def foo
    :baz
  end
end

Then rendering it would return something like { "foo": "baz" }.

The changes are available on the same repo as always: github.com/cfcosta/dynamic-entity-poc , and you can find examples on how this work on view_spec.rb, and examples of schemas on spec/fixtures/view_import.*


On Tue, Jul 18, 2017 at 9:42 AM, Heiko Rupp <hrupp@redhat.com> wrote:
On 17 Jul 2017, at 15:59, Caina Costa wrote:

> If we have a WildflyDomainControllerServer to render, first it will
> try to find WildFlyDomainControllerServerView, then

I (still) consider that a problem, even if better than what we have now.
I can't tell e.g. the Infinispan folks "Listen you know your stuff
better than we do, so please start writing Ruby code and create a
pull-request against the hawkular-provider gem"

My goal really is to externalise that as much as possible (in to the
hawkular-server or agent side), so that it is
possible for other groups to write the description in e.g. JSON for
their UI and the relation between Entities.

Having that in Hawkular/Agent also allows us to introduce new supported
stuff outside the release cycles of ManageIQ and their downstream
CloudForms.
I am not even sure if e.g. introducing support for Infinispan could be
part of a z-Stream release, which is supposed to be bugfixes only.
So if we'd miss CF 4.6 GA, we can only support Fuse in the CF release
after 4.6 GA, while if the UI is driven from (meta)-data on the Hawkular
side, we can update the Middleware Manager / agent and the support would
show automagically.
Of course we may at some point in time create more specific UIs for some
task, but the 80% case should work without modification of MiQ code.

We need to generate the views dynamically, by fetching the (meta) data
and the schema and generating the view from that. That means we don't
need to change anything on ui-classic to add new entity types.
Those *EntityView Ruby objects need to be created from data retrieved
from the Hawkular side and not by checking in new code into the
hawkular-provider gem when supporting new Entities.

The metadata should probably stored inside MiQ for faster access, but
that is a 2ndary concern.

_______________________________________________
hawkular-dev mailing list
hawkular-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/hawkular-dev