[ 
https://issues.apache.org/jira/browse/QPID-8361?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16930559#comment-16930559
 ] 

ASF GitHub Bot commented on QPID-8361:
--------------------------------------

vavrtom commented on pull request #36: QPID-8361: [Broker-J] Create a developer 
guide for Qpid Broker-J
URL: https://github.com/apache/qpid-broker-j/pull/36#discussion_r324201489
 
 

 ##########
 File path: doc/developer-guide/src/main/markdown/architecture.md
 ##########
 @@ -0,0 +1,399 @@
+# High Level Architecture
+
+This article provides a high level description of the architecture of Qpid 
Broker-J.
+
+Broker-J is messaging broker that implements the AMQP protocols (version 0-8, 
0-9, 0-91, 0-10 and 1.0).
+Any AMQP compliant messaging library can be used with the Broker. The Broker 
supports on the fly message translation
+from one AMQP protocol to another, meaning it is possible to use the Broker to 
allow clients that use different
+AMQP protocol version to exchange messages. It can be managed over a built in 
HTTP interface
+(that presents a REST API and a Web Management Console), or by AMQP Management 
(early draft implementation).
+
+The Broker has a highly pluggable architecture that allows alternative 
implementations to be substituted for any concern.
+For instance, you can simply build a module delegating to your own storage or 
own authentication provider linking
+to your enterprise authentication backend.
+
+Broker-J is 100% pure Java.  It can be run standalone or embedded within 
another Java applications.
+
+## Model
+
+A tree of manageable categories, all of which extend of the interface 
`ConfiguredObject`, underpin the `Broker`.
+A `ConfiguredObject` has zero or more attributes, zero or more children and 
zero or more context variable name/value pairs.
+A `ConfiguredObject` may be persisted to a configuration store so its state 
can be restored when the Broker is restarted.
+The manageable categories are arranged into a tree structure.  `SystemConfig` 
is at the root and has a single descendent
+`Broker`.  The `Broker` itself has children: `Port`, `AuthenticationProvider`, 
`VirtualHostNode` amongst others.
+`VirtualHostNode` has a child `VirtualHost`.  The children of the 
`VirtualHost` are categories that directly involved
+in messaging such as `Queue`. The diagram below illustrates the category 
hierarchy but many categories are elided for brevity.
+The model tree structure is codified in the `BrokerModel` class.
+
+![Broker Model](images/model.png)
+
+## Category Specializations
+
+Some categories have specialisations.  An example is the category `Queue`.  It 
has specialisations corresponding to
+the queue types supported by the `Broker` e.g. `StandardQueue`, 
`PrirorityQueue` etc.
+
+### Attributes
+
+Each `ConfiguredObject` instance has zero or more attributes.   Attributes 
have a name and a value which can be
+a Java primitive value or an instance of any class for which an 
`AttributeValueConverter` exist.  This mechanism allows
+ attribute values to be `Lists`, `Sets`, `Maps`, or arbitrary structured types 
`ManagedAttributeValues`.
+
+Attributes are marked up in the code with method annotations 
`@ManagedAttribute` which defines things
+whether the attribute is mandatory or mutable.  Attributes can also be marked 
a secure which indicates restrictions
+ no how the attribute is used (used for attributes that that store passwords 
or private-keys).
+
+Attributes can have default values. The default value applies if the user 
omits to supply a value when the object
+is created.  Defaults themselves can be defined in terms of `context variable` 
references.
+
+### Context Variables
+
+Each `ConfiguredObject` instance has zero or more context variable 
assignments. These are simply name/value pairs
+where both name and value are strings.
+
+When resolving an attribute's value, if the attribute's value (or attribute's 
default) contains a context variable
+reference (e.g. `${foo}`), the variable is first resolved using the 
`ConfiguredObject`'s own context variables.
+If the `ConfiguedObject` has no definition for the context variable, the 
entity's parent is tried,
+then its grandparent and so forth, all the way until the `SystemContext` is 
reached.
+If the `SystemContext` provides no value, the JVM's system properties are 
consulted.
+
+A context variable's value can be defined in terms of other context variables.
+
+Context variables are useful for extracting environment specific information 
from configuration for instance path stems
+or port numbers.
+
+## Lifecycle
+
+`ConfiguredObjects` have a lifecycle.
+
+A `ConfiguredObject` is created exactly once by a call its parent's 
`#createChild()` method.
+This brings the object into existence.  It goes through a number of phases 
during creation (`ConfiguredObject#create`)
+
+ * resolution (where the attribute values are resolved and assigned to the 
object)
+ * creation validation (ensuring business rules are adhered to)
+ * registration with parents
+ * implementation specific creation (`#onCreate`)
+ * implementation specific opening (`#onOpen`)
+
+When the `Broker` is restarted objects that exist in the configuration store 
are said to be recovered.
+During recovery, they follow the opening (`ConfiguredObject#open`)
+
+ * resolution (where the attribute values are resolved and assigned to the 
object)
+ * validation (ensuring business rules are adhered to)
+ * implementation specific opening (#onOpen)
+
+Some `ConfiguredObjects` support starting (`ConfiguredObject#start()`) and 
stopping (`ConfiguredObject#stop()`)
+ but this have not yet been extended to all objects.
+
+`ConfiguredObject#delete()` caused the object to be deleted.
+
+## AbstractConfiguredObject
+
+Most configured object implementations extend `AbstractConfiguredObject` 
(ACO). ACO provides the mechanics
+behind the configured implementations: attributes, context variables, state 
and lifecycle,
+and a listener mechanism: `ConfigurationChangeListener`.
+
+## Threading
+
+The threading model used by the model must be understood before changes can be 
made safely.
+
+The `Broker` and `VirtualHost` `ConfiguredObject` instances have a task 
executor backed by single configuration thread.
+Whenever the a configuration object needs to be changed, that change MUST be 
made by the nearest ancestor's
+configuration thread.  This approach ensures avoids the need to employ 
locking.  Any thread is allowed to observe
+ the state of a `ConfiguredObject` at any time.  For this reasons, changes 
must be published safely, so they can be
+read consistently by the observing threads.
+
+The implementations of the mutating methods (`#setAttributes()`, `#start()`, 
#`stop()`, etc) within
+`AbstractConfiguredObject` are already implemented to adhere to these rules.
+
+## Configuration Persistence
+
+`ConfiguredObject` categories such as `SystemConfig` and `VirtualhostNode` 
take responsibility for managing the storage
+of their children.  This is marked up in the model with the `@ManagedObject` 
annotation (`#managesChildren`).
+These objects utilise a `DurableConfigurationStore` to persist their durable 
children to storage.
+`ConfigurationChangeListener` are used to trigger the update of the storage 
each time a `ConfiguredObject` is changed.
+
+## AMQP Transport Layer
+
+At the high level, the transport layer
+
+ * accepts bytes from the wire and passes them to the protocol engines.
+ * pulls bytes from the protocol engines and pushes them down the wire.
+
+There are two AMQP Transport Layers in Broker-J.
+
+ * Traditional TCP/IP connections
+ * Websocket
+
+We'll consider the two layers separately below.
+
+The transport is responsible for TLS.  The TLS configuration is defined on the 
`Port`, `Keystore` and `Truststore`
+model objects.  If so configured, it is the transport's responsibility to 
manage the TLS connection.
+
+### TCP/IP
+
+This layer is implemented from first principles using Java NIO.
+
+It is non-blocking in nature.
+
+It uses a `Selector` to monitor all connected sockets (and the accepting 
socket) for work.
+Once work is detected (i.e. the `selector` returns) the connection work is 
serviced by threads drawn from
+an IO thread pool.  An 
[eat-what-you-kill](https://webtide.com/eat-what-you-kill/) pattern is used to 
reduce dispatch latency.
+This works in the following way. The worker thread that performed the select, 
after adding all the ready connections
+to the work queue, adds the selector task to the work queue and then starts to 
process the work queue itself
+(this is the eat what you kill bit).  This approach potentially avoids the 
dispatch latency between the thread
+ that performed select and another thread from the IO thread pool. The 
`Selector` is the responsibility of the
+`SelectorThread` class.
+
+A connections to a client is represented by a `NonBlockingConnection` 
instance.  The `SelectorThread` causes the
+`NonBlockingConnections` that require IO work to be executed 
(`NonBlockingConnection#doWork`) on a thread from
+an IO thread pool (owned by `NetworkConnectionScheduler`).  On each work 
cycle, the `NonBlockingConnection` first goes
+through a write phase where pending work is pulled from the protocol engine 
producing bytes for the wire in the process.
+If all the pending work is sent completely (i.e. the outbound network buffer 
is not exhausted),
+the next phase is a read phase. The bytes are consumed from the channel and 
fed into the protocol engine.
+Finally, there is a further write phase to send any new bytes resulting from 
the input we have just read.
+The write/read/write sequence is organised so in order that the `Broker` first 
evacuates as much state from memory
+ as possible (thus freeing memory) before reading new bytes from the wire.
+
+In addition to the `NonBlockingConnection` being scheduled when singled by the 
`Selector`, the `Broker` may need
+to awaken them at other times.  For instance, if a message arrives on a queue 
that is suitable for a consumer,
+the `NonBlockingConnection` associated with that consumer must awoken. The 
mechanism that does this is
+`NetworkConnectionScheduler#schedule` method which adds it to the work queue. 
This is wired to the protocol engine via
+a listener.
+
+### Threading
+
+The only threads that execute `NonBlockingConnnections` are those of the 
`NetworkConnectionScheduler`.
+Furthermore, it is imperative that no `NonBlockingConnnection` is executed by 
more than one thread at once.
+It is the job of `ConnectorProcessor` to organise this exclusivity. Updates 
made by `NonBlockingConnnection` must
+be published safely so they can be read consistently by the other threads in 
the pool.
+
+There is a `NetworkConnectionScheduler` associated with each AMQP Port and 
each `VirtiualHost`.
+When a connection is made to the `Broker`, the initial exchanges between peer 
and broker
+(protocol headers, authentication etc) take place on the thread pool of the 
`NetworkConnectionScheduler` of the `Port`.
+Once the connection has indicated which `VirtualHost` it wishes to connect to, 
responsibility for the
+`NonBlockingConnection` shifts to the `NetworkConnectionScheduler` of the 
`VirtualHost`.
+
+### TLS
+
+The TCP/IP transport layer responds to the TLS configuration provided by the 
`Port`, `Keystore` and `Truststore model` objects.
 
 Review comment:
   Inline code should be only for word `Truststore`
 
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


> [Broker-J] Create a developer guide for Qpid Broker-J
> -----------------------------------------------------
>
>                 Key: QPID-8361
>                 URL: https://issues.apache.org/jira/browse/QPID-8361
>             Project: Qpid
>          Issue Type: Task
>          Components: Broker-J
>            Reporter: Alex Rudyy
>            Priority: Major
>             Fix For: qpid-java-broker-8.0.0
>
>
> The developer documentation is currently scattered over various Qpid 
> confluence pages. It could be challenging for people interested in 
> contributing to the project to find that documentation. A developer guide 
> could be added to cover such aspects as
> * Environment Setup
> * Building project
> * Running tests
> * Releasing
> * Architecture overview
> The following wiki pages are good candidates for inclusion into a developer 
> guide:
> [High Level 
> Architecture|https://cwiki.apache.org/confluence/display/qpid/High+Level+Architecture]
> [How To Build Qpid 
> Broker-J|https://cwiki.apache.org/confluence/display/qpid/How+To+Build+Qpid+Broker-J]
> [Releasing Qpid 
> Broker-J|https://cwiki.apache.org/confluence/display/qpid/Releasing+Qpid+Broker-J]
> The wiki pages below might be included as well
> [Java Coding 
> Standards|https://cwiki.apache.org/confluence/display/qpid/Java+Coding+Standards]
> [Qpid Java Run 
> Scripts|https://cwiki.apache.org/confluence/display/qpid/Qpid+Java+Run+Scripts]
> The developer documentation should be easy to modify, maintain and preview. 
> Thus, it can be written in  markdown or 
> [asciidoc|https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/]. The 
> latter is also supported on github. 
> Potentially, it can be published on Qpid  project site as part of release 
> process.



--
This message was sent by Atlassian Jira
(v8.3.2#803003)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@qpid.apache.org
For additional commands, e-mail: dev-h...@qpid.apache.org

Reply via email to