[SERVER-1111] Per-environment etag support for the environment_classes endpoint Created: 2016/01/27 Updated: 2016/02/08 Status: Project: Component/s: Affects Version/s: Fix Version/s: Ready for Merge Puppet Server None None Type: Reporter: Resolution: Labels: Remaining Estimate: Time Spent: Original Estimate: New Feature Jeremy Barlow Unresolved None Not Specified Issue Links: Blocks is blocked SERVERby 1110 Duplicate Relates relates to SERVER1130 relates to SERVER1114 Template: Epic Link: Scrum Team: Sub-team: Story Points: Sprint: QA Status: QA Risk Assessment: Description SERVER 2.3.0 Priority: Assignee: Votes: Normal Unassigned 0 Not Specified Not Specified Implement environment_classes Ready for Test endpoin... environment_classes etag / expiration... Documentation for the environment_cla... customfield_10700 true NC Refresh Classes Puppet Server emerald 3 Server Emerald 2016-02-10 Reviewed Low Open Ready for Engineering As a follow-on to SERVER-1110, this ticket would add on the ability for requests to the environment_classes en environment to return an "Etag" that uniquely identifies the returned resource body. That "Etag" could then be ro caller in a subsequent "If-None-Match" header, returning an HTTP 304 (Not Modified) response if the requested latest parsed data available. Some examples: Initial request from the client without tag: Request: URL: GET /puppet/v3/environment-classes?environment=production Response: Status: 200 (OK) Header: Etag: “ABC123” Body: { "name": "production", "files": [ { "path": "/etc/puppetlabs/code/environments/production/manifests/ "classes": [] }, { "path": "/etc/puppetlabs/code/environments/production/modules/sample/manifests/cla "classes": [ { "name": "sample::class1", "params": [ { "default_literal": "literal default", “default_source”: “\”literal default\”, "name": "string_with_literal_default", "type": "String" }, { "default_source": "undef", "name": "string_with_undef_default", "type": "String" }, { "default_source": “default”, "name": "string_with_default_default", "type": "String" }, { "name": "string_with_no_default", "type": "String" }, { "name": "variant_with_no_default", "type": "Variant[Boolean, String, Enum['one', 'three', ' }, { "default_source”: “/^123*/“, "name": "regex_with_default", "type": "Regexp" } ] } ] }, { "path": "/etc/puppetlabs/code/environments/production/modules/sample/manifests/cla "classes": [ { "name": "sample::class2", "params": [] } ] }, { "path": "/etc/puppetlabs/code/environments/production/modules/sample/manifests/cor "error": "Syntax error at 'up' at /etc/puppetlabs/code/environments/production/modules/sample/manifests/corr }, { "path": "/etc/puppetlabs/code/environments/production/modules/sample/manifests/ini "classes": [ { "name": "sample", "params": [] } ] } ] } ] } Request from client with tag: Request: Header: If-None-Match: “ABC123” URL: GET /puppet/v3/environment-classes?environment=production Response: Status: 304 (Not Modified) Header: Etag: “ABC123” Body: <None> Request from client with invalidated tag (i.e., because the data on the server has been updated) Request: Header: If-None-Match: “ABC123” URL: GET /puppet/v3/environment-classes?environment=production Response: Status: 200 Header: Etag: “DEF234” Body: { "name": "production", "files": [ { "path": "/etc/puppetlabs/code/environments/production/manifests/somethingnew.pp”, "classes": [] }, … ] } Implementation tasks for this ticket will include: Each time class information is parsed for an environment_classes request, a SHA-1 of the environment c will be computed, with the SHA-1 being returned as the "Etag" HTTP header in the web service response Adding an in-memory Clojure cache that maps environments to the latest computed Etag for each enviro would be updated per environment_classes request. The cache would likely live inside of the JRubyPupp Trapperkeeper context. Change the environment_classes request handling to look for an "If-None-Match" header. If it finds one value is non-empty and matches the corresponding value in the in-memory cache of environment etags, r (Not Modified) response, else call through to the Puppet Server Ruby layer to parse environment content Any call into JRubyPuppetService.mark-environment-expired! - whether via a File Sync update or cache” endpoint being invoked - would cause the corresponding “environment” tag in the “environment be cleared. Calls to JRubyPuppetService.mark-all-environments-expired! would clear the environment “tags environments currently in the “environment class info cache”. Generated at Tue Feb 09 05:14:46 PST 2016 using JIRA 6.4.12#64027sha1:e3691cc1283c0f3cef6d65d3ea82d47743692b57.