[
https://issues.apache.org/jira/browse/JAMES-3581?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17343774#comment-17343774
]
René Cordier commented on JAMES-3581:
-------------------------------------
https://github.com/apache/james-project/pull/391 answers this
https://github.com/apache/james-project/pull/427 enhances this with no breaking
change
> As a JMAP extension writer, I want to PUSH state changes for my extensions
> --------------------------------------------------------------------------
>
> Key: JAMES-3581
> URL: https://issues.apache.org/jira/browse/JAMES-3581
> Project: James Server
> Issue Type: Improvement
> Components: JMAP
> Affects Versions: 3.6.0
> Reporter: Benoit Tellier
> Assignee: Antoine Duprat
> Priority: Major
> Fix For: 3.7.0
>
> Time Spent: 1.5h
> Remaining Estimate: 0h
>
> h2. Why?
> JMAP specifications defines the minimal features to get a basic email
> reading/writing experience.
> However, as part of our job at Linagora, writing a collaborative email suite,
> we need advanced collaborative features that uses custom, off-spec, JMAP
> extensions.
> We thus want to implement these collaborative features as JMAP extensions
> (because JMAP is so much of a nice protocol!).
> We were able to:
> - Write custom methods pretty much directly.
> - We needed to contribute modular definition of session "capabilities" to be
> advertising our custom ones.
> But we are missing the push for custom extensions.
> h2. What?
> As an extension developper I want to be able to register my type states and
> have states matching my format:
> {code:java}
> object IntState {
> def parse(string: String): Either[IllegalArgumentException, IntState] =
> Try(Integer.parseInt(string))
> .toEither
> .map(IntState(_))
> .left.map(new IllegalArgumentException(_))
> }
> case class IntState(i: Int) extends State {
> override def serialize: String = i.toString
> }
> case object CustomTypeName extends TypeName {
> override val asString: String = "MyTypeName"
> override def parse(string: String): Option[TypeName] = string match {
> case CustomTypeName.asString => Some(CustomTypeName)
> case _ => None
> }
> override def parseState(string: String): Either[IllegalArgumentException,
> IntState] = IntState.parse(string)
> }
> {code}
> Given this, I want to be injecting my extensions to the push in the guice
> module definition:
> {code:java}
> Multibinder.newSetBinder(binder(), classOf[TypeName])
> .addBinding()
> .toInstance(CustomTypeName)
> Multibinder.newSetBinder(binder(), classOf[GuiceProbe])
> .addBinding()
> .to(classOf[JmapEventBusProbe])
> {code}
> Doing so should allow me to emit 'custon' state change push notifications:
> {code:java}
> val stateChangeEvent: StateChangeEvent = StateChangeEvent(eventId =
> CustomMethodContract.eventId, username = BOB, map = Map(CustomTypeName ->
> intState))
> SMono(jmapEventBus.dispatch(stateChangeEvent,
> AccountIdRegistrationKey(accountId))).block()
> {code}
> Which allows generating state change events PUSH notifications carried over
> via webSocket or SSE for your extensions :-)
> h2. How?
> Modularize the definition of State (extensions might not want to have it
> backed by a UUID), allow creating custom type states (parse them, and from
> them be able to parse the associated state). We also need to transport these
> additional type states as part of our event system.
> h2. Definition of done
> Write an integration test where you emit a custom type state with an exotic
> state implementation (meaning not backed by a UUID) and have the StateChange
> event carried over to the client, for instance using WebSocket.
> h2. Proof of concept
> Quan had been putting this PR together:
> https://github.com/apache/james-project/pull/391
--
This message was sent by Atlassian Jira
(v8.3.4#803005)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]