Details

    • Type: Sub-task Sub-task
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: 1.8.0
    • Component/s: monitor
    • Labels:
      None

      Description

      The monitor works well for what it does, but it's very much so cobbled together. HTML is hand generated. Static state is used liberally which makes testing near impossible. View and controller logic are tightly intertwined which also adds to the testability problem.

      I've been working on porting the functionality from the existing monitor to a proper rest service using dropwizard. It's not completely functional yet, but it has a number of improvements of the existing monitor code.

      I thought I would post what I have already and let people give some feedback if they're interested. Help is always welcome. https://github.com/joshelser/accumulo/tree/dropwizard.

        Issue Links

          Activity

          Josh Elser created issue -
          Mike Drob made changes -
          Field Original Value New Value
          Link This issue contains ACCUMULO-2031 [ ACCUMULO-2031 ]
          Hide
          Mike Drob added a comment -

          Is this at odds with ACCUMULO-1013?

          Show
          Mike Drob added a comment - Is this at odds with ACCUMULO-1013 ?
          Hide
          Josh Elser added a comment -

          Is this at odds with ACCUMULO-1013?

          I'm not really sure what a URL builder is, but I would imagine that this issue would subsume that issue.

          Show
          Josh Elser added a comment - Is this at odds with ACCUMULO-1013 ? I'm not really sure what a URL builder is, but I would imagine that this issue would subsume that issue.
          Hide
          Mike Drob added a comment -

          You're thinking of ACCUMULO-2031, which, yes, this subsumes that. ACCUMULO-1013 is about replacing the monitor with something different (i.e. external).

          Show
          Mike Drob added a comment - You're thinking of ACCUMULO-2031 , which, yes, this subsumes that. ACCUMULO-1013 is about replacing the monitor with something different (i.e. external).
          Hide
          Josh Elser added a comment -

          Oh, I clicked the wrong link. I didn't realize that there were two different tickets. Mea culpa.

          Personally, I don't think that we'll get to a totally replaced system in the near future. There's too many specifics in how the monitors does what it does to allow direct integration with another tool. However, I am envisioning that these changes would ease integration into other tools. By breaking out each facet of metrics information that the monitor presents, external tools can much easier integrate and do whatever they want with that data.

          Show
          Josh Elser added a comment - Oh, I clicked the wrong link. I didn't realize that there were two different tickets. Mea culpa. Personally, I don't think that we'll get to a totally replaced system in the near future. There's too many specifics in how the monitors does what it does to allow direct integration with another tool. However, I am envisioning that these changes would ease integration into other tools. By breaking out each facet of metrics information that the monitor presents, external tools can much easier integrate and do whatever they want with that data.
          Hide
          Josh Elser added a comment -

          A mostly functional "clone" of the data which the current monitor currently calculates and provides. Uses Dropwizard, which bundles Jersey, Jetty and Jackson into one very usable package.

          • Creates proper resources which data structures to HTTP resources
          • Defines an API by the data we return
          • Presently standalone (existing monitor still works and wasn't modified)
          • Objects serialized as JSON
          • Basic health check for Accumulo
          • Forwarded log4j messages not currently wired up (had issues, need to revisit – thought it deserved discussion as to whether or not that should be included in this service)
          • Still uses the Monitor class for most of heavy lifting from other services over Thrift
          • Wired up to Accumulo bash scripts (will start/stop via start-all/stop-all, currently).

          Please take a glance at the patch. I think this is a step in the right direction to make a maintainable monitor.

          Show
          Josh Elser added a comment - A mostly functional "clone" of the data which the current monitor currently calculates and provides. Uses Dropwizard , which bundles Jersey, Jetty and Jackson into one very usable package. Creates proper resources which data structures to HTTP resources Defines an API by the data we return Presently standalone (existing monitor still works and wasn't modified) Objects serialized as JSON Basic health check for Accumulo Forwarded log4j messages not currently wired up (had issues, need to revisit – thought it deserved discussion as to whether or not that should be included in this service) Still uses the Monitor class for most of heavy lifting from other services over Thrift Wired up to Accumulo bash scripts (will start/stop via start-all/stop-all, currently). Please take a glance at the patch. I think this is a step in the right direction to make a maintainable monitor.
          Josh Elser made changes -
          Hide
          Mike Drob added a comment -

          Any chance this makes it onto RB?

          Show
          Mike Drob added a comment - Any chance this makes it onto RB?
          Hide
          Josh Elser added a comment -

          Any chance this makes it onto RB?

          Since you asked, sure.

          Show
          Josh Elser added a comment - Any chance this makes it onto RB? Since you asked, sure.
          Josh Elser made changes -
          Remote Link This issue links to "rb (Web Link)" [ 16365 ]
          Hide
          Mike Drob added a comment -

          I did not realize this was 95% POJOs + Annotations when I made that request.

          Show
          Mike Drob added a comment - I did not realize this was 95% POJOs + Annotations when I made that request.
          Hide
          Josh Elser added a comment -

          I did not realize this was 95% POJOs + Annotations when I made that request.

          There is a lot of "useless" pojos for jackson to use, but I think that's a necessary step. Right now, those objects are just wrapping their thrift counterparts, but we want to do this so we can separate the backend transport information from the information that users will expect (e.g. put them in public api, w/e).

          Show
          Josh Elser added a comment - I did not realize this was 95% POJOs + Annotations when I made that request. There is a lot of "useless" pojos for jackson to use, but I think that's a necessary step. Right now, those objects are just wrapping their thrift counterparts, but we want to do this so we can separate the backend transport information from the information that users will expect (e.g. put them in public api, w/e).
          Josh Elser made changes -
          Parent ACCUMULO-3034 [ 12731106 ]
          Issue Type Improvement [ 4 ] Sub-task [ 7 ]
          Hide
          Josh Elser added a comment -

          I was playing around with this some more tonight. Made a "client POJOs" artifact and split up the server into its own shaded jar (server-side only, doesn't rebundle hadoop/zk/accumulo classes). This also removed a bunch of cruft in special handling in the shell scripts which was nice.

          The sad part is that it appears that ch.qos.logback:logback-classic shaded in an SLF4J impl which prints a lovely warning every time you initialize the logging infrastructure because of the binding we expect it to use provided by slf4j-log4j12 we already have on the classpath. As sad as this is, I don't think there's a way to work around it. It's looking like I'll have to bite the bullet and just roll jetty/jersey/jackson on my own and just lift the "nice" bits from dropwizard that I like. Ugh.

          Show
          Josh Elser added a comment - I was playing around with this some more tonight. Made a "client POJOs" artifact and split up the server into its own shaded jar (server-side only, doesn't rebundle hadoop/zk/accumulo classes). This also removed a bunch of cruft in special handling in the shell scripts which was nice. The sad part is that it appears that ch.qos.logback:logback-classic shaded in an SLF4J impl which prints a lovely warning every time you initialize the logging infrastructure because of the binding we expect it to use provided by slf4j-log4j12 we already have on the classpath. As sad as this is, I don't think there's a way to work around it. It's looking like I'll have to bite the bullet and just roll jetty/jersey/jackson on my own and just lift the "nice" bits from dropwizard that I like. Ugh.
          Hide
          Josh Elser added a comment -

          Been hacking on this some more. I was able to lift the resources and annotated classes from previously into a version that works with Jersey, Jackson and Grizzly

          https://github.com/joshelser/accumulo/tree/jersey-monitor

          Need to address some minor semantic issues in the resources, but that won't be too bad. I need to start looking how to replace the HTML renderings which is the big unknown presently. Looking at https://jersey.java.net/documentation/latest/mvc.html, but I need to figure out what sounds the best. Would using the "standard" JSP be easiest?

          Switching over from embedded Jetty to Grizzly has been nice, but I'm not sure of the technical reasons for choosing one over the other. I mainly used Grizzly because it worked and I had some examples I could leverage from Jersey. Any info would be appreciated.

          Show
          Josh Elser added a comment - Been hacking on this some more. I was able to lift the resources and annotated classes from previously into a version that works with Jersey, Jackson and Grizzly https://github.com/joshelser/accumulo/tree/jersey-monitor Need to address some minor semantic issues in the resources, but that won't be too bad. I need to start looking how to replace the HTML renderings which is the big unknown presently. Looking at https://jersey.java.net/documentation/latest/mvc.html , but I need to figure out what sounds the best. Would using the "standard" JSP be easiest? Switching over from embedded Jetty to Grizzly has been nice, but I'm not sure of the technical reasons for choosing one over the other. I mainly used Grizzly because it worked and I had some examples I could leverage from Jersey. Any info would be appreciated.
          Hide
          Christopher Tubbs added a comment -

          I think we mainly used Jetty over Grizzly, because it came with Hadoop. Now that we provide our own dependency for that, I'm not sure it matters. I wouldn't want to switch on the basis of personal preference, though... are there specific advantages you've encountered that make the switch compelling?

          Show
          Christopher Tubbs added a comment - I think we mainly used Jetty over Grizzly, because it came with Hadoop. Now that we provide our own dependency for that, I'm not sure it matters. I wouldn't want to switch on the basis of personal preference, though... are there specific advantages you've encountered that make the switch compelling?
          Hide
          Josh Elser added a comment -

          are there specific advantages you've encountered that make the switch compelling?

          In using JaxRS resources over Servlets, there is definitely much more literature on configuring Grizzly with said resources, which is primarily how my decision was made so far. I haven't actually been able to find a technical difference (or even a comparison) between the two as to why you'd choose Jetty over Grizzly or vice versa (oddly..). I also haven't found any docs on how to configure Jetty to do the jaxrs stuff (as opposed to servlets) either.

          I did find that Grizzly publishes a WADL automagically which was pretty cool for me to at least validate that my resources were being loaded. I could see some benefit from that for consumers as well, but that's by no means a strong differentiation.

          Show
          Josh Elser added a comment - are there specific advantages you've encountered that make the switch compelling? In using JaxRS resources over Servlets, there is definitely much more literature on configuring Grizzly with said resources, which is primarily how my decision was made so far. I haven't actually been able to find a technical difference (or even a comparison) between the two as to why you'd choose Jetty over Grizzly or vice versa (oddly..). I also haven't found any docs on how to configure Jetty to do the jaxrs stuff (as opposed to servlets) either. I did find that Grizzly publishes a WADL automagically which was pretty cool for me to at least validate that my resources were being loaded. I could see some benefit from that for consumers as well, but that's by no means a strong differentiation.
          Hide
          Christopher Tubbs added a comment -

          In my experience, I didn't have to do much special for Jetty. I just put @ApplicationPath("some/path/off/root") on my application which extended PackagesResourceConfig, and whose no-arg constructor called the parent constructor with a base package name for automatically searching for resources. And that was optional... and just to avoid providing the xml file.

          Granted, the last time I did this, I was not using an embedded Jetty, so I don't know if that requires anything extra.

          Show
          Christopher Tubbs added a comment - In my experience, I didn't have to do much special for Jetty. I just put @ApplicationPath("some/path/off/root") on my application which extended PackagesResourceConfig, and whose no-arg constructor called the parent constructor with a base package name for automatically searching for resources. And that was optional... and just to avoid providing the xml file. Granted, the last time I did this, I was not using an embedded Jetty, so I don't know if that requires anything extra.
          Hide
          Josh Elser added a comment -

          Cool, thanks for the information. I didn't make an explicit Application (just made a ResourceConfig() and did things that way), but I was thinking that might be better for portability across containers? Now that I have something that works, I need to go back and figure out what is best for portability and functionality (not to mention making sure the same can also be deployed in a standalone container).

          Show
          Josh Elser added a comment - Cool, thanks for the information. I didn't make an explicit Application (just made a ResourceConfig() and did things that way), but I was thinking that might be better for portability across containers? Now that I have something that works, I need to go back and figure out what is best for portability and functionality (not to mention making sure the same can also be deployed in a standalone container).
          Hide
          Christopher Tubbs added a comment -

          One of the biggest problems with portability is that the Login mechanisms tend to be container-specific. This is going to cause an issue if we want to do, say, client-auth with TLS certificates and protect the shell-in-the-monitor resource with confidential transport guarantees, as we do today. We can still probably write this more sensibly with JAX-RS annotations, but the wiring is a bit more complicated if we support portability between containers.

          That said, I'm a big fan of separating the library portion of the web service (the POJOs, servlets, resources, whatever) from the container, so it can be made portable. I just don't know that we need multiple modules for the monitor right now to support that separation.

          Show
          Christopher Tubbs added a comment - One of the biggest problems with portability is that the Login mechanisms tend to be container-specific. This is going to cause an issue if we want to do, say, client-auth with TLS certificates and protect the shell-in-the-monitor resource with confidential transport guarantees, as we do today. We can still probably write this more sensibly with JAX-RS annotations, but the wiring is a bit more complicated if we support portability between containers. That said, I'm a big fan of separating the library portion of the web service (the POJOs, servlets, resources, whatever) from the container, so it can be made portable. I just don't know that we need multiple modules for the monitor right now to support that separation.
          Hide
          Josh Elser added a comment -

          Thanks for the information – I'm still fumbling blindly through a forest of possibilities.

          I just don't know that we need multiple modules for the monitor right now to support that separation.

          What kind of module? Maven module? Assuming that's what you mean – I think we would want two: one that produces a jar (and is designed to run an embedded server using the normal Accumulo classpath) and then one that makes a war (designed to be more self-contained, sans maybe Hadoop deps?). IIRC, Maven doesn't really like creating more than one artifact per module, so I'm not sure how to get around that one. Not to mention, I don't know what would be standard to include in the war to, say, deploy it "easily" to a Tomcat or JBoss instance.

          Show
          Josh Elser added a comment - Thanks for the information – I'm still fumbling blindly through a forest of possibilities. I just don't know that we need multiple modules for the monitor right now to support that separation. What kind of module? Maven module? Assuming that's what you mean – I think we would want two: one that produces a jar (and is designed to run an embedded server using the normal Accumulo classpath) and then one that makes a war (designed to be more self-contained, sans maybe Hadoop deps?). IIRC, Maven doesn't really like creating more than one artifact per module, so I'm not sure how to get around that one. Not to mention, I don't know what would be standard to include in the war to, say, deploy it "easily" to a Tomcat or JBoss instance.
          Hide
          Christopher Tubbs added a comment -

          Yes, I meant multiple maven modules. I think ideally, there'd be a maven module with the POJOs and resources and stuff (the "library"; technically, this could be server-base), and then a separate module for each supported service (embedded jetty launcher, war packaging, tomcat-specific support).

          When I say "I just don't know that we need... right now...", I'm mainly expressing my dislike of the monitor being part of the core project (as well as the fact that we haven't really discussed multiple modules in terms of the future of the monitor). I think that I'd much rather prefer all the monitor be a client-only service which simply talks to Accumulo's metrics API and displays it conveniently. That way, we can separate out the service as a truly separate thing (modules and all), but which could also just as easily be swapped out for another monitoring service, if desired. Until things get to that point, I think I'd rather just stick with a single, convenient module which launches the service in one way (embedded Jetty). Maybe it could also build a generic WAR package for deployment in a separate container, but I wouldn't want to see a lot of heavyweight refactoring support for the monitor as it exists in the core project. I'd rather see work to make it replaceable and moved to its own contrib repo, with support for additional containers supported in separate modules there.

          However, I place emphasis on the "don't know" part of my comment, because I think additional thought needs to be put into this (including reviewing on my part of patches/contributions).

          Show
          Christopher Tubbs added a comment - Yes, I meant multiple maven modules. I think ideally, there'd be a maven module with the POJOs and resources and stuff (the "library"; technically, this could be server-base), and then a separate module for each supported service (embedded jetty launcher, war packaging, tomcat-specific support). When I say "I just don't know that we need... right now...", I'm mainly expressing my dislike of the monitor being part of the core project (as well as the fact that we haven't really discussed multiple modules in terms of the future of the monitor). I think that I'd much rather prefer all the monitor be a client-only service which simply talks to Accumulo's metrics API and displays it conveniently. That way, we can separate out the service as a truly separate thing (modules and all), but which could also just as easily be swapped out for another monitoring service, if desired. Until things get to that point, I think I'd rather just stick with a single, convenient module which launches the service in one way (embedded Jetty). Maybe it could also build a generic WAR package for deployment in a separate container, but I wouldn't want to see a lot of heavyweight refactoring support for the monitor as it exists in the core project. I'd rather see work to make it replaceable and moved to its own contrib repo, with support for additional containers supported in separate modules there. However, I place emphasis on the "don't know" part of my comment, because I think additional thought needs to be put into this (including reviewing on my part of patches/contributions).
          Hide
          Josh Elser added a comment -

          Understood. Right now, I'm aiming to keep a single module for the "API" and then let that be runnable via some embedded server (jetty or grizzly). I'd like to get a separate module for a generic WAR, but I'm guessing my motivation to test it for "generalness" will run out after the 2nd container/app-server.

          It would be nice to at least support (non-embedded) Jetty and Tomcat for a first pass, I think. I agree with you – let's take a step back once things are solidified and we can decide the path we want to take after. Feel free to look at the diff on my github if you're curious. After I get it converted over to an Application, I'll try to put up a proper patch.

          Show
          Josh Elser added a comment - Understood. Right now, I'm aiming to keep a single module for the "API" and then let that be runnable via some embedded server (jetty or grizzly). I'd like to get a separate module for a generic WAR, but I'm guessing my motivation to test it for "generalness" will run out after the 2nd container/app-server. It would be nice to at least support (non-embedded) Jetty and Tomcat for a first pass, I think. I agree with you – let's take a step back once things are solidified and we can decide the path we want to take after. Feel free to look at the diff on my github if you're curious. After I get it converted over to an Application, I'll try to put up a proper patch.
          Hide
          Dave Marion added a comment -

          I need to start looking how to replace the HTML renderings which is the big unknown presently.

          Looking at some of your resources (for example, MasterResource), the class produces only JSON and returns simple Java objects (String, Map<>, List<>). You could instead return JAX-B annotated objects, then register serialization providers to support things other than JSON, to include HTML. Looks like an example in the Jersey docs is located at: https://jersey.java.net/documentation/latest/message-body-workers.html#d0e5405. I'm more familiar with JBoss RestEasy, but Jersey is the reference implementation I believe, so it should be able to do the same things at the spec level.

          Show
          Dave Marion added a comment - I need to start looking how to replace the HTML renderings which is the big unknown presently. Looking at some of your resources (for example, MasterResource), the class produces only JSON and returns simple Java objects (String, Map<>, List<>). You could instead return JAX-B annotated objects, then register serialization providers to support things other than JSON, to include HTML. Looks like an example in the Jersey docs is located at: https://jersey.java.net/documentation/latest/message-body-workers.html#d0e5405 . I'm more familiar with JBoss RestEasy, but Jersey is the reference implementation I believe, so it should be able to do the same things at the spec level.
          Hide
          Josh Elser added a comment -

          Thanks, Dave Marion. I was just trying to get something basic that worked with Jackson as a first pass. I need to figure out how all of these things work too – I thought Jackson would provide both XML and JSON support, but I'm not quite sure if I just need to wire things up differently, or what.

          Show
          Josh Elser added a comment - Thanks, Dave Marion . I was just trying to get something basic that worked with Jackson as a first pass. I need to figure out how all of these things work too – I thought Jackson would provide both XML and JSON support, but I'm not quite sure if I just need to wire things up differently, or what.
          Hide
          Dave Marion added a comment -

          I've only used Jackson for JSON support. Not sure if is supports XML. On my project, we return JAX-B objects from all of our JAX-RS endpoints. We have providers for XML, JSON, HTML, and even Protobuf (via protostuff) mapped to different MediaTypes. The HTTP request will/should have an Accept header and the JAX-RS engine will match the provider with the MediaType, and use that Provider to serialize the object. We also put our JAX-B objects in a separate Client jar for those users that only want to use XML, JSON, etc as the transport serialization and then deserialize back to POJOs.

          Show
          Dave Marion added a comment - I've only used Jackson for JSON support. Not sure if is supports XML. On my project, we return JAX-B objects from all of our JAX-RS endpoints. We have providers for XML, JSON, HTML, and even Protobuf (via protostuff) mapped to different MediaTypes. The HTTP request will/should have an Accept header and the JAX-RS engine will match the provider with the MediaType, and use that Provider to serialize the object. We also put our JAX-B objects in a separate Client jar for those users that only want to use XML, JSON, etc as the transport serialization and then deserialize back to POJOs.
          Hide
          Josh Elser added a comment -

          From Jackson's Github README:

          Jackson is a suite of data-processing tools for Java (and JVM platform), including the flagship JSON parsing and generation library, as well as additional modules to process data encoded in Avro, CBOR, CSV, Smile, XML or YAML (and list of supported format is still growing – see additional experimental/external projects listed below!)

          I'll just have to dig and see how it works (or move to jax-b or something else)

          Show
          Josh Elser added a comment - From Jackson's Github README: Jackson is a suite of data-processing tools for Java (and JVM platform), including the flagship JSON parsing and generation library, as well as additional modules to process data encoded in Avro, CBOR, CSV, Smile, XML or YAML (and list of supported format is still growing – see additional experimental/external projects listed below!) I'll just have to dig and see how it works (or move to jax-b or something else)
          Hide
          Christopher Tubbs added a comment -

          You're not using Jackson directly, are you? I'd imagine you're just using it as the registered provider for @Produces("application/json")?

          Show
          Christopher Tubbs added a comment - You're not using Jackson directly, are you? I'd imagine you're just using it as the registered provider for @Produces("application/json") ?
          Hide
          Josh Elser added a comment -

          Something like that, and then the Jackson MessageWriter (or something) is picked up off the classpath after I do some registration.

          Show
          Josh Elser added a comment - Something like that, and then the Jackson MessageWriter (or something) is picked up off the classpath after I do some registration.
          Josh Elser made changes -
          Fix Version/s 1.8.0 [ 12329879 ]
          Fix Version/s 1.7.0 [ 12324607 ]

            People

            • Assignee:
              Josh Elser
              Reporter:
              Josh Elser
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:

                Development