--- title: 'Configuration' weight: 10 --- ## Configuration Let's start by creating a new Apache Maven project. We'll need a POM with the proper dependencies. We expect you to be familiar with Apache Maven, so we'll just show you a working POM file: **pom.xml** ```xml 4.0.0 li.strolch strolch-bookshop 0.1.0-SNAPSHOT war strolch-bookshop Bookshop built on Strolch 2017 UTF-8 yyyy-MM-dd HH:mm:ss ${maven.build.timestamp} 1.8 2.25.1 1.7.25 1.2.3 2.1.0 2.7.1 42.1.4 2.8.2 1.3.1 1.6.0 3.1.0 2.1 4.12 1.3 2.0.8-beta 3.7.0 3.0.1 3.0.2 3.1.0 1.6.0-SNAPSHOT bookshop ${warFinalName} org.slf4j slf4j-api ${slf4j.version} ch.qos.logback logback-classic ${logback.version} runtime li.strolch li.strolch.utils ${strolch.version} li.strolch li.strolch.privilege ${strolch.version} li.strolch li.strolch.model ${strolch.version} li.strolch li.strolch.agent ${strolch.version} li.strolch li.strolch.rest ${strolch.version} li.strolch li.strolch.service ${strolch.version} li.strolch li.strolch.testbase ${strolch.version} test com.google.code.gson gson ${gson.version} javax.servlet javax.servlet-api ${serverlet.version} provided javax.ws.rs javax.ws.rs-api ${jaxrs.api.version} org.glassfish.jersey.core jersey-common ${jersey.version} org.glassfish.jersey.core jersey-server ${jersey.version} org.glassfish.jersey.containers jersey-container-servlet ${jersey.version} junit junit ${junit.version} test org.hamcrest hamcrest-core ${hamcrest.version} test org.hamcrest hamcrest-library ${hamcrest.version} test src/main/resources true **/*.properties src/main/resources false **/*.properties org.apache.maven.plugins maven-compiler-plugin ${maven-compiler-plugin.version} ${jdk.version} ${jdk.version} org.apache.maven.plugins maven-war-plugin ${maven-war-plugin.version} false ${warFinalName} m2e.eitchpc user.name eitch unix dev.eitchpc ``` Now we need the rest of the directory structure: ```text ../strolch-bookshop/ - src/main/java/ - li/strolch/bookshop/ - - src/main/resources/ - ENV.properties - appVersion.properties - logback.xml - src/main/webapp/WEB-INF/ - StrolchBootstrap.xml - runtime - config/ - PrivilegeConfig.xml - PrivilegeRoles.xml - PrivilegeUsers.xml - StrolchConfiguration.xml - StrolchPolicies.xml - data/ - StrolchModel.xsd - defaultModel.xml - templates.xml - temp/ ``` A few notes to the resource files: * The `ENV.properties` file is filtered by maven and the environment to load is written in it using the environment variable strolch.env. * The `appVersion.properties` file is also filtered by maven and allows to reflect on the version of this app at runtime. * The `logback.xml` file configures logging using SLF4j and Logback. The `StrolchBootstrap.xml` file is used to configure Strolch's environment and root directory. For a webapp it can be annoying to store Strolch's configuration inside the webapp, which is why we can define an absolute path where the configuration is kept. In the following example we keep it in the root of the sources: ```xml /home/eitch/src/git/strolch-bookshop/runtime dev ``` Here we define two environments, but the both redefine the environment to dev. This is because we want this app to start on two different machines with different user home directories. See the profiles in the POM as to how these environments are activated using a environment property strolch.env. In this next step we'll create Strolch's configuration at the location we defined in the StrolchBootstrap.xml file. Strolch's configuration contains of three directories: config, data and temp. config contains static files which usually aren't changed, data contains model files in XML format and temp is used at runtime for any temporary files, e.g. storing active sessions. The configuration as well as the model has been described on Strolch's documentation web page, we'll just provide you with the files for the bookshop: **PrivilegeConfig.xml** ```xml ``` **PrivilegeRoles.xml** ```xml true li.strolch.bookshop.search.BookSearch true true true true true true true true true true true true true true true true true true true true true true true true true true true true li.strolch.runtime.privilege.StrolchSystemAction li.strolch.runtime.privilege.StrolchSystemActionWithResult li.strolch.persistence.postgresql.PostgreSqlSchemaInitializer true true true true true true true true true true true true true true true Persist PersistSessions GetCertificates true true true ``` **PrivilegeUsers.xml** ```xml Jill Someone ENABLED en-GB User UserPrivileges Jill Someone ENABLED en-GB StrolchAdmin UserPrivileges SYSTEM agent ``` **StrolchConfiguration.xml** ```xml Bookshop en true PrivilegeHandler li.strolch.runtime.privilege.PrivilegeHandler li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler PrivilegeConfig.xml RealmHandler li.strolch.agent.api.RealmHandler li.strolch.agent.impl.DefaultRealmHandler PrivilegeHandler defaultRealm TRANSIENT defaultModel.xml true ServiceHandler li.strolch.service.api.ServiceHandler li.strolch.service.api.DefaultServiceHandler RealmHandler PrivilegeHandler true PolicyHandler li.strolch.policy.PolicyHandler li.strolch.policy.DefaultPolicyHandler true ExecutionHandler li.strolch.execution.ExecutionHandler li.strolch.execution.EventBasedExecutionHandler RealmHandler PrivilegeHandler RestfulHandler li.strolch.rest.RestfulStrolchComponent li.strolch.rest.RestfulStrolchComponent SessionHandler false false false ALL SessionHandler li.strolch.rest.StrolchSessionHandler li.strolch.rest.DefaultStrolchSessionHandler PrivilegeHandler 30 true MailHandler li.strolch.handler.mail.MailHandler li.strolch.handler.mail.SmtpMailHandler relayer@eitchnet.ch Susi ]]> eitch@eitchnet.ch test test true true smtp.gmail.com 587 ``` **StrolchPolicies.xml** ```xml ``` A few notes on the configuration: * Note how there are three users. Jill is a user with currently no privileges as it's role definition is empty. Admin can do everything, and the agent user is a system user which can also do everything. * There is one realm defined in the `RealmHandler` component which references the `defaultModel.xml` file in the `data` directory. This file then includes the currently still empty `templates.xml` file. * We have defined a `global` environment, but are using the `dev` environment. The dev environment includes the definitions in the global environment. * In `PrivilegeConfig.xml` we have enabled persistence of sessions, so you will be needing the unlimited JCE libraries for your JVM. When you restart the server, you don't need to log back in, if your session is still alive. * In `PrivilegeRoles.xml` there seems to be a lot of boilerplate. One thing about a highly configurable system is that sometimes the configuration is bigger. In this case we have opted to have the configuration shown and not use default values which you don't see, so that privilege access is clearly seen. Your project is now ready to be imported into your favourite IDE. We have used both IntelliJ and Eclipse so this is up to you. Now that we have a configuration, it is time to have Strolch started when the WAR is deployed and started. In your IDE create a new class as follows: **StartupListener.java** ```java package li.strolch.bookshop.web; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; import java.io.InputStream; import li.strolch.agent.api.StrolchAgent; import li.strolch.agent.api.StrolchBootstrapper; import li.strolch.utils.helper.StringHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @WebListener public class StartupListener implements ServletContextListener { private static final Logger logger = LoggerFactory.getLogger(StartupListener.class); private static final String APP_NAME = "Bookshop"; private StrolchAgent agent; @Override public void contextInitialized(ServletContextEvent sce) { logger.info("Starting " + APP_NAME + "..."); long start = System.currentTimeMillis(); try { String boostrapFileName = "/WEB-INF/" + StrolchBootstrapper.FILE_BOOTSTRAP; InputStream bootstrapFile = sce.getServletContext().getResourceAsStream(boostrapFileName); StrolchBootstrapper bootstrapper = new StrolchBootstrapper(StartupListener.class); this.agent = bootstrapper.setupByBoostrapFile(StartupListener.class, bootstrapFile); this.agent.initialize(); this.agent.start(); } catch (Throwable e) { logger.error("Failed to start " + APP_NAME + " due to: " + e.getMessage(), e); throw e; } long took = System.currentTimeMillis() - start; logger.info("Started " + APP_NAME + " in " + (StringHelper.formatMillisecondsDuration(took))); } @Override public void contextDestroyed(ServletContextEvent sce) { if (this.agent != null) { logger.info("Destroying " + APP_NAME + "..."); try { this.agent.stop(); this.agent.destroy(); } catch (Throwable e) { logger.error("Failed to stop " + APP_NAME + " due to: " + e.getMessage(), e); throw e; } } logger.info("Destroyed " + APP_NAME); } } ``` Now configure your IDE to start the web project, and then once it has started, you should see the following in the logs: ```text Bookshop:dev All 8 Strolch Components started. Took 44ms. Strolch is now ready to be used. Have fun =)) ``` This log tells us the name of the app as defined in the StrolchConfiguration.xml file as well as which environment was loaded. Further we can see that 8 components were configured and started. This concludes the initial setup of a new Strolch project. We can now go ahead and start building the business logic.