Last time on Batman A Quick Recap
In my last blog post (First Light: Part 1 - Questions & Answers) I talked about simplicity and our approach to have users "just ask your question". That simplicity is founded in the logical, relational schema within our OData abstraction layer. We expose relationships between objects much as you would in an SQL join on multiple tables. The nice part is that you don't have to worry about the semantics of those "joins" and which key should match on which tables. Kind of like a DB "view" but more flexible. We can add new relationships without DB schema changes and can enable a more flexible layer above a typically ridged core "data structure".
Overview of schema and basic architectural principals
Our OpenAPI OData implementation is the abstraction layer that provides the link between our in-memory Item Repository (IRep) and our disk-based Vertica Data Repository. The configuration aspects of the question are handled by IRep without the need for Disk I/O while the data fetches are managed through Vertica's "big-data" architecture. The best of both worlds and a great foundation for our scale and performance aspirations.
We also simplify the process by providing the relationships available to the user dynamically. As you build out your question we can provide the available logical associations. Basically "what's next". For example, in our CA Performance Manager QueryBuilder once the user defines the endpoint (group, device, etc) the options available to continue to build out the question are presented scoped to the initial endpoint. If the user selects Router, then the logical schema associations to Router (Groups, CPUs, etc.) are exposed in the filter mechanism and those which are not associated (Servers, Monitoring Profiles, etc.) are hidden. By ensuring these logical or relational consistencies in the question we add a nice coat of "easy paint" to the QueryBuilder.
Questions turned to Queries
"QueryBuilder? What's that?" - Great question! QueryBuilder is basically an easy way to turn your question into a valid OData compliant and functional URL. Though a faceted search approach we enable the user to easily understand how to construct their question within the context of our API schema and OData syntax.
Let's take a closer look!
There are 3 components to the QueryBuilder:
1. Search - Provides a way to ask your question in a way that allows QueryBuilder to translate that question into a valid OData URL. That OData URL can then be leveraged to generate the target results set - aka the answer.
2. Formatting - Allows the refinement of the output method and format. This includes paging (via a top and offset) to enable larger queries which would result very-large result payloads.
3. Output - Here's we we provide a sneak-peak at the answer.The output is not necessarily provided as the final format but options exist to export CSV results for quicker, ad-hoc type queries. This is a great way to answer configuration only questions. For more complex answers, the sneak peak provides insights into the data-set returned to help you make sure you asked the "right question" before turning that data into content.
That "Just Right' fit
The key to our approach is to ask the "ask the right question". We want to avoid providing too much information or not enough information. We enable this through our filtering mechanism. We provide advanced filtering capabilities to both refine the configuration results (the devices, interfaces, groups, etc) as well as the data (bytes > 0). This is where QueryBuilder shines! Advanced filters can be rather difficult and prone to error within OData syntax but a couple of clicks and voila! The correct URL is generated.
Real simple example, let's say I want to find all of the Cisco gigabit interfaces that have experience 0 traffic (bits-in/out) at any point within by Boston site. Here's how it looks in the QueryBuilder filter UI's:
And here's what the OData syntax looks like:
$filter=(substringof( 'CIsco',device/Description ) eq true and SpeedIn ge 1000000000 ) and ( portmfs/im_BitsIn eq 0 or portmfs/im_BitsOut eq 0 )
Not impossible to construct but you can imagine this can get pretty tricky pretty fast!
Next time: Let's look at some data and begin to answer some "questions"!
Thanks for your time!