fr33r / noti Goto Github PK
View Code? Open in Web Editor NEWA RESTful API offering resources to power an notification system.
A RESTful API offering resources to power an notification system.
Target
resource and have it appended to the collection of Target
resources.Target
resource.In order to accommodate multiple incoming media types for representations, duplicative methods within resource classes (AudienceResource
, TargetResource
, etc.) are created. Examples include:
AudienceResource#createAndAppend_XML
AudienceResource#replace_XML
TargetResource#createAndAppend_XML
TargetResource#replace_XML
It's worth noting that a fair amount of troubleshooting went into figuring out why 415 Unsupported Media Type
responses were being received from response class methods that had the appropriate @Consumes
/@Produces
annotiations. It was discovered that it was due to the fact the representation classes were constrained to a single media type, and the instantiation of those representation classes must not have been possible.
api.representations
package contains a sub-package per media type, such as json
, xml
, siren
, etc.InputStream
to resource classes, and perform the parsing on the InputStream
.
MessageBodyReaders
?_JSON
, _XML
, _Siren
, etc.Audience
resources to the collection of Audience
resources....maybe?
Target
resources to Audience
resources as members.Target
resource must exist before-hand.After running through RFC7231, I further clarified my understanding of what information is officially considered a "representation":
For the purposes of HTTP, a "representation" is information that is
intended to reflect a past, current, or desired state of a given
resource, in a format that can be readily communicated via the
protocol, and that consists of a set of representation metadata and a
potentially unbounded stream of representation data. - Section 3
More importantly, I was exposed to a more formal definition of "representation metadata". More specifically, the RFC explains that the following HTTP headers are used to communicate representation metadata:
Header Field Name | Defined in... |
---|---|
Content-Type | Section 3.1.1.5 |
Content-Encoding | Section 3.1.2.2 |
Content-Language | Section 3.1.3.2 |
Content-Location | Section 3.1.4.2 |
As currently implemented, the resource metadata recorded for a representation already includes the media type and location (although as currently implemented, the "location" is always the request target URI - which could more abstractly be represented as the "content location" to communicate that a representation's location is not always the request target URI). I propose introducing representation encoding and language into the representation metadata set stored and utilized within the application for optimistic concurrency control and cache validation.
As per the RFC definition of a representation (above), a representation "consists of a set of representation metadata and a potentially unbounded stream of representation data". In other words, the metadata is considered part of the representation itself. Due to this, these metadata fields (discussed above) are a necessity when selecting the correct representation during content negotiation.
Essentially, the representation location (used for representation identification), media type, encoding, and language serve as a composite key - two sets of representation metadata that differ in any one of these fields is considered a different representation altogether, as this metadata plays a role in defining the representation itself. To use an example, two representations communicating the same resource state but differ in target language audiences, are different representations of the current resource state. Similarly, a representation encoded using the gzip
coding scheme is a different representation altogether than a representation encoded using the deflate
coding scheme, even though they both communicate the same resource state.
Since tracking all of the representation metadata fields (discussed above) is pivotal for defining a representation, this metadata additionally has downstream impact on determining whether a representation's content has changed. When handling conditional requests, we must first be sure to complete proper representation selection to ensure that we are comparing the same representation.
RFC7232 provides insight on what a "strong validator" (strong ETag) is:
A "strong validator" is representation metadata that changes value
whenever a change occurs to the representation data that would be
observable in the payload body of a 200 (OK) response to GET. Section 2.1
There are a variety of strong validators used in practice. The best
are based on strict revision control, wherein each change to a
representation always results in a unique node name and revision
identifier being assigned before the representation is made
accessible to GET. A collision-resistant hash function applied to
the representation data is also sufficient if the data is available
prior to the response header fields being sent and the digest does
not need to be recalculated every time a validation request is
received. However, if a resource has distinct representations that
differ only in their metadata, such as might occur with content
negotiation over media types that happen to share the same data
format, then the origin server needs to incorporate additional
information in the validator to distinguish those representations. Section 2.1
The application should be able to leverage the benefits of strong validators either with or without persistence of the validators. In other words, generating the validator should be decoupled from persisting the validator for optimization purposes. This allows the application to provide cache validation with or without the presence of an online persistence mechanism, which maintains the benefits of caching mechanisms even in the event validator storage is offline (perhaps due to software or hardware failure, data center fail over, etc.).This decoupling also better enables the diversification of storage mechanisms used, since there is no coupling between the generation of the validator and the means of which it is stored. This means that multiple methods of persistence can be utilized for application-defined optimizations (such as storing frequent validators in an in-memory persistence mechanism, while placing infrequent validators in a relational data store).
It is tempting to embed timestamps recording when resource state was last updated, version numbers, etc. directly with the resource data itself. Besides implications induced due to violation separation of concerns (one concept is utilized for tracking changes to representations, the other for recording the current state of the resource; one is used primarily for caching purposes, while the other serves as the definition of state managed by the application; one is relatively disposable and serves mostly as an optimization, while the other is critical path in order for the application to fulfill is purpose), it also is abrasive in the effectiveness of the caching mechanisms achieved by introducing such metadata.
To provide the most effective caching mechanism, we should not assume that a change to resource state is a change to the representation of that state. Such an assumption should be considered a heavy-handed approach, as it will discard (recompute) strong validators when they could still be leveraged. Bear with me on this example:
Let's say we have a resource
A
with two representations,å
and∫
. ResourceA
consists ofgiven name
andsurname
as its state. Representationå
contains a field communicating thegiven name
of resourceA
, but notsurname
. However, representation∫
contains a field corresponding to resourceA
'ssurname
, but does not includegiven name
. We increment a version number or update a timestamp once eithergiven name
orsurname
of resourceA
changes.
If this timestamp or version number is utilized to calculate a strong validator for representations of resource A
(such as representations å
and ∫
), than we will unnecessarily revoke validators when content of the representation doesn't change. In terms of the example, we will revoke the validators for both å
and ∫
when just given name
changes, even though the only validator that should recomputed is for representation å
.
The solution is to not associate such timestamps or versioning schemes with resource data, but instead with representation data. This warrants isolating such data items from where resource data is stored and maintained, and instead maintain a separate storage for this representation data. Due to this, I encourage that the proposed additions of representation metadata be kept separate as currently implemented.
When issuing the mvn site
command to generate project and javadoc documentation, an issue is experienced when retrieving details about the project's dependencies. Here is an example of the console output encountered:
[INFO] Generating "Dependencies" report --- maven-project-info-reports-plugin:2.9
[WARNING] The repository url 'http://packages.confluent.io/maven/' is invalid - Repository 'confluent' will be blacklisted.
[WARNING] The repository url 'https://flywaydb.org/repo' is invalid - Repository 'flyway-repo' will be blacklisted.
[WARNING] The repository url 's3://flyway-repo/release' is invalid - Repository 'flyway-repo-private' will be blacklisted.
[WARNING] The repository url 'http://repository.springsource.com/maven/bundles/external' is invalid - Repository 'spring-external' will be blacklisted.
[WARNING] The repository url 'http://nexus.codehaus.org/snapshots/' is invalid - Repository 'codehaus-snapshots' will be blacklisted.
[WARNING] The repository url 'https://github.com/tzolov/maven-repo/raw/master/' is invalid - Repository 'git-tzolov' will be blacklisted.
[ERROR] Unable to determine if resource antlr:antlr:jar:2.7.7:compile exists in http://maven.glassfish.org/content/groups/glassfish
[ERROR] Unable to determine if resource antlr:antlr:jar:2.7.7:compile exists in http://download.java.net/maven/2/
[ERROR] Unable to determine if resource antlr:antlr:jar:2.7.7:compile exists in http://oss.sonatype.org/content/repositories/jetty-snapshots
[ERROR] Unable to determine if resource antlr:antlr:jar:2.7.7:compile exists in http://download.java.net/maven/glassfish
[ERROR] Unable to determine if resource ch.qos.logback:logback-access:jar:1.2.3:compile exists in http://maven.glassfish.org/content/groups/glassfish
[ERROR] Unable to determine if resource ch.qos.logback:logback-access:jar:1.2.3:compile exists in http://download.java.net/maven/2/
[ERROR] Unable to determine if resource ch.qos.logback:logback-access:jar:1.2.3:compile exists in http://oss.sonatype.org/content/repositories/jetty-snapshots
[ERROR] Unable to determine if resource ch.qos.logback:logback-access:jar:1.2.3:compile exists in http://download.java.net/maven/glassfish
[ERROR] Unable to determine if resource ch.qos.logback:logback-classic:jar:1.2.3:compile exists in http://maven.glassfish.org/content/groups/glassfish
[ERROR] Unable to determine if resource ch.qos.logback:logback-classic:jar:1.2.3:compile exists in http://download.java.net/maven/2/
[ERROR] Unable to determine if resource ch.qos.logback:logback-classic:jar:1.2.3:compile exists in http://oss.sonatype.org/content/repositories/jetty-snapshots
[ERROR] Unable to determine if resource ch.qos.logback:logback-classic:jar:1.2.3:compile exists in http://download.java.net/maven/glassfish
[ERROR] Unable to determine if resource ch.qos.logback:logback-core:jar:1.2.3:compile exists in http://maven.glassfish.org/content/groups/glassfish
[ERROR] Unable to determine if resource ch.qos.logback:logback-core:jar:1.2.3:compile exists in http://download.java.net/maven/2/
[ERROR] Unable to determine if resource ch.qos.logback:logback-core:jar:1.2.3:compile exists in http://oss.sonatype.org/content/repositories/jetty-snapshots
[ERROR] Unable to determine if resource ch.qos.logback:logback-core:jar:1.2.3:compile exists in http://download.java.net/maven/glassfish
[ERROR] Unable to determine if resource com.101tec:zkclient:jar:0.10:compile exists in http://maven.glassfish.org/content/groups/glassfish
[ERROR] Unable to determine if resource com.101tec:zkclient:jar:0.10:compile exists in http://download.java.net/maven/2/
As a short-term mitigation, <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
is specified for maven-project-info-reports-plugin
.
POST
/PUT
.Target
resource.curl
configuration files for each request.
Audience
resource.SMSMessageQueue
during the unit of work’s execution.Target
resource.noti
makes use of DriverManager.getConnection()
directly.io.dropwizard.db
contains types that allow for usage of connection pools.For example:
application/protobuf
application/x-protobuf
How should I handle this?
Audience
resource.Audience
resource.It would be beneficial to support another hypermedia-based representation format. HAL seems like a great candidate.
It should support:
application/hal+json
application/hal+xml
UnitOfWork
extend AutoCloseable
.PUT
request on the parent resource itself.Audience
resource when an HTTP PUT
request is issued for that Audience
resource. However, if a PUT
request is issued for any of the sub-resource within that Audience
resource, such as to change the state of one of its members, the representation revision would not be incremented, and thus, and new entity tag would not be generated.There is a need to be able to trace through various aspects of the system to determine bottlenecks. It is also important to support tracing so that external clients that also utilize the Open Tracing standard can analyze traces across service boundaries.
application/json
for example):{
"countryCode" : "1",
"number": "1231231234",
"E164": "+1.1231231234"
}
Audience
resource.Identity Map
.
UnitOfWork#save()
or UnifOfWork#undo()
....its time.
DriverManager.getConnection()
is used to establish a connection to the MySQL storage. This solution does not optimize connections to the database.NOTI
should leverage a connection pool to make more efficient use of database connections.Accept*
headers are analyzed for proactive negotiation purposes.
Accept
header when determining how to generate outgoing representations.health
topic.string
.Tag
was the first swing at providing a mechanism for grouping various Target
s in a logical way.Audience
, there is no longer a need for the concept of Tag
. Therefore it should be removed.A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.