strolch-website/docs/documentation/runtime-configuration/index.html

111 lines
24 KiB
HTML

<!doctype html><html lang=en class="js csstransforms3d"><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=generator content="Hugo 0.80.0"><meta name=description content="Strolch is a parameterized framework for use on servers and IoT"><meta name=author content="Strolch"><link rel=icon href=/favicon.ico type=image/ico><title>Runtime Configuration - Strolch</title><link href=/css/nucleus.css?1626091328 rel=stylesheet><link href=/css/fontawesome-all.min.css?1626091328 rel=stylesheet><link href=/css/hybrid.css?1626091328 rel=stylesheet><link href=/css/featherlight.min.css?1626091328 rel=stylesheet><link href=/css/perfect-scrollbar.min.css?1626091328 rel=stylesheet><link href=/css/auto-complete.css?1626091328 rel=stylesheet><link href=/css/atom-one-dark-reasonable.css?1626091328 rel=stylesheet><link href=/css/theme.css?1626091328 rel=stylesheet><link href=/css/hugo-theme.css?1626091328 rel=stylesheet><link href=/css/theme-green.css?1626091328 rel=stylesheet><script src=/js/jquery-3.3.1.min.js?1626091328></script><style>:root #header+#content>#left>#rlblock_left{display:none!important}</style></head><body data-url=/documentation/runtime-configuration/><nav id=sidebar><div id=header-wrapper><div id=header><a id=logo href=/><img src=/logo.png></a></div><div class=searchbox><label for=search-by><i class="fas fa-search"></i></label><input data-search-input id=search-by type=search placeholder=Search...>
<span data-search-clear><i class="fas fa-times"></i></span></div><script type=text/javascript src=/js/lunr.min.js?1626091328></script><script type=text/javascript src=/js/auto-complete.js?1626091328></script><script type=text/javascript>var baseurl="https:\/\/strolch.li\/";</script><script type=text/javascript src=/js/search.js?1626091328></script></div><section id=homelinks><ul><li><a class=padding href=/><i class="fas fa-home"></i>Home</a></li></ul></section><div class=highlightable><ul class=topics><li data-nav-id=/api/ title=API class=dd-item><a href=/api/>API</a></li><li data-nav-id=/history/ title=History class=dd-item><a href=/history/>History</a></li><li data-nav-id=/documentation/ title=Documentation class="dd-item
parent"><a href=/documentation/>Documentation</a><ul><li data-nav-id=/documentation/architecture/ title=Architecture class=dd-item><a href=/documentation/architecture/>Architecture</a></li><li data-nav-id=/documentation/model/ title=Model class=dd-item><a href=/documentation/model/>Model</a></li><li data-nav-id=/documentation/do-and-donts/ title="Do and Don't" class=dd-item><a href=/documentation/do-and-donts/>Do and Don't</a></li><li data-nav-id=/documentation/runtime-configuration/ title="Runtime Configuration" class="dd-item active"><a href=/documentation/runtime-configuration/>Runtime Configuration</a></li><li data-nav-id=/documentation/realms/ title=Realms class=dd-item><a href=/documentation/realms/>Realms</a></li><li data-nav-id=/documentation/components/ title=Components class=dd-item><a href=/documentation/components/>Components</a></li><li data-nav-id=/documentation/services-and-commands/ title="Services and Commands" class=dd-item><a href=/documentation/services-and-commands/>Services and Commands</a></li><li data-nav-id=/documentation/searches/ title=Searches class=dd-item><a href=/documentation/searches/>Searches</a></li><li data-nav-id=/documentation/queries/ title=Queries class=dd-item><a href=/documentation/queries/>Queries</a></li><li data-nav-id=/documentation/transactions/ title=Transactions class=dd-item><a href=/documentation/transactions/>Transactions</a></li><li data-nav-id=/documentation/policies/ title=Policies class=dd-item><a href=/documentation/policies/>Policies</a></li><li data-nav-id=/documentation/observers/ title=Observers class=dd-item><a href=/documentation/observers/>Observers</a></li><li data-nav-id=/documentation/versioning/ title=Versioning class=dd-item><a href=/documentation/versioning/>Versioning</a></li><li data-nav-id=/documentation/reports/ title=Reports class=dd-item><a href=/documentation/reports/>Reports</a></li><li data-nav-id=/documentation/priviles/ title=Privileges class=dd-item><a href=/documentation/priviles/>Privileges</a></li></ul></li><li data-nav-id=/plc/ title=PLC class=dd-item><a href=/plc/>PLC</a><ul><li data-nav-id=/plc/architecture/ title=Architecture class=dd-item><a href=/plc/architecture/>Architecture</a></li><li data-nav-id=/plc/example-set-up/ title="Example Set-Up" class=dd-item><a href=/plc/example-set-up/>Example Set-Up</a></li></ul></li><li data-nav-id=/tutorial/ title=Tutorial class=dd-item><a href=/tutorial/>Tutorial</a><ul><li data-nav-id=/tutorial/configuration/ title=Configuration class=dd-item><a href=/tutorial/configuration/>Configuration</a></li><li data-nav-id=/tutorial/model/ title=Model class=dd-item><a href=/tutorial/model/>Model</a></li><li data-nav-id=/tutorial/crud-book/ title="CRUD Book" class=dd-item><a href=/tutorial/crud-book/>CRUD Book</a></li></ul></li><li data-nav-id=/download/ title=Download class=dd-item><a href=/download/>Download</a></li><li data-nav-id=/development/ title=Development class=dd-item><a href=/development/>Development</a></li></ul><section id=shortcuts><h3>More</h3><ul><li><a class=padding href=https://strolch.li/tags><i class="fas fa-tags"></i>Tags</a></li><li><a class=padding href=https://github.com/strolch-li><i class="fab fa-github"></i>GitHub project</a></li></ul></section><section id=footer><p>Built with <a href=https://github.com/matcornic/hugo-theme-learn><i class="fas fa-heart"></i></a>from <a href=https://getgrav.org>Grav</a> and <a href=https://gohugo.io/>Hugo</a></p></section></div></nav><section id=body><div id=overlay></div><div class="padding highlightable"><div><div id=top-bar><div id=top-github-link><a class=github-link title="Edit this page" href=https://github.com/Pi4J/pi4j.github.io/tree/main/contentdocumentation/runtime-configuration.md target=blank><i class="fas fa-code-branch"></i><span id=top-github-link-text>Edit this page</span></a></div><div id=breadcrumbs itemscope itemtype=http://data-vocabulary.org/Breadcrumb><span id=sidebar-toggle-span><a href=# id=sidebar-toggle data-sidebar-toggle><i class="fas fa-bars"></i></a></span><span id=toc-menu><i class="fas fa-list-alt"></i></span><span class=links><a href=/>Strolch Overview</a> > <a href=/documentation/>Documentation</a> > Runtime Configuration</span></div><div class=progress><div class=wrapper><nav id=TableOfContents><ul><li><a href=#runtime-configuration>Runtime Configuration</a></li><li><a href=#strolchconfigurationxml>StrolchConfiguration.xml</a></li><li><a href=#privilege-configuration>Privilege Configuration</a></li><li><a href=#implementing-a-strolchcomponent>Implementing a StrolchComponent</a></li><li><a href=#starting-the-agent>Starting the agent</a></li></ul></nav></div></div></div></div><div id=head-tags></div><div id=body-inner><h1>Runtime Configuration</h1><h2 id=runtime-configuration>Runtime Configuration</h2><p>A Strolch runtime configuration comprises two parts: a configuration part, and
a model part. The configuration are files located in the <code>..config/</code> folder,
and the model are files located in the <code>../data</code> folder.</p><p>In an absolute minimal configuration, the Strolch runtime requires the
following folder structure:</p><ul><li><code>../config/</code><ul><li><code>../StrolchConfiguration.xml</code> → configures the Strolch agent</li><li><code>../PrivilegeConfig.xml</code> → configures user management</li><li><code>../PrivilegeUsers.xml</code> → contains the users in an XML based user management file</li><li><code>../PrivilegeRoles.xml</code> → contains the roles and privileges in an XML based user management</li></ul></li></ul><h2 id=strolchconfigurationxml>StrolchConfiguration.xml</h2><p>The StrolchConfiguration.xml file configures the Strolch agent. The StrolchConfiguration.xml defines the following:</p><ul><li><code>&lt;StrolchConfiguration></code> root element</li><li><code>&lt;env id="xxx"></code> different environments with the possibility of having a
global environment for configuration valid in multiple environments.<ul><li><code>&lt;Runtime></code> element which defines the agents name and a few other
properties e.g. <code>locale</code> and <code>verbose</code>:</li><li><code>&lt;applicationName></code> the agent&rsquo;s name</li><li><code>&lt;Properties></code><ul><li><code>&lt;locale></code> the agent&rsquo;s internal locale for log messages etc.</li><li><code>&lt;verbose></code> the logging level for some internal logging. (Logging is
mostly done using log4j over slf4j)</li></ul></li><li><code>&lt;Component></code> elements for each component used in the agent. A component
is configured by defining the following child elements:<ul><li><p><code>&lt;name></code> the name of the component, use when defining dependencies
between components. The name is mostly set to the simple name of the
interface of the component</p></li><li><p><code>&lt;api></code> the full class name to the interface of the component. During
runtime this interface will be used to access the component e.g.:</p><p><code>ServiceHandler svcHandler = agent.getContainer().getComponent(ServiceHandler.class);</code></p></li><li><p><code>&lt;impl></code> the full class name of the concrete implementation of the
component. During initialization this class will be instantiated and
registered under the component name and interface. This class must
extend the class li.strolch.agent.api.StrolchComponent</p></li><li><p><code>&lt;depends></code> any number of these elements, where the content is the name
of another component, on which this component depends. Depending
components are initialized and started after the component they depend
on and are stopped and destroyed before</p></li><li><p><code>&lt;Properties></code></p></li><li><p><code>&lt;...></code> any number of properties which the component requires. The
element&rsquo;s name will be the key with which the value can be accessed at
runtime.</p></li></ul></li></ul></li></ul><div class="notices warning"><p>When a property is missing, and the component has a hard coded default value, then when the component is initialized, the use of the default value and its key is logged. This makes it easy to see which new properties can be configured. Should the component not define a default value, then the component will thrown an exception on initialization. In this case it can be a good moment to read the JavaDoc (or source code) for the component in question to see how it is configured.</p></div><h2 id=privilege-configuration>Privilege Configuration</h2><p>In Strolch authentication and authorization is baked in. To open a transaction,
and thus access the Strolch model, a Certificate object is required, which
means the user has been authenticated and possibly authorized.</p><p>The PrivilegeConfig.xml defines the following:</p><ul><li><code>&lt;Privilege></code> root element<ul><li><code>&lt;Container></code> configures the individual Privilege components<ul><li><code>&lt;Parameters></code> base configuration properties for Privilege</li><li><code>&lt;EncryptionHandler></code> configures the hashing algorithms and other
encryption specific configuration</li><li><code>&lt;PersistenceHandler></code> configures the persistence of the roles and users</li><li><code>&lt;UserChallengeHandler></code> configures a challenge handler so that a user
can reset their password. The default challenge handler is the
<code>li.strolch.privilege.handler.MailUserChallengeHandler</code> which sends a
challenge to the user&rsquo;s defined e-mail address.</li><li><code>&lt;SsoHandler></code> the SSO Handler is used to implement a SingleSignOn and
can be used to start a session using a LDAP token, etc. There is no
default implementation as this is project specific.</li></ul></li><li><code>&lt;Policies></code> configures the available privilege policies at runtime, the
name is referenced from the model file</li></ul></li></ul><p>The <code>PrivilegeUsers.xml</code> and <code>PrivilegeRoles.xml</code> define the users and roles
and is used when in <code>PrvilegeConfig.xml</code> the <code>PersistenceHandler</code> is set to
<code>ch.eitchnet.privilege.handler.XmlPersistenceHandler</code>:</p><ul><li><code>&lt;Users></code> configures all users<ul><li><code>&lt;User></code> configures a specific user<ul><li><code>&lt;Firstname></code> configures a user&rsquo;s first name</li><li><code>&lt;Lastname></code> configure a user&rsquo;s last name</li><li><code>&lt;State></code> configures the user&rsquo;s state, see <code>li.strolch.privilege.model.UserState</code></li><li><code>&lt;Locale></code> configure the user&rsquo;s locale</li><li><code>&lt;Roles></code> configures the user&rsquo;s roles<ul><li><code>&lt;Role></code> adds a role to the user</li><li><code>&lt;Properties></code> configures user specific properties. What properties
are used is not specified and is dependent on the concrete agent<ul><li><code>&lt;Property></code> defines a single property</li></ul></li></ul></li></ul></li><li><code>&lt;Roles></code> configures all roles<ul><li><code>&lt;Role></code> configures a specific role<ul><li><code>&lt;Privilege></code> configures a specific privilege for this role<ul><li><code>&lt;AllAllowed></code> if set to true, then defines that all values
associated with this privilege are allowed</li><li><code>&lt;Allow></code> defines one allowed value for this privilege</li><li><code>&lt;Deny></code> defines one denied value for this privilege</li></ul></li></ul></li></ul></li></ul></li></ul><h2 id=implementing-a-strolchcomponent>Implementing a StrolchComponent</h2><p>Implementing a strolch component requires an interface, which defines the
component&rsquo;s API and a concrete class which implements the interface and
extends the class <code>StrolchComponent</code>.</p><p>The StrolchComponent class adds the state model to the class, which
transitions as follows:</p><p><code>UNDEFINED => SETUP => INITIALIZED => STARTED &lt;=> STOPPED => DESTROYED</code></p><p>Components can switch between <code>STARTED</code> and <code>STOPPED</code>, but once <code>DESTROYED</code> no
further state change is possible. The component&rsquo;s state is changed by changes
to the agent&rsquo;s lifecycle.</p><p>A component&rsquo;s state is changed by a call to the appropriate method on the
component, override the methods as necessary. Note that it is good practice
that the <code>initialize()</code>-method is used to get all the configuration properties,
and that they should there be evaluated and that the method so return quickly.
The <code>start()</code>-method is called after the agent&rsquo;s initialization and should be
where additional threads are started. Correctly implementing these methods
allows to quickly detect a wrongly configured agent, which might take longer
to start for whatever reason.</p><p>The following shows a basic implementation of a component on the basis of a
post initializer (a component which performs some actions in its
<code>start()</code>-method which should be done after everything else is started in the
agent).</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=color:#66d9ef>public</span> <span style=color:#66d9ef>class</span> <span style=color:#a6e22e>SimplePostInitializer</span>
<span style=color:#66d9ef>extends</span> StrolchComponent
<span style=color:#66d9ef>implements</span> PostInitializer <span style=color:#f92672>{</span>
<span style=color:#66d9ef>public</span> <span style=color:#a6e22e>SimplePostInitializer</span><span style=color:#f92672>(</span>ComponentContainer container<span style=color:#f92672>,</span>
String componentName<span style=color:#f92672>)</span> <span style=color:#f92672>{</span>
<span style=color:#66d9ef>super</span><span style=color:#f92672>(</span>container<span style=color:#f92672>,</span> componentName<span style=color:#f92672>);</span>
<span style=color:#f92672>}</span>
<span style=color:#a6e22e>@Override</span>
<span style=color:#66d9ef>public</span> <span style=color:#66d9ef>void</span> <span style=color:#a6e22e>initialize</span><span style=color:#f92672>(</span>ComponentConfiguration configuration<span style=color:#f92672>)</span> <span style=color:#f92672>{</span>
<span style=color:#75715e>// do some initialization, validate configuration values, etc.
</span><span style=color:#75715e></span> <span style=color:#75715e>// now call super, to update state
</span><span style=color:#75715e></span> <span style=color:#66d9ef>super</span><span style=color:#f92672>.</span><span style=color:#a6e22e>initialize</span><span style=color:#f92672>(</span>configuration<span style=color:#f92672>);</span>
<span style=color:#f92672>}</span>
<span style=color:#a6e22e>@Override</span>
<span style=color:#66d9ef>public</span> <span style=color:#66d9ef>void</span> <span style=color:#a6e22e>start</span><span style=color:#f92672>()</span> <span style=color:#f92672>{</span>
<span style=color:#75715e>// start any threads, or perform long running start work
</span><span style=color:#75715e></span> <span style=color:#75715e>// now call super, to update state
</span><span style=color:#75715e></span> <span style=color:#66d9ef>super</span><span style=color:#f92672>.</span><span style=color:#a6e22e>start</span><span style=color:#f92672>();</span>
<span style=color:#f92672>}</span>
<span style=color:#a6e22e>@Override</span>
<span style=color:#66d9ef>public</span> <span style=color:#66d9ef>void</span> <span style=color:#a6e22e>stop</span><span style=color:#f92672>()</span> <span style=color:#f92672>{</span>
<span style=color:#75715e>// stop threads and timers, but be ready to start again
</span><span style=color:#75715e></span> <span style=color:#75715e>// now call super, to update state
</span><span style=color:#75715e></span> <span style=color:#66d9ef>super</span><span style=color:#f92672>.</span><span style=color:#a6e22e>stop</span><span style=color:#f92672>();</span>
<span style=color:#f92672>}</span>
<span style=color:#a6e22e>@Override</span>
<span style=color:#66d9ef>public</span> <span style=color:#66d9ef>void</span> <span style=color:#a6e22e>destroy</span><span style=color:#f92672>()</span> <span style=color:#f92672>{</span>
<span style=color:#75715e>// destroy this component, release all resources and don&#39;t worry about
</span><span style=color:#75715e></span> <span style=color:#75715e>// being called to start again now call super, to update state
</span><span style=color:#75715e></span> <span style=color:#66d9ef>super</span><span style=color:#f92672>.</span><span style=color:#a6e22e>destroy</span><span style=color:#f92672>();</span>
<span style=color:#f92672>}</span>
<span style=color:#f92672>}</span>
</code></pre></div><p>The new component would then be registered in the <code>StrolchConfiguration.xml</code>
as follows:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-xml data-lang=xml><span style=color:#f92672>&lt;StrolchConfiguration&gt;</span>
<span style=color:#f92672>&lt;env</span> <span style=color:#a6e22e>id=</span><span style=color:#e6db74>&#34;...&#34;</span><span style=color:#f92672>&gt;</span>
...
<span style=color:#f92672>&lt;Component&gt;</span>
<span style=color:#f92672>&lt;name&gt;</span>SimplePostInitializer<span style=color:#f92672>&lt;/name&gt;</span>
<span style=color:#f92672>&lt;api&gt;</span>li.strolch.agent.api.PostInitializer<span style=color:#f92672>&lt;/api&gt;</span>
<span style=color:#f92672>&lt;impl&gt;</span>li.strolch.documentation.SimplePostInitializer<span style=color:#f92672>&lt;/impl&gt;</span>
<span style=color:#f92672>&lt;/Component&gt;</span>
...
<span style=color:#f92672>&lt;/env&gt;</span>
<span style=color:#f92672>&lt;/StrolchConfiguration&gt;</span>
</code></pre></div><p>And can be access at runtime using:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java>PostInitializer postInitializer <span style=color:#f92672>=</span> getContainer<span style=color:#f92672>().</span><span style=color:#a6e22e>getComponent</span><span style=color:#f92672>(</span>PostInitializer<span style=color:#f92672>.</span><span style=color:#a6e22e>class</span><span style=color:#f92672>);</span>
</code></pre></div><h2 id=starting-the-agent>Starting the agent</h2><p>When a Strolch runtime is started, then the root path to the runtime configuration must be passed. In Java this is done by calling:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java>StrolchAgent agent <span style=color:#f92672>=</span> <span style=color:#66d9ef>new</span> StrolchAgent<span style=color:#f92672>();</span>
agent<span style=color:#f92672>.</span><span style=color:#a6e22e>setup</span><span style=color:#f92672>(</span>environment<span style=color:#f92672>,</span> rootPath<span style=color:#f92672>);</span>
agent<span style=color:#f92672>.</span><span style=color:#a6e22e>initialize</span><span style=color:#f92672>();</span>
agent<span style=color:#f92672>.</span><span style=color:#a6e22e>start</span><span style=color:#f92672>();</span>
</code></pre></div><p>In Servlet 3.0 applications one would implement the
<code>javax.servlet.ServletContextListener</code> interface, add the <code>@WebListener</code>
annotation to the class and in the <code>contextInitialized()</code>-method start Strolch:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java>String realPath <span style=color:#f92672>=</span> sce<span style=color:#f92672>.</span><span style=color:#a6e22e>getServletContext</span><span style=color:#f92672>().</span><span style=color:#a6e22e>getRealPath</span><span style=color:#f92672>(</span><span style=color:#e6db74>&#34;/WEB-INF&#34;</span><span style=color:#f92672>);</span>
String environment <span style=color:#f92672>=</span> StrolchEnvironment<span style=color:#f92672>.</span><span style=color:#a6e22e>getEnvironmentFromEnvProperties</span><span style=color:#f92672>(</span>pathF<span style=color:#f92672>);</span>
<span style=color:#66d9ef>this</span><span style=color:#f92672>.</span><span style=color:#a6e22e>agent</span> <span style=color:#f92672>=</span> <span style=color:#66d9ef>new</span> StrolchAgent<span style=color:#f92672>();</span>
<span style=color:#66d9ef>this</span><span style=color:#f92672>.</span><span style=color:#a6e22e>agent</span><span style=color:#f92672>.</span><span style=color:#a6e22e>setup</span><span style=color:#f92672>(</span>environment<span style=color:#f92672>,</span> <span style=color:#66d9ef>new</span> File<span style=color:#f92672>(</span>realPath<span style=color:#f92672>));</span>
<span style=color:#66d9ef>this</span><span style=color:#f92672>.</span><span style=color:#a6e22e>agent</span><span style=color:#f92672>.</span><span style=color:#a6e22e>initialize</span><span style=color:#f92672>();</span>
<span style=color:#66d9ef>this</span><span style=color:#f92672>.</span><span style=color:#a6e22e>agent</span><span style=color:#f92672>.</span><span style=color:#a6e22e>start</span><span style=color:#f92672>();</span>
</code></pre></div><footer class=footline></footer></div></div><div id=navigation><a class="nav nav-prev" href=/documentation/do-and-donts/ title="Do and Don't"><i class="fa fa-chevron-left"></i></a><a class="nav nav-next" href=/documentation/realms/ title=Realms style=margin-right:0><i class="fa fa-chevron-right"></i></a></div></section><div style=left:-1000px;overflow:scroll;position:absolute;top:-1000px;border:none;box-sizing:content-box;height:200px;margin:0;padding:0;width:200px><div style=border:none;box-sizing:content-box;height:200px;margin:0;padding:0;width:200px></div></div><script src=/js/clipboard.min.js?1626091328></script><script src=/js/perfect-scrollbar.min.js?1626091328></script><script src=/js/perfect-scrollbar.jquery.min.js?1626091328></script><script src=/js/jquery.sticky.js?1626091328></script><script src=/js/featherlight.min.js?1626091328></script><script src=/js/highlight.pack.js?1626091328></script><script>hljs.initHighlightingOnLoad();</script><script src=/js/modernizr.custom-3.6.0.js?1626091328></script><script src=/js/learn.js?1626091328></script><script src=/js/hugo-learn.js?1626091328></script><script src=/mermaid/mermaid.js?1626091328></script><script>mermaid.initialize({startOnLoad:true});</script></body></html>