Uploaded image for project: 'Solr'
  1. Solr
  2. SOLR-58

Change Admin components to return XML like the rest of the system

Details

    • New Feature
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • None
    • 1.1.0
    • Admin UI
    • None

    Description

      I need to expose the admin functionality to an external application. I think returning admin data as XML may be a good and simple first step towards that.

      To do that I think I'll mostly need to modify JSPs (but I haven't had a good look at Admin GUI yet). From what I saw a few weeks ago when I briefly looked at this, no Java code will need to be modified. If you have concrete ideas about how this should be done, please comment before I start next week (week of October 23rd 2006).

      Attachments

        1. SOLR-58.patch
          39 kB
          Otis Gospodnetic

        Activity

          siren Sami Siren added a comment -

          Havent checked how admin GUI is constructed but if there is a cleanAPIi it might be easier to use something like hessian http://www.caucho.com/hessian/ instead of hacking the jsps to emit xml and writing a custom client.

          siren Sami Siren added a comment - Havent checked how admin GUI is constructed but if there is a cleanAPIi it might be easier to use something like hessian http://www.caucho.com/hessian/ instead of hacking the jsps to emit xml and writing a custom client.

          Once the admin components emit XML, The XSLT transformation code written for SOLR-49 could be used to recreate an HTML user interface easily.

          bdelacretaz Bertrand Delacretaz added a comment - Once the admin components emit XML, The XSLT transformation code written for SOLR-49 could be used to recreate an HTML user interface easily.

          I went to the original thread where I started discussion about exposing some admin functionality as XML, http://www.mail-archive.com/solr-user@lucene.apache.org/msg01012.html and realized Yonik had pointed out that the 'stats'(.jsp) page already spits out XML and has the XSL that transforms it to HTML: http://www.mail-archive.com/solr-user@lucene.apache.org/msg01074.html

          The same with 'registry.jsp' - it's really XML + XSL.

          Is there anything else that I could expose as XML?

          $ ls -1 src/webapp/resources/admin/*jsp
          src/webapp/resources/admin/action.jsp
          src/webapp/resources/admin/analysis.jsp
          src/webapp/resources/admin/distributiondump.jsp
          src/webapp/resources/admin/form.jsp
          src/webapp/resources/admin/get-file.jsp
          src/webapp/resources/admin/get-properties.jsp
          src/webapp/resources/admin/header.jsp
          src/webapp/resources/admin/index.jsp
          src/webapp/resources/admin/_info.jsp
          src/webapp/resources/admin/logging.jsp
          src/webapp/resources/admin/ping.jsp
          src/webapp/resources/admin/raw-schema.jsp
          src/webapp/resources/admin/registry.jsp
          src/webapp/resources/admin/stats.jsp
          src/webapp/resources/admin/threaddump.jsp

          Here is what I think could still be XMLized:

          • action.jsp - action + success/failure status, but that seems to be used only from logging.jsp, so converting action.jsp to XML seems a bit useless.
          • threaddump.jsp - JVM version, deadlock printout, and then just one big XML element with the dump of all threads
          • ping.jsp - ? I don't have any slaves running here, so I'm not even sure what that's supposed to look like

          Everything else in src/webapp/resources/admin/ is either an image or a helper JSP.

          Thoughts?

          otis Otis Gospodnetic added a comment - I went to the original thread where I started discussion about exposing some admin functionality as XML, http://www.mail-archive.com/solr-user@lucene.apache.org/msg01012.html and realized Yonik had pointed out that the 'stats'(.jsp) page already spits out XML and has the XSL that transforms it to HTML: http://www.mail-archive.com/solr-user@lucene.apache.org/msg01074.html The same with 'registry.jsp' - it's really XML + XSL. Is there anything else that I could expose as XML? $ ls -1 src/webapp/resources/admin/*jsp src/webapp/resources/admin/action.jsp src/webapp/resources/admin/analysis.jsp src/webapp/resources/admin/distributiondump.jsp src/webapp/resources/admin/form.jsp src/webapp/resources/admin/get-file.jsp src/webapp/resources/admin/get-properties.jsp src/webapp/resources/admin/header.jsp src/webapp/resources/admin/index.jsp src/webapp/resources/admin/_info.jsp src/webapp/resources/admin/logging.jsp src/webapp/resources/admin/ping.jsp src/webapp/resources/admin/raw-schema.jsp src/webapp/resources/admin/registry.jsp src/webapp/resources/admin/stats.jsp src/webapp/resources/admin/threaddump.jsp Here is what I think could still be XMLized: action.jsp - action + success/failure status, but that seems to be used only from logging.jsp, so converting action.jsp to XML seems a bit useless. threaddump.jsp - JVM version, deadlock printout, and then just one big XML element with the dump of all threads ping.jsp - ? I don't have any slaves running here, so I'm not even sure what that's supposed to look like Everything else in src/webapp/resources/admin/ is either an image or a helper JSP. Thoughts?
          billa William Au added a comment -

          ping.jsp does not retrun any content. It checks the solr server by sending the query defined in SolrConfig.xml (pingQuery) and returns 200 if the query works without any exception. Otherwise it returns 500.

          action.jsp is a secondary JSP that performs action from the main page (enable/disable) and the logging page (set log level). So I agree that there is probably no need to XMLized it.

          billa William Au added a comment - ping.jsp does not retrun any content. It checks the solr server by sending the query defined in SolrConfig.xml (pingQuery) and returns 200 if the query works without any exception. Otherwise it returns 500. action.jsp is a secondary JSP that performs action from the main page (enable/disable) and the logging page (set log level). So I agree that there is probably no need to XMLized it.

          I took a stab at analysis page, and it turned out it lends itself to XMLization. I'm attaching two files:
          1) analysis XML output
          2) analysis-xml.jsp - the JSP that replaces the output portion of analysis.jsp
          (if this looks good, then I'll just change the FORM action in analysis.jsp to point to analysis-xml.jsp and somebody familiar with XSL could provide that piece)

          Please comment.

          These are my targets for XMLization, and I'm going to work on them next.

          ANALYSIS (this attachment)
          STATISTICS (already XMLized)
          INFO
          DISTRIBUTION
          PING
          LOGGING
          THREAD DUMP

          otis Otis Gospodnetic added a comment - I took a stab at analysis page, and it turned out it lends itself to XMLization. I'm attaching two files: 1) analysis XML output 2) analysis-xml.jsp - the JSP that replaces the output portion of analysis.jsp (if this looks good, then I'll just change the FORM action in analysis.jsp to point to analysis-xml.jsp and somebody familiar with XSL could provide that piece) Please comment. These are my targets for XMLization, and I'm going to work on them next. ANALYSIS (this attachment) STATISTICS (already XMLized) INFO DISTRIBUTION PING LOGGING THREAD DUMP

          Ping was simple, I just made it return <solr><status="200"/></solr> if ping was OK (attached), and if there was an error, then:

          <solr>
          <status="500">exception trace here</status>
          </solr>

          Thoughts?

          N.B.
          I'm not attaching diffs for JSPs, as I'm letting both the original and the XML versions live side by side locally for now, but if you'd prefer diffs, let me know.

          otis Otis Gospodnetic added a comment - Ping was simple, I just made it return <solr><status="200"/></solr> if ping was OK (attached), and if there was an error, then: <solr> <status="500">exception trace here</status> </solr> Thoughts? N.B. I'm not attaching diffs for JSPs, as I'm letting both the original and the XML versions live side by side locally for now, but if you'd prefer diffs, let me know.

          Here is threaddump-xml.jsp and the example of its output.

          otis Otis Gospodnetic added a comment - Here is threaddump-xml.jsp and the example of its output.

          Here is the XML version of logging.jsp, named logging-xml.jsp.
          Its output is trivial:

          <solr>
          <logLevel>INFO</logLevel>
          </solr>

          I imagine the XSL would take this XML, convert it to HTML, and append the HTML with links to action.jsp with different logging levels.

          otis Otis Gospodnetic added a comment - Here is the XML version of logging.jsp, named logging-xml.jsp. Its output is trivial: <solr> <logLevel>INFO</logLevel> </solr> I imagine the XSL would take this XML, convert it to HTML, and append the HTML with links to action.jsp with different logging levels.

          A few comments/questions in no particular order...

          0) in general, i've found it's difficult to know how hard some XML will be to style, untill you've tried styling it

          1) the assumption is that these will include xsl-stylesheet headers list stats/registry do right now and let teh browser apply them right?

          2) Within the outermost <solr> tag, it would probably be good to have another wrapper tag specific to each of the pages .. it might make reusing a single (or a small number of) XSL file(s) for multiple pages easier.

          3) I think for analysis.jsp you're going to want a <form> block containing info about the options used and a <results> block containing what you've got right now ... otherwise it's going to be hard for an XSLT to recreate the form with the current state filled in (as i recall: there are ways of getting the URI of the current document in XSLT, and parsing out it's query params, but they have issues ... and they don't work if someone attempts to save the file locally to review later)

          4) it would probably make more sense to group the <token>s as children of the <factorry>s when verbose is turned on ... acctaully it would probably make sense to group them under the <factory> even if verbose isn't on....

          5) as long as we are outputing structured XML, we should render the factory.getArgs() as individual key/val pairs instead of just a string, maybe something like...

          <factory class="org.apache.solr.analysis.WordDelimiterFilterFactory">
          <args>
          <arg name="catenateWords">1</arg>
          <arg name="catenateNumbers">1</arg>
          </args>
          <tokens>
          <token type="word" pos="1" start="0" end="6">Search</token>
          <token type="word" pos="2" start="7" end="12">Stuff</token>
          <token type="word" pos="2" start="0" end="12">SearchStuff</token
          </tokens>
          </factory>

          ...or if verbose is off...

          <factory>
          <tokens>
          <token type="word" pos="1" start="0" end="6">Search</token>
          <token type="word" pos="2" start="7" end="12">Stuff</token>
          <token type="word" pos="2" start="0" end="12">SearchStuff</token
          </tokens>
          </factory>

          6) converting action.jsp to XML might actually make sense if you want to programatically hit it to change the logging level and test that the operation succeeded (right now you'd have to parse the HTML)

          7) ping's utilitiy for monitoring systems like nagios and load balancers is that it's trivial to check if the port is functioning just by checking the HTTP status code (where the definition of functioning is defined by a query in the solrconfig) ... it must have a genuine HTTP status code != 200 if there is a failure, returning an HTTP status code of 200 with a response body that says <status="500">...</status> just makes everything more complicated.

          ...either it shouldn't be converted, or it should manually set the reponse status to 500 before outputing the XML representation of the exception (incidently: it will need to be XML escaped too)

          hossman Chris M. Hostetter added a comment - A few comments/questions in no particular order... 0) in general, i've found it's difficult to know how hard some XML will be to style, untill you've tried styling it 1) the assumption is that these will include xsl-stylesheet headers list stats/registry do right now and let teh browser apply them right? 2) Within the outermost <solr> tag, it would probably be good to have another wrapper tag specific to each of the pages .. it might make reusing a single (or a small number of) XSL file(s) for multiple pages easier. 3) I think for analysis.jsp you're going to want a <form> block containing info about the options used and a <results> block containing what you've got right now ... otherwise it's going to be hard for an XSLT to recreate the form with the current state filled in (as i recall: there are ways of getting the URI of the current document in XSLT, and parsing out it's query params, but they have issues ... and they don't work if someone attempts to save the file locally to review later) 4) it would probably make more sense to group the <token>s as children of the <factorry>s when verbose is turned on ... acctaully it would probably make sense to group them under the <factory> even if verbose isn't on.... 5) as long as we are outputing structured XML, we should render the factory.getArgs() as individual key/val pairs instead of just a string, maybe something like... <factory class="org.apache.solr.analysis.WordDelimiterFilterFactory"> <args> <arg name="catenateWords">1</arg> <arg name="catenateNumbers">1</arg> </args> <tokens> <token type="word" pos="1" start="0" end="6">Search</token> <token type="word" pos="2" start="7" end="12">Stuff</token> <token type="word" pos="2" start="0" end="12">SearchStuff</token </tokens> </factory> ...or if verbose is off... <factory> <tokens> <token type="word" pos="1" start="0" end="6">Search</token> <token type="word" pos="2" start="7" end="12">Stuff</token> <token type="word" pos="2" start="0" end="12">SearchStuff</token </tokens> </factory> 6) converting action.jsp to XML might actually make sense if you want to programatically hit it to change the logging level and test that the operation succeeded (right now you'd have to parse the HTML) 7) ping's utilitiy for monitoring systems like nagios and load balancers is that it's trivial to check if the port is functioning just by checking the HTTP status code (where the definition of functioning is defined by a query in the solrconfig) ... it must have a genuine HTTP status code != 200 if there is a failure, returning an HTTP status code of 200 with a response body that says <status="500">...</status> just makes everything more complicated. ...either it shouldn't be converted, or it should manually set the reponse status to 500 before outputing the XML representation of the exception (incidently: it will need to be XML escaped too)
          gludington Greg Ludington added a comment -

          This may be slightly OT for this issue, but since the ticket discusses XSLT in the browser, and the Self Service wiki page, I though to put up for comments a quick and dirty XSLT-based schema browser I made. It transforms schema.xml into a single page tree view, so you can inspect fields and types, with some cross referencing between fieldtypes and fields, and field copyField source/dests. I have only tried it against Firefox 2 and IE7, but it should work in all browsers with an XSLT engine, or, failing that, it could be done server-side, and the resulting HTML sent to the browser.

          Unzipping and opening schema.xml in a browser is enough to see it, but it will be missing some styles and images referenced in the admin webapp. To use it in a solr webapp against your own schema, you have to:

          a) place schema.xml and the gifs in the /admin/ directory
          b) add the xsl directive to your schema.xml
          <?xml-stylesheet type="text/xsl" href="schema.xsl"?>

          c) modify get-file.jsp to set a content type of text/xml, and not to emit any whitespace

          I have only tried it with my prototype small-scale schemas, but, if it works for people with larger schemas, and fits in with the "Self Service" aims, I could take suggestions, clean up the xsl, and submit the a-b-c changes above as a patch.

          gludington Greg Ludington added a comment - This may be slightly OT for this issue, but since the ticket discusses XSLT in the browser, and the Self Service wiki page, I though to put up for comments a quick and dirty XSLT-based schema browser I made. It transforms schema.xml into a single page tree view, so you can inspect fields and types, with some cross referencing between fieldtypes and fields, and field copyField source/dests. I have only tried it against Firefox 2 and IE7, but it should work in all browsers with an XSLT engine, or, failing that, it could be done server-side, and the resulting HTML sent to the browser. Unzipping and opening schema.xml in a browser is enough to see it, but it will be missing some styles and images referenced in the admin webapp. To use it in a solr webapp against your own schema, you have to: a) place schema.xml and the gifs in the /admin/ directory b) add the xsl directive to your schema.xml <?xml-stylesheet type="text/xsl" href="schema.xsl"?> c) modify get-file.jsp to set a content type of text/xml, and not to emit any whitespace I have only tried it with my prototype small-scale schemas, but, if it works for people with larger schemas, and fits in with the "Self Service" aims, I could take suggestions, clean up the xsl, and submit the a-b-c changes above as a patch.
          ehatcher Erik Hatcher added a comment -

          The XML is being written (in the few attachments I sampled) as out.println() style. This has several drawbacks: 1) what about XML escaping/encoding issues? 2) What about clients that want JSON, Ruby, or some other format from a response writer? I strongly feel that the admin capability should work just like the front-end search capability, using a response writer for its output, not out.println's, making this much more flexible in the future. Refactoring so there is no difference between the front and "admin" sides would really make Solr shine!

          ehatcher Erik Hatcher added a comment - The XML is being written (in the few attachments I sampled) as out.println() style. This has several drawbacks: 1) what about XML escaping/encoding issues? 2) What about clients that want JSON, Ruby, or some other format from a response writer? I strongly feel that the admin capability should work just like the front-end search capability, using a response writer for its output, not out.println's, making this much more flexible in the future. Refactoring so there is no difference between the front and "admin" sides would really make Solr shine!

          Hoss, thanks for the comments.

          0) I have yet to find out - I haven't started writing that yet.
          1) Right, XSL in header and let the browser apply them.
          2) Not sure how that will help, but I'll add a new element in modified pages.
          3) Will do: <form> + <result>
          4) & 5) I agree
          6) & 7) Ok, I'll think about that tomorrow.

          Erik:
          Will using o.a.s.util.XML.escapeCharData do?
          I'll stick to XML output for now, because that's the current itch, plus any client can easily deal with it, but I agree that down the road it might be nice to support different formats.

          otis Otis Gospodnetic added a comment - Hoss, thanks for the comments. 0) I have yet to find out - I haven't started writing that yet. 1) Right, XSL in header and let the browser apply them. 2) Not sure how that will help, but I'll add a new element in modified pages. 3) Will do: <form> + <result> 4) & 5) I agree 6) & 7) Ok, I'll think about that tomorrow. Erik: Will using o.a.s.util.XML.escapeCharData do? I'll stick to XML output for now, because that's the current itch, plus any client can easily deal with it, but I agree that down the road it might be nice to support different formats.

          Hoss, regarding your point 7) about ping - makes sense. I think this is what Walter Underwood was talking about in a recent thread, too. So what should the ping response look like in case of success and in case of error?

          Is this ok?

          <solr>
          <ping>
          <status>200|500</status>
          <error> .... include this element only in case of error... </error>
          </ping>
          </solr>

          otis Otis Gospodnetic added a comment - Hoss, regarding your point 7) about ping - makes sense. I think this is what Walter Underwood was talking about in a recent thread, too. So what should the ping response look like in case of success and in case of error? Is this ok? <solr> <ping> <status>200|500</status> <error> .... include this element only in case of error... </error> </ping> </solr>

          Sorry, forgot to add that, in addition to the above 200/500/error stuff, I'd change the HTTP response to 500 in case of error, and stick to 200 in case of success.

          otis Otis Gospodnetic added a comment - Sorry, forgot to add that, in addition to the above 200/500/error stuff, I'd change the HTTP response to 500 in case of error, and stick to 200 in case of success.

          Here are the new outputs for:
          Analysis
          Thread dump
          Ping

          All other outputs remain the same as before.

          Does this look ok?

          otis Otis Gospodnetic added a comment - Here are the new outputs for: Analysis Thread dump Ping All other outputs remain the same as before. Does this look ok?

          And here are the 3 JSPs that created those outputs.
          They now do XML character escaping.

          If this (and other attachments from a few weeks back) looks good, I'll move onto XSLT.

          otis Otis Gospodnetic added a comment - And here are the 3 JSPs that created those outputs. They now do XML character escaping. If this (and other attachments from a few weeks back) looks good, I'll move onto XSLT.

          Greg: schemaxsl stuff looks fancy, but it doesn't really belong to this issue. I suggest you take it out and put it into a new JIRA issue, where it will get more visibility and attention than it's getting here.

          otis Otis Gospodnetic added a comment - Greg: schemaxsl stuff looks fancy, but it doesn't really belong to this issue. I suggest you take it out and put it into a new JIRA issue, where it will get more visibility and attention than it's getting here.

          Updated ping-xml.jsp + ping.xsl
          I took the simplest XML output to transform to XSL, as I've never touched XSL before. Please comment if anything there doesn't look right or could be done better.

          I removed that <status> element from ping XML output, and tested this in the JSP:

          out.println("<error>");
          XML.escapeCharData(SolrException.toStr(resp.getException()), out);
          out.println("</error>");
          response.sendError(500);

          Unfortunately, this results ina generic 500 Error from Jetty, without this XML in the output. Does anyone know how to get around this?

          otis Otis Gospodnetic added a comment - Updated ping-xml.jsp + ping.xsl I took the simplest XML output to transform to XSL, as I've never touched XSL before. Please comment if anything there doesn't look right or could be done better. I removed that <status> element from ping XML output, and tested this in the JSP: out.println("<error>"); XML.escapeCharData(SolrException.toStr(resp.getException()), out); out.println("</error>"); response.sendError(500); Unfortunately, this results ina generic 500 Error from Jetty, without this XML in the output. Does anyone know how to get around this?

          logging.xsl + slightly modified ping.xsl

          otis Otis Gospodnetic added a comment - logging.xsl + slightly modified ping.xsl

          analysis-xml.jsp - the converted analysis.jsp that output XML
          analysis-xml-out.txt - the XML output by the new version
          analysis.xsl - XSLT to transform the XML back to HTML

          otis Otis Gospodnetic added a comment - analysis-xml.jsp - the converted analysis.jsp that output XML analysis-xml-out.txt - the XML output by the new version analysis.xsl - XSLT to transform the XML back to HTML

          threaddump-xml.jsp - the converted threaddump.jsp that outputs XML
          threaddump-xml-out.txt - sample XML output of the new version
          threaddump.xsl - XSLT to transform the XML back to HTML

          otis Otis Gospodnetic added a comment - threaddump-xml.jsp - the converted threaddump.jsp that outputs XML threaddump-xml-out.txt - sample XML output of the new version threaddump.xsl - XSLT to transform the XML back to HTML

          Here is the patch with modified JSPs + XSLs.

          I know there are a few small things missing:

          • I lost the solr/schema part that goes in the parentheses in page headings.
          • I lost the cwd, hostname, and the little stuff that I think _info.jsp gathers.
          • maybe something else...

          The above omissions can easily be re-added, but let's see the review of the existing changes first.

          otis Otis Gospodnetic added a comment - Here is the patch with modified JSPs + XSLs. I know there are a few small things missing: I lost the solr/schema part that goes in the parentheses in page headings. I lost the cwd, hostname, and the little stuff that I think _info.jsp gathers. maybe something else... The above omissions can easily be re-added, but let's see the review of the existing changes first.
          yseeley@gmail.com Yonik Seeley added a comment -

          Yeah, some of those little things are really helpful when debugging.
          For instance, hostname can be important when going through a load-balancer to know exactly what host you are hitting.

          yseeley@gmail.com Yonik Seeley added a comment - Yeah, some of those little things are really helpful when debugging. For instance, hostname can be important when going through a load-balancer to know exactly what host you are hitting.

          Yeah, I'll make sure to put those back, but that's the easy part, whereas this XSL was new for me, so I want to make sure everything else looks okay first.

          otis Otis Gospodnetic added a comment - Yeah, I'll make sure to put those back, but that's the easy part, whereas this XSL was new for me, so I want to make sure everything else looks okay first.

          The new version with hostname:port, cwd, solrHome, and the collection name restored.
          I'll commit tomorrow, when I'm less zombied out.

          otis Otis Gospodnetic added a comment - The new version with hostname:port, cwd, solrHome, and the collection name restored. I'll commit tomorrow, when I'm less zombied out.

          Committed. Please reopen if there are issues or additional fixes are needed.

          otis Otis Gospodnetic added a comment - Committed. Please reopen if there are issues or additional fixes are needed.


          analysis.jsp currently isn't working properly ... it doesn't display the form by default, and if you manually create a URl that should work, you get a malformed XML response back.

          hossman Chris M. Hostetter added a comment - analysis.jsp currently isn't working properly ... it doesn't display the form by default, and if you manually create a URl that should work, you get a malformed XML response back.
          yseeley@gmail.com Yonik Seeley added a comment -

          If this isn't an easy/quick fix, perhaps we could roll back just analysis.jsp so we can continue with release 1.1?

          yseeley@gmail.com Yonik Seeley added a comment - If this isn't an easy/quick fix, perhaps we could roll back just analysis.jsp so we can continue with release 1.1?

          I'll resolve this as Fixed, even though it should be resolved as "No longer relevant", since I believe Ryan has changed or will change all admin stuff to work with handlers/writers....or at least that's what I recall reading.

          otis Otis Gospodnetic added a comment - I'll resolve this as Fixed, even though it should be resolved as "No longer relevant", since I believe Ryan has changed or will change all admin stuff to work with handlers/writers....or at least that's what I recall reading.

          This bug was modified as part of a bulk update using the criteria...

          • Marked ("Resolved" or "Closed") and "Fixed"
          • Had no "Fix Version" versions
          • Was listed in the CHANGES.txt for 1.1

          The Fix Version for all 38 issues found was set to 1.1, email notification
          was suppressed to prevent excessive email.

          For a list of all the issues modified, search jira comments for this
          (hopefully) unique string: 20080415hossman3

          hossman Chris M. Hostetter added a comment - This bug was modified as part of a bulk update using the criteria... Marked ("Resolved" or "Closed") and "Fixed" Had no "Fix Version" versions Was listed in the CHANGES.txt for 1.1 The Fix Version for all 38 issues found was set to 1.1, email notification was suppressed to prevent excessive email. For a list of all the issues modified, search jira comments for this (hopefully) unique string: 20080415hossman3

          People

            otis Otis Gospodnetic
            otis Otis Gospodnetic
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: