strolch-website/docs/documentation/index.xml

25 lines
16 KiB
XML

<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Documentation on Strolch</title><link>https://strolch.li/documentation/</link><description>Recent content in Documentation on Strolch</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><atom:link href="https://strolch.li/documentation/index.xml" rel="self" type="application/rss+xml"/><item><title>Architecture</title><link>https://strolch.li/documentation/architecture/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/architecture/</guid><description>Architecture Birds View A Strolch agent&amp;rsquo;s architecture can be seen as a simple three-tier architecture. The presentation layer is mostly a web frontend, where the communication with the agent is done via REST API calls.
The agent itself implements the business logic using Services, Commands, Queries etc.
The agent can communicate with other 3rd systems using any API, where it is preferred to use JSON over REST.
The agent can use a standard RDBMS as a storage system, where currently DAOs have been implemented only for PostgreSQL.</description></item><item><title>Model</title><link>https://strolch.li/documentation/model/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/model/</guid><description>Model Before we dive into the entire model, let&amp;rsquo;s show an example and how it would be modelled in Strolch and use in Strolch:
A possible model would look as follows:
&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34; ?&amp;gt; &amp;lt;StrolchModel xmlns=&amp;#34;https://strolch.li/xsd/StrolchModel-1.6.xsd&amp;#34;&amp;gt; &amp;lt;Resource Id=&amp;#34;Product&amp;#34; Name=&amp;#34;Product Template&amp;#34; Type=&amp;#34;Template&amp;#34;&amp;gt; &amp;lt;ParameterBag Id=&amp;#34;parameters&amp;#34; Name=&amp;#34;Parameters&amp;#34; Type=&amp;#34;Parameters&amp;#34;&amp;gt; &amp;lt;Parameter Id=&amp;#34;description&amp;#34; Name=&amp;#34;Description&amp;#34; Type=&amp;#34;String&amp;#34; Value=&amp;#34;&amp;#34;/&amp;gt; &amp;lt;Parameter Id=&amp;#34;color&amp;#34; Name=&amp;#34;Color&amp;#34; Type=&amp;#34;String&amp;#34; Value=&amp;#34;&amp;#34;/&amp;gt; &amp;lt;Parameter Id=&amp;#34;form&amp;#34; Name=&amp;#34;Form&amp;#34; Type=&amp;#34;String&amp;#34; Value=&amp;#34;&amp;#34;/&amp;gt; &amp;lt;/ParameterBag&amp;gt; &amp;lt;ParameterBag Id=&amp;#34;relations&amp;#34; Name=&amp;#34;Relations&amp;#34; Type=&amp;#34;Relations&amp;#34;&amp;gt; &amp;lt;Parameter Id=&amp;#34;articles&amp;#34; Name=&amp;#34;Articles&amp;#34; Type=&amp;#34;StringList&amp;#34; Interpretation=&amp;#34;Resource-Ref&amp;#34; Uom=&amp;#34;Article&amp;#34; Value=&amp;#34;&amp;#34;/&amp;gt; &amp;lt;/ParameterBag&amp;gt; &amp;lt;/Resource&amp;gt; &amp;lt;Resource Id=&amp;#34;Article&amp;#34; Name=&amp;#34;Article Template&amp;#34; Type=&amp;#34;Template&amp;#34;&amp;gt; &amp;lt;ParameterBag Id=&amp;#34;parameters&amp;#34; Name=&amp;#34;Parameters&amp;#34; Type=&amp;#34;Parameters&amp;#34;&amp;gt; &amp;lt;Parameter Id=&amp;#34;description&amp;#34; Name=&amp;#34;Description&amp;#34; Type=&amp;#34;String&amp;#34; Value=&amp;#34;&amp;#34;/&amp;gt; &amp;lt;Parameter Id=&amp;#34;barcode&amp;#34; Name=&amp;#34;Barcode&amp;#34; Type=&amp;#34;String&amp;#34; Value=&amp;#34;&amp;#34;/&amp;gt; &amp;lt;/ParameterBag&amp;gt; &amp;lt;ParameterBag Id=&amp;#34;relations&amp;#34; Name=&amp;#34;Relations&amp;#34; Type=&amp;#34;Relations&amp;#34;&amp;gt; &amp;lt;Parameter Id=&amp;#34;product&amp;#34; Name=&amp;#34;Product&amp;#34; Type=&amp;#34;String&amp;#34; Interpretation=&amp;#34;Resource-Ref&amp;#34; Uom=&amp;#34;Product&amp;#34; Value=&amp;#34;&amp;#34;/&amp;gt; &amp;lt;/ParameterBag&amp;gt; &amp;lt;/Resource&amp;gt; &amp;lt;Resource Id=&amp;#34;Customer&amp;#34; Name=&amp;#34;Customer Template&amp;#34; Type=&amp;#34;Template&amp;#34;&amp;gt; &amp;lt;ParameterBag Id=&amp;#34;address&amp;#34; Name=&amp;#34;Address&amp;#34; Type=&amp;#34;Address&amp;#34;&amp;gt; &amp;lt;Parameter Id=&amp;#34;street&amp;#34; Name=&amp;#34;Street&amp;#34; Type=&amp;#34;String&amp;#34; Value=&amp;#34;&amp;#34;/&amp;gt; &amp;lt;Parameter Id=&amp;#34;zip&amp;#34; Name=&amp;#34;Zip&amp;#34; Type=&amp;#34;String&amp;#34; Value=&amp;#34;&amp;#34;/&amp;gt; &amp;lt;Parameter Id=&amp;#34;city&amp;#34; Name=&amp;#34;City&amp;#34; Type=&amp;#34;String&amp;#34; Value=&amp;#34;&amp;#34;/&amp;gt; &amp;lt;Parameter Id=&amp;#34;country&amp;#34; Name=&amp;#34;Country&amp;#34; Type=&amp;#34;String&amp;#34; Value=&amp;#34;&amp;#34;/&amp;gt; &amp;lt;/ParameterBag&amp;gt; &amp;lt;/Resource&amp;gt; &amp;lt;Order Id=&amp;#34;Order&amp;#34; Name=&amp;#34;Order&amp;#34; Type=&amp;#34;Template&amp;#34;&amp;gt; &amp;lt;ParameterBag Id=&amp;#34;quantities&amp;#34; Name=&amp;#34;Quantities per Article Id&amp;#34; Type=&amp;#34;Quantities&amp;#34;&amp;gt; &amp;lt;Parameter Id=&amp;#34;quantity&amp;#34; Name=&amp;#34;Quantity&amp;#34; Type=&amp;#34;Float&amp;#34; Value=&amp;#34;0&amp;#34;/&amp;gt; &amp;lt;/ParameterBag&amp;gt; &amp;lt;ParameterBag Id=&amp;#34;relations&amp;#34; Name=&amp;#34;Relations&amp;#34; Type=&amp;#34;Relations&amp;#34;&amp;gt; &amp;lt;Parameter Id=&amp;#34;articles&amp;#34; Name=&amp;#34;Articles&amp;#34; Type=&amp;#34;StringList&amp;#34; Interpretation=&amp;#34;Resource-Ref&amp;#34; Uom=&amp;#34;Article&amp;#34; Value=&amp;#34;&amp;#34;/&amp;gt; &amp;lt;Parameter Id=&amp;#34;customer&amp;#34; Name=&amp;#34;Customer&amp;#34; Type=&amp;#34;String&amp;#34; Interpretation=&amp;#34;Resource-Ref&amp;#34; Uom=&amp;#34;Customer&amp;#34; Value=&amp;#34;&amp;#34;/&amp;gt; &amp;lt;/ParameterBag&amp;gt; &amp;lt;/Order&amp;gt; &amp;lt;/StrolchModel&amp;gt; Let&amp;rsquo;s go through this model:</description></item><item><title>Do and Don't</title><link>https://strolch.li/documentation/do-and-donts/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/do-and-donts/</guid><description>This page discusses things you should and shouldn&amp;rsquo;t do when using Strolch The following is a simple list of do&amp;rsquo;s and don&amp;rsquo;ts:
1 Service per use-case, should mostly delegate to Commands. Commands implement use-cases or parts of it, and are thus reusable. Subclass ResourceSearch, OrderSearch and ActivitySearch when implementing use-case specific search - this allows privilege checking. One Transaction at a time - no TX inside of another TX. Commands are added to TXs and performed on close: tx.</description></item><item><title>Runtime Configuration</title><link>https://strolch.li/documentation/runtime-configuration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/runtime-configuration/</guid><description>Runtime Configuration A Strolch runtime configuration comprises two parts: a configuration part, and a model part. The configuration are files located in the ..config/ folder, and the model are files located in the ../data folder.
In an absolute minimal configuration, the Strolch runtime requires the following folder structure:
../config/ ../StrolchConfiguration.xml → configures the Strolch agent ../PrivilegeConfig.xml → configures user management ../PrivilegeUsers.xml → contains the users in an XML based user management file .</description></item><item><title>Realms</title><link>https://strolch.li/documentation/realms/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/realms/</guid><description>Realms Realms implement multi-tenant capabilities. A Strolch agent can have an arbitrary number of realms configured and each realm has its own persistence configuration, allowing to separate mandates completely.
A realm can run in one of the following modes:
EMPTY This is a transient data store mode, where no model changes are persisted - they are only kept in memory. When the Strolch agent is started, this realm is empty as no data is loaded.</description></item><item><title>Components</title><link>https://strolch.li/documentation/components/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/components/</guid><description>Components A Strolch agent can be easily extended with arbitrary components. An agent is basically a container for classes extending StrolchComponent with a life cycle. These classes mostly implement an interface which describes the operations that are supported by the component.
The following represents a list of the most used components:
RealmHandler: li.strolch.agent.impl.DefaultRealmHandler PrivilegeHandler: li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler EnumHandler: li.strolch.runtime.query.enums.DefaultEnumHandler PolicyHandler: li.strolch.policy.DefaultPolicyHandler ServiceHandler: li.strolch.service.api.DefaultServiceHandler StrolchSessionHandler: li.strolch.rest.DefaultStrolchSessionHandler PersistenceHandler: multiple implementations PostInitializer: project specific implementation MailHandler: li.</description></item><item><title>Services and Commands</title><link>https://strolch.li/documentation/services-and-commands/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/services-and-commands/</guid><description>Services and Commands Services are written to implement a specific use-case. Commands are written to implement re-usable parts of a use-case. The use-case can be abstract e.g., AddResourceService or very specific e.g. CreatePatientService.
Should the use-case be re-usable in different scenarios, then commands should implement the logic, and the services should then execute the commands. E.g. The CreatePatientService would use a CreatePatientResourceCommand and then use an AddResourceCommand in a single transaction, so that the task of creating the actual Patient Resource can be re-used somewhere else.</description></item><item><title>Searches</title><link>https://strolch.li/documentation/searches/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/searches/</guid><description>Searches As is custom for every framework, querying, or searching, the model must be possible. Strolch searches are implemented using the StrolchSearch class and one of its concrete implementations: ResourceSearch, OrderSearch, ActivitySearch.
A Strolch element always has two identifiers: Type and Id. The type is important as it classifies an element. So if a car and a house would be modelled in Strolch, then those would both be a Resource, but one of type Car and the other of type House.</description></item><item><title>Queries</title><link>https://strolch.li/documentation/queries/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/queries/</guid><description>Queries The Query API is deprecated and the search API should be used instead.
As is custom for every framework, querying the model must be possible. Strolch queries are implemented using the StrolchQuery interface and one of its concrete implementations: ResourceQuery, OrderQuery, ActivityQuery.
A Strolch element always has two identifiers: Type and Id. The type is important as it classifies an element. So if a car and a house would be modelled in Strolch, then those would both be a Resource, but one of type Car and the other of type House.</description></item><item><title>Transactions</title><link>https://strolch.li/documentation/transactions/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/transactions/</guid><description>Transactions Strolch Transactions play a central role in a Strolch agent. A transaction is opened for a realm, and grants access to the model of the agent. Transactions are implemented as a Java try-with-resources by implementing the AutoCloseable interface. This makes it trivial to understand the scope of a transaction.
Transactions handle the following:
Opening and closing database connections Releasing locks to strolch elements, if tx.lock(StrolchRootElement) or tx.lock(Locator) was called Performing Commands by executing them in the added order, and validating them first.</description></item><item><title>Policies</title><link>https://strolch.li/documentation/policies/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/policies/</guid><description>Policies Policies are an integral part when writing business logic in Strolch. In many cases it would suffice to write all such logic in Services and Commands, but as soon as behaviour can change, depending on the element being accessed, then this would quickly lead to many if/else blocks.
Since writing large if/else blocks is not maintanable in the long run, Strolch offers a different approach. All Strolch elements can store Policy definitions.</description></item><item><title>Observers</title><link>https://strolch.li/documentation/observers/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/observers/</guid><description>Observers All changes done in a Strolch transaction are recorded and then propagated to any registered observers.
The observer feature is opt-in and is configured for each realm. In the StrolchConfiguration.xml file enable observers by adding the enableObserverUpdates property per realm:
&amp;lt;StrolchConfiguration&amp;gt; &amp;lt;env id=&amp;#34;dev&amp;#34;&amp;gt; ... &amp;lt;Component&amp;gt; &amp;lt;name&amp;gt;RealmHandler&amp;lt;/name&amp;gt; &amp;lt;api&amp;gt;li.strolch.agent.api.RealmHandler&amp;lt;/api&amp;gt; &amp;lt;impl&amp;gt;li.strolch.agent.impl.DefaultRealmHandler&amp;lt;/impl&amp;gt; &amp;lt;depends&amp;gt;PrivilegeHandler&amp;lt;/depends&amp;gt; &amp;lt;Properties&amp;gt; &amp;lt;realms&amp;gt;defaultRealm, otherRealm&amp;lt;/realms&amp;gt; &amp;lt;enableObserverUpdates&amp;gt;true&amp;lt;/enableObserverUpdates&amp;gt; &amp;lt;dataStoreMode&amp;gt;TRANSIENT&amp;lt;/dataStoreMode&amp;gt; &amp;lt;dataStoreFile&amp;gt;StrolchModel.xml&amp;lt;/dataStoreFile&amp;gt; &amp;lt;enableObserverUpdates.otherRealm&amp;gt;true&amp;lt;/enableObserverUpdates.otherRealm&amp;gt; &amp;lt;dataStoreMode.otherRealm&amp;gt;TRANSIENT&amp;lt;/dataStoreMode.otherRealm&amp;gt; &amp;lt;dataStoreFile.otherRealm&amp;gt;StrolchModel.xml&amp;lt;/dataStoreFile.otherRealm&amp;gt; &amp;lt;/Properties&amp;gt; &amp;lt;/Component&amp;gt; &amp;lt;/env&amp;gt; ... &amp;lt;/StrolchConfiguration&amp;gt; Registering for updates is done by registering an Observer on the ObserverHandler of the realm itself:</description></item><item><title>Versioning</title><link>https://strolch.li/documentation/versioning/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/versioning/</guid><description>Versioning One of Strolch&amp;rsquo;s features that sets it apart from other frameworks, is that versioning is baked into Strolch&amp;rsquo;s fabric. The feature is opt-in, as it is not required in all projects, but it only needs enabling, for all modifications to objects to be versioned, so that rollbacks can be done when needed.
The feature is enabled for each realm. In the StrolchConfiguration.xml file enable it by adding the enableVersioning propery per realm:</description></item><item><title>Reports</title><link>https://strolch.li/documentation/reports/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/reports/</guid><description>Reports Since Strolch has a generic model, it was rather straight forward to create a simple API for writing reports. In Strolch a report is defined by using its own model, i.e. a Report is a Resource of type Report.
A report consists of the following parts:
policy definition, thus allowing extensions basic configuration like base object type, order direction, etc. column definitions joins ordering definition filters An example of a report is as follows:</description></item><item><title>Privileges</title><link>https://strolch.li/documentation/priviles/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://strolch.li/documentation/priviles/</guid><description>Privileges No framework is complete without user management and privilege validation. The basic form would be Users and Roles, and then validating that an authenticated user has a given role. In Strolch we go a step further: A User has roles assigned, and each role has a set of Privileges. The privileges can overlap, a validation is performed to make sure that the one role doesn&amp;rsquo;t deny and another role allows a specific action.</description></item></channel></rss>