lunr-index.json 514 KB
Newer Older
1
[{"title":"Basics","tags":["audit","trace","trail"],"href":"/addons/audit/","content":"The Audit add on provides the ability to trace who does what in your application Maven dependencies If you want to use the audit writer based on Logback replace the dependency by the following see the section on LogbackTrailWriter org seedstack addons audit audit logback Concepts The Audit allows you to trace somewhere log file for example each time a user executes a portion of code You can record a message and get access to information like the date the connected user or the application concerned Following is the model of what is given to the object in charge of writing the audit audit model puml business business api domain audit puml png AuditEvent Main object passed to the trail writer It contains the date of the audit and the accompanying message It also has the trail Trail A trail represents several events occurring in the same execution All events of a trail have the same Initiator and are requested on the same Host Initiator Represents the user triggering the audit It contains his id and his name as well has his Address Host represents the application on which the audit is made It contains the name and id of the application as well as its address Address Contains Network information if available ip address and dns name API The Audited Annotation You can mark a method with the annotation Audited so the framework will automatically audit this the execution of the method Audited messageBefore Doing critical work with parameter args 0 messageAfter Done critical work with result result messageOnException Error doing critical work public String doCriticalWork String someString return result someString There are 3 attributes you can define the first being mandatory messageAfter the message to trace when the method has been executed Can be an EL expression with properties args for the method arguments and result for the return For example messageAfter the argument is args 0 someMethod and the result says result say messageBefore optionally you can define a message to be traced just before executing the method Can be an EL expression but only arguments are available messageOnException define a generic message when an unhandled exception occurs in the execution of the method If a handler handles the exception this message is ignored Can be an EL expression the exception is available via property exception For instance messageOnException kaboom exception getMessage AuditService You can programmatically write a trail by injecting the AuditService First create a new Trail that you can reuse later It will be initialized automatically with the current Host and Initiator Then trail as many messages as required with the given Trail Inject AuditService auditService Trail trail auditService createTrail String message dummy auditService trail message trail TrailWriter A trail writer effectively writes each message and its trail an AuditEvent The framework brings a writer based on Logback that can write on a file in the console named LogbackTrailWriter You can implement your own TrailWriter For example public class SysoutTrailWriter implements TrailWriter public void writeEvent AuditEvent auditEvent System out println auditEvent getDate auditEvent getMessage auditEvent getTrail getInitiator getId TrailExceptionHandler A TrailExceptionHandler is used in conjunction with the Audited annotation When the annotated method throws an exception if a handler is able to handle the exception it will create a String describing it being the message that will be trailed The framework brings an exception handler for AuthorizationException You can implement your own handler public class BusinessTrailExceptionHandler implements TrailExceptionHandler public String describeException MyBusinessException e return My business description to trail Configuration Several things can be configured via the props file The TrailWriters You can choose which TrailWriter s to use fill in the property org seedstack audit writers with the name or simple name of the class of the TrailWriters to use This property is optional if empty no writer will be used The TrailExceptionHandlers You can choose which TrailExceptionHandler s to use fill in the property org seedstack audit exceptionHandlers with the name or simple name of the class of the TrailExceptionHandler to use This property is optional if empty every TrailExceptionHandler found on the classpath will be used The LogbackTrailWriter If you choose to use the LogbackTrailWriter you must fill the property org seedstack audit logPattern It is the pattern that will be used when writing each message It can be an EL expression with the following properties available event the AuditEvent trail the trail Could also be accessed via event getTrail initiator the initiator Could also be accessed via event getTrail getInitiator host the application host Could also be accessed via event getTrail getHost Here is an example of pattern you could use org seedstack audit logPattern At event getFormattedDate yyyy MM dd HH mm ss SSS user initiator getName initiator getId requested application host getName event getMessage You must also configure logback to add the appender and logger in the file logback xml Note that you can choose any appender that holds an encoder ConsoleAppender FileAppender as long as you define the right layout class","summary":"The Audit add-on provides the ability to trace who does what in your application.\n\nMaven dependencies\n\n\n\nIf you want to use the audit writer based on Logback, replace the dependency by the following \n(see the...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Audit","path":"audit"}},{"title":"Basics","tags":["persistence","indexing","elastic","search","data"],"href":"/addons/elasticsearch/","content":"The ElasticSearch add on allows you to configure inject and use ElasticSearch https www elastic co clients Main features Embedded indexes Remote indexes callout info More information about the ElasticSearch Java API here https www elastic co guide en elasticsearch client java api current index html callout Configuration To access an ElasticSearch index you need to declare a client in configuration Multiple clients can be configured They must be listed in the following property ini org seedstack elasticsearch clients client1 client2 Remote instance To access a remote ElasticSearch index you need to specify the host s of one or more node s of the ElasticSearch cluster ini org seedstack elasticsearch client client1 hosts host1 port1 host2 port2 You can omit the port in which case will be set to the ElasticSearch default 9300 Embedded instance If you don t specify the hosts property a local ElasticSearch node will be created and stored in the persistence elasticsearch client name subdirectory of the Seed local storage location where client name is the name of the ElasticSearch client Other options You can specify any configuration property of the ElasticSearch client with the following syntax ini org seedstack elasticsearch client client1 property name of elasticsearch property value Usage To use a configured ElasticSearch client simply inject it where needed java Inject Named client1 Client client1 Example Configuration for an embedded ElasticSearch instance ini org seedstack elasticsearch clients test org seedstack elasticsearch client test property cluster name test cluster 1 To inject this configured client use the following syntax ini Inject Named test Client testClient","summary":"The ElasticSearch add-on allows you to configure, inject and use ElasticSearch clients.\n\n\n\nMain features:\n\nEmbedded indexes,Remote indexes.\n\n\nMore information about the...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"ElasticSearch","path":"elasticsearch"}},{"title":"Basics","tags":["i18n","locale","date","time","format","localization","internationalization","culture"],"href":"/addons/i18n/","content":"The i18n addon provides backend services and a Web UI to manage your application s locales and translations locale view img keys png Integration To add the i18n addon to your project start by adding the following dependency Then configure the persistence and the security Persistence The i18n addon uses JPA to store its data No persistence xml file is provided as it expects your application to be configured with automatically generated persistence information addons jpa without persistence xml You just need add the JPA unit seed i18n domain to the global list of JPA units and specify its datasource ini org seedstack seed persistence jpa units seed i18n domain org seedstack jpa unit seed i18n domain datasource my datasource Security All the REST APIs are secured with permissions These permissions are bound to two default roles seed i18n reader for read access seed i18n translator for read write delete access Bind the i18n roles to yours for instance ini org seedstack seed security users john password MYPROJECT DEVELOPER admin password MYPROJECT TRANSLATOR org seedstack seed security roles Read access seed i18n reader MYPROJECT DEVELOPER Read Write Delete access seed i18n translator MYPROJECT TRANSLATOR callout info It is possible to create more fine grained security roles using the provided permissions Here is the list of available permissions ini seed i18n locale read seed i18n locale write seed i18n locale delete seed i18n key read seed i18n key write seed i18n key delete seed i18n translation read seed i18n translation write seed i18n translation delete callout Cache Optional The addon uses cache to improve i18n performances By default this cache does not need configuration but it is possible to change the configuration as follow ini Default configuration used by the i18n addon org seedstack seed i18n cache max size 8192 concurrency 32 initial size 2048 Backup Restore CSV The Manage Keys interface provides CSV import export functionality callout info The exported CSV file is in UTF 8 in order to support all the possible languages This encoding is not used by default in Microsoft Excel callout All data In order to backup restore all data with their metadata e g default locale or outdated indicator the addon provides shell docs seed manual operations shell commands To use it enable the Shell support Then use the core export or core import commands cf Core data documentation docs seed manual more data import export Java API usage Locales The i18n addon stores application available locales and default locale Available locales are the locales in which the application is translated i e available to users The default locale is the native language of the application This locale will be used as starting locale for translations Locales can be managed with i18n administration interface or programatically with the java Inject private LocaleService localeService Localization Localization is provided by the which allows to localize date number string and currency java Inject private LocalizationService localizationService The allows to translate i18n keys in different locales using the localize String String method This method will fallback on the parent locale if the required locale is not present java Case 1 fr BE translation is present localizationService localize fr BE key1 translation fr BE Case 2 fr BE translation is NOT present but fr translation is present localizationService localize fr BE key1 translation fr Case 2 no translation present localizationService localize fr BE key1 key","summary":"The i18n addon provides backend services and a Web UI to manage your application's locales and translations.\n\n\n\nIntegration\n\nTo add the i18n addon to your project, start by adding the following dependency. Then configure the persistence\nand the security.\n\n{{< dependency g="org.seedstack...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Internationalization (i18n)","path":"i18n"}},{"title":"Advanced CSV","tags":["export","csv"],"href":"/addons/io/advanced-csv-export","content":"A CSV template is defined with a csv properties file This properties gives you options to change general configuration define format or provide custom validation The available options are Key Default Description charsetName UTF 8 Option to change the charset name quote The quote character is used when a cell contains special characters such as the delimiter char a quote char or spans multiple lines separator The delimiter character separates each cell in a row endOfLine n The end of line symbols to use when writing showHeader true If true show the column headers columns N A Mandatory List of the model fields to render xxxx name N A Header name to write If the name property is not present the header will be the field name xxxx type String Available types are date boolean int double long bigdecimal xxxx format N A Used to format date boolean and number ex birthdate format dd MM yyyy For the boolean type you can specify how to write true or false values by two comma separated values married format Yes No xxxx notNull false Is used to define if the field is optional or not xxxx unique false Is used to define the field must be unique Example General configuration quote separator endOfLine n charsetName UTF 8 columns customerNo firstName lastName birthDate mailingAddress married numberOfKids favouriteQuote email loyaltyPoints customerNo must be unique customerNo name ID customerNo nullable false customerNo unique true firstName firstName name First name firstName nullable false lastName lastName name Last name lastName nullable false birthDate birthDate name Birth date birthDate nullable false birthDate type date birthDate format dd MM yyyy mailingAddress mailingAddress name Mailling address mailingAddress nullable false married married name Married married nullable true birthDate type boolean birthDate format Yes No numberOfKids numberOfKids name Number of kids numberOfKids nullable true favouriteQuote favouriteQuote name Favorite quote favouriteQuote nullable false email email name Email email nullable false loyaltyPoints loyaltyPoints name Loyalty points loyaltyPoints nullable false","summary":"A CSV template is defined with a *.csv.properties file. This properties gives you options to change general\nconfiguration, define format or provide custom validation. The available options are:\n\n <table class="table table-bordered">\n <thead>\n <tr>\n <th>Key</th&gt...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Document import/export","path":"io"}},{"title":"Custom parsers","tags":["parser","document","import","template"],"href":"/addons/io/custom-parsers","content":"If available parsers don t fit your needs the IO add on provide an SPI for custom parsers There are three options to provide your own parser static template dynamic template or without template Static template In this case templates are loaded from files within the META INF templates directory You need to extend three classes and The template loader loads the template from the corresponding resource in META INF templates directory The template have all information necessary to parse a file The parser is able to parse an InputStream and produce a model using the template information Dynamic template In the case of a dynamic template your loader will completely handle the loading logic Implement the interface public class MyDynamicTemplateLoader implements TemplateLoader Override public MyTemplate load String name throws Exception Gets your template from anywhere return myTemplate Override Set names Returns all the templates you know return names Override boolean contains String name Checks if you know this template return bool Override public String templateRenderer Returns the name of the associated renderer if exists null otherwise return MyTemplateRenderer Override public String templateParser Returns the name of the associated parser return MyTemplateParser Without template A parser without template doesn t need any information to parse the model It is often the case of specific parsers that are not meant to be reusable Extend and annotate it with Named custom public class CustomParser extends AbstractBaseParser public CustomParser Override public List parse InputStream inputStream Class clazz List beans new ArrayList return beans You can inject it as usual Parse custom Parser parser","summary":"If available parsers don't fit your needs, the IO add-on provide an SPI for custom parsers. There are three options to\nprovide your own parser: static template, dynamic template or without template.\n\nStatic template\n\nIn this case, templates are loaded from files within the META-INF/templates...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Document import/export","path":"io"}},{"title":"Custom renderers","tags":["renderer","export","template","document"],"href":"/addons/io/custom-renderers","content":"If available renderers don t fit your needs the IO add on provides an SPI to register your custom renderers There are three options to provide your own renderer static template dynamic template or without template Static template In this case templates are loaded from files within the META INF templates directory You need to extend three classes and The template loader loads the template from the corresponding resource in META INF templates directory The template have all information necessary to render a model The renderer is able to render a model into an OutputStream using the template information Dynamic template In the case of a dynamic template your loader will completely handle the loading logic Implement the interface public class MyDynamicTemplateLoader implements TemplateLoader Override public MyTemplate load String name throws Exception Gets your template from anywhere return myTemplate Override Set names Returns all the templates you know return names Override boolean contains String name Checks if you know this template return bool Override public String templateRenderer Returns the name of the associated renderer return MyTemplateRenderer Without template A renderer without template doesn t need any information to render the model It is often the case of specific renderers that are not meant to be reusable Extend and annotate it with Named custom public class CustomRenderer extends AbstractBaseRenderer public CustomRenderer Override public void render OutputStream outputStream Object model render outputStream model null null Override public void render OutputStream outputStream Object model String mimeType Map parameters try outputStream write Hello World getBytes catch IOException e throw new RuntimeException e You can inject it as usual Renderer custom Renderer renderer","summary":"If available renderers don't fit your needs, the IO add-on provides an SPI to register your custom renderers. There are\nthree options to provide your own renderer: static template, dynamic template or without template.\n\nStatic template\n\nIn this case, templates are loaded from files within the...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Document import/export","path":"io"}},{"title":"Basics","tags":["document","export","import","csv","pdf"],"href":"/addons/io/","content":"The IO add on gives simple way to export and import data in multiple formats This add on comes with two modules CSV through SuperCSV http super csv github io super csv JasperReports To use the IO add on add the module io supercsv and or the module io jasper to your project classpath Writing CSV files To export a POJO to a CSV file make sure the io supercsv module is in your classpath We will export the following POJO public class CustomerBean private String firstName private String lastName private int age Add a customerbean csv properties file in META INF templates directory columns firstName lastName age firstName name First name lastName name Last name age name Age age type int In your code inject a renderer Render customerbean private Renderer renderer private List customers public void exportCustomers OuputStream os renderer render os customers Or programatically obtain the required renderer Inject private Renderers renderers public void exportCustomers OuputStream os String name Renderer renderer renderers getRendererFor name renderer render os customers Reading CSV files To import the POJO the configuration is the same as export configuration Then inject a Parser with the Parse annotation Parse customerbean private Parser parser private List customers public void importCustomers InputStream is customers parser parse is CustomerBean class Or use Parsers to programatically obtain the required parser Inject private Parsers parsers public void importCustomers InputStream is String name Parser parser parsers getParserFor name renderer render os customers customers parser parse is CustomerBean class Writing PDF files PDF files are generated with JasperReports Make sure to have the io jasper module in your classpath and put a JRXML file in META INF templates directory Example Render pdftemplate Renderer renderer List customers public void exportCustomers OuputStream os renderer render os customers application pdf parameters You can pass any Jasper parameter like SUBREPORT_DIR using the fourth parameter or render which is a Map callout info The Jasper module does not provide a parser callout","summary":"The IO add-on gives simple way to export and import data in multiple formats. This add-on comes with two modules:\n\nCSV through SuperCSV,JasperReports.\n\nTo use the IO add-on, add the module io-supercsv and/or the module io-jasper to your project classpath.\n\n{{< dependency g="org.seedstack...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Document import/export","path":"io"}},{"title":"Basics","tags":["mail","email","smtp","pop","imap"],"href":"/addons/javamail/","content":"The JavaMail add on integrates JavaMail API JSR 919 with SeedStack To add the JavaMail add on to your project use the following dependency snippet You may also need to add the JavaMail API depending on your runtime environment javax mail mail 1 4 7 provided Configuration You can configure mail providers by using the following configuration org seedstack seed mail providers myProvider1 myProvider2 myProvider3 SMTP To configure a provider as an SMTP one use the following configuration org seedstack seed mail provider myProvider1 property mail transport protocol smtp mail smtp host mail smtp port mail smtp auth mail smtp user mail smtp password Any property specified here will be used to configure the corresponding JAVA mail session IMAP To configure a provider as an IMAP one use the following configuration org seedstack seed mail provider myProvider2 property mail store protocol imap mail imap user mail imap host mail imap port mail imap auth login disable mail imap auth plain disable Any property specified here will be used to configure the corresponding JAVA mail session POP3 To configure a provider as a POP3 one use the following configuration org seedstack seed mail provider myProvider3 property mail store protocol pop3 mail pop3 user mail pop3 host mail pop3 port Any property specified here will be used to configure the corresponding JAVA mail session Testing JavaMail add on provides testing fixtures which enable to emulate an SMTP server and easily assert that your sent mails are valid You can then use the annotation and the in your tests WithMailServer host localhost port 6457 public class SmtpIT extends AbstractSeedIT Inject Named smtp test Session smtpSession Inject MessageRetriever retriever Test public void test_send throws MessagingException Transport transport null try Message message new MimeMessage smtpSession message setRecipient Message RecipientType TO new InternetAddress message setFrom new InternetAddress message setSubject message setText message setSentDate new Date transport smtpSession getTransport transport connect transport sendMessage message message getAllRecipients finally if transport null transport close for Message message retriever getSentMessages MockMailServerAssertions assertThat message hasRecipients Message RecipientType TO MockMailServerAssertions assertThat message recipientEqualsTo Message RecipientType TO InternetAddress parse TestConstantsValues DEFAULT_RECIPIENT The following configuration is needed to define the smtp test session to the corresponding mock mail server org seedstack seed mail providers smtp test org seedstack seed mail provider smtp test property mail transport protocol smtp mail smtp host localhost mail smtp port 6457","summary":"The JavaMail add-on integrates JavaMail API (JSR 919) with SeedStack. To add the JavaMail add-on to your project, use\nthe following dependency snippet:\n\n<\n\nYou may also need to add the JavaMail API...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"JavaMail","path":"javamail"}},{"title":"Basics","tags":["cache"],"href":"/addons/jcache/","content":"The JCache add on integrates the JCache API a k a JSR 107 which allows to interact with compliant caching providers in a declarative or a programmatic way Implementations are not provided by this add on and must be configured depending on your caching solution JCache specification jar dependency is required as well javax cache cache api 1 0 0 provided The full specification PDF can be found here http download oracle com otn pub jcp jcache 1_0 fr eval spec JSR107FinalSpecification pdf Configuration You must define the cache s you will use in your application in the configuration org seedstack jcache caches myCache1 myCache2 You can then further configure each cache specifically by using the org seedstack jcache cache prefix followed by the cache name org seedstack jcache cache myCache1 Cache provider If you have exactly one compliant cache provider in the classpath it will be automatically picked by the cache support Otherwise you must specify which provider to use for each cache org seedstack jcache cache myCache1 provider fully qualified classname of caching Provider You can also specify a global default provider which will be picked for every cache without an explicitly specified provider org seedstack jcache default provider fully qualified classname of default caching Provider Expiry policy factory You can specify a custom expiry policy factory for each cache org seedstack jcache expiry policy factory fully qualified classname of expiry policy Factory An expiry policy factory must implement javax cache configuration Factory Usage You must define the cache s you will use in your application in the configuration org seedstack jcache caches myCache1 myCache2 You can then further configure each cache specifically by using the org seedstack jcache cache prefix followed by the cache name org seedstack jcache cache myCache1 Cache provider If you have exactly one compliant cache provider in the classpath it will be automatically picked by the cache support Otherwise you must specify which provider to use for each cache org seedstack jcache cache myCache1 provider fully qualified classname of caching Provider You can also specify a global default provider which will be picked for every cache without an explicitly specified provider org seedstack jcache default provider fully qualified classname of default caching Provider Expiry policy factory You can specify a custom expiry policy factory for each cache org seedstack jcache expiry policy factory fully qualified classname of expiry policy Factory An expiry policy factory must implement javax cache configuration Factory","summary":"The JCache add-on integrates the JCache API (a.k.a. JSR 107) which allows to interact with compliant caching providers\nin a declarative or a programmatic way.\n\nImplementations are not provided by this add-on and must be configured depending on your caching solution.\n\n{{< dependency g="org...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"JCache","path":"jcache"}},{"title":"Basics","tags":["persistence","jdbc","data","database"],"href":"/addons/jdbc/","content":"Seed JDBC persistence add on enables your application to interface with any relational database through the JDBC API Configuration You can configure the add on in one or more of your props files Declare you list of data source names you will be configuring later org seedstack jdbc datasources datasource1 datasource2 Configure each data source separately Notice the use of the keyword property to specify any property that will be used by the datasource as specific configuration org seedstack jdbc datasource datasource1 provider HikariDataSourceProvider driver org hsqldb jdbcDriver url jdbc hsqldb mem testdb1 user sa password property specific jdbc prop value property prop for datasource value If your app server declares a JNDI datasource org seedstack jdbc datasource datasource2 jndi name java comp env jdbc my datasource context The context property is optional and can be used to specify a particular context name configured in core support docs seed manual core jndi to make the lookup Otherwise the default context will be used JDBC Connection The following examples show how to get a JDBC connection public class MyRepository Inject private Connection connection public void updateStuff int id String bar try String sql INSERT INTO FOO VALUES PreparedStatement statement connection prepareStatement sql statement setInt 1 id statement setString 2 bar statement executeUpdate catch SqlException e throw new SomeRuntimeException e message Any interaction with this connection will have to be realized inside a transaction Refer to the transaction support documentation docs seed manual transactions for more detail Below is an example using the annotation based transaction demarcation notice the data source name in Jdbc annotation public class MyService Inject private MyRepository myRepository Transactional Jdbc datasource1 public void doSomethingRelational myRepository updateStuff 1 bar callout info Note that the Jdbc annotation is optional if you have only one type of transactional resources in your application AND if you only have one datasource If you happen to be in this situation we still recommend to explicitly specify the annotation to avoid doing so when the project evolves down the road callout DataSource providers When using a non JNDI datasource we recommend the use of pooled datasource through a DataSourceProvider defined in the configuration Three DataSource providers are currently supported out of the box HikariCP http brettwooldridge github io HikariCP with HikariDataSourceProvider Commons DBCP http commons apache org proper commons dbcp with DbcpDataSourceProvider C3P0 http www mchange com projects c3p0 with C3p0DataSourceProvider We also provide a test oriented DataSource that gives connection directly from the driver Use PlainDataSourceProvider or do not specify a provider In case you want to use another data source you can create your own DataSourceProvider by implementing the interface public class SomeDataSourceProvider implements DataSourceProvider Override public DataSource provideDataSource String driverClass String url String user String password Properties jdbcProperties SomeDataSource sds new SomeDataSource sds setDriverClass driverClass sds setJdbcUrl url sds setUser url sds setPassword user sds setProperties jdbcProperties return sds You will be able to declare it in your configuration as SomeDataSourceProvider the simple name of your class Note that if you want to use one of the three datasource providers described above you will have to add the corresponding dependency to your project","summary":"Seed JDBC persistence add-on enables your application to interface with any relational database through the JDBC API. \n\n\n\nConfiguration\n\nYou can configure the add-on in one or more of your *.props files. Declare you...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"JDBC","path":"jdbc"}},{"title":"Configuration","tags":["jms","messaging","connection","message"],"href":"/addons/jms/configuration","content":"Configuring your messaging solution is mandatory in order to be able to use Seed JMS add on Connection factories The connectionFactory is the base to create connections Connection factories are declared using the following property org seedstack jms connection factories connection factory 1 connection factory 1 Direct instantiation configuration In direct instantiation mode Seed will create the connection factory and configure it by setting properties on its instance Use the following property syntax to define the configuration org seedstack jms connection factory connection factory 1 vendor class fully qualified vendor classname connection factory connection factory 1 vendor property property1 value1 connection factory connection factory 1 vendor property property2 value2 connection factory connection factory 1 vendor property property3 value3 Seed will instantiate the specified class and will set each property as defined above With JNDI In JNDI mode Seed will lookup for connection factory instances using the name and optionally the specified context org seedstack jms connection factory connection factory 1 jndi name name to lookup for connection factory connection factory 1 jndi context context for lookup Optional The context must be specified according to the list of JNDI contexts defined in core support see the corresponding documentation docs seed manual core jndi If no context is specified the default context is used Connections Multiple connections can be created and managed by Seed All connections must be listed in the following property org seedstack jms connections connection 1 connection 2 Each connection can then be configured as follows org seedstack jms connection connection 1 connection factory connection factory 1 user Optional password Optional Exception listener You can specify an exception listener on a connection with the following property org seedstack jms connection connection 1 exception listener fully qualified class of the exception listener Automatic reconnection Seed managed JMS connections can automatically reconnect after they go down This behavior is enabled by default but can be disabled by the following property org seedstack jms connection connection 1 managed connection false The delay before automatic reconnection is 30 seconds but it can be changed with the following property org seedstack jms connection connection 1 reconnection delay 10000 Note that the delay is specified in milliseconds Client ID Seed will automatically set the client ID of the connection if not in JEE mode see below To disable the setting of the client ID use the following property org seedstack jms connection connection 1 set client id false The client ID itself can be defined with the following property org seedstack jms connection connection 1 client id my client id If not specified the default client ID is formed by concatenating the application identifier with the connection name JEE mode In a strict JEE environment some JMS methods are forbidden refer to the EE 6 7 section of the JavaEE platform specification You can enable the JEE mode on a connection with the following property org seedstack jms connection connection 1 jee mode true In this mode the forbidden methods are not invoked It prevents the uses of asynchronous message reception driven by the JMS provider after setMessageListener so polling must be used instead Seed allows to still use a MessageListener when in polling mode but a message poller must be specified when registering the listener Having a MessageListener defined without a corresponding message poller while in JEE mode results in an error","summary":"Configuring your messaging solution is mandatory in order to be able to use Seed JMS add-on.\n\nConnection factories\n\nThe connectionFactory is the base to create connections. Connection factories are declared using the following property:\n\n[org.seedstack.jms]\nconnection-factories = connection-factory...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"JMS","path":"jms"}},{"title":"Basics","href":"/addons/jms/","content":"Java Message Service JMS is a Java API that allows applications to create send receive and read messages This add on provides a JMS 1 1 integration a k a JSR 914 It automatically manages connection factories connections sessions and message consumers listeners while retaining the standard JMS API Moreover connection and session try to reconnect automatically after a JMS connection failure callout info JMS provider implementation is not provided by this add on and must be configured depending on your messaging solution callout The JMS specification jar dependency is required as well since Seed JMS support doesn t transitively provide this dependency javax jms jms api 1 1 rev 1 provided","summary":"Java Message Service (JMS) is a Java API that allows applications to create, send, receive, and read messages.\nThis add-on provides a JMS 1.1 integration (a.k.a. JSR 914). It automatically manages connection factories,\nconnections, sessions and message consumers/listeners while retaining the...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"JMS","path":"jms"}},{"title":"Receiving messages","tags":["receiving","message","jms","polling","listener"],"href":"/addons/jms/receiving","content":"To receive JMS messages create a listener class which implements the javax jms MessageListener interface and is annotated with JMSMessageListener This annotation takes the following parameters The connection parameter specifying the connection that will be used to receive the messages The destinationType parameter specifying what kind of destination the class will listen to queue or topic The destinationName parameter specifying the name of the destination The poller parameter is optional and is used to enable polling on this listener Polling When a poller parameter is specified no asynchronous message reception driven by the JMS provider after a setMessageListener call takes place Polling behavior is delegated to the specified class which must implement org seedstack jms spi MessagePoller Simple message poller If polling is needed on a particular listener you may use the org seedstack jms SimpleMessagePoller class for basic polling needs It spawns a thread which calls to receive in a loop dispatching the message to the onMessage method when a message is received If an exception occurs during receive the exception is dispatched to the connection exception listener if any If an exception is thrown during the reception or message handling the polling thread is shutdown and scheduled to restart 10 seconds later When used in conjunction with the automatic reconnection the exception also triggers a connection refresh In that case the poller may retry to receive messages several times before the connection is up again depending on the configured connection refresh timeout","summary":"To receive JMS messages, create a listener class which implements the javax.jms.MessageListener interface and is \nannotated with @JMSMessageListener. This annotation takes the following parameters:\n\nThe connection parameter specifying the connection that will be used to receive the messages.The...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"JMS","path":"jms"}},{"title":"Sending messages","tags":["jms","message","sending","transaction"],"href":"/addons/jms/sending","content":"Seed Managed Session Using a managed session consists in the following steps 1 Inject a Session note that a session is transactional 2 Specify the connection to use with the JmsConnection annotation 3 Use the session to create the destination Queue or Topic 4 Transaction will be automatically committed or rolled back according to your Transactional annotation 5 Session object is managed by Seed There is no need to care about thread safe usage or closing it 6 To fine tune the Transaction please refer to the transaction support documentation Below is an example using a session to create a queue and send a TextMessage public class ClassWithJMSSending Inject private Session session Transactional JmsConnection connection 1 public void send String stringMessage throws JMSException Destination queue session createQueue queue1 TextMessage message1 session createTextMessage message1 setText stringMessage MessageProducer producer session createProducer queue producer send message1 Manually Created Session A connection can be injected directly inject and used to manually create all needed objects to send a message In this case except for the connection nothing is managed by Seed Objects life cycles have to be dealt with creation closing etc public class MyUnManagedMessageSender Inject Named connection 1 private Connection connection public void send String stringMessage throws JMSException Session session connection createSession false Session AUTO_ACKNOWLEDGE Destination queue session createQueue queue2 TextMessage message session createTextMessage message setText stringMessage message setJMSExpiration 1000 message setJMSReplyTo queue MessageProducer producer session createProducer queue producer send message session close Automatic reconnection When you inject a session or a connection and automatic reconnection is enabled Seed provides managed objects which embed a reconnection mechanism When the connection is down creating a producer or sending a message will throw a JMSException But when the underlying connection is up again the connection and the session will be refreshed So you won t need to get new connection or session By default Seed attempt to reconnect every 30 seconds but this is configurable see here configuration automatic reconnection callout info Notice that it is still up to you to handle the retry policy of the sent message callout","summary":"Seed Managed Session\n\nUsing a managed session consists in the following steps:\n\nInject a Session (note that a session is transactional).Specify the connection to use with the @JmsConnection annotation.Use the session to create the destination Queue or Topic.Transaction will be automatically...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"JMS","path":"jms"}},{"title":"Alternate configuration","tags":["jpa","persistence","data","database","relational","unit","xml"],"href":"/addons/jpa/alternative","content":"As an alternative to the automatic configuration configuration you can let JPA manage its own datasource instead of referencing one defined in the JDBC add on In this case you must provide a persistence xml file This file has to be placed under the META INF directory of your classpath for instance in src main resources META INF xml org seedstack jpa sample Item1 In the example above you can find The JPA version 2 1 in this example A unit named my jpa unit A local transaction type RESOURCE_LOCAL The list of persistence classes to map You can declare as many units as required in a persistence xml file You can also add configuration properties directly in this file although it is recommended to specify them in the configuration When using a persistence xml file you must either specify a datasource via properties or via JNDI Option 1 datasource via properties The datasource can be specified through properties either in the configuration ini org seedstack jpa unit my jpa unit property javax persistence jdbc driver property javax persistence jdbc url property javax persistence jdbc user property javax persistence jdbc password Or in the directly in the persistence xml file xml The specification of properties in the configuration is recommended as it allows greater flexibility access to environment variables and system properties usage of configuration profiles macros Option 2 datasource via JNDI In some environments like in a Web server it may be preferable to use JNDI instead of configuration properties You can do so by specifying the JNDI name of the datasource in the persistence xml file xml java comp env jdbc my datasource In case of a JTA data source use following line instead xml java comp env jdbc my datasource In case of a Web application add the following JNDI reference in your web xml file xml jdbc my datasource javax sql DataSource Container You may need to add additional files depending on your Web container Please refer to the the dedicated container documentation","summary":"As an alternative to the automatic configuration you can let JPA manage its own datasource instead of referencing\none defined in the JDBC add-on. In this case you must provide a persistence.xml file. This file has to be placed under\nthe META-INF directory of your classpath (for instance in src/main...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"JPA","path":"jpa"}},{"title":"Basics","tags":["jpa","persistence","data","database","relational","unit"],"href":"/addons/jpa/","content":"Seed JPA persistence add on enables your application to interface with any relational database through a JPA compliant ORM Note that This version doesn t enforce a specific JPA version It is currently tested with JPA 1 0 JPA 2 0 and JPA 2 1 This add on is compatible with any ORM implementation callout tips If you want to use the popular Hibernate ORM http hibernate org orm use the following Maven dependency org hibernate hibernate core org hibernate hibernate entitymanager Only add the JPA specification to declare entity classes in any module that does not have the hibernate dependency org hibernate javax persistence hibernate jpa 2 1 api 1 0 0 Final provided callout Configuration The JPA add on doesn t need any persistence xml file in its default mode of operation as it will automatically generate persistence unit information First declare the list of your persistence units in the configuration ini org seedstack jpa units my jpa unit The you must reference a JDBC datasource for each JPA unit To do so please refer to the JDBC add on configuration jdbc ini org seedstack jpa unit my jpa unit datasource my datasource Note that Seed has no way of knowing to which persistence unit belong each entity class so you must indicate this with the following configuration ini org myorganization myapp domain jpa unit my jpa unit This will put all the entities scanned in the org myorganization myapp domain package and its subpackages into the my jpa unit persistence unit Options You can specify the type of transactions by using the following configuration more info http docs oracle com javaee 6 api javax persistence spi PersistenceUnitInfo html getTransactionType 28 29 ini org seedstack jpa unit my jpa unit transaction type JTA RESOURCE_LOCAL If you prefer to use XML JPA mapping files instead of annotations you can specify them with the following configuration more info http docs oracle com javaee 6 api javax persistence spi PersistenceUnitInfo html getMappingFileNames 28 29 ini org seedstack jpa unit my jpa unit mapping files path to mapping file1 xml path to mapping file2 xml You can specify the validation mode with the following configuration more info http docs oracle com javaee 6 api javax persistence spi PersistenceUnitInfo html getValidationMode 28 29 ini org seedstack jpa unit my jpa unit validation mode path to mapping file1 xml path to mapping file2 xml You can specify the shared cache mode with the following configuration more info http docs oracle com javaee 6 api javax persistence spi PersistenceUnitInfo html getSharedCacheMode 28 29 ini org seedstack jpa unit my jpa unit shared cache mode ALL NONE ENABLE_SELECTIVE DISABLE_SELECTIVE UNSPECIFIED Properties If you need to pass any property to the persistence unit you can do so with the following configuration ini org seedstack jpa unit my jpa unit property name of the property1 value of the property1 property name of the property2 value of the property2 Using the Entity Manager To use the Entity Manager in your code simply inject it java public class MyRepository Inject private EntityManager entityManager All JPA interactions have to be realized inside a transaction Refer to the transaction support documentation docs seed manual transactions for more detail Below is an example using the annotation based transaction demarcation notice the persistence xml unit name in annotation java public class MyService Inject private MyRepository myRepository Transactional JpaUnit my jpa unit public void doSomethingWithMyJpaUnit callout info Note that the annotation is NOT optional as the JPA add on includes the JDBC add on as a dependency so the conditions that you must have only one type of transactional resources in your application cannot be fulfilled You can omit the name of the unit if you only have one unit in your application although we recommend you to always specify it explicitly callout","summary":"Seed JPA persistence add-on enables your application to interface with any relational database through a JPA-compliant\nORM. Note that:\n\nThis version doesn't enforce a specific JPA version. It is currently tested with JPA 1.0, JPA 2.0 and JPA 2.1.This add-on is compatible with any ORM...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"JPA","path":"jpa"}},{"title":"Basics","tags":["persistence","nosql","mongodb","data","database"],"href":"/addons/mongodb/","content":"SeedStack MongoDB add on enables your application to connect with MongoDB instances You also need to add the MongoDB Java client org mongodb mongo java driver You can choose to use the MongoDB asynchronous client instead or in addition as you can mix asynchronous and synchronous clients in the same application org mongodb mongodb driver async Configuration MongoDB clients are used to access databases and are declared with the following configuration property ini org seedstack mongodb clients client1 client2 Each client must then be configured separately with the following configuration ini org seedstack mongodb client client1 configuration of client1 org seedstack mongodb client client2 configuration of client2 callout info As MongoDB has a different Java driver for synchronous and asynchronous clients the type of a client will determine how it can be configured and used Clients use the synchronous driver http mongodb github io mongo java driver 3 0 driver by default to switch to the asynchronous driver http mongodb github io mongo java driver 3 0 driver async specify the following configuration ini org seedstack mongodb client client1 async true callout URI connection string A client can be configured with an URI ini org seedstack mongodb client client1 uri mongodb username password host1 port1 host2 port2 hostN portN database options URI allows to directly specify a set of options common to synchronous and asynchronous clients More information about the URI and its options can be found here http docs mongodb org manual reference connection string Explicit hosts As an alternative a client can be configured by directly specifying the MongoDB host s ini org seedstack mongodb client client1 hosts host1 27017 host2 In this case the client options must be specified using additional properties which a are different for synchronous and asynchronous clients See the Synchronous client options synchronous client options and Asynchronous client options asynchronous client options sections below for more information callout info When no port is specified whether in the URI or in the hosts property the default MongoDB port is used 27017 callout When configuring the connection with explicit hosts connection credentials can be specified as the following ini org seedstack mongodb client client1 credentials db1 user1 password1 This will authenticate with the username user1 and the password password1 The user will be lookup up in the db1 database The authentication mechanism will be automatically selected To force an authentication mechanism use the following syntax ini org seedstack mongodb client client1 credentials mechanism db1 user1 password1 The available authentication mechanisms are PLAIN MONGODB_CR SCRAM_SHA_1 MONGODB_X509 and GSSAPI You can specify multiple credentials like the following ini org seedstack mongodb client client1 credentials mechanism db1 user1 password1 mechanism db2 user2 password2 callout tips It is recommended to avoid specifying the authentication mechanism as it will be automatically selected Also note that often only one credential is enough callout Databases You can choose to inject and use the MongoClient object s directly and access the database s programatically As a convenience Seed also allows to inject the MongoDatabase object s with the following configuration ini org seedstack mongodb client client1 databases db1 db2 Each declared database can then be injected accordingly See the usage usage section below for more information Database names must be unique across the application so you can encounter a situation when multiple configured clients may need to access databases with the same name In that case you can use the alias feature Consider the following clients ini org seedstack mongodb client client1 databases db1 db2 org seedstack mongodb client client2 databases db2 db3 You can note that a database named db2 exists in MongoDB instances accessed by both client1 and client2 To resolve this ambiguity one of the db2 databases must be aliased in the application ini org seedstack mongodb client client2 databases db2 db3 alias db2 db2bis In this example the db2 database present on the MongoDB instance accessed by client2 will be referred in the application by the db2bis name Note that you can use this feature even when there are no name collision Synchronous client options Additional options can be specified on synchronous clients with the option prefix ini org seedstack mongodb client client1 option optionName1 value1 option optionName2 value2 All the options from the MongoClientOptions Builder http api mongodb org java 3 0 com mongodb MongoClientOptions Builder html class are available Each method of the builder translates to an option of the same name Consider the following example ini org seedstack mongodb client client1 option connectionsPerHost 75 This will invoke the connectionsPerHost method on the option builder with the value 75 converted to an integer callout tips If you use a URI configuration you can combine the URI options with the option syntax The specified option s will complement their URI counterpart and override them if present in both callout Asynchronous client options Additional options can be specified on asynchronous clients with the setting prefix ini org seedstack mongodb client client1 setting settingNamespace1 settingName1 value1 setting settingNamespace1 settingName2 value2 setting settingNamespace2 settingName3 value3 All the settings from the MongoClientSettings Builder builder and its sub builders are available Each sub builder translates to a setting namespace and each of the builders method translates to a particular setting The list of the builders and their corresponding namespace is Namespace Builder cluster ClusterSettings Builder connectionPool ConnectionPoolSettings Builder socket SocketSettings Builder heartbeatSocket SocketSettings Builder server ServerSettings Builder ssl SslSettings Builder Consider the following example ini setting connectionPool maxSize 75 This will invoke the maxSize method on a ConnectionPoolSettings Builder instance with the value 75 converted to an integer This builder instance will in turn be be set on a MongoClientSettings Builder instance via the connectionPoolSettings method callout info The global settings directly available on MongoClientSettings Builder can be specified without namespace More information on the global builder here http api mongodb org java current com mongodb async client MongoClientSettings Builder html The cluster hosts and credentialList settings are ignored since they are already mapped from the hosts and the credentials properties callout Usage As MongoDB doesn t support transactions usage simply consists in injecting a MongoClient or a MongoDatabase object and using it accordingly to the MongoDB documentation As an example you can inject the client as the following java Inject Named client1 MongoClient client1 This will inject the configured MongoDB client named client1 You can also inject a database directly as the following java Inject Named db1 MongoDatabase db1 This will inject the configured MongoDB database named db1 Note that you must use the aliased name instead of the real database name if you aliased it in the configuration see the databases databases section for information about aliases callout info If your client or database is configured as synchronous the default you must use the com mongodb MongoClient and com mongodb client MongoDatabase classes If your client or database is configured as asynchronous you must use the com mongodb async client MongoClient and com mongodb async client MongoDatabase classes instead callout callout tips You can inject a client or a database without any Named qualifier as long as there is only one client or only one database of the injected type configured callout Morphia Morphia https github com mongodb morphia is an Object document mapper Api it Provides Annotation based Java objects mapping and fluent query update API s SeedStack Morphia add on enables your application to connect and interact with MongoDB instances only by injecting and using a Morphia Datastore Configuration callout info Requirements Morphia Datastores need synchronous mongodb databases please refer to mongodb synchronous client asynchronous client options and database Databases configuration before starting with morphia callout Seed has the ability to create a new Morphia Datastore linked to single Morphia mapped objects or java packages Two morphia properties clientName and dbName are available and can be set using Seed object props configuration as followed Required Mongodb configuration ini org seedstack mongodb clients client1 org seedstack mongodb client client1 hosts localhost option connectionsPerHost 50 databases db1 Datastore linked to a single Morphia mapped object ini org mycompany myapp domain user morphia clientName client1 morphia dbName db1 Datastore linked to Morphia mapped objects in a package ini org mycompany myapp domain user User morphia clientName client1 morphia dbName db1 Usage Configuration for affecting a package to a Datastore linked to the database db1 ini org seedstack mongodb clients client1 org seedstack mongodb client client1 hosts localhost option connectionsPerHost 50 databases db1 org mycompany myapp domain user morphia clientName client1 morphia dbName db1 callout info Morphia only support synchronous client as so the Mongodb database must be synchronous callout Mapping Object under the package defined above java Entity public class User implements AggregateRoot Id private long id private String name private String lastname Embedded private Address address Embedded public class Address implements ValueObject private String country private String zipcode private String city private String street private Integer number A Morphia Datastore can be injected simply by specifying the associated morphia clientName and morphia dbName with the appropriate binding annotation MorphiaDatastore as followed java public class MorphiaIT extends AbstractSeedIT Inject MorphiaDatastore clientName client1 dbName db1 private Datastore datastore Test public void datastore_test User user new User Key keyUser datastore save user Assertions assertThat keyUser isNotNull Repositories The Morphia addon also provides repositories which can be use with the Business Framework http seedstack org docs business Default repositories can be used by injecting the interface with both the Inject and annotations as followed java public class MongodbRepositoryIT extends AbstractSeedIT Inject Morphia private Repository userRepository Inject Factory myUserFactory Test public void mongodb_repository_test userRepository delete myUserFactory create User loadedUser userRepository load user1 getEntityId Assertions assertThat user isEqualTo null Custom repositories can be added simply by extending the class as followed java public interface UserRepository extends Repository public class UserMongodbRepository extends BaseMongodbRepository The repository can be injected as followed java Inject private UserRepository userRepository callout info To use a inside the repository simply call the method this getDatastore callout","summary":"SeedStack MongoDB add-on enables your application to connect with MongoDB instances. \n\n\n\nYou also need to add the MongoDB Java client:\n\n<dependency>\n    <groupId>org.mongodb</groupId>\n    &lt...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"MongoDB","path":"mongodb"}},{"title":"Batch monitoring","tags":["monitoring","batch","job","spring"],"href":"/addons/monitoring/batch/","content":"You can use the monitoring add on batch module to inspect jobs executions and steps Execution statistics are also provided To add this module in you project add the following dependency to your Web application callout info This module will provide a REST API to query for batch execution information You can use the UI provided by this add on or write your own callout Integration This module must be configured Create Spring Batch metadata tables If you don t have already existing Spring Batch tables you can create them with the SQL scripts that are located in the spring batch core JAR inside org springframework batch core package callout info The tables BATCH _ prefix can be changed but this requires a change in two places tablePrefix property within batch jobRepository bean configuration table prefix property within props org seedstack seed monitoring batch datasource section of the Web appplication callout Configure the datasource In a batch module Each batch module must be configured to write its batch execution information to a specified datasource xml In a Web module The Web module should be configured to access the same datasource as your batch jobs It will use the tables to fetch and display batch execution information ini org seedstack batch monitoring datasource driver url user password table prefix pool size Example ini org seedstack batch monitoring datasource driver oracle jdbc OracleDriver url jdbc oracle thin TEST 1521 test user test password test table prefix BATCH_ pool size 6 Security All batch monitoring REST resources are secured with permissions These permissions have to be bound to application roles docs seed manual security in order to allow access to the user interface In the configuration file of your web application ini org seedstack seed security permissions monitoring seed monitoring batch read ConfigurationRealm example ini org seedstack seed security users jane password SEED MONITORING admin password SEED MONITORING org seedstack seed security roles monitoring SEED MONITORING org seedstack seed security permissions monitoring seed monitoring batch read Usage By default all views are loaded at once with current available data The Update button allows to force a refresh data every 5 seconds when clicked red Jobs detail The Jobs detail view allows a user to inspect jobs that are known to the system ie monitoring data in same DB tables set Jobs img jobsDetails png Job executions detail The Job executions detail view shows all jobs executions ordered by date descending order and a brief summary of their status STARTED COMPLETED FAILED etc Executions img jobExecutions png Steps detail The Steps detail view offers two kinds of feedback global feedback A list of all steps and their average time consumption ms across all past job executions as a bar chart this provides a statistical feel of global performance characteristics For example a developer running a job in an integration test environment might use the statistics here to compare different configurations of a job in order to optimize those eg commit interval in an item processing step steps feedback Upon selection of a step in the list first step selected by default the bottom part of the screen gives detail on this step with a progression bar and figures about read write commit rollback For more details this section also provides View full detail and View history buttons Corresponding views are described below Steps img stepsDetails png Step full detail The Step detail view has the detailed meta data for the step status read count write count commit count skip count etc as well as an extract of the stacktrace from any exception that caused a failure of the step statusExitDescription value Step details img stepDetails png Step history The Step history view shows the history of the execution of this step across all job executions eg max min and average of commit rollback read write counts Step history img history png","summary":"You can use the monitoring add-on batch module to inspect jobs, executions and steps. Execution statistics are also\nprovided. To add this module in you project add the following dependency to your Web application:\n\n{{< dependency g="org.seedstack.addons.monitoring" a="monitoring...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Monitoring","path":"monitoring/batch"}},{"title":"Basics","tags":["monitoring"],"href":"/addons/monitoring/","content":"The SeedStack monitoring add on provides modules exposing API which report the monitoring status of your application Batch monitoring module batch which reports upon the status of Spring batch jobs Other monitoring modules will be provided in the future Monitoring UI You can write your custom UI or benefit from the built in W20 UI provided by this add on To do so add the following dependency to your Web application callout info This dependency will not provide the monitoring itself only the UI You must also add one or more monitoring modules provided by this add on callout","summary":"The SeedStack monitoring add-on provides modules exposing API which report the monitoring status of your application:\n\nBatch monitoring module which reports upon the status of Spring batch jobs.\n\nOther monitoring modules will be provided in the future.\n\nMonitoring UI\n\nYou can write your custom UI or...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Monitoring","path":"monitoring"}},{"title":"Basics","tags":["persistence","graph","neo4j","database","data"],"href":"/addons/neo4j/","content":"Coming soon","summary":"Coming soon...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Neo4J","path":"neo4j"}},{"title":"Basics","tags":["persistence","data","database","store","key","value","structure"],"href":"/addons/redis/","content":"Coming soon","summary":"Coming soon...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Redis","path":"redis"}},{"title":"Basics","tags":["scheduling","task","quartz","cron","timer"],"href":"/addons/scheduling/","content":"Scheduling add on provides a simple API to schedule task in Seed Declarative API Create a Class implementing and add a annotation with a cron expression Your task will be detected and scheduled according to the annotation content at Seed startup Scheduled 0 2 public class MyTask implements Task Override public void execute throws Exception return calculateSomething As shown in above snippet the default value attribute of Scheduled is used for cron expression If any other attribute is required the annotation becomes for instance Scheduled value 0 2 taskName TASK1 exceptionPolicy UNSCHEDULE_ALL_TRIGGERS exceptionPolicy defines the behaviour on Task s exception Refer to Scheduled JavaDoc for all its attributes Refer to Quartz Documentation http quartz scheduler org generated 2 2 1 html qs all page Quartz_Scheduler_Documentation_Set 2Fco trg_crontriggers html 23 for cron expression details Programmatic API Inject a ScheduledTaskBuilderFactory and programmatically define a scheduled task not necessarily at application startup with following DSL Cron expression Inject private ScheduledTaskBuilderFactory factory ScheduledTaskBuilder scheduledTaskBuilder factory createScheduledTaskBuilder MyTask class withCronExpression 0 2 scheduledTaskBuilder schedule Note Above cron expression implicitly defines a Trigger With a Trigger When a cron expression can not define the expected triggering conditions a Quartz Trigger can be defined For example Inject private ScheduledTaskBuilderFactory factory Trigger trigger TriggerBuilder newTrigger withIdentity TriggerKey triggerKey myTrigger myTriggerGroup withSchedule SimpleScheduleBuilder simpleSchedule withIntervalInSeconds 1 repeatForever startAt DateBuilder futureDate 2 DateBuilder IntervalUnit SECOND build ScheduledTaskBuilder scheduledTaskBuilder factory createScheduledTaskBuilder MyTask class withTrigger trigger withPriority 10 scheduledTaskBuilder schedule Listeners Create a Class implementing TaskListener in order to listen to the Task execution The Task is bound to the by declaring the Task as the Type parameter public class MyTaskListener implements TaskListener Logging private Logger logger Override public void before SchedulingContext schedulingContext logger info Before MyTask Override public void after SchedulingContext schedulingContext logger info After MyTask Override public void onException SchedulingContext schedulingContext Exception e logger info Something gets wrong e ScheduledTaskBuilder scheduledTaskBuilder factory createScheduledTaskBuilder MyTask class scheduledTaskBuilder unschedule sc getTriggerName callout tips Keep Code In Listeners Concise And Efficient Performing large amounts of work is discouraged as the thread that would be executing the job or completing the trigger and moving on to firing another job etc will be tied up within the listener callout callout warning Handle Exceptions Every listener method should contain a try catch block that handles all possible exceptions If a listener throws an exception it may cause other listeners not to be notified and or prevent the execution of the job etc callout Exception handling When exception occurs during the task execution you can choose to unschedule the Task or refire it immediately You just have add an ExceptionPolicy to the Scheduled annotation Scheduled value 0 2 exceptionPolicy UNSCHEDULE_ALL_TRIGGERS ExceptionPolicy can take the following values REFIRE_IMMEDIATELY Immediately re execute the task This option SHOULD BE USED VERY CAREFULLY as the Task will be fired indefinitely until successful or the application crashes UNSCHEDULE_FIRING_TRIGGER Unschedule the Trigger firing the Task This option is convenient when a Task fails due to a specific trigger UNSCHEDULE_ALL_TRIGGERS Unschedule all triggers associated to the Task NONE Do nothing Default value You can also choose to handle exception by yourself with a TaskListener It will be possible to use the UNSCHEDULE_ALL_TRIGGERS option and then reschedule the Task java public class MyTaskListener implements TaskListener Inject private ScheduledTaskBuilderFactory factory Override public void onException SchedulingContext schedulingContext Exception e logger info Something gets wrong try Repair then reschedule ScheduledTaskBuilder scheduledTaskBuilder factory createScheduledTaskBuilder TimedTask class scheduledTaskBuilder reschedule sc getTriggerName catch Exception e logger error e getMessage e callout info Exception handling in a TaskListener is called asynchronously in order to be sure to apply the Task s exception policy Be careful in your implementation as it is impossible to know whether the Task s exceptionPolicy or TaskListener s onException method is called first callout","summary":"Scheduling add-on provides a simple API to schedule task in Seed. \n\n\n\nDeclarative API\n\nCreate a Class implementing  and add a\n{{< java &quot...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Scheduling","path":"scheduling"}},{"title":"Basics","tags":["solr","persistence","indexing","search","data"],"href":"/addons/solr/","content":"Coming soon","summary":"Coming soon...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Solr","path":"solr"}},{"title":"Batch","tags":["batch","spring","job","bridge"],"href":"/addons/spring-bridge/batch","content":"A specific Spring Batch integration is also provided Spring Batch is a comprehensive solution to implement full featured batch jobs in Java More information about Spring Batch on http docs spring io spring batch http docs spring io spring batch All Spring context XML files must be in under the META INF spring classpath location Running jobs The org seedstack seed cli SeedRunner class contains a main method Its role is to launch a named command directly from the operating system command line SeedStack Spring Batch support provides the run job command to start a Spring Batch job java java options org seedstack seed cli SeedRunner run job run job options This will start the Spring Batch job named job Options A number of options are available for customizing the run job command behavior Short option Long option Description j job jobName Specify the job to launch by name job by default l jobLauncher jobLauncherName Specify the job launcher by name jobLauncher by default P jobParameters paramName paramValue Specify a job parameter Can be used multiple times Example Consider the following command sh java cp Dsysprop sysvalue org seedstack seed cli SeedRunner run job job myJob jobParameter param1 value1 jobParameter param2 value2 This will execute a Spring Batch job with the following characteristics The classpath will be defined by the cp option of the JVM A system property sysprop with the value sysvalue will be set The job named myJob will be executed Two parameters will be passed to the job param1 with value value1 and param2 with value value2 Executable ber JAR To run the batch from a unique JAR you can build the project with the Apache Maven Shade Plugin This plugin will package the artifact as an ber JAR with all necessary dependencies For more information please refer to the plugin documentation http maven apache org plugins maven shade plugin examples executable jar html You can find a typical configuration of the plugin below org apache maven plugins maven shade plugin META INF spring handlers META INF spring schemas org seedstack seed cli SeedRunner package shade Testing To be able to do SeedStack integration testing add the Seed integration test support to your project Check the documentation here docs seed manual testing integration The following example checks that the batch returns with the exit code 0 and subsequently that injection works import org seedstack seed it AbstractSeedIT public class RunnerBatchIT extends AbstractSeedIT Inject MessageService messageService Test WithCommandLine command run job args job mySimpleJob expectedExitCode 0 public void testBatch assertThat messageService isNotNull We could easily use the service or any injectable class to check for the batch results The WithCommandLine annotation simulates the running of a command from the operating system command line All the arguments of the run job command can be used in the args attribute Look here running jobs for information about these arguments callout info Note that the test method is called after the job is completed Before annotated methods are executed after Kernel startup so you can use injection in them but before job execution so you can prepare a dataset if needed callout Full example The goal of this section is to create your first batch This one step job will just print My Simple Job Add Maven dependencies This example requires business core org seedstack seed spring batch org seedstack business business core Create the application context We need to set up a Spring Batch environment Spring files must be in the META INF spring classpath location and end with context xml to be automatically detected The application context xml file Description of the beans JobRepository responsible for persistence of batch meta data information JobLauncher responsible for launching the batch job TransactionManager As this example won t be dealing with transactional data we are using ResourcelessTransactionManager which is mainly used for testing purpose Don t use in production Create the service We will create a service that will be injected directly in a Spring Batch tasklet The service interface package org myorg myapp domain services import org seedstack seed business api Service Service public interface MessageService public String getMessage The service implementation package org myorg myapp infrastructure services import org myorg myapp domain services MessageService public class MessageServiceImpl implements MessageService public String getMessage return","summary":"A specific Spring-Batch integration is also provided. Spring-Batch is a comprehensive solution to implement full-featured\nbatch jobs in Java. More information about Spring Batch on http://docs.spring.io/spring-batch/.\n\n{{< dependency g="org.seedstack.addons.spring" a="spring-bridge...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Spring bridge","path":"spring-bridge"}},{"title":"Basics","tags":["spring","bridge","bean","injection","context"],"href":"/addons/spring-bridge/","content":"Seed Spring support is a bi directional injection bridge between Seed managed instances and Spring beans It allows to inject Spring beans in Seed instances and Seed instances as Spring beans Additionally this support fills in a gap between Seed and Spring code allowing for instance to initiate a Spring based transaction from Seed code Tt also provides a Spring namespace handler to make its features as easy to use as possible Spring to Seed Any Spring context located in the META INF spring classpath directory and named with the pattern context xml will be autodetected by Seed You can turn off auto detection with the following configuration property org seedstack spring autodetect false You can add custom contexts located anywhere in the classpath with the following configuration property org seedstack spring contexts resource path to context1 xml resource path to context2 xml You can inject any Spring bean from contexts detected by Seed in any Seed injectable component You can inject using the bean Class and the bean name Inject Named theBeanId BeanClass bean You can inject using the bean parent s Class if not Object and the bean name Inject Named theBeanId BeanParentClass bean You can inject using any directly implemented Interface and the bean name Inject Named theBeanId BeanImplementedInterface bean Note that you always need to qualify your injection with the bean identifier Named theBeanId Seed to Spring To use Seed instances in Spring contexts you need to add the Seed namespace to your Spring files You can then create a spring bean from any Seed instance bound with a class name It is equivalent to this Seed injection Inject org myorganization myproject MyService myService Named Seed bindings bound with a Named qualifier are also supported It is equivalent to this Seed injection Inject Named myQualifier org myorganization myproject MyService myService Since Seed can inject Spring beans and Spring can inject Seed instances there is a circular dependency between the two injectors To alleviate this problem Seed instances are by default proxied for lazy initialization It allows Spring to initialize its context without needing the Seed injector to be initialized too You can explicitly disable this proxy You can also inject configuration values directly It is equivalent to this Seed configuration injection Configuration org myorganization myproject my configuration value String configurationValue Configuration values don t require Seed injector to be initialized and are all available at context initialization You can specify a default value It is equivalent to this Seed configuration injection Configuration value org myorganization myproject my configuration value defaultValue myDefaultValue String configurationValue You can control if a property is mandatory with the mandatory attribute true by default If no configuration value nor default value is available and the injection is not mandatory null will be used","summary":"Seed Spring support is a bi-directional injection bridge between Seed managed instances and Spring beans. It allows to\ninject Spring beans in Seed instances and Seed instances as Spring beans.\n\nAdditionally, this support fills in a gap between Seed and Spring code allowing for instance to initiate a...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Spring bridge","path":"spring-bridge"}},{"title":"Transactions","tags":["spring","bridge","transaction","jpa"],"href":"/addons/spring-bridge/transactions","content":"When using Spring framework along SeedStack you might need to trigger transactions accross framework boundaries The Spring bridge add on provides a solution that goes both ways and lets you choose beteween either Managing Spring transactions from Seed code Managing Seed transactions from Spring code Seed managed transactions You can specify a Spring based transaction handler in your Seed transaction demarcation by adding the SpringTransactionManager annotation besides the Transactional one You can define any valid Spring transaction manager in any Spring context known by Seed Spring support Example The value of the SpringTransactionManager annotation is used to choose the right transaction manager Its default value is transactionManager Example of use in an integration test RunWith SeedITRunner class public class SpringTransactionHandlerIT Inject Named customerDao CustomerDao customerDao Test Transactional SpringTransactionManager myTransactionManager public void testTransactional Assertions assertThat customerDao isNotNull Customer customer new Customer john doe john doe gmail com null customerDao save customer customerDao delete customer Assertions assertThat customer isNotNull Spring managed transactions Seed has the ability to inject a Spring configured JPA EntityManger in your Seed components In that case Spring will be managing all the JPA transactions Seed code will be executed whithin Spring transactions This feature can be very useful in batch jobs when you need to let Spring manage transactions for performance reasons Spring configuration As stated above Spring will be the one that will manage all JPA features mapping transaction As such your Spring context files need to be configured explicitly with JPA context JPA Datasources TransactionManagers EntityManagerFactories Seed configuration Seed JPA add on can be removed if possible or at least left unconfigured Add the following configuration for Spring bridge add on instead ini org seedstack spring manage transactions true","summary":"When using Spring framework along SeedStack, you might need to trigger transactions accross framework boundaries. The Spring bridge add-on provides a solution that goes both ways and lets you choose beteween either:\n\nManaging Spring transactions from Seed code,Managing Seed transactions from Spring...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Spring bridge","path":"spring-bridge"}},{"title":"Basics","tags":["bean","validation"],"href":"/addons/validation/","content":"SeedStack validation add on allows developers to use Bean Validation 1 0 and 1 1 Bean Validation 1 0 brings static validation aka JSR 303 Bean Validation API 1 1 brings dynamic validation aka JSR 349 Data validation is a very common concern at each and every layer of an application As such it has been standardized through Bean Validation using JSR 303 and JSR 349 Implementation uses Hibernate Validator that you need to add explicitly in your project Use Hibernate Validator version 4 x to support Bean Validation 1 0 only like in strict JEE6 environments Use Hibernate Validator version 5 x to support Bean Validation 1 1 To use this add on add the following dependency","summary":"SeedStack validation add-on allows developers to use Bean Validation 1.0 and 1.1:\n\nBean Validation 1.0 brings static validation (aka JSR 303).Bean Validation API 1.1 brings dynamic validation (aka JSR 349).\n\nData validation is a very common concern at each and every layer of an application. As such...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Validation","path":"validation"}},{"title":"Basics","tags":["css","bootstrap","design"],"href":"/addons/w20-bootstrap-2/","content":"The W20 Bootstrap 2 addon provides the Twitter Bootstrap framework in its 2 3 2 version the last version of the 2 0 branch It also provides a compatible angular bootstrap library and a compatible font awesome set of icons Installation bower install w20 bootstrap 2 Configuration To include the addon declare it in the application manifest bower_components w20 bootstrap 2 w20 bootstrap 2 w20 json","summary":"The W20 Bootstrap 2 addon provides the Twitter Bootstrap framework in its 2.3.2 version, the last version of the 2.0 branch.\nIt also provides a compatible angular-bootstrap library and a compatible font-awesome set of icons.\n\nInstallation\n\n\nbower install w20-bootstrap-2\n\n\nConfiguration\n\nTo include...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"W20 Bootstrap 2","path":"w20-bootstrap-2"}},{"title":"Basics","tags":["css","bootstrap","design"],"href":"/addons/w20-bootstrap-3/","content":"The W20 Bootstrap 3 addon provides the Twitter Bootstrap framework in its latest version It also provides a compatible angular bootstrap library and a compatible font awesome set of icons Installation bower install w20 bootstrap 3 Configuration To include the addon declare it in the application manifest bower_components w20 bootstrap 3 w20 bootstrap 3 w20 json","summary":"The W20 Bootstrap 3 addon provides the Twitter Bootstrap framework in its latest version.\nIt also provides a compatible angular-bootstrap library and a compatible font-awesome set of icons.\n\nInstallation\n\n\nbower install w20-bootstrap-3\n\n\nConfiguration\n\nTo include the addon, declare it in the...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"W20 Bootstrap 3","path":"w20-bootstrap-3"}},{"title":"Basics","tags":["w20","bridge","frontend","configuration","security"],"href":"/addons/w20-bridge/","content":"The SeedStack W20 bridge acts as an integration bridge between the Seed Java framework and the W20 Web framework You can add it with the following dependency How it works The W20 bridge automatically generates and serves W20 resources that should normally be written manually The W20 masterpage is automatically generated and served under There is no need to provide an index html file except for advanced use cases see below The W20 configuration file w20 app json is read from the META INF configuration classpath location and a managed enriched version is served under seed w20 application configuration A resource for basic authentication is served under seed w20 security basic authentication A resource for retrieving the authorizations of the authenticated subject is served under seed w20 security authorizations Automatic activation of fragments The W20 bridge automatically detects W20 fragments manifests ending with the w20 json extension present in the classpath under META INF resources and enables them in the generated W20 configuration callout warning Note that the W20 bridge cannot detect fragments located outside the local classpath like the ones in the document root or external to the application Those fragments must still be explicitly specified in the W20 configuration callout Fragment variables The W20 bridge provides several fragments variables containing path information about the application These variables can be used as variable name default value placeholders in the fragment manifests seed base path the application base path without a trailing slash seed base path slash the application base path with a trailing slash seed rest path the path under which the REST resources are served without a trailing slash seed rest path slash the path under which the REST resources are served with a trailing slash components path the path under which the Web components are served without a trailing slash components path slash the path under which the Web components are served with a trailing slash Automatic configuration Several aspects of the configuration are automatically managed The application identifier w20 core application id is automatically set with the same value as the backend application identifier The environment type w20 core env type is automatically set to the org seedstack w20 environment property if any Several elements in the masterpage are automatically derived from the bridge configuration values See the configuration section below configuration for more details callout info The interface can be implemented to further enrich or override the generated configuration As an example it is used by the i18n add on i18n for automatically managing the frontend culture module if backend internationalization is active callout Configuration The behavior of W20 bridge can be altered with several backend configuration properties described below Application title You can set the W20 application title with the following option org seedstack w20 application title My application The default value is set to the Seed application name coming from the org seedstack seed core application name Application subtitle You can set the W20 application subtitle with the following option org seedstack w20 application subtitle A great application There is no default value Application version You can set the W20 application version with the following option org seedstack w20 application version 1 2 3 The version is treated as a string so there is no restriction format The default value is set to the Seed application version coming from the org seedstack seed core application version It is not recommended to change this default value other than for testing purposes or special cases The version string is appended to all assets URLs by the W20 loader to ensure that resources are refreshed when the version change Loading timeout The W20 loader has a predefined time limit to load all the application assets Although the default value of 30 seconds should be enough for all applications tt is sometimes desirable to increase it with the following option org seedstack w20 timeout 60 CORS with credentials To allow the application to access secured resources from other domains than its own use the following option org seedstack w20 cors with credentials true This option is not necessary when accessing its own resources or publicly accessible cross origin resources only Masterpage disabling The generation of the masterpage can be completely disabled with the following configuration org seedstack w20 disable masterpage true Custom masterpage template The function uses a default html template for constructing the masterpage of the SPA You can override this template by providing your own in the classpath and still benefit from the variables org seedstack w20 masterpage template path to masterpage template html Below is the default template used by the function It uses variables and directives for themes You may want to use it as a base for overriding applicationTitle The available variables are applicationTitle applicationSubtitle applicationVersion timeout corsWithCredentials basePath basePathSlash restPath restPathSlash componentsPath componentsPathSlash","summary":"The SeedStack W20 bridge acts as an integration bridge between the Seed Java framework and the W20 Web framework. You can\nadd it with the following dependency:\n\n\n\nHow it works\n\nThe W20 bridge automatically...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"W20 bridge","path":"w20-bridge"}},{"title":"Forms","tags":["w20","frontend","form","generation","rich"],"href":"/addons/w20-components/forms","content":"Forms are one of the most common element in a web application The web framework provides support for forms building through programmatic configuration Internally it relies on Angular Formly http docs angular formly com an advanced library for managing forms with AngularJS This approach reduces the amount of HTML in favor of JavaScript to provide flexibility reusability maintainability and simplicity Forms Overview To display a form we declare a form element with a unique child The child element will itself declare the w20Form directive the model attribute which binds the form data to its value on the scope the fields attribute which reads the configuration object for the form fields on the scope Submit The w20Form directive transcludes Its child elements get appended to the end of the form This allow to declare the submit button inside the directive element In the JavaScript we can configure the form elements scope form model fields key name type text templateOptions label Name submit function The end result is an input element with a binding to scope model name key a type text type and a label Name label Benefits Using this approach offer several benefits such as Simpler declaration CSS agnostic no Bootstrap classes tightly linked to the form for instance Automatic validation Easier to declare conditional logic Creation of custom element types i18n capability Configuration Fragment declaration To include the form support in your application declare the form module in your w20 components addon fragment configuration of the application manifest bower_components w20 components w20 components w20 json forms Fields A field is an object which can accept theses properties template String or templateUrl String An HTML template or an URL to one This is useful to declare a title in the middle of the form for instance template Title key String The name of the property of the model to which this field NgModel will be binded className String The name of a css class to apply to the field Useful for layout type String The type of the field By default several types are available text email password date number url datetime local tel search color time week month checkbox radio textarea select templateOptions Object This property allow setting different options on the field element template label String The label of the field placeholder String The placeholder of the field Any additional template options are set as attributes on the field element This allow the registration of validation properties such as required Boolean Specify if the field is mandatory minlength Number Specify the field minimum length input min Number Specify the field minimum value maxlength Number Specify the field maximum length input max Number Specify the field maximum value pattern String A regular expression to which the input needs to validate against Some properties of the templateOptions only make sense for certain field type Select options Array of Object with properties name string value value group group The list of options for the select element Textarea rows Number Number of rows cols Number Number of columns Field group A field group is a way to group fields together which is useful for advanced layout It can also be used to group fields that are associated with the same model key person fieldGroup key sex type radio className col md 4 templateOptions name radioGroup label Male value M key sex type radio className col md 4 templateOptions name radioGroup label Female value F key married type checkbox className col md 4 templateOptions label Married y n In the above example the model will look something like this person sex M married true Internationalization Strings used for label placeholder etc can be replaced by i18n key They are automatically localized templateOptions label application w20 label to localize Expression properties Expression properties can be used to evaluate property on the field dynamically For instance key myThing type someType templateOptions label Label expressionProperties this would make the label change to what the user has typed templateOptions label viewValue This sets data someProp to be true or false data someProp model myThing length 5 Hide expression The hideExpression property is similar to the expressionProperties although it accepts both a string or a function It allows to show hide the corresponding field hideExpression function viewValue modelValue scope return scope model baz foobar Validation Validators Form validation is an important part of the user experience while completing the form You can add validation rule easily with the validators property type text key ip templateOptions required true label IP Address validators notLocalHost viewValue 127 0 0 1 ipAddress expression function viewValue modelValue scope var value modelValue viewValue return d 1 3 3 d 1 3 test value message viewValue is not a valid IP Address In the above example we register two validators notLocalHost and ipAddress The first one will validate the field if and only if the viewValue that is the value the user entered in the field is different from the localhost ip address The second validator demonstrate another way of declaring validators with more options Here we test against an IP regex and register a validation message to be displayed if the field does not validate Validation We already saw how to register a message alongside a validator but you can also register messages for any property For this you can use the validation option key id type text templateOptions label Id placeholder Id required true minlength 6 validation messages required options templateOptions label is mandatory minlength Minimum length allowed is options templateOptions minlength In the above example leaving the field empty will show Id is mandatory while providing an id with a length inferior to 6 will show Minimum length allowed is 6 The options templateOptions refer to the field templateOptions You can also use a shortcut syntax to for options templateOptions validation messages required to label is mandatory minlength Minimum length allowed is to minlength Disabling validation Default validation messages appear by the use of a wrapper around template You can completely disable the wrapper with the wrapper property or provide your own wrapper see Registering wrapper below key id type text wrapper null callout warning Please note that messages are strings which means they need to be between quotes For instance if you use an i18n key for the message it needs to be declared as application i18n key not just application i18n key callout callout info There are common default validation messages already registered for the en and fr locales callout callout info See Angular formly field configuration object http docs angular formly com docs field configuration object for an exhaustive description of all options available callout Customization FormsService The FormsService main goals are the registration of global validation messages custom template types and custom wrappers Global validation messages Although you can register a validation message for each field as we saw previously most of the time you will like to register a message for a certain validation that apply to all fields that declare this validation rule You can proceed in several ways Register a string message with validation addStringMessage name string formsService validation addStringMessage required This field is required You can also pass an i18n key formsService validation addStringMessage maxlength application form validation maxlength Register a template option value message sometime a string message is not enough because you need to display a variable value in the message To accomplish this you can use the validation addTemplateOptionValueMessage name property prefix suffix alternate This is easy to understand with an example scope form fields key id type text templateOptions label Id minlength 6 minlengthstring six key other type text templateOptions label Other minlength 6 formsService validation addTemplateOptionValueMessage minlength minlengthstring Minimum length is characters Too short In the example above we register a validation message for the minlength attribute first parameter The message displayed if the validation fail will be Minimum length is six characters i e prefix property suffix for the id field Too short for the other field because it uses the alternate message if the property does not exist Registering type The forms module provide default template type listed in the Fields section of this page However you can create your own type for maximum flexibility formsService config setType name customTitle to is a shortcut for options templateOptions template Custom title to customSetting scope form fields key id type customTitle templateOptions customSetting Some value Registering wrapper To set a wrapper use the config setWrapper wrapper method formsService config setWrapper template validationTemplate The validation template need to declare the element at the position where you want your field to be inserted inside the wrapper For instance this wrapper will add a above every field Layout and styling Layout When using a grid framework like Bootstrap you can achieve the desired layout using the className property of fields You can also combine this with the fieldGroup property for inner layout Style The default validation wrapper have these CSS classes for the label messages wrapper and message element w20 form error label for the form element label w20 form error messages for the ng messages div that wrap all the validation messages w20 form error message for each validation message","summary":"Forms are one of the most common element in a web application. The web framework provides support for \nforms building through programmatic configuration. Internally it relies on Angular Formly, \nan advanced library for managing forms with AngularJS. This approach reduces the amount of HTML in favor...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"W20 components","path":"w20-components"}},{"title":"Basics","tags":["w20","frontend","rich","component"],"href":"/addons/w20-components/","content":"W20 Components The W20 Components addon provides various UI components Installation bower install w20 components Configuration To include the addon declare it in the application manifest bower_components w20 components w20 components w20 json","summary":"W20 Components\n\nThe W20 Components addon provides various UI components.\n\nInstallation\n\n\nbower install w20-components\n\n\nConfiguration\n\nTo include the addon, declare it in the application manifest:\n\n\n"bower_components/w20-components/w20-components.w20.json": {}\n","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"W20 components","path":"w20-components"}},{"title":"UI Select","tags":["w20","frontend","select","combo","rich"],"href":"/addons/w20-components/select","content":"Angular UI select Angular UI select https github com angular ui ui select is an AngularJS native version of Select2 https select2 github io and Selectize http brianreavis github io selectize js Configuration bower_components w20 components w20 components w20 json select","summary":"Angular UI select\n\nAngular UI select is an AngularJS-native version of Select2\nand Selectize.\n\nConfiguration\n\n\n"bower_components/w20-components/w20-components.w20.json": {\n    "select": {}\n}\n","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"W20 components","path":"w20-components"}},{"title":"UI grid","tags":["w20","frontend","rich","component","grid"],"href":"/addons/w20-components/ui-grid","content":"Angular UI grid Angular UI grid http ui grid info is a datagrid fully integrated with AngularJS It is part of the AngularUI http angular ui github io suite Configuration bower_components w20 components w20 components w20 json grid","summary":"Angular UI grid\n\nAngular UI grid is a datagrid fully integrated with AngularJS. It is part of the \nAngularUI suite.\n\nConfiguration\n\n\n"bower_components/w20-components/w20-components.w20.json": {\n    "grid": {}\n}\n","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"W20 components","path":"w20-components"}},{"title":"Basics","tags":["frontend","w20","chart","data","visualization"],"href":"/addons/w20-dataviz/","content":"The W20 Dataviz addon provides supports for charts and graphical representation It is based on the NVD3 http nvd3 org charting library which itself uses D3 http d3js org Installation bower install w20 dataviz Configuration To include the addon declare it in the application manifest bower_components w20 bootstrap 3 w20 dataviz w20 json Configuration information is provided in the Jsdoc of the addon","summary":"The W20 Dataviz addon provides supports for charts and graphical representation. It is based on the \nNVD3 charting library which itself uses D3.\n\nInstallation\n\n\nbower install w20-dataviz\n\n\nConfiguration\n\nTo include the addon, declare it in the application manifest:\n\n\n"bower_components/w2...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"W20 dataviz","path":"w20-dataviz"}},{"title":"Basics","tags":["w20","frontend","extras","analytics"],"href":"/addons/w20-extras/","content":"The W20 Extras addon provides various functionality such as website analytics Installation bower install w20 extras Configuration To include the addon declare it in the application manifest bower_components w20 extras w20 extra w20 json If you are using the w20 bridge addon be sure to include the w20 extras module org seedstack addons w20 w20 bridge web extras Analytics Analytical tools allow statistical reporting and data analysis for your web applications Counting and tracking visitor s actions Statistics on page viewed Keyword searched E commerce specific report Setting cookies for tracking visit Displaying comprehensive and detailed reports Analytics providers generally requires a script inclusion in all web pages to track user actions based on the URL However in SPA since the routing is done at the front end this integration is a bit more tricky W20 uses Angulartics http luisfarzati github io angulartics internally to provide an easy integration of a wide range of providers Fragment configuration Include the extra fragment configuration in your fragment manifest and enable its analytics module To configure you analytics provide use the following properties provider string The name of the analytic provider to use Supported providers are given below Class Description adobe Adobe analytics chartbeat Chartbeat analytics flurry Flurry analytics ga Google Analytics ga cordova Google Analytics for Cordova gtm Google Tag Manager kissmetrics Kissmetrics mixpanel Mix Panel analytics piwik Piwik analytics segmentio Segment io analytics splunk Splunk woopra Woopra virtualPageViews boolean By default automatic virtual page view tracking is enabled meaning the entire user navigation across the different routes of your application is tracked You can turn it off with this property settings object If the chosen provider has a supported default configuration in W20 you can use this property to configure it Piwik After deploying your Piwik server you are provided with a site id for your registered website Set it to the siteId property and paste the URL to the javascript tracker piwik js into the jsUrl property and your Piwik PHP server address into the trackerUrl property path to extra w20 extra w20 json modules analytics provider piwik virtualPageViews true settings jsUrl url or path to piwik javascript tracker trackerUrl url to piwik javascript tracker siteId 1 Your website visits should be monitored by Piwik The trackPageView and enableLinkTracking options of Piwik are already applied An angular service PiwikService can now be injected to configure Piwik This service provide the following methods getAPI return the Piwik http developer piwik org api reference tracking javascript object configure settings Called initially to configure the provider with the settings property configured in the manifest It can be called programatically to change these settings later","summary":"The W20 Extras addon provides various functionality such as website analytics.\n\nInstallation\n\n\nbower install w20-extras\n\n\nConfiguration\n\nTo include the addon, declare it in the application manifest:\n\n\n"bower_components/w20-extras/w20-extra.w20.json": {}\n\n\nIf you are using the w20-bridge...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"W20 extras","path":"w20-extras"}},{"title":"Basics","tags":["frontend","w20","material","design","css"],"href":"/addons/w20-material/","content":"The W20 Material addon provides the Angular Material https material angularjs org latest framework Installation bower install w20 material Configuration To include the addon declare it in the application manifest bower_components w20 material w20 material w20 json","summary":"The W20 Material addon provides the Angular Material framework.\n\nInstallation\n\n\nbower install w20-material\n\n\nConfiguration\n\nTo include the addon, declare it in the application manifest:\n\n\n"bower_components/w20-material/w20-material.w20.json": {}\n","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"W20 material","path":"w20-material"}},{"title":"Consuming","tags":["web-service","jax-ws","metro","consume"],"href":"/addons/web-services/consume_hello_webservice","content":"The goal of this page is to detail the consumption of an Hello World SOAP based Web Service Configure the jaxws maven plugin and use wsimport to generate web service client java from wsdl You can then use the wsimport generated class in your application code java HelloService helloService new HelloService Hello helloServicePort helloService getHelloServicePort BindingProvider helloServicePort getRequestContext put BindingProvider ENDPOINT_ADDRESS_PROPERTY http localhost wsPort ws hello helloServicePort sayHello World","summary":"The goal of this page is to detail the consumption of an Hello World SOAP based Web Service. Configure the jaxws-maven-plugin\nand use wsimport to generate web service client java from wsdl.\n\nYou can then use the wsimport generated class in your application code:\n\njava\nHelloService helloService = new...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Web-Services","path":"web-services"}},{"title":"Basics","tags":["web-service","jax-ws","metro","endorse"],"href":"/addons/web-services/","content":"SeedStack Web Services add on provides a JAX WS integration JAX WS offers facilities to create and connect to web services To enable Web Services standalone add on without a Web environment use the following dependency snippet in your module In a Web environment you must use the following dependency snippet instead Best practices Since classes generated maven tools from WSDL are both for client and server side this logic should belong to a shared module This module can then be used as a dependency both on client and server side Keep one source WSDL per Web Service and use copy resources of maven resources plugin just after generating classes from WSDL Reasons are successful code generation means the WSDL is probably valid and generated code match that WSDL a copy of last valid WSDL is copied everywhere it is required eg published to META INF ws Endorsement JDK 6 JDK 6 contains an older version of the JAX WS specifications than the one used in WS add on Therefore the endorsed mechanism has to be used with required version of webservices api jar available here http search maven org remotecontent filepath org glassfish metro webservices api 2 3 webservices api 2 3 jar Endorse WS API There are two options 1 Java Endorsed Standards Override Mechanism applies to all projects using the JDK with endorsed library Copy webservices api jar into JDK6 folder jre lib endorsed create endorsed directory if it does not exist Alternative set the java endorsed dirs system property to the directory containing webservices api jar Documentation is available here http docs oracle com javase 6 docs technotes guides standards 2 IDE classpath override This method must be applied per project Add the webservices api jar library to the bootstrap classpath of your project This ensures that this library overrides the one in the JRE Endorse the Web server To use the WS add on in a Web application the server JRE has to endorse the library as well Add the webservices api jar JAR to the server endorsed directory or to server buildpath As described in Java Endorsed Standards Override Mechanism you can check endorsed directories through java endorsed dirs java System property JDK 7 JDK 7 works out of the box as required version of JAX Ws is already embedded","summary":"SeedStack Web-Services add-on provides a JAX-WS integration. JAX-WS offers facilities to create and connect to web services.\nTo enable Web-Services standalone add-on (without a Web environment) use the following dependency snippet in your module.\n\n{{< dependency g="org.seedstack.addons.ws...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Web-Services","path":"web-services"}},{"title":"Maven tools","tags":["web-service","jax-ws","metro","maven","wsimport"],"href":"/addons/web-services/maven-tools","content":"Source folder The WSDL file must be placed in the META INF ws directory of the classpath ini src it java resources META INF ws main java resources META INF ws WS import WS import is a tool which generates JAX WS artifact from WSDL such as Service Endpoint Interface SEI Client Service Exception class mapped from wsdl fault JAXB generated value types mapped java classes from schema types You have to use the jaxws maven plugin The following code is a sample of WS import configuration xml org jvnet jax ws commons jaxws maven plugin 2 3 wsimport wsimport generate sources true org myorganization ws hello src main resources META INF ws META INF ws Hello wsdl Hello wsdl true 2 1 false You can find more information about jaxws maven plugin here https jax ws commons java net jaxws maven plugin wsimport mojo html","summary":"Source folder\n\nThe WSDL file must be placed in the META-INF/ws directory of the classpath. \n\nini\nsrc\n    |-it\n        |-java\n        |-resources\n            |-META-INF\n                |-ws\n    |-main\n        |-java\n        |-resources\n            |-META-INF\n                |-ws\n\n\nWS-import\n\nWS...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Web-Services","path":"web-services"}},{"title":"Publishing","tags":["web-service","jax-ws","metro","example","wsdl"],"href":"/addons/web-services/publish_hello_webservice","content":"The goal of this page is to detail the creation of an Hello World soap based Web Service WSDL xml Hello World Java code Configure the jaxws maven plugin and use the wsimport goal to generate web service java interface Then create a class which implement the generated interface by ws import java WebService endpointInterface org myorganization myproject wsdl seed hello HelloService targetNamespace http myproject myorganization org wsdl seed hello serviceName HelloService portName HelloServicePort public class HelloServiceTest implements HelloService public String sayHello String param return Hello param Configuration To configure your endpoint just add the following properties to your configuration ini org seedstack ws endpoints HelloService endpoint HelloService implementation fully qualified package name HelloServiceTest endpoint HelloService wsdl Hello wsdl endpoint HelloService url ws hello Note that the WSDL location is relative to META INF ws","summary":"The goal of this page is to detail the creation of an Hello World soap based Web Service.\n\nWSDL\n\n`xml\n<?xml version="1.0" encoding="UTF-8"?>\n<wsdl:definitions\n        xmlns="http://schemas.xmlsoap.org/wsdl/"\n        xmlns:xsd="http://www.w3.org/200...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Web-Services","path":"web-services"}},{"title":"Testing","tags":["web-service","jax-ws","metro","testing"],"href":"/addons/web-services/testing","content":"Web Services can be tested in Seed managed integration tests You can find more about these kind of tests here testing integration and here testing integration web You ll find a Web black box example below java public class HelloWSIT extends AbstractSeedWebIT Deployment public static WebArchive createDeployment return ShrinkWrap create WebArchive class setWebXML WEB INF web xml Test RunAsClient public void webservice_is_working_correctly ArquillianResource URL baseURL throws Exception HelloService helloServiceClient new HelloService Hello helloServicePort helloServiceClient getHelloServicePort BindingProvider helloServicePort getRequestContext put BindingProvider ENDPOINT_ADDRESS_PROPERTY baseURL ws hello String response helloServicePort sayHello World Assertions assertThat response isEqualTo Hello World You have to specify the endpoint using ArquillianResource URL baseURL because Arquillian generates a different base URL for each run You may also create standalone integration tests outside a Web environment and as such without Arquillian callout info If you need to do manual testing you can access the WSDL via HTTP at http server port ws hello wsdl callout","summary":"Web Services can be tested in Seed managed integration tests. You can find more about these kind of tests \nhere and here. You'll find a Web black box example below:\n\n`java\npublic class HelloWSIT extends AbstractSeedWebIT {\n    @Deployment\n    public static WebArchive createDeployment...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Web-Services","path":"web-services"}},{"title":"Transports","tags":["web-service","jax-ws","metro","transport","jms","http"],"href":"/addons/web-services/transports","content":"The WS add on supports HTTP and JMS transports Each URL syntax described below Standalone HTTP In a standalone environment you need to specify the full URL with the binding address and the port http localhost 4578 ws hello Web server HTTP In a Web server environment you only need to specify the URL pattern ws hello JMS JMS URIs are unchanged whatever the environment They conform to the SOAP JMS specification http www w3 org TR soapjms There are three lookup variants to retrieve connection factories and destinations JNDI lookup This variant allows to retrieve the connection factory and the destination from JNDI jms jndi lookupNameForDestination jndiConnectionFactoryName lookupNameForConnectionFactory This is the minimal required URI where lookupNameForDestination is the configured JNDI name of the JMS destination listened on lookupNameForConnectionFactory is the configured JNDI name of the Connection Factory jndiInitialContextFactory fully qualified classname of jndi initial context factory jndiURL url to jndi context jndiConnectionFactoryName lookupNameForConnectionFactory replyToName REPLY DESTINATION NAME The replyToName parameter can be omitted in which case the implementation will create a temporary queue for the response Queue lookup This variant allows to directly specify a queue name using a connection factory from the one s configured via the Seed JMS plugin jms queue QUEUE NAME connectionFactoryName nameOfConfiguredConnectionFactory replyToName REPLY QUEUE NAME The replyToName can be omitted in which case the implementation will create a temporary queue for the response Topic lookup This variant allows to directly specify a queue name using a connection factory from the one s configured via the Seed JMS plugin jms topic TOPIC NAME connectionFactoryName nameOfConfiguredConnectionFactory The topicReplyToName can be omitted in which case the implementation will create a temporary queue for the response not a temporary topic Message type The Web Services add on uses binary JMS messages by default as they have a number of advantages over text messages https www w3 org TR soapjms textmessage considerations In case you want to force the use of text messages you can do so by specifying the messageType parameter in the URI as in this example jms queue QUEUE NAME connectionFactoryName nameOfConfiguredConnectionFactory messageType text","summary":"The WS add-on supports HTTP and JMS transports. Each URL syntax described below.\n\nStandalone HTTP\n\nIn a standalone environment you need to specify the full URL with the binding address and the port:\n\nhttp://localhost:4578/ws/hello\n\nWeb server HTTP\n\nIn a Web server environment you only need to...","zone":{"path":"/addons","label":"Add-ons","logo":"addons-logo.svg"},"section":{"label":"Web-Services","path":"web-services"}},{"title":"Bibliography","tags":["ddd","book"],"href":"/docs/business/bibliography/","content":"To go beyond what is described in this documentation we recommend a few books which will help you to better understand DDD independently of the business framework Eric Evans Domain Driven Design This is the original book of Domain Driven Design the one which introduced this approach to the world Buy it online http www amazon com Domain Driven Design Tackling Complexity Software dp 0321125215 Vaughn Vernon Implementing Domain Driven Design This books builds upon the one from Eric Evans and a decade of DDD experience to provide concrete guidance on implementing the DDD in real world projects This book is a must read for anybody looking to put DDD into practice It also addresses the use of DDD in relation to popular architectural styles like REST Buy it online http www amazon com Implementing Domain Driven Design Vaughn Vernon dp 0321834577 Abel Avram Floyd Marinescu Domain Driven Design Quickly This book is a short quickly readable summary and introduction to the fundamentals of DDD it does not introduce any new concepts it attempts to concisely summarize the essence of what DDD is drawing mostly Eric Evans original book as well other sources since published such as Jimmy Nilsson s Applying Domain Driven Design and various DDD discussion forums The main topics covered in the book include Building Domain Knowledge The Ubiquitous Language Model Driven Design Refactoring Toward Deeper Insight and Preserving Model Integrity Free PDF version also available in french http blog infosaurus fr public docs DDDViteFait pdf or in chinese You can also buy a paper version http www amazon com Domain Driven Design Quickly Abel Avram dp 1411609255","summary":"To go beyond what is described in this documentation, we recommend a few books which will help you to better understand\nDDD, independently of the business framework. \n\nEric Evans: Domain-Driven Design\n\n{{< figure src="img/book_ddd.jpg" class="img-thumbnail pull-right" &gt...","zone":{"path":"/docs/business","label":"Business framework","logo":"business-logo.svg"},"section":{"label":"Introduction","icon":"fa fa-file-text","path":""}},{"title":"Introduction","href":"/docs/business/","content":"SeedStack business framework is a simple and coherent set of building blocks that enable you to code high quality business logic efficiently It is based on the Domain Driven Design DDD software development approach from which it implements the main concepts Following the DDD principles will help you to produce a supple and scalable design Using the business framework will help you to implement it quickly and cleanly The term term has been coined by Eric Evans in his book Domain Driven design published in 2003 It is an approach of software development for medium to complex needs based on the following premises Placing the project s primary focus on the core domain and domain logic Basing design on a model of the domain Initiating a creative collaboration between technical and domain experts to iteratively refine a conceptual model that addresses particular domain problems DDD really shines when applied on medium to complex business needs but can also be used successfully on simpler projects especially since the business framework considerably lowers the cost of implementing such projects by providing many helpers and base implementations callout info This documentation is not intended to replace a good understanding of DDD principles which can be gathered from various source material described in the bibliography bibliography callout Requirements An iterative process An iterative design and development process is required to successfully implement DDD in a project Any agile methodology that fits the team can be used Frequent communication between domain experts and the development team is key to get the model right before too much code is written This communication should not cease after the first version of the model is produced because the software will probably be continuously refined until it is no longer needed by the business Business involvement The domain being the area of application of the software an access to domain experts is critical to achieve a high quality model One goal of the DDD is to express the mental model spread across business experts into a refined precise and usable domain model To be able to achieve this goal domain experts should contribute to software design by defining the with the development team This collaboration will lead to a software that is exactly what is needed by business Development To successfully apply DDD and use the business framework some prerequisites must be met by the development team Being fluent with Object Oriented OO programming paradigm with a focus on polymorphism encapsulation and composition Have a good knowledge of design patterns Identify patterns Know when to use them Know when NOT use them Some patterns are widely employed in the business framework and in SeedStack in general Having a good understanding of them is required The business framework The business framework is a Java implementation of the DDD approach that builds upon the java framework to provide high level ready to use building blocks Your will be guided through the design and development of your project but it is crucial for its success to understand the concepts and the associated building blocks While the business framework provides a rich set of helpers and base implementations no code is generated The development team has to design and write the code according to this documentation and the DDD philosophy Sometimes several design or implementation choices are possible for a given business need In that case the pros and cons of each choice are presented to help you decide which is right for you specific need When available additional source material is referenced for a further understanding callout info Because the business framework is mostly about development it focus itself on the of DDD with the implementation of concepts such as entities repositories aggregates and so on But there is a to DDD that you shouldn t overlook and is crucial to your project success especially if its domain is large or complex SeedStack inherent modularity will help you to separate bounded contexts in modules and reuse them across multiple projects easily callout A majority of DDD concepts are implemented as building blocks by the business framework to help you code faster But you don t always want to go for the fastest implementation and may need to abstract your code from the framework a bit further Three abstraction levels The business framework allows you to choose the abstraction level you want for your code There are three abstraction level that can you can choose from on a class by class basis Annotation level You can make the framework recognize your classes simply by annotating them No need to implement any interface nor extend base classes While this mode is great for decoupling your code from the framework you may find that some of the helpers cannot work these classes as they won t have the required signatures You will have full dependency injection though provided that you define interfaces for your classes yourself Framework coupling is at the minimum but development speed is reduced Also note that this mode is preferably reserved to people fluent with DDD principles Interface level Implementing framework interfaces will make the framework recognize your classes and will allow it to work with them as they will have the required signatures In this mode you benefit from full dependency injection and almost full framework functionality Some predefined behaviors may be missing for some objects like out of the box equality for entities and value objects It is a good balance between framework coupling and development speed and is suitable to people that know the DDD principles well Base class level Extending framework base classes will provide you full framework functionality including base behavior Framework coupling is higher but a higher development speed is gained It allows people starting with DDD to benefit from implementation correctness in various areas callout info Note that although you can mix the three levels in the same project it is recommended to define which approach suits your team best and stick with it callout Code pattern detection To recognize your classes the business framework scans them and recognize code patterns depending on the abstraction level you use see above It works in two steps First it scans interfaces that are annotated with a recognized concept Then is collects classes implementing those interfaces If multiple implementations are found for an interface it can detects qualifiers to differentiate them See qualified injection qualified injection below for more information Once a code pattern is properly recognized it can be injected through its interface in any managed instance","summary":"SeedStack business framework is a simple and coherent set of building blocks that enable you to code high quality business \nlogic efficiently. It is based on the "Domain-Driven Design (DDD)" software development approach from which it implements\nthe main concepts. Following the DDD...","zone":{"path":"/docs/business","label":"Business framework","logo":"business-logo.svg"},"section":{"label":"Introduction","icon":"fa fa-file-text","path":""}},{"title":"Assemblers","tags":["dto","mapping","object","aggregate","factory","repository"],"href":"/docs/business/manual/assemblers","content":"The assembler pattern is used to transfer a representation of the state of Aggregates to DTO Representation objects The Business Framework provides a interface and few base classes to ease the development of assemblers Default assembler By default if your mapping is obvious you don t have to create an explicit assembler You just add the DtoOf annotation on your DTO class to link them to their related Aggregate root DtoOf Product class class ProductRepresentation You can then inject a ModelMapper based assembler with the ModelMapper annotation Inject ModelMapper Assembler productAssembler This assembler uses the default settings of the ModelMapper library http modelmapper org callout warning It is strongly recommended to always have a DTO Never serialize domain objects to your clients Even with the default assembler you can define a DTO that is a flat and or partial mapping of your domain Aggregate ModelMapper will automatically figure out the field mapping if you respect their conventions http modelmapper org getting started mapping Besides you should always have integration tests that checks that the automatic mapping is correct callout Explicit assembler Create an assembler extending BaseAssembler class It will contains the logic of the copy between aggregate and DTO Then inject your assembler in your class There are two methods to implement doAssembleDtoFromAggregate dto aggregate doMergeAggregateWithDto aggregate dto The first method creates a DTO from an aggregate root The second merge the mutable fields of an existing aggregate with the data from the dto callout info Note that the aggregate identity should never be updated by the DTO callout Example An assembler assembling a representation of a product public class ProductAssembler extends BaseAssembler Override protected void doAssembleDtoFromAggregate ProductRepresentation targetDto Product sourceAggregate Flatten the id targetDto setStoreId sourceAggregate getAggregateId getStoreId targetDto setProductCode sourceAggregate getAggregateId getProductCode targetDto setName sourceAggregate getName targetDto setDescription sourceAggregate getDescription Override protected void doMergeAggregateWithDto Product targetAggregate ProductRepresentation sourceDto The id is not modified targetAggregate setName sourceDto getName targetAggregate setDescription sourceDto getDescription You can inject the assembler via its interface or directly via the implementation class Both way are acceptable but the first way provides a more encapsulated interface to the developer using it Inject Assembler productAssembler Inject ProductAssembler productAssembler Then assemble a representation representation productAssembler assembleDtoFromAggregate product merge an aggregate Product productToMerge catalog retrieve productId productAssembler mergeAggregateWithDto productToMerge productRepresentationSource catalog update productToMerge Domain Specific Language Assembler implementations remains simple but its usage can become tedious when using lists or complexe worflows To simplify this use cases the Business Framework provides a DSL throught FluentAssembler Lists Replace common boilerplate code List representations new ArrayList for Product product products representations add productAssembler assembleDtoFromAggregate product by oneliners fluentAssembler assemble products to ProductRepresentation class Tuples fluentAssembler assemble product order to RecipeRepresentation class Qualified assemblers You can specify the assembler the DSL should use by specifying a qualifier For instance the following example use the default ModelMapper assembler So in this case you don t even have to create an assembler class fluently assemble products with AssemblerTypes MODEL_MAPPER to MyDto class Advanced usage When we merge a representation to an aggregate the assembler expects an existing aggregate root instance Normally you have to retreive this instance from a repository or to create it from a factory This can become a little tedious when you have to do it a lot Or by adding few metadata to your DTO you can have the DSL doing it for you Get an aggregate from its factory If the aggregate root to merge doesn t exists you can tell the DSL to create it from its factory fluentAssembler merge repr into Product class fromFactory It will search the aggregate root s factory GenericFactory Then it will search the appropriate method to call In order to indicate to the DSL which method should be called annotate the DTO s getters matching the factory method s parameters with MatchingFactoryParameter index 0 The index represents the position of the parameters in the factory method public class ProductRepesentation private Short storeId private Short productCode private String name private String description MatchingFactoryParameter index 0 public Short getStoreId MatchingFactoryParameter index 1 public Short getProductCode MatchingFactoryParameter index 2 public Short getName public Short getDescription public interface ProductFactory extends GenericFactory Product createProduct Short storeId Short productCode String name Get an aggregate from its repository If the aggregate root to merge already exists you can tell the DSL to get it from its repository If the DSL doesn t find the aggregate root from the repository two strategies are possible The first throw an exception the second fall back to the fromFactory method try product fluentAssembler merge representation into Product class fromRepository orFail catch AggregateNotFoundException e return Response status Response Status NOT_FOUND build product fluentAssembler merge repr into Product class fromRepository thenFromFactory It will search the aggregate root s repository GenericRepository Then it will call its load method In order to indicate to the DSL how to find the ID annotate the DTO getter matching the aggregate root ID with MatchingEntityId callout info If the ID is composite annotate the getter methods matching the ID constructor parameters with MatchingEntityId index 0 In this case the index is mandatory and represents the position of the parameters in the constructor method callout public class ProductRepesentation private Short storeId private Short productCode private String name private String description MatchingEntityId index 0 public Short getStoreId MatchingEntityId index 1 public Short getProductCode public Short getName public Short getDescription public class ProductId extends BaseValueObject private Short storeId private Short productCode public ProductId Short storeId Short productCode this storeId storeId this productCode productCode Getters Automation with ModelMapper DTOs are meant to expose domain objects or a part of these objects So there are often similarities between the DTOs and the domain object This can lead to a lot of boilerplate code when the assembler doesn t hold complex logic but just populates objects For this use case you can now use a default assembler based on ModelMapper http modelmapper org It s an automatic assembler which provides an intelligent mapping How to use it The only thing you have to do is to annotate the DTO with DtoOf MyAggregate class It tells the framework to bind a default assembler for assembling MyAggregate into the annotated DTO After you can inject the assembler as follows and use it as usual DtoOf MyProduct class public class MyDto Inject ModelMapper private Assembler myDtoAssemebler How does it work It uses a intelligent mapping provided by the ModelMapper library You can find the detailed explanation here matching documentation http modelmapper org user manual how it works Can I customize it Yes If there are ambiguities or if you only want to change the mapping of one field you don t need to fall back to the old assembler You can just create an assembler extending the ModelMapperAssembler class and implement the methods returning a ModelMapper instance callout info See here how to override the mapping http modelmapper org user manual property mapping callout It supports Deep mapping Skipping properties Providers Conditional mapping String mapping Can I see some code Below is an example from the Web application sample https github com seedstack store webapp sample The Product contains a field entityId and a field categoryId but the representation only contains a field id So ModelMapper doesn t know which field match To fix this extend ModelMapperAssembler and add a PropertyMap to the modelMapper callout info Note that as you implemented an assembler you don t use the default assembler anymore So remove the DtoOf annotation on the DTO callout public class ProductModelMapperAssembler extends ModelMapperAssembler Override protected void configureAssembly ModelMapper modelMapper modelMapper addMappings new PropertyMap Override protected void configure Required due to the ambiguity with the categoryId field map setId source getEntityId Override protected void configureMerge ModelMapper modelMapper Then use it as usual Inject private Assembler assembler assembler assembleDtoFromAggregate aProduct","summary":"The assembler pattern is used to transfer a representation of the state of Aggregates to DTO/Representation objects. \nThe Business Framework provides a interface and few base classes to ease the development of assemblers.\n\nDefault assembler\n\nBy default, if your mapping is obvious, you don't have...","zone":{"path":"/docs/business","label":"Business framework","logo":"business-logo.svg"},"section":{"label":"Business manual","icon":"fa fa-book","path":"manual"}},{"title":"Domain events","tags":["publish","subscribe","aggregate","event"],"href":"/docs/business/manual/events","content":"Seed Business Framework contains an API to manage domain events The EventService service is used to fire events Events must be immutable and extend DomainEvent which extends BaseValueObject callout info Notice Events can also be defined by implementing the Event interface Nevertheless this requires to implement equals and hashCode methods Otherwise event test fixtures and call cycle detection will not work callout For instance this event class MyEvent extends DomainEvent could be fired as follows Inject private EventService Inject private MyEventFactory eventFactory eventService fire eventFactory createMyEvent Handling events EventHandlers must implement EventHandler in order to receive fired events class MyHandler implements EventHandler Override public void handle MyEvent event MyHandler implements EventHandler which means it listens to events of MyEvent type handle method has to be implemented to define the handler s behaviour Synchronous behavior Events are fired synchronously and belong to current transaction Depending on Exception management a fired exception might rollback the transaction Event inheritance If a triggered event is assignable to MyEvent by inheritance it will also be handled consequently a handler that implements EventHandler will be called on any event implementing DomainEvent Testing events The seed business core test module provides an EventFixture class for integration tests on events Test that a given event was handled by an expected EventHandler Inject private EventFixture fixture fixture given eventFactory createMyEvent whenFired wasHandledBy MyHandler class Test that a given event was handled by exactly a provided list of EventHandler s Inject private EventFixture fixture fixture given eventFactory createMyEvent whenFired wasHandledExactlyBy MyHandler class MyHandler2 class Test that a given event was not handled by an expected EventHandler Inject private EventFixture fixture fixture given eventFactory createMyEvent whenFired wasNotHandledBy MyHandler3 class Test that a given event was generated from an expected method with appropriate parameters Inject private EventFixture fixture MyEvent myEvent eventFactory createMyEvent SOME_EVENT_PARAM fixtures given MyService class whenCalled doSomething SOME_METHOD_PARAM eventWasHandledBy myEvent MyHandler class Test if MyHandler handler received myEvent event when doSomething method of MyService is called Provided events Aggregate events Seed Business Framework provides following events AggregateReadEvent triggered when reading an aggregate eg repository load method AggregatePersistedEvent triggered when persisting an aggregate eg repository save method AggregateDeletedEvent triggered when deleting an aggregate eg repository delete method Above behaviour is defined by method annotations respectively Read Persist and Delete These annotations are only intercepted and functional within a repository class implementing GenericRepository read more business doc hands on domain repository on repositories This mechanism is disabled by default To enable this feature use following property org seedstack business event domain watch true Handle aggregate read events Define a custom read method public interface MyRepository extends GenericRepository Read AgregateRoot loadByName String name GenericRepository methods load delete persist save are already annotated with appropriate annotations The repository reading method is called triggering an AggregateReadEvent fire an AggregateReadEvent for the AgregateRoot productRepository loadByName aggregateName MyHandler handles the triggered AggregateReadEvent event handle an AggregateReadEvent class MyHandler implements EventHandler public void handle BaseRepositoryEvent event callout info IMPORTANT Above handler receives all AggregateReadEvent from any repository Read annotated method Since AggregateReadEvent events contain the aggregate root class and a context with the called method and its arguments the handler behaviour can be defined accordingly callout","summary":"Seed Business Framework contains an API to manage domain events. The EventService service is used to fire events. Events\nmust be immutable and extend DomainEvent (which extends BaseValueObject).\n\n\nNotice: Events can also be defined by implementing the Event interface...","zone":{"path":"/docs/business","label":"Business framework","logo":"business-logo.svg"},"section":{"label":"Business manual","icon":"fa fa-book","path":"manual"}},{"title":"Finders","tags":["query","data"],"href":"/docs/business/manual/finders","content":"A Finder is an object that queries the domain to get lists of domain objects optionally matching some criteria A Finder queries the domain but returns representations Creating a Finder with the Business Framework consists in Creating a finder interface Creating a finder implementation located in the infrastructure as it depends upon a persistence technology Business Framework Finders are POJOs there is no mandated interface Just annotate your finder interface with the Finder annotation Interface Create the interface for your finder A finder is annotated with Finder and is declared as read only Finder public interface CustomerFinder List findAllCustomers Implementation In the infrastructure layer provide the implementation here with JPA public class CustomerJpaFinder implements CustomerFinder Inject private FluentAssembler assembler Override public List findAllCustomer CriteriaBuilder cb entityManager getCriteriaBuilder CriteriaQuery q cb createQuery Customer class q select q from Customer class return fluentAssembler assemble entityManager createQuery q getResultList to CustomerRepresentation class","summary":"A Finder is an object that queries the domain to get lists of domain objects optionally matching some criteria. A Finder\nqueries the domain but returns representations.\n\nCreating a Finder with the Business Framework, consists in:\n\nCreating a finder interface,Creating a finder implementation, located...","zone":{"path":"/docs/business","label":"Business framework","logo":"business-logo.svg"},"section":{"label":"Business manual","icon":"fa fa-book","path":"manual"}},{"title":"Basics","tags":["architecture","package","injection","tuple","design"],"href":"/docs/business/manual/","content":"This manual will begin by to introducing and explaining all the concepts that you will need to know and master to build successful business applications These concepts come from the DDD software approach which is central to the Business framework You will NOT be presented with in depth coverage of all the DDD subtleties so to go beyond the basics you should have a look at the bibliography bibliography Moreover links will be provided in the text when related quality content is available Domain Driven Design is more about a way of thinking than about code but this approach has nonetheless a great impact on the way your business will be coded DDD does not introduce new concepts or design patterns on its own As a matter of fact you will surely recognize some patterns you already know behind DDD names It goes beyond design patterns though as it dictates when where and how to use them to solve real business problems callout info As its name suggest DDD is focused on the business and its model This model exists independently of applications and specific use cases and should be designed a such Applications are clients of the model software that will use this model to address enterprise needs Naturally particular use cases and UI ideas can be used as inputs for thinking about the model as the software is produced But the model itself should be independent of its clients callout Architecture For starters it is important to know that DDD doesn t require a particular architecture Since the domain is defined and contained inside a it doesn t influence the architecture of the whole application or system There are several pertinent architectural styles that you can apply to the surroundings of the domain Some are very broad and tend to define every aspect of the system others are more focused and try to address a specific demand The business framework can itself adapt to several of these architectural styles In this section we will present the layers architecture pattern Layers The layers architecture pattern is commonly used in Web enterprise and desktop applications In this architecture pattern the concerns are separated into well defined layers Traditional definition The main rule of this pattern is that each layer may couple only to itself and below The strict layers architecture only allows to couple to the layer directly below We recommend to use the relaxed layers architecture though which allows any higher level layer to couple to any layer below it DDD applied to layers architecture img layers png Dependency Inversion Principle In the traditional view of the layers architecture the infrastructure is at the bottom containing technical mechanisms like persistence messaging or any component dependent on third party libraries So every upper layer must couple to the infrastructure layer to use the technical facilities It is not desirable in DDD where we want to avoid any coupling of the domain to the infrastructure In fact we want to avoid any coupling of any layer to the infrastructure To achieve this independence we will apply the which states that High level modules should not depend on low level modules Both should depend on abstractions Abstractions should not depend upon details Details should depend upon abstractions What does it mean in terms of code is that a low level component should implement interfaces defined by high components As such we can move the infrastructure layer to the side DDD applied to layers architecture img layers_dip png As an example of this architecture we would have a JpaCustomerRepository implementation class which would belong to the infrastructure and which implements the CustomerRepository interface defined in the domain layer When injecting the repository elsewhere like in services we would only use the interface The dependency injection mechanism docs seed concepts dependency injection of the Java framework would provide the correct implementation from the infrastructure Interface layer The interface layer contains the components that handle interactions with other systems such as Web application views REST resources Web Services etc It handles the interpretation validation and translation of the inputs It handles the serialization of the outputs such as DTO classes to JSON XML etc Application layer The application layer is responsible for driving the workflow of the application executing the use cases of the system These operations are independent of the interfaces by which they are exposed This layer is well suited for spanning transactions high level logging and security The application layer is thin in terms of domain logic it merely coordinates the domain layer objects to perform the actual work through Application Services Domain layer The Domain Layer is where the business is expressed The domain is independent of the use cases of the system but is used to achieve their realization It is a very behaviour rich and expressive model of the domain based on entities values objects and aggregates It contains additional blocks such as domain services repositories factories policies etc Infrastructure layer The infrastructure layer contains the technology specific implementations of interfaces defined in other layers It supports all of the three other layers in different ways facilitating communication between the layers It consists of everything that would still exist without the application external libraries database engine application server messaging backend and so on This layer can be completely replaced by another one with other technological choices without altering the system behavior We often declare interfaces in Interfaces Application and Domain layers and implement them in the infrastructure Layer A good example is the repository interfaces are located in the domain layer but the implementation is in the infrastructure Supple design The ultimate purpose of software is to serve users But first that same software has to serve developers Eric Evans A software is not a piece code written in a one shot sprint It is project that evolves A lot of developers will have to work on it to refactor it or add new features Supple design is about making it a pleasure It should invite to change and avoid the maintenance hell Complex and monolithic methods make hard to refactor or reuse parts of the code When developers are not confident about what the software does they start duplicating code When this happens iterative process and refactoring stops A supple design reveals the intent of the design Side effects should contained and easy to predict Behaviour should be obvious making it easy to reason about without having to investigate the implementation There is no one way to achieve this suppleness but Eric Evans provides us some clues with a set of patterns We will try to define and illustrate them Intention Revealing Interface This concept is all about communication between developers through code Names of classes and methods should describe intents instead of means The ubiquitous language must be used to define these names It will improves the comprehension of the code by the other members of the team If a developer must consider the implementation of a component in order to use it the value of encapsulation is lost Implementation changes should not affect the expected behaviour You can also make methods signatures clearer using meaningful Value Objects and Entities rather than primitives and associated classes eg String long BigDecimal etc For instance given the following method java void setAddress String address How the client developer can know what the address should look like Does the model allow to change the address or is it just for initialization purpose Using the concept of Intention Revealing Interface will leads us to this newer version of the method java void changeAddress Address address Side Effect Free Function We just explained how a good naming can improve the comprehension of a model but this is not always enougth Complex methods usually call a combination of other methods When all these nested methods have side effects it become hard to predict the overall behaviour In computer science side effect means any modification in the state of a system Lets say we are working on a software managing teams We had to implement a method allowing to merged teams So we first wrote this java teamOne add teamTwo Ok it takes members of the teamTwo and add them to the teamOne It does the job Wait What happens to teamTwo Has it been modified also We can t be sure whithout looking at the code of the add method because this method is not side effect free After refactoring the code here is the second version java Team newTeam teamOne mergeWith teamTwo In the newer version teamOne and teamTwo are not modified Instead we create a new object like that developers don t have to understand the implementation The knowledge is capture in the newly created team The idea here is not to remove all the side effects otherwise the code will just allow you to perform queries But side effects should be contained in small entities methods and complex computation isoltated in value objects Assertion In the previous section we talk about limiting side effects But some of them will remains The problem is that when they are implicit it becomes impossible to anticipate the changes on the state of the application whithout following the execution path Which breaks the encapsulation So in order to make them explicit use assertions It can be done using method post condition for instance with Valid from the Validation JSR or by using unit tests Going further In this article we described methods for making intentions explicit using Intention Revealing Interface Side Effect Free Functions and Assertion These methods allow us to communicate intents protecting encapsulation This is very important if we want to keep the advantages of using a Object oriented language It also allow the client developer to focus on his design instead of having understand all the inner workings of the API he uses In his book Domain Driven Design Eric Evans go further describing three additional concepts Conceptual contour Standalone Closure of Operations I invite you to read his book if you want to have all the tools to reach the suppleness Package layout We propose and recommend a well defined package layout for organizing your business code which is described in this section The domain Standalone domain If you want to build a reusable domain it must be located in its own project It is the recommended way to build a domain because it allows to reuse it across applications and doesn t cost more than in application domains In that case the domain must be named and live in its own package for instance org myorganization domains mydomain Here the domain is named mydomain Its prefix would naturally be adapted to your organization rules In application domain If you plan to place the domain inside to your application which is not recommended you can just code it along your application packages In that case it can stay without name and live as a subpackage of your project for instance org myorganization myproject domain Here the domain is not named as it lives under the domain subpackage of the project The project package would naturally be adapted to your organization rules Package organization In the DDD approach entities are grouped in sets called aggregates Aggregates are represented as a package containing an aggregate root and possibly additional entities This package also contains the factory interface and implementation the repository interface and the possible value objects or policies related to your aggregate Value objects and policies which may be used by multiple aggregates should be placed in a shared package Services are located in their own package Implementations can be located in the internal subpackage if they are independent of technical aspects like a third party library Otherwise they must be located in the infrastructure plain org myorganization domains mydomain can also be org myorganization myproject domain for in application domain model myaggregate1 MyAggregateRoot MyEntity1 MyEntity2 MyAggregateFactory MyValueObject MyRepository MyPolicy internal MyPolicyImpl MyAggregateFactoryImpl myaggregate2 services MyService1 MyService2 internal MyService1Impl shared MySharedValueObject MySharedPolicy1 internal MySharedPolicy1Impl callout warn The domain should never depends on specific technical aspects As such no infrastructure package have a place in a reusable domain The infrastructure for the domain should reside in the client of the domain the application using the domain as it is specific to it a same domain can be persisted very differently in different applications callout The application The application layer contains application services which should be located in the application package Implementations can be in internal subpackages if they are independent of technical aspects third party library Otherwise they must be located in the infrastructure package plain org myorganization myproject application services MyService3 MyService4 internal MyService3Impl infrastructure services 3rdparty lib MyService4Lib repositories jpa MyRepositoryJpa callout info Note that the infrastructure also contains the implementation of domain concepts related to a specific technology such as implementations of repositories or of some services callout The interfaces plain org myorganization myproject rest usecase1 UseCase1Assembler UserCase1Resource UseCase1Finder UseCase1Representation usecase2 infrastructure finders jpa UseCase1FinderJpa UseCase2FinderJpa Tuples A tuple is a data structure corresponding to a sequence of immutable objects It s just like an array of objects but typed and which can t be changed i e tuples are immutable Tuples are commonly used to Represent a set of data without creating temparary object that have no real meaning Easy access to and manipulation of a data set Returning mutliple values from a method Passing multiple values to a method through a single parameter In the Business framework we usually see them in factories and assemblers As implementation for tuples we use javatuples org http javatuples org It provides tuple classes from one to ten elements Unit 1 element Pair 2 elements Triplet 3 elements Quartet 4 elements Quintet 5 elements Sextet 6 elements Septet 7 elements Octet 8 elements Ennead 9 elements Decade 10 elements Plus a couple of very common 2 element tuple classes equivalent to Pair just for the sake of code semantics java KeyValue LabelValue All the tuple classes respect the following properties Typesafe Immutable Iterable Serializable Comparable implements Comparable Implementing equals and hashCode Implementing toString Usage java Pair pair new Pair 10 foo Integer value0 pair getValue0 String value1 pair getValue1 We also provide an helper class to create tuples java Pair pair Tuples create 10 foo Tuple tuple Tuples create 10 foo new Customer Qualified injection The Business framework supports the use of qualifiers defined by the JSR 330 This feature provides the ability to create multiple implementations for the same interface This is useful when you have multiple algorithms or implementation technologies for an interface An example with policies This pattern can be used in various situations but proves itself very useful in the case of DDD policies To leverage it define a Policy interface as follows java Policy public interface TaxesPolicy Integer computeTaxes Order order Then define an implementation annotated by a qualifier The annotation Named allows to qualify an implementation with a String java Named FR public class FranceTaxesPolicy implements TaxesService Integer computeTaxes Order order Finally you can inject it as follows java Inject Named FR private TaxesPolicy frenchTaxes Inject Named UK private TaxesPolicy ukTaxes Or you can select it dynamically using the java TaxesPolicy userTaxesPolicy domainRegistry getPolicy TaxesPolicy class userLocal Use a custom qualifier If a qualifier is often used you can create a custom qualifier annotation as follows java import static java lang annotation ElementType FIELD import static java lang annotation ElementType METHOD import static java lang annotation ElementType TYPE import static java lang annotation RetentionPolicy RUNTIME import java lang annotation Retention import java lang annotation Target import javax inject Qualifier Qualifier Target TYPE METHOD FIELD Retention RUNTIME public interface France Then you use it like the Named annotation java Inject France private TaxesService taxesService List of concepts supporting qualifiers Qualified injection can be used on these concepts out of the box Assembler Repository Factory Policy Service Finder","summary":"This manual will begin by to introducing and explaining all the concepts that you will need to know and master to build\nsuccessful business applications. These concepts come from the DDD software approach which is central to the Business\nframework. You will NOT be presented with in-depth coverage of...","zone":{"path":"/docs/business","label":"Business framework","logo":"business-logo.svg"},"section":{"label":"Business manual","icon":"fa fa-book","path":"manual"}},{"title":"Aggregates and their lifecycle","tags":["repository","factory","aggregate","lifecycle","identity"],"href":"/docs/business/manual/lifecycle/","content":"Domain objects have a lifecycle they are created go through various states and eventually die either being archived or deleted Many of these objects are simple transient objects which are simply created with a call to their constructor and thrown away after use There is no need to complicate such objects But some objects are more rich with a complex lifecycle and numerous relationships with other objects The challenges of managing these objects can be addressed by three patterns Aggregates which define clear ownership and boundaries between domain objects Repositories which encapsulate the logic of persisting and retrieving aggregates Factories which encapsulate the logic of creating aggregates Aggregates Most business domains have very interconnected Entities sometimes up to the point where there is always a path going from any Entity to any other We can try to minimize the number of associations in our design and this is a good practice but it can lead to a translation loss between business and software In a typical object model it is difficult to clearly see the boundaries of a change This is particularly acute in systems with concurrent access such as Web applications callout info It is difficult to guarantee the consistency of changes to objects in a model with complex associations and no clear boundaries between objects Considering every object as independent from each other is not a valid approach but on the other side refreshing every object because of a change is not practical A balanced solution must be found callout To help us with this delicate problem the Aggregate pattern can be applied It is a cluster of associated objects that are considered as a unit for the purpose of data changes Each Aggregate has root and a boundary which determines what is inside the Aggregate The Aggregate root is a specific Entity contained in the Aggregate It is the only entry point of the Aggregate meaning that it is the only Aggregate Entity that client objects can hold references to Other objects of the Aggregate are only accessible through the context of the Aggregate root Characteristics The following rules apply to Aggregates The Aggregate root has a global identity and is responsible for checking invariants within the Aggregate Non root Entities inside the Aggregate have a local identity that is only unique within the Aggregate Code outside the Aggregate can only hold references to the Aggregate root The root can hand references to internal entities but they must only use them transiently and not hold to the reference Value Objects can be handed without any concern because they are immutable and side effect free Only Aggregate roots can be loaded directly from the persistence All other objects must be found by traversal of associations Any change within the Aggregate boundary must satisfy all the Aggregate invariants Declaration Creating an Aggregate with the Business Framework consists in Creating a package with the Aggregate name Create all the domain objects belonging to the Aggregate in this package From all those domain objects one Entity should be created as the Aggregate root This step is the focus of this section To create an Aggregate root using the Business framework you have three choices Extend the BaseAggregateRoot class This class directly extends BaseEntity and as such the equals hashCode and compareTo methods will be provided out of the box Implement the AggregateRoot interface You must implement the equals hashCode and compareTo methods in this case Simply annotate any class with the DomainAggregateRoot annotation In this case you won t be able to use helpers and tools from the framework With the two first options base class and interface you have to provide a generic parameter with the type of the Aggregate root identifier Example public class Order extends BaseAggregateRoot private Long orderId private Date checkoutDate private double price private List items Order Override public Long getEntityId return orderId public void addOrderItem int quantity long productId double price OrderItem orderItem new OrderItem orderItem setQuantity quantity orderItem setProductId productId orderItem setPrice price items add orderItem public void clearOrderItems items clear public Long getOrderId return orderId Repositories A Repository is used to store and retrieve Aggregates from persistence Aggregates are only manipulated by repositories through their Aggregate roots Default repository The Business Framework provides a default repository that can perform CRUD actions on an aggreate It can be injected with the Repository interface and a qualifier Inject Jpa private Repository customerRepo Customer customer customerRepo load customerId callout info By default you have to explicitly specify the qualifier But if you have only one persistence and one default repository you can configure the one to use The default repository can be configured for all the application org example default repository qualifier org seedstack jpa Jpa And then overriden for a specific aggregate root org example domain customer Customer default repository qualifier another qualifier The default repository qualifier property expects a qualifier annotation class or a string when the qualifier use Named another qualifer callout Explicit repository The default CRUD repository is interesting to start quickly and might be enough for some use cases But it is possible to add your own repositories in order to extend the CRUD behavior with your domain requirements First create a repository interface extending GenericRepository This interface is usually located in the aggregate package import org seedstack business domain Repository public interface OrderRepository extends GenericRepository Order findOrderByCategory String categoryId callout info It is possible not to use the GenericRepository interface and instead annotate the class with the DomainRepository annotation But you won t be able to use the framework s helpers like the assembler DSL fromRepository method callout Then add an implementation in the infrastructure layer public class OrderJpaRepository extends BaseJpaRepository implements OrderRepository Override public Order findOrderByCategory String categoryId Usage An explicit repository can be injected like a default one with the Repository interface or with its own interface Inject private Repository repository Inject private OrderRepository repository Factories A factory is used to create domain objects checking that provided data is complete and consistent To be created by a factory the domain object must also implements Producible This is necessary because all the domain objects are not producible by a factory For instance an entity is only be producible by an aggregate root The types implementing DomainObject and Producible are the followings AggregateRoot DomainPolicy ValueObject DomainEvent DomainService Default factory The default factory has a single method create with varargs that will match via reflection the constructor corresponding to the passed arguments The created domain object should implement the desired constructors public class Customer extends BaseAggregate private Long id Customer Customer String firstName String lastName This constructor will be called The default factory can then be injected and used by invoking its create method with arguments unambiguously corresponding to only one constructor Inject Factory factory Customer customer factory create John Doe One benefit over the plain constructor approach is that default factories will invoke identity generation see below identity generation and or validation automatically after object instantiation The As other factories this method will provide validation on the created object But it won t survive to refactoring so be careful using the method ie unit test it callout info This factory can only be used to create domain objects that implement the Producible and DomainObject interfaces Classes extending Business framework base classes will already implement those interfaces but annotated POJO such as policies or services must implement them explicitly As an alternative you implement the GenericDomainPolicy and GenericDomainService interfaces instead callout Explicit factory An explicit factory is composed of an interface which is located in the package of the aggregate it constructs and an implementation which can be located either In the aggregate package too Or in an infrastructure package if it is dependent upon a specific technology The factory interface has to extend the GenericFactory interface package org mycompany myapp domain model order import org javatuples Triplet import org seedstack business domain GenericFactory public interface OrderFactory extends GenericFactory Order createOrder String customerId Date checkoutDate Double price List Triplet orderItemTriplets Order is the type which is the expected to be returned by all the create methods createOrder method creates an Order aggregate with the required parameters Some parameters can be grouped with a tuple like oderItemTriplets which represents a list OrderItem entities belonging to the Order aggregate See here business doc concepts oop tuples for more information on tuple pattern The factory implementation must extend the BaseFactory abstract class and implement its own interface package org mycompany myapp domain model order import org javatuples Triplet import org seedstack business domain BaseFactory import org mycompany myapp domain customer CustomerId public class OrderFactoryImpl extends BaseFactory implements OrderFactory Override public Order createOrder String customerId Order o new Order o setCustomerId new CustomerId customerId o setCheckoutDate new Date return o Here the factory encapsulates the logic of creating a minimal but valid Order aggregate This order can be further populated by an assembler or by custom logic callout info When the implementation and its interface share the same package the implementation should be in package visibility It prevents any direct use of the implementation callout Identity generation Factories provide methods to create entities with a well defined identity But sometimes you want to delegate the identity creation for instance to an Oracle sequence For this use case Seed provides an identity generation strategies A generation strategy makes sure a unique identity is provided to any new Entity before it is even persisted Declaration Below is an aggregate using the identity strategy package org mycompany myapp domain model myaggregate public class MyAggregate extends BaseAggregateRoot Identity handler UUIDHandler class private UUID id private String name private MyEntity mySubEntity private Set mySubEntities Below is an Entity using the identity strategy package org mycompany myapp domain model myaggregate public class MyEntity extends BaseEntity Identity handler SequenceHandler class private Long id The Identity annotation is applied on attribute holding the object identity This annotation takes two arguments handler strategy implementation source a String that can be used in a custom handler For instance it could provide a SEQUENCE name for DB Only specifying the identity strategy is not enough to effectively generate an identity An implementation of the strategy must be configured org mycompany myapp domain model myaggregate MyAggregate identity handler qualifier simple UUID org mycompany myapp domain model myaggregate MyEntity identity handler qualifier oracle sequence identity sequence name SEQ_TEST In this case we can see that the simple UUID implementation will be used for MyAggregate Similarly the oracle sequence implementation will be used for MyEntity but is further configured with a sequence name Usage The chosen identity strategy is applied Automatically on methods annotated with the Create annotation They are intercepted to apply the identity strategy on their return value public class MyAggregateFactoryDefault extends BaseFactory implements MyAggregateFactory Create Override public MyAggregate createMyAggregate String name MyAggregate myAggregate new MyAggregate myAggregate setName name MyEntity myEntity createMyEntity myAggregate setMyEntity myEntity return myAggregate Create MyEntity createMyEntity return new MyEntity Manually by injecting the IdentityService service and invoking its identify method with the entity to generate an identity for as argument public class MyAggregateFactoryDefault extends BaseFactory implements MyAggregateFactory Inject IdentityService identityService Override public MyAggregate createMyAggregate String name MyAggregate myAggregate new MyAggregate identityService identify myAggregate myAggregate setName name MyEntity myEntity new MyEntity identityService identify myEntity myAggregate setMyEntity myEntity return myAggregate Note that identity generation doesn t walk the object graph to generate identities for eventual sub entities You must trigger identity generation automatically or manually separately on each entity callout tips If all methods of a factory delegate identity generation to Seed a Create annotation can be applied directly at the class or interface level callout Custom identity handler identity seed img manage entity spi svg Two different options are available to define custom identity handlers identity seed img manage entity usage png Below is an example of a basic Timestamp id generation strategy package org mycompany myapp infrastructure domain import org seedstack business domain BaseEntity import org seedstack business domain identity IdentityHandler Named timestamp id public class TimestampIdentityHandler implements IdentityHandler BaseEntity Long Override public Long handle BaseEntity entity Map entityConfig return new Date getTime Provided identity strategies SequenceHandler Handles sequence generated ID Two implementations are provided OracleSequenceHandler Get next oracle sequence value for new entity id The following properties org mycompany myapp YourEntity identity handler qualifier oracle sequence identity sequence name your_sequence_name InMemorySequenceHandler To be used ONLY for testing preserves behaviour without a database The following properties org mycompany myapp YourEntity identity handler qualifier inmemory sequence UUIDHandler Use for handling UUID generated ID One implementation is provided SimpleUUIDHandler Get new random UUID from java util UUID randomUUID Need one property using entity props configuration org mycompany myapp YourEntity identity handler qualifier simple UUID For a full description of Entity properties configuration refer to this documentation business doc hands on domain entity configuration spi","summary":"Domain objects have a lifecycle: they are created, go through various states and eventually die (either being archived\nor deleted). Many of these objects are simple, transient objects which are simply created with a call to their constructor\nand thrown away after use. There is no need to complicate...","zone":{"path":"/docs/business","label":"Business framework","logo":"business-logo.svg"},"section":{"label":"Business manual","icon":"fa fa-book","path":"manual"}},{"title":"Domain model","tags":["entity","value-object","service","model","identifier"],"href":"/docs/business/manual/model","content":"The domain model is expressed through three patterns Entity which is an object defined primarily by its identity Value Object which is an object with no conceptual identity and solely defined by is attributes Service which hold domain logic that doesn t clearly belong to an entity nor a value object Entities Entities are used to represent a domain concept which has an identity Often DDD beginners have a tendency to focus more on data than on the software This often leads in all the concepts of the domain being coded as entities Specially in anemic entities using only getters and setters Using them is not wrong but it s not enough to hold the insights of a domain That s why designing entities should be taken very carefully The entity concept should be used for an element of your domain when you take care of its identity An identity must be unique and immutable Even it an object can change during its lifetime its identity must stay untouched If this is not true for your element you should consider using a value object value objects instead When designing an entity the critical part is to determine what is the identity and how to create it An identity can be hold by a set of properties In this case a value object can be well fitted to guaranty the identity consistency and immutability There are different kind of creation strategies for identities The client can pass values handling himself the uniqueness The application can generate the identity using an algorithm The application can rely on an external identity generator like a database sequence The first case is easily handled using factories The other cases can be usually more complicated but the Business framework provides an API for them see identity generation lifecycle identity generation Declaration To create an Entity using the Business framework you have three choices Extend the BaseEntity class The equals hashCode and compareTo methods will be provided out of the box You must implement the getEntityId method Implement the Entity interface You must implement the equals hashCode compareTo and getEntityId methods in this case Simply annotate any class with the DomainEntity annotation In this case you won t be able to use helpers and tools from the framework With the two first options base class and interface you have to provide a generic parameter with the type of the Entity identifier Example Consider the following example in which a Customer Entity is identified by an e mail of String type public class Customer extends BaseEntity private String email private Address address private List orders Package protected constructor Customer String identity Address address this email identity Override public String getEntityId return this email Meaningful methods public void changeAddress Address newAddress Getters public Address getAddress public String getEmail public List getOrders Try to avoid setters as they allow to alter the internal state of the entity Value Objects An object that don t have a conceptual identity but is just describing some characteristics of a thing is called a Value Object Because the most visible objects in a model are usually Entities there is a natural tendency to assign an identity to every domain object But this tendency should be refrained Here are the main characteristics of a Value Object It measures quantifies or describes a thing in the domain It is immutable meaning that its state cannot be changed after creation It describes a conceptual whole Its attributes are related to each other and are all participating to the description This means that all the required values should be assigned upon creation i e in the constructor It is comparable to others using value equality Its behavior is side effect free Declaration To create a Value Object using the Business framework you have three choices Extend the BaseValueObject class In this case the equals hashCode and compareTo methods will be provided out of the box Implement the ValueObject interface You must implement the equals hashCode and compareTo methods in this case Simply annotate any class with the DomainValueObject annotation In this case you won t be able to use helpers and tools from the framework Example Cars are identified by a Vehicle Identification Number VIN See this wikipedia article http en wikipedia org wiki Vehicle_Identification_Number Components_of_the_VIN for the conceptual definition To simplify our example we will just consider the VIN as composed respectively of 3 parts 3 DIGITS World Manufacturer Identifier 6 DIGITS Vehicle descriptor section 8 DIGITS Vehicle identifier section Here is a possible implementation of the VIN class package org mycompany myapp shared domain after sales vehicle import org seedstack business domain BaseValueObject public class VIN extends BaseValueObject private final String worldManufacturerIdentifier private final String vehicleDescriptorSection private final String vehicleIdentifierSection public vehicleIdentificationNumber String worldManufacturerIdentifier String vehicleDescriptorSection String vehicleIdentifierSection this worldManufacturerIdentifier worldManufacturerIdentifier this vehicleDescriptorSection vehicleDescriptorSection this vehicleIdentifierSection vehicleIdentifierSection public vehicleIdentificationNumber String vin this worldManufacturerIdentifier vin substring 0 3 this vehicleDescriptorSection vin substring 3 9 this vehicleIdentifierSection vin substring 9 17 Getters public String getWorldManufacturerIdentifier public String getVehicleDescriptorSection public String getVehicleIdentifierSection Override public String toString return worldManufacturerIdentifier vehicleDescriptorSection vehicleIdentifierSection Usage as identifiers Value Object can also be used to represent complex identifiers for entities For instance you can use the VIN class defined in the example above to identity a Vehicle class You can also add meaning and behavior to a simple value by embedding it into a Value Object package org mycompany myapp domain customer import javax persistence Embeddable import org seedstack business domain BaseValueObject public class CustomerId extends BaseValueObject private String value public CustomerId String customerId this value customerId public String getValue return value In this example the CustomerId Value Object add meaning to the plain string You won t manipulate a String anymore in your code but a CustomerId with its own type This type can evolve later to provide additional behavior or to be adapt its internal structure Services Services are stateless objects that implement logic which doesn t fit in the aggregates Services can be found in various locations The domain where services contain pure business logic Naming should come from the or be introduced into it if necessary Parameters and return values should be domain objects Example a bank account transfer service The infrastructure where services deal with specific technological aspects Example a notification sending service The application where services contain coordination logic between other services and are more tied to a specific use case These services are often the ideal place to begin and end a transaction callout info A good service is always stateless That doesn t mean that a service cannot change the global state of the application that is it may have side effects but it should never hold a state of its own that could affect its behavior callout Declaration Creating a Service with the Business Framework consists in Creating a service interface annotated with the Service annotation Business Framework Services are POJOs there is no mandated super interface Creating a service implementation Example Let s consider a bank account transfer which is a service belonging to the domain From the domain of a bank account management perspective the transfer consists of an amount debited on an account which is credited on another account The inherent logic of the transfer does not belong to any of the accounts but to a service of the Domain It s implementation can be rather simple or complex depending on the rules applying to the process currency exchange rate transfer authorisation between countries amount on originating account etc Service public interface AccountTransferService public AccountTransferReport transferMoney Account toBeDebited Account toBeCredited Amount transferAmount callout info Avoid services named like AccountManagement as they tend to become the place to handle all behaviour for a sub domain instead of clearly specifying the intent and responsibility callout","summary":"The domain model is expressed through three patterns:\n\nEntity which is an object defined primarily by its identity.Value Object which is an object with no conceptual identity and solely defined by is attributes.Service which hold domain logic that doesn't clearly belong to an entity nor a value...","zone":{"path":"/docs/business","label":"Business framework","logo":"business-logo.svg"},"section":{"label":"Business manual","icon":"fa fa-book","path":"manual"}},{"title":"Pagination","tags":["pagination","data","page","chunk","range"],"href":"/docs/business/manual/pagination","content":"The data presentation API helps developers presenting the data from their domain to external actors Those are generally remote REST clients like a browser web services consumers or RPC RMI clients The data presentation API supports patterns often used in data restitution pagination infinite scroll random chunk access Concepts The following describes the API We ll specialize some concepts already presented like the finder We focus the creation of this API on solving the problem of returning portion result out of very big one domain aggregates puml business business api interfaces finder puml png A Range is just a class that represents an offset and a size A Result symbolises a canonical representation of the ranged return of a request made from a persistence It holds the list that contains the result itself the actual list size the full size of the whole request A View represents a viewpoint of an already existing list Its focus is the restitution of a portion of the given list RangeFinder is a High level interfaces for finder that sum up the following assertion Given a Range and a Criteria please find the Result for the Item type Notice that Criteria here is not a type but a generic to be substituted when subclassing For instance a Map lt String Object gt or a custom class In order to move out the complex computation page chunk away from the RangeFinder we only provide him a Range Its first and only objective is to fetch data from persistence according to a given criteria View management is completely orthogonal to the restitution a given list from a criteria The actual Range can be greater than the needed portion This way the result can be reused according that the Criteria and the result size has not changed Example Create a finder by extending the BaseRangeFinder class This abstract class needs you to implement two methods The computeResultList method which should return the list of matching entity with the expected range The computeFullRequestSize method should return the size of complete list matching the criteria For instance create the following interface Finder public interface Dto1Finder extends RangeFinder Dto1 Map PaginatedView findItemByQuery Page page String searchQuery Implement it as follows JpaUnit my unit Transactional public class Dto1SimpleJpaFinder extends BaseRangeFinder implements Dto1Finder Inject private EntityManager entityManager Override public PaginatedView findItemByQuery Page page String query Range range Range rangeFromPageInfo page getIndex page getCapacity Result result find range query return new PaginatedView result page Override protected List computeResultList Range range String criteria CriteriaQuery query getAggRoot1CriteriaQuery criteria List resultList entityManager createQuery query setFirstResult new BigDecimal range getOffset intValue setMaxResults new BigDecimal range getSize intValue getResultList return assemblers assembleDtoFromAggregate resultList Override protected long computeFullRequestSize String criteria CriteriaQuery query getAggRoot1CountCriteriaQuery criteria return entityManager createQuery query getSingleResult Then inject the finder with its interface and use it as follows java Inject Dto1Finder dto1Finder GET Rel search Produces MediaType APPLICATION_JSON public Response list QueryParam q String searchQuery DefaultValue 0 QueryParam pageIndex Long pageIndex DefaultValue 10 QueryParam pageSize Integer pageSize Call the finder with the requested page Page page new Page pageIndex pageSize PaginatedView view dto1Finder findItemByQuery page searchQuery Create an HAL representation with the page and the total number of elements Dto1sRepresentation representation new Dto1sRepresentation page view getResultSize Add the list of item to the representation representation embedded items view getView If a next page is available add to link to it if view hasNext Page next view next representation link next relRegistry uri search set pageIndex next getIndex set pageSize next getCapacity expand If a previous page is available add to link to it if view hasPrev Page prev view prev representation link prev relRegistry uri search set pageIndex prev getIndex set pageSize prev getCapacity expand return Response ok representation build callout info The following example uses the HAL media type For more information about it read the documentation about hypermedia docs seed manual rest restful api callout","summary":"The data presentation API helps developers presenting the data from their domain to external actors. Those are\ngenerally remote REST clients like a browser, web services consumers or RPC/RMI clients. The data presentation API supports\npatterns often used in data restitution: pagination, infinite...","zone":{"path":"/docs/business","label":"Business framework","logo":"business-logo.svg"},"section":{"label":"Business manual","icon":"fa fa-book","path":"manual"}},{"title":"Policies","tags":["policy","strategy"],"href":"/docs/business/manual/policies","content":"A policy is a variant of the Strategy pattern to encapsulate one or more business rules Definition Creating a Policy with the Business Framework consists in Creating a policy interface in the domain Creating a policy implementation located either in the domain or in the infrastructure if it depends upon any specific technology Business Framework Policies are POJOs there is no mandated interface Just annotate your policy interface with the DomainPolicy annotation Usage To use a policy simply inject it in your code Inject MyPolicy myPolicy Example Let s consider a bonus policy for car sellers according to the sales they ve done This policy could allow the sellers and their manager to know what the amount of their bonus is at a given time in the current month BonusPolicy interface In org mycompany myapp policy package package org mycompany myapp policy import org mycompany myapp domain model carsold CarSold import org mycompany myapp domain shared vo Price import org seedstack business domain DomainPolicy import java util List DomainPolicy public interface BonusPolicy Price computeBonus List carSolds BonusPolicy implementation Below is an implementation example In org mycompany myapp policy internal package package org mycompany myapp policy internal import public class BonusPolicyInternal implements BonusPolicy Override public Price computeBonus List soldCarsList return finalBonus BonusPolicy usage Wherever the policy is used to compute the bonus of a particular employee just retrieve the cars sold by this employee through the sold cars repository and call the policy Interface package org mycompany myapp application service import org mycompany myapp domain model employee Employee import org seedstack business Service Service public interface SalesBonusService double calculateCurrentBonusFor Employee employee Implementation package org mycompany myapp application service internal import public class SalesBonusServiceInternal implements SalesBonusService Inject CarSoldRepository carSoldRepository Inject CarForSaleRepository carForSaleRepository Inject BonusPolicy bonusPolicy Override public double calculateCurrentBonusFor Employee employee List findByEmployee carSoldRepository findByEmployee employee getEntityId Price bonus bonusPolicy computeBonus findByEmployee return bonus getPriceValue Then one can just inject the service and compute a bonus whenever an Employee entity is at reach eg while building an employee profile page","summary":"A policy is a variant of the Strategy pattern to encapsulate one or more business rules.\n\nDefinition\n\nCreating a Policy with the Business Framework, consists in:\n\nCreating a policy interface in the domain,Creating a policy implementation, located either in the domain or in the infrastructure if it...","zone":{"path":"/docs/business","label":"Business framework","logo":"business-logo.svg"},"section":{"label":"Business manual","icon":"fa fa-book","path":"manual"}},{"title":"Introduction","tags":["modular","jar","package","lifecycle","classpath"],"href":"/docs/seed/","content":"SeedStack Java framework also simply known as Seed is a comprehensive solution enabling you to build Java applications or cloud services easily and efficiently Opinionated Whatever you aim to build from a small command line tool to the next successful cloud based service Seed provides you with the right set of concepts and technologies from the start More importantly it does so without getting in your way and yet scales well when applied on full blown enterprise projects yet modular Built on an extensible plugin system concepts Seed is highly modular and allows you to choose the technologies you really need while leaving out the unnecessary bits Besides you can extend the core framework abilities by cherry picking modules from the add ons library addons or by rolling out your own The framework is composed of several separate modules each one providing a particular technology The seed core module implements basic framework functionality like application lifecycle configuration or dependency injection Its presence is required in any running application along its companion module seed specs containing the corresponding API classes callout info Modules are automatically detected and activated when present in the classpath As such simply adding a module JAR to your project will enable it and all its features callout JAR organisation When relevant modules provide their API in a separate sub module suffixed with specs in which case the corresponding module implementation is suffixed core This allows to implement classes using the API without activation This is useful when designing reusable components Besides to provide a better separation of concerns some modules are further split into optional sub modules seed module specs for the API and or the SPI seed module core for the main implementation seed module option for an optional implementation module Package organisation The code of each module lives in several Java packages all prefixed by org seedstack seed where is the name of the module org seedstack seed module which contains classes destined to be used by client code org seedstack seed module spi which contains the classes needed to extend the module features org seedstack seed module internal which contains the module internal classes org seedstack seed module test which contains testing tools for the module callout danger Note that application code should never rely on any class from the internal package It is implementation specific and subject to change between versions without notice callout Class organisation Seed follows SOLID principles https en wikipedia org wiki SOLID_ object oriented_design and each class tend to only have one responsibility allowing to easily understand what it does It also does help to keep you implementation simple and testable Lifecycle At the heart of Seed lies the kernel which is started by different means depending on the runtime context web application standalone java app test runner The responsibility of the kernel is to orchestrate all the plugins in order to setup a fully working application In turn each plugin has its own responsibility such as providing application configuration integrating a specific technology or augment the application code with a particular behavior Classpath scanning At the start of kernel all plugins have the opportunity to request information about classes and resources Using this mechanism they can detect predefined code patterns such as Classes annotated or meta annotated with a specific annotation Classes implementing an interface or extending a base class Classes matching a complex predefined specification Resources matching a specific regex etc callout info Code pattern detection is heavily used throughout SeedStack for instance to dynamically define injection bindings to automatically register classes or to enable particular features Combined with the convention over configuration principle and sensible default values it greatly simplifies SeedStack usage callout Phases The kernel orchestrates the application lifecycle through the following phases In the bootstrapping phase the runtime starts the kernel which uses the Java service loader mechanism to detect all the plugins present in the classpath These plugins register their classpath information requests to the kernel and express their requirements on other plugins In the initialization phase the kernel resolve all the classpath requests in only one full classpath scan and invoke the initialization logic of all plugins in the correct order In the starting phase the kernel collects the injection bindings dynamically defined by each plugin from the results of the initialization phase and builds the application main injector Then the kernel invokes the starting logic of all plugins in the correct order At this point the application is fully operational In the stopping phase the runtime stops the kernel which invokes the stopping logic of all plugins in the correct order A this point the application is stopped callout info The kernel is a part of Nuun IO https github com nuun io and is independent of SeedStack For more information about it please check its own documentation https github com nuun io kernel wiki callout Next start reading the manual","summary":"SeedStack Java framework, also simply known as "Seed", is a comprehensive solution enabling you to build Java applications\nor cloud services easily and efficiently. \n\nOpinionated...\n\nWhatever you aim to build, from a small command-line tool to the next successful cloud-based service, Seed...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Introduction","icon":"fa fa-file-text","path":""}},{"title":"Cryptography","tags":["cryptography","certificate","keystore","encryption","hashing"],"href":"/docs/seed/manual/crypto","content":"Seed provides helpers for Java cryptography Private key encryption Secure hashing KeyStore configuration SSL configuration Encryption Seed provides an EncryptionService which allows you to securely store or exchange data It is based on a Public Key Infrastructure PKI i e it encrypt data using a public key and then decrypt it with a private key To use it you will have to declare the key pair to use In java keys are stored using a KeyStore KeyStores Key stores are created using the keytool command line tool see keytool documentation http docs oracle com javase 8 docs technotes tools windows keytool html Here is an example creating a keystore with a key pair ini keytool genkeypair dname cn Mark Jones ou Java o Oracle c US alias database keypass keystore src main resources app keystore storepass validity 180 Then it is possible to declare the key store in your configuration as follows Notice that multiple key stores can be registered The key store configuration is prefixed by org seedstack seed crypto keystore The prefix ends with a logical key store name ini org seedstack seed crypto keystores keystoreName keystoreName2 org seedstack seed crypto keystore keystoreName path src main resources app keystore password Optional configuration type provider org seedstack seed crypto keystore keystoreName2 callout tips Two keytstore names are registered by default master and default The usage of the master keystore is described later in this documentation configuration files protection The default is only a shortcut when you don t need to have multiple keystores So you don t have to specify ini org seedstack seed crypto keystores default master callout Key pairs Java key stores protect keys using passwords and associate public private key pairs to aliases For instance if you want to register the previously key pair do it as follows ini org seedstack seed crypto keystore keystoreName alias database password 21B06221FC9EC83BAAD ssl password 70E65711ACFEF03F59A callout warning It is recommended for security to store certificates in a key store But if you can t it is still possible to use an external certificate as follows callout ini org seedstack seed crypto cert client1 resource client cer client2 file src main resources seed crt In this example client1 and client2 correspond to keystore aliases The first alias is loaded from a resource and the second from a file A current limitation with external certificates is that the aliases have to be present in one of the configured keystores EncryptionService When a key store is configured it is then possible to inject an EncryptionService for a specific alias The alias password has to be configured for accessing the private key Otherwise the EncryptionService will still be bound but it won t be able to decrypt data Only the encryption will be possible java Inject Named database named with the key pair alias private EncryptionService encryptionService And use it to crypt or decrypt data as follows java final String stringToCrypt secret in plain text byte encryptedString encryptionService encrypt chaine getBytes byte decryptedString encryptionService decrypt encrypt Secure hashing Seed crypto also comes with an HashService which provides the current best default hashing algorithms java Inject private HashingService hashingService Hash hash hashingService createHash string to hash It also provides a secure password validation It takes a password hashes it and checks it against the previously hashed password java Hash hash hashingService validatePassword passwordToCheck verifiedHash Configuration files protection Sometimes you need to have sensitive data in your configuration files Using Seed cryto it is possible to encrypt values in your props files This values are decrypted at runtime For instance you can encrypt a password and specify it in the props file with the password XXX syntax ini org seedstack seed crypto keystore keystoreName alias client password password 70E65711ACFEF03F59AFCED F96563A19B18954B49DD59 The password decrypting is done using an EncryptionService This service expect a key store named master with a key alias named seed ini org seedstack seed crypto keystore master path src main resources masterkeystore jck password env KS_PASSWD alias seed password env KEY_PASSWD","summary":"Seed provides helpers for Java cryptography:\n\nPrivate key encryptionSecure hashingKeyStore configurationSSL configuration\n\n\n\nEncryption\n\nSeed provides an EncryptionService which allows you to securely store or...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Seed manual","icon":"fa fa-book","path":"manual"}},{"title":"Basics","tags":["startup","shutdown","configuration","injection","diagnostic","lifecycle","logging"],"href":"/docs/seed/manual/","content":"SeedStack Java framework or simply Seed is a solution for building Java applications no matter how simple or advanced without pain It does so by providing a simple yet highly modular architecture and by taking charge of various technical aspects frequently encountered in enterprise applications It accommodates any kind of Java 1 6 runtime and offers the same level of features from command line standalone JVMs to full fledged Web application servers Dependencies A minimal Seed based project only requires the seed core module and its dependencies in the classpath This module provides basic Seed functionality to your application like lifecycle management configuration dependency injection logging or error diagnostics To include seed core in your application you have two main options Using a dependency manager like Maven http maven apache org or Gradle http gradle io This is the recommended solution Add seed jar manually to your application This JAR contains all Seed code and the required dependencies in a single convenient yet big library callout tips If you re using Maven SeedStack provides comprehensive dependency management in its distribution whether by inheriting from its parent or by importing its BOM We recommend doing so to ensure that versions of Seed dependencies are consistent across the project Additionally you won t have to specify the version tag of any Seed dependency Check the distribution documentation page docs getting started distribution for more information callout Startup and shutdown Starting a Seed application consists in creating a Kernel instance and invoking its startup logic Later the application can be cleanly stopped by invoking the kernel stopping logic All these steps are already encapsulated by Seed for two main runtime environments The command line The external servlet based Web application server Command line Launch from command line This is the simplest way to launch a Seed application You do so by executing the class with the JVM java jvm args cp org seedstack core SeedMain app args The SeedMain class will search the classpath for an implementation of the interface and execute its launch method with the application arguments Exactly one launcher must be present in the classpath or an exception will be thrown callout info Launchers live in various Seed modules such as the seed cli module handling command line interface CLI applications or the seed web undertow module providing an Undertow http undertow io embedded Web server Without such module containing a launcher in classpath an exception will be thrown callout callout tips One difficulty of running a Java application from the command line is to properly set its classpath As such launching a Seed application from the command line is often used in combination with ber JAR packaging where a unique JAR contains all the necessary classes and dependencies to run the application With this kind of packaging launching the application becomes as simple as java jvm args jar app jar app args Check the SeedStack Maven plugin docs tools maven plugin for more information about how to easily package such a JAR callout Shutdown from command line To shutdown a Seed application from the command line you simply have to gracefully stop the JVM You can do this on any operating system this by hitting CTRL C if the JVM is a foreground process You can also do this under UNIX systems if the JVM is a background process by issuing a SIGINT signal to the JVM process kill 2 pid In any case the shutdown logic of the Seed application will be invoked callout warning Warning If you abruptly terminate or kill the JVM process the application will NOT gracefully shutdown callout Launch in Web application server A servlet based Web application server directly manages the lifecycle of an application If your server is at least at the Servlet 3 0 level of Servlet API the seed web core module already contains the necessary classes to trigger Seed startup and shutdown in response to server events callout tips If your Servlet API level is lower than 3 0 please check this page web for the required configuration of your application callout Logging Logging is a necessity in almost any application Seed is built upon the popular SLF4J logging facade http www slf4j org and provides its Java Commons Logging bridge and Java Util Logging bridge out of the box The choice of the SLF4J implementation is left to you but we recommend Logback http logback qos ch Seed provides sensible defaults for Logback in the org seedstack seed core logging logback defaults xml resource which can be imported in any Logback configuration file callout tips These defaults include two stdout console appenders called STDOUT for a monochrome output or STDOUT COLOR for a colorized output You can use these appenders in any of your configured loggers at your discretion callout You can inject a logger in any class by annotating an SLF4J logger field with Logging Logging private Logger logger This will automatically inject a logger for the enclosing class This also works on static fields although if you need your logger fields to be final you must use the traditional SLF4J syntax instead Configuration Seed provides an unified configuration mechanism that is simple to use thanks to its strict key value paradigm but also very powerful Classpath scanning is used to discover all application configuration files present in the META INF configuration locations of the classpath which are aggregated in a global configuration available from anywhere in the application Seed supports two configuration file formats The recommended Props format which is a superset of the classic Java Properties format providing a more concise and expressive configuration language Props files must have the props extension The legacy Properties format which is described here All files must be located under the META INF configuration directory plain META INF configuration my app props security props legacy properties callout tips Lots of configuration features such as profiles sections appending etc are only supported with the Props format Try to avoid the legacy Properties format if possible callout Bootstrap configuration A few configuration values must be configured in a special configuration file that must be named seed props or seed properties This file must also be put in the META INF configuration folder The most frequent usage of this file is to define the base package s that Seed must scan You can do so with the following ini org seedstack seed base packages org my package com my other package callout warning It is important to set the org seedstack seed base packages property of bootstrap configuration for Seed to scan your classes If you omit to do so Seed will only scan org seedstack and its sub packages by default callout callout tips Note that the bootstrap configuration contents will also be available as normal application configuration As such you can choose to put all your configuration bootstrap or not in this file callout Props format Base characteristics By default props files are UTF 8 encoded but can be encoded in any encoding Leading and trailing spaces will be trimmed from section names property names Either equal sign or colon are used to assign property values Comments begin with either a semicolon or a sharp sign and extend to the end of line It doesn t have to be the first character A backslash escapes the next character e g is a literal is a literal uXXXX is encoded as character Also t r and f are encoded as characters Sections Sections looks very much like Windows INI file sections In props files a section simply represents a key prefix for following keys until the section end or end of file Section names are enclosed between and Properties following a section header belong to that section Section name is added as a prefix to section properties Section ends with empty section definition or with new section start or end of file The following example users data weight 49 5 height 87 7 age 63 comment this is base property is equivalent to this one users data weight 49 5 users data height 87 7 users data age 63 comment this is base property Profiles Seed provides a configuration profile concept which is activated via the org seedstack seed profiles system property Profiles are determined at application initialization and cannot be changed afterwards You can activate several profiles simultaneously by using a comma separated list For example following JVM argument activates both dev and debug profiles Dorg seedstack seed profiles dev debug Profile names are enclosed between They can be used as a part of a property key One key can contain one or more profile name A good practice consists in keeping them at the end but they could be used anywhere in a key Properties without a profile are base properties and are available without providing any profile For example db port 3086 db url localhost db username root db url productionmachine myorganization org db username securedaccount In above example db port key provides a base property that will always be available whereas other keys are dependant on a profile name dev or prod Therefore these values would be available only if the corresponding profiles environments here are requested through JVM org seedstack seed profiles argument Since profiles can be anywhere in the key name section names can contain profile definitions as well The above example can also be written as follows db port 3086 db url localhost username root db url productionmachine myorganization org username securedaccount There are cases where two ore more profiles share most of their configuration and only few properties are different or specific to one profile To avoid repeating shared properties for each profile it is possible to define different specific properties assigned to inner profiles only Props will first lookup keys in inner profiles then go up to the base level For example key1 Hi key2 key100 key1 Hola This example defines two profiles First one is named one and contains 100 properties Second profile is an inner property named one two It contains only 1 property key1 but all properties from its parent profile are available Macros A macro is a reference to some keys value inside the value of another key Macros are enclosed between and Here is a simple example key1 Something foo foo nice Value of key1 is Something nice Macros can refer to any existing property key no matter where it is defined Therefore nested macros are also supported as in following example key1 key key3 key3 2 key2 foo Value of key1 is foo Multi line values Multi lines values are defined with triple quotes Everything in between is considered as a value For example email body Hello n welcome Note that multi line values are NOT trimmed Therefore the value from the example will consist of 5 lines There is no need to escape new lines in multi line values Value appending Values with the same key name are automatically appended to each other with a comma separator With the following configuration org myorganization myproject toto val1 org myorganization myproject toto val2 The org myorganization myproject toto value evaluates to val1 val2 You can then retrieve this kind of value as a normal string or as a string array Copy operator The copy operator can be used to share a set of properties in different sections by copying them Consider the following example org myorganization myproject1 action1 value1 org myorganization myproject1 action2 value2 org myorganization myproject2 action1 value1 org myorganization myproject2 action2 value2 org myorganization myproject3 etc Props allows you to use copy operator in order to minimize and clarify the declarations required Above props can be written as follows instead actions action1 value1 action2 value2 org myorganization myproject1 actions org myorganization prd2 actions org myorganization myproject3 actions The above example shows 3 different but equivalent ways to use copy operator without sections with partial section with full section Note that copied values are set as macros so all above copied properties are identical to org myorganization myproject1 action1 actions action1 org myorganization myproject1 action2 actions action2 org myorganization myproject2 action1 actions action1 All rules for resolving macros apply Environment variables System environment variables are provided through configuration using a macro prefixed by env For example db url jdbc mysql env MYSQL_SERVER test Please note that the environment variable lookup is case sensitive contrary to the System getenv variableName java method Its behavior is equivalent to System getenv get variableName System properties JVM system properties are provided through configuration using a macro prefixed by sys For example indexer path sys java io tmpdir sys file separator my index The system property lookup is case sensitive just as System getProperty propertyName java method Constant values Class constant values i e static final fields are available in props configuration with const prefix For example action1 key const java awt event KeyEvent VK_CANCEL The value of action1 key is the value of VK_CANCEL constant retrieved from java awt event KeyEvent class Override Nominal configuration can be overridden explicitly using resources names ending with override properties and override props Nominal and override configuration are loaded completely separately and cannot interact with each other except in the following ways If a key is present both in nominal and override configuration the override value completely replaces the nominal one If a key is present in override configuration but not in nominal configuration it is added to the nominal configuration If a key is present both in nominal and override configuration but prefixed by a dash in override configuration it is removed from nominal configuration As an example with this nominal configuration overriddenValue I m overridden removedValue I m removed emptiedValue I m emptied And this override configuration overriddenValue I m overriding removedValue emptiedValue removedNonExistentValue You end with the following overriddenValue evaluates to I m overriding emptiedValue evaluates to an empty string removedValue evaluates to null as if it was never declared in the first place callout tips Please note that as the nominal and the override configurations are completely separate no macro resolution can take place between the two Also note that the whole property name is used for the dash prefix check so you can t add the dash character in a categorized property category property1 This will NOT be removed since the full property name will be category property1 Instead use the following form outside any category block category property1 You can use this particularity to remove several keys from the same category category property1 property2 This will remove category property1 and category property2 from the nominal configuration callout Dependency injection In a Seed application the dependency injection is provided by a Guice injector created by the kernel in its starting phase The injector is configured in explicit mode meaning that all the application injection points are checked during application startup and must be resolvable This mode ensures that injection errors are detected as soon as possible in the development process Although Guice is operating behind the scenes it is invisible for the application which only needs to rely on JSR 330 annotations for defining injection points Injection points When applying the dependency injection pattern the dependencies are passed in instead of being requested directly or by calling factories The process of setting dependencies into an object is called injection In SeedStack the injections are explicit and almost always marked with the Inject annotation The element marked with the Inject annotation is called the injection point There are multiple injection styles described below and they all can be used simultaneously Constructor injection Constructor injection combines instantiation with injection To use it annotate the constructor with the Inject annotation This constructor should accept class dependencies as parameters It is then recommended to assign the parameters to final fields in the constructor public class MyServiceImpl implements MyService private final OtherService otherService Inject public MyServiceImpl OtherService otherService this otherService otherService If your class has no Inject annotated constructor a public no arguments constructor will be used if it exists otherwise an exception will be thrown upon application startup The constructor injection style has two main benefits The ability to construct injected immutable instances The explicit constructor arguments will make unit testing easier when you construct a test instance manually you are still required by compiler to provide all the dependencies Field injection Fields injection points are fields annotated with Inject and are injected just after instance creation public class MyServiceImpl implements MyService Inject private OtherService otherService Avoid using field injection with final fields which are not guaranteed to succeed in some contexts Method injection Method injection points are methods annotated with Inject are called just after field injections Dependencies take the form of parameters which the injector resolves before invoking the method Injected methods may have any number of parameters and the method name does not impact injection public class MyServiceImpl implements MyService private OtherService otherService Inject public void doInjection OtherService otherService this otherService otherService Injection scopes By default the injector returns a new instance each time it supplies a value This behavior can be altered by applying a scope to the implementation class Scopes allow to reuse instances like the Singleton scope which will make the injector always return the same instance for the lifetime of the application Annotations are used to identify scopes Specify the scope for a type by applying the scope annotation to the implementation class Singleton public class MyServiceStatefulImpl implements MyService everything here should be thread safe By default in SeedStack almost every class managed by the injector has no scope associated which means that a new instance is created for each injection This is a desirable behavior because it minimizes the mutability of your code and as such minimizes the need to use concurrency protection synchronized ThreadLocal In the end all the bugs associated with such techniques are avoided In some cases you ll need to specify a scope though If an object is inherently stateful like a counter or a cache If an object is expensive to create If an object is tied up to external resource Note that since the technical aspects that are often the motivation to implement a singleton are already handled by the framework it is unlikely that you will need to apply this scope yourself Remember that by keeping your application code as stateless and immutable as possible you will Reduce the probability of bugs Improve its scalability Improve its testability Static injections Injection on static fields is a specific case of injection that requires an explicit binding that is very rarely used in SeedStack internal code and never in application code It means that by default injection on static fields of your classes won t be enabled This is a good thing because static injections are difficult to test make dependencies opaque and rely on global state Custom injections Custom injections can be used for advanced injection behavior that is not possible to achieve through the standard Inject injection points They rely instead on specific annotations to trigger the injection The Logging annotation described here logging is an example of custom injection SeedStack doesn t rely heavily on custom injection using standard injection when possible Method interception To complement dependency injection method interception is sometimes used in SeedStack It allows to execute code each time a matching method is invoked It is suitable for cross cutting concerns aspects and is notably used among other things for transaction and security Method interception is transparent for the application code but its implementation which works by dynamically sub classing and overriding matching methods impose some limitations that you should know Classes must be public or package private Classes must be non final Methods must be public package private or protected Methods must be non final Instances must be created by the injector It is not possible to use method interception on instances that aren t constructed by the injector More information For more information about the injector used in the Java framework you can look at the Guice documentation wiki https github com google guice wiki Please note that some Guice features described in this documentation are not available in SeedStack or implemented differently A knowledge of Guice is NOT necessary to develop a Seed based application Error diagnostic Seed can dump diagnostic information when an exception is catched at key application locations Core support dumps diagnostic information when an uncaught exception occurs in a thread but other supports can trigger dumps in various conditions Diagnostic information is an aggregation of values gathered from various diagnostic collectors in a single map This map is then handled by the diagnostic reporter Diagnostic collectors A diagnostic collector is a class implementing the interface and annotated with DiagnosticDomain org my organization my project my diagnostic domain public class MyDiagnosticCollector implements DiagnosticInfoCollector Override public Map collect All diagnostic collectors are automatically detected by Seed and will be used in diagnostic information gathering The diagnostic domain uniquely identifies the information of the collector Diagnostic reporter The default diagnostic reporter dumps the map as a YAML document in the system temporary directory The diagnostic reporter can be changed by setting the org seedstack seed diagnostic reporter system property to a class implementing","summary":"SeedStack Java framework (or simply Seed) is a solution for building Java applications, no matter how simple or advanced,\nwithout pain. It does so by providing a simple yet highly modular architecture and by taking charge of various technical \naspects frequently encountered in enterprise...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Seed manual","icon":"fa fa-book","path":"manual"}},{"title":"More","tags":["jdni","data"],"href":"/docs/seed/manual/more","content":"JNDI Seed provides the ability to inject external JNDI resources through the Resource annotation Multiple JNDI contexts can be used in an application by using the FromContext annotation Declaring JNDI contexts The default JNDI context is automatically configured by Seed if you provide a jndi properties file in META INF configuration classpath included folder This JNDI context is named default by Seed Additional JNDI contexts can be specified using the following configuration properties additional jndi contexts additional1 additional2 additional jndi context additional1 jndi ctx 1 properties additional jndi context additional2 jndi ctx 2 properties The above code defines two additional JNDI contexts named additional1 and additional2 The specified properties files are jndi properties like files Using JNDI context Declarative API You can inject JNDI resource using the Resource annotation from JSR 245 public class Holder Resource name THE_JNDI_NAME private DataSource datasource The above lookup for THE_JNDI_NAME in default JNDI context is injected into datasource attribute In case you have several JNDI contexts in your application you can specify the context name as follows public class Holder Resource name THE_JNDI_NAME FromContext additional1 private DataSource datasource Programmatic API You can retrieve any context by injecting it into your code Then you can use the JNDI programmatic API to lookup for resources in that context You can inject the default context as follows public class Holder Inject private Context defaultCtx public void m MyJNDIResource test defaultCtx lookup THE_JNDI_NAME If you need to precise another context you can specify the context as follows public class Holder Inject Named additional1 private Context additional1 public void m MyJNDIResource test additional1 lookup THE_JNDI_NAME Data import export Seed provides features to backup and restore data This could be done through Seed Shell docs seed manual operations shell or data could be loaded at the application startup Data can be backed up and restored independently from the type of persistence since JSON is used as the pivotal format Consequently no SQL script or conversion script is needed Data import can also be used to initialize data for integration tests Data Export Your export class has to implement DataExporter This interface provides an exportData method returning the data to export The class implementing DataExporter should be annotated with DataSet which provides a functional ID to the data As below described DataSet takes a group eg application ID and a name eg the type of objects being exported Implementation example JpaUnit seed i18n domain Transactional DataSet group seed i18n name key public class KeyDataExporter implements DataExporter Inject private KeyRepository keyRepository Inject private FluentAssembler fluentAssembler Override public Iterator exportData List keys keyRepository loadAll return fluentAssembler assemble keys to KeyDTO class iterator Import data Your export class has to implement DataImporter This interface provides an isInitialized method to check before importing data can be disabled with a property an importData method consuming the data to import eg feed a staging collection a commit method to commit data after importData a rollback method to roll back data upon error in prior steps The class implementing DataImporter should be annotated with DataSet As for Export this annotation provides a functional ID to the imported data As below described DataSet takes a group eg application ID and a name eg the type of objects being imported Implementation example from seed i18n function Transactional DataSet group seed i18n name key public class KeyDataImporter implements DataImporter Inject private KeyRepository keyRepository private Set staging new HashSet Inject private Assemblers assemblers Override public boolean isInitialized check if data are already initialized return initialized Override public void importData KeyDTO data staging add data Override public void commit boolean clear if clear delete data before adding new one for KeyDTO keyDTO staging persist data staging clear Override public void rollback staging clear Shell command Seed also provides commands to import and export data You can invoke this kind of commands through Seed Shell docs seed manual management shell core export g group filter on group s set filter on name core import c clear Clear existing data if import is succeeding Usage ssh t admin localhost p 2222 core export data json ssh t admin localhost p 2222 core import data json DataManager If you want to handle import or export from your code you can do it by injecting the DataManager class Auto initialization Data can be automatically loaded at the application startup by adding the exported JSON file s in META INF data group name json These data files will be loaded unless the application is already initialized according to your isInitialized method implementation Initialization can be forced each time this application is started by adding this property org seedstack seed core data initialization force Data loading can also be disabled by setting the property to none org seedstack seed core data initialization none","summary":"JNDI\n\nSeed provides the ability to inject external JNDI resources through the @Resource annotation. Multiple JNDI contexts can\nbe used in an application by using the @FromContext annotation.\n\nDeclaring JNDI contexts\n\nThe default JNDI context is automatically configured by Seed if you provide a jndi...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Seed manual","icon":"fa fa-book","path":"manual"}},{"title":"Operations","tags":["shell","metrics","monitoring","ssh"],"href":"/docs/seed/manual/operations","content":"Seed provides the necessary tools to closely monitor the performance and the availability of your application or service and even to take action if necessary It does so by capturing metrics on key application components and checking their health status Custom metrics and health checks can be defined If you need to take action you can execute predefined or custom management commands through SSH Metrics When enabled this module will automatically capture key metrics throughout the framework Additionally it provides the ability for you to define 5 types of custom metrics Gauge which simply collects a value Counter which is an incrementing or decrementing value Histogram which measures the distribution of values in a stream of data Meter which measure the rate at which a set of events occur Timer which combines an histogram of an event duration and a meter of the rate of its occurrence callout info Seed metrics module implementation is based on the Metrics http metrics codahale com library Please check its documentation for more information callout Annotations Metrics can automatically be registered through annotations To register a Gauge use the annotation on any method Gauge name queueSize public int getQueueSize return queue size You can also use its counterpart which allows for a more efficient reporting of value which are expensive to calculate CachedGauge name queueSize timeout 30 timeoutUnit TimeUnit SECONDS public int getQueueSize return queue getSize The annotation will create a counter of the invocations of the method it is applied to Counted name fancyName public String fancyName String name return Sir Captain name Note that if the monotonic parameter is set to false the counter is increment upon method entry and decremented upon method exit If set to true the counter only increments effectively counting the number of method invocations The annotation will create a meter which will measure the rate of invocation of the method it is applied to Metered name fancyName public String fancyName String name return Sir Captain name Its counter part the annotation will create a meter which will measure the rate of exception throwing of the method it is applied to ExceptionMetered public String fancyName String name return Sir Captain name The more generic annotation permits two different uses When applied on an empty Metric field the corresponding metric will be created and injected Metric public Meter meter When applied on a non empty Metric field the metric will be registered Metric public Histogram uniformHistogram new Histogram new UniformReservoir In both cases it is up to the client code to interact with the metric Registry If you need more control over the metrics registration process you can inject the Inject MetricRegistry metricRegistry This also allows you to interact programatically with any registered metrics Health checks An health check is a class that will check a specific state of the application and report it To create an health check you must extend the class and annotate it with the annotation HealthChecked public class GoodHealthCheck extends HealthCheck Inject MyService myService Override protected Result check throws Exception if myService isOk return Result healthy I m fine else return Result unhealthy Boo Note that you have access to any injectable instance in your health check Shell Seed shell provides administrative access to application commands through SSH protocol in two different modes Interactive mode consists in providing of a simple line based shell with auto completion history and the ability to display command results as a string In this mode commands have no access to low level input output and error streams They take and produce discrete objects that are displayed as strings Direct mode consists of a single command executed through an ssh remote invocation In this mode commands have access to low level input output and error streams and thus can be combined with other commands on the client system Configuration The configuration properties defining the shell support behavior are org seedstack seed shell enabled which determines if shell access is enabled or not org seedstack seed shell port defines the port the SSH server will listen to Defaults to 2222 org seedstack seed shell key type defines what type of cryptographic key to use generated is the simplest and default mode It generates a key in the application storage directory which is used in subsequent authentication challenges Please note that this key type is NOT secured from a SSH perspective file mode specifies the cryptographic key location on the filesystem via the org seedstack seed shell key location configuration property The key must be provided in a JCE serialized format resource mode specifies the cryptographic key location on the classpath via the org seedstack seed shell key location configuration property The key must be provided in a JCE serialized format callout warning For security reasons shell access is disabled by default even when the dependency is in the classpath If shell access is required set the org seedstack seed shell enabled configuration property to true In that case it is strongly recommended to configure a real SSH key callout Commands All commands registered in the can be invoked from both interactive and direct modes You can specify command name arguments and options using a GNU like syntax scope cmdname s sval long option long option with arg argval arg0 arg1 arg2 Note that The command scope must be specified as a prefix of the command name delimited by a colon character Short options are specified using the dash character immediately followed by the option name and a value if needed Long options are specified with two dash characters immediately followed by the option name and if required an equal sign with a value Arguments are specified respecting the command arguments order","summary":"Seed provides the necessary tools to closely monitor the performance and the availability of your application or service,\nand even to take action if necessary. It does so by capturing metrics on key application components and checking their \nhealth status. Custom metrics and health-checks can be...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Seed manual","icon":"fa fa-book","path":"manual"}},{"title":"REST","tags":["jax-rs","resource","http","hypermedia","api","link","json"],"href":"/docs/seed/manual/rest","content":"Seed provides support for Representational State Transfer 1 REST architectural style through the JAX RS specification Implementation rely on Jersey https jersey java net To enable REST support in your project add the seed rest jersey1 module JAX RS 101 Within JAX RS context resources are classes annotated with Path All these classes are automatically detected and registered by Seed This means that you can inject any other classes managed by Seed in your resources A new instance of the resource class is created for each request callout info In order to avoid possible conflict with static resources all REST resources are prefixed by default with rest callout Below is an example of a simple Hello World REST resource Path hello public class HelloResource GET Produces text plain Path msg public String sayHello PathParam msg String message return Response ok Hello message build This resource is exposed by default on rest hello You can request the resource with curl http localhost 8080 rest hello world The returned response body will be plain Hello world Requests An HTTP request is mapped to resource method according to its path verb and content type If no resource method matches an HTTP request the HTTP status 405 Method not allowed is returned Path The path is determined by the annotation Path This annotation is mandatory on the class and can be also added on the method to express the notion of sub resources The annotation value 1 is the relative URI path but can also contain a URI template or a regex expression Verb HTTP verb is determined by a corresponding annotation Each verb has its own annotation GET POST PUT etc Content type The content type is determined with Produces MediaType APPLICATION_JSON and Consumes MediaType APPLICATION_JSON Responses JAX RS allows to return a detailed response with the resource representation and an HTTP status code For instance the following resource will return HTTP status code 201 Created with the URI of the created resource POST public Response createPerson PersonRepresentation pr Context UriInfo uriInfo PersonRepresentation createdPerson accountService register pr URI newUri new URI uriInfo getRequestUri toString createdPerson getId return Response created newUri entity createdPerson build Exception handling Exception handling is an important part of any API design Carefully designed error handling will allow you to provide meaningful status codes and messages to the client instead of dumping raw stacktraces in your HTTP response Web application exceptions One way to implement clean exception handling in your REST API is to extend the class public class NotFoundException extends WebApplicationException public NotFoundException String msg super Response status Response Status NOT_FOUND entity msg build If the exception is thrown from within a resource method the server will return an HTTP status code 404 Exception mappers Another way of implementing exception handling is to map existing exceptions to Response using an ExceptionMapper Provider public class MyBusinessExceptionMapper implements ExceptionMapper Override public Response toResponse MyBusinessException exception return Response status Response Status BAD_REQUEST entity exception getMessage build If the a MyBusinessException exception class is thrown from within a resource method the server will return an HTTP status code 400 Testing Testing REST resources can be done in a real Web environment by using Seed Web integration testing testing web integration tests Consider this example public class ProductsResourceIT extends AbstractSeedWebIT Deployment public static WebArchive createDeployment return ShrinkWrap create WebArchive class setWebXML WEB INF web xml RunAsClient Test public void testCreate ArquillianResource URL baseURL throws JSONException JSONObject obj new JSONObject obj put summary The world s highest resolution notebook obj put categoryId 1 obj put designation macbook pro obj put picture mypictureurl obj put price 200 0 assert response code String response expect statusCode 201 given header Accept application json header Content Type application json body obj toString post baseURL toString rest products asString assert body JSONAssert assertEquals obj new JSONObject response false This example uses two libraries for easy REST testing REST Assured https github com jayway rest assured which can test various HTTP request response scenarios JSONassert https github com skyscreamer JSONassert which can assert conditions on JSON documents Working with streams Send a stream To send bytes like images JAX RS can return special stream GET Produces text plain public StreamingOutput hello return new StreamingOutput Override public void write OutputStream output throws IOException WebApplicationException output write Hello World getBytes Receive a stream To read a data stream file image or bytes JAX RS can inject a Reader or an InputStream Path files public class FileResource POST Path upload Consumes application pdf public void doSomething InputStream is readFileWithInputStream is POST Path upload image public void doSomethingWithReader FormDataParam file Reader reader readFileWithReader reader Custom formats Seed REST support works out of the box with XML and JSON formats If your project requires a custom format you can implement your own readers and or writers Create a class which implements and or with the custom format specified as the generic type Add the annotation Add the if this is a writer Produces and Consumes if relevant Add the if this is a reader Implement the necessary methods More documentation is available in the JAX RS Javadoc http docs oracle com javaee 6 api javax ws rs ext package summary html RESTful API design The Representational State Transfer 1 REST architectural style was defined in 2000 by Roy Fielding This architectural style defines a set of constraints based on the Web architecture These constraints are the following 1 Client Server 2 Stateless 3 Cache 4 Uniform interface 5 Layered System 6 Code On Demand In this section we will focus on the fourth constraint and how to implement it in a Seed application Uniform interface REST is defined by four interface constraints identification of resources manipulation of resources through representations self descriptive messages and hypermedia as the engine of application state Roy T Fielding Identification of resources The identification of resources means that each resource should be accessible through an URI For instance a book 123 will be accessible though the books 123 URI Manipulation of resources through representations Resources should be manipulated through representation This means that you should not expose your resource like a business object directly because it will make refactoring impossible without breaking the clients Self descriptive messages The messages should be context free to respect the stateless constraint Each message should embedded self descripting messaging For this the HTTP 1 1 specification defines a list of HTTP verbs 7 status codes 6 and headers 2 to exchange metadata For instance the following JAX RS method specify that the HTTP verb is POST it accepts the media type application json and return 201 Created POST Consumes MediaType APPLICATION_JSON public Response createPerson PersonRepresentation pr Context UriInfo uriInfo PersonRepresentation createdPerson accountService register pr URI newUri new URI uriInfo getRequestUri toString createdPerson getId return Response created newUri entity createdPerson build Hypermedia as the engine of application state HATEOAS According to Roy T Fielding a REST API is a set of resources that can be explored by following links Each resource is a representation of a state of the application and the links are the transitions between those states The name Representational State Transfer is intended to evoke an image of how a well designed Web application behaves a network of web pages a virtual state machine where the user progresses through the application by selecting links state transitions resulting in the next page representing the next state of the application being transferred to the user and rendered for their use Roy T Fielding Such a Web application has the following advantages The state of the application controlled by the server as it tells the client what it can do next It allows the refactoring of server s URI scheme without breaking clients It helps client developers to explore the API It allows the server developers to advertise deprecation or new capabilities by adding hints on existing links or by adding new links The benefits of an hypermedia API are obvious but it is often seen as difficult to implement in real life applications With Seed we want to make it so easy that all Seed REST application will support hypermedia by default In order to do this Seed supports two dedicated media types They are both based on JSON and describe conventions to link to other resources JSON HOME To ease REST API discovery Seed exposes an API home resource with the JSON HOME 3 media type This is similar to a Website homepage but for REST APIs The goal of the JSON HOME media type is to expose an home resource which provides all the entry points of the application s API It tells the client developer what it can do and give him hints on how to use the resources The following example shows a JSON HOME resource with two entry points widgets and widget For the widgets resource the JSON HOME provides just an href indicating the URI of the resource But for the widget resource the JSON HOME provides an href template instead json GET HTTP 1 1 Host example org Accept application json home HTTP 1 1 200 OK Content Type application json home Cache Control max age 3600 Connection close resources http example org rel widgets href widgets http example org rel widget href template widgets widget_id href vars widget_id http example org param widget hints allow GET PUT DELETE PATCH formats application json accept patch application json patch accept post application xml accept ranges bytes To expose a JAX RS resource in the JSON HOME resource annotate the resource with Rel and set the home attribute to true The annotation can be on the class or the method Rel value CatalogRels PRODUCT home true Add it to JSON HOME Path products title Produces MediaType APPLICATION_JSON application hal json public class ProductResource GET public Response getProduct Hypertext Application Language HAL Beyond providing an API homepage you have to provide a way to navigate between these pages That s the role of the HAL JSON 4 media type which establishes conventions for expressing hypermedia controls An HAL representation looks like this json GET orders HTTP 1 1 Host example org Accept application hal json HTTP 1 1 200 OK Content Type application hal json _links self href orders next href orders page 2 find href orders id templated true _embedded orders _links self href orders 123 basket href baskets 98712 customer href customers 7809 total 30 00 currency USD status shipped _links self href orders 124 basket href baskets 97213 customer href customers 12369 total 20 00 currency USD status processing currentlyProcessing 14 shippedToday 20 It is a JSON representation with just two reserved keywords _links this property is used to share links to other resources Links are represented as a set of keys and values The keys represents a relation type rel and the value a link object The only required value of the link object is href which can be an URI or an URI template orders id By convention a resource always returns a self link with its own URI However the propery _links is optional For more information on link object see the section 5 5 of the specification _embedded this property is a set of keys and values Keys are relation types and values can be a resource object or an array of resource objects The embedded resources can be full or partial representations of a resource Usage Creating HAL resources Seed provides two options to simplify the creation of HAL representations First you can take an existing representation and transform it to an HAL representation using the HALBuilder HalRepresentation representation HalBuilder create ProductRepresentation self rest products productId link tags rest products productId tags embedded related relatedProducts The second option is to make your representation inherit the HalRepresentation public class ProductsRepresentation extends HalRepresentation private long totalProduct private long currentPage ProductsRepresentation public ProductsRepresentation PaginatedView page this totalProduct page getResultSize this currentPage page getPageIndex embedded products page getView public long getTotalProduct return totalProduct public long getCurrentPage return currentPage Building links Concatenating strings for building hrefs can quickly become painful and error prone With Seed you have access to a RelRegistry which can greatly simplify the task This registry contains all the resources annotated by Rel and their href For instance the href of the following resource Path products public class ProductsResource GET Rel value CatalogRels CATALOG defines the resource rel Produces MediaType APPLICATION_JSON application hal json ublic Response products DefaultValue 0 QueryParam pageIndex Integer pageIndex DefaultValue 10 QueryParam pageSize Integer pageSize can be created as follows String self relRegistry uri CatalogRels CATALOG set pageIndex pageIndex set pageSize pageSize expand 1 https www ics uci edu fielding pubs dissertation rest_arch_style htm 2 http www w3 org Protocols rfc2616 rfc2616 sec14 html sec14 3 http tools ietf org html draft nottingham json home 03 4 https tools ietf org html draft kelly json hal 06 5 https tools ietf org html draft kelly json hal 06 section 5 6 http www w3 org Protocols rfc2616 rfc2616 sec10 html 7 http www w3 org Protocols rfc2616 rfc2616 sec9 html","summary":"Seed provides support for Representational State Transfer (REST) architectural style through the JAX-RS \nspecification. Implementation rely on Jersey. To enable REST support in your project, add \nthe seed-rest-jersey1 module.\n\n{{< dependency g="org.seedstack.seed" a="seed-rest...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Seed manual","icon":"fa fa-book","path":"manual"}},{"title":"Security","tags":["authentication","authorization","permission","access-control","identification","role","data"],"href":"/docs/seed/manual/security","content":"Seed provides application security through a powerful security model which is equally easy to configure and to enforce It takes charge of the following tasks Identification provides the identity of a subject Authentication verifies the subject identity Authorization defines which roles and permissions a subject can have Access control enforces access restrictions to entry points and or to any arbitrary code To enable security to your project you need to add the seed security core module In a Web application you may want to enable HTTP based security by adding the seed web security module callout info The internal security engine is Apache Shiro http shiro apache org Seed provides additional benefits on top of Shiro such as Easy unified configuration Built in security realms such as LDAP X509 certificate or configuration based A plugin mechanism to dynamically register additional entry point security Security scopes which restrict roles and permissions to specified scopes like a geographical area Data security which can nullify or obfuscate object attributes based on subject authorizations callout Definitions Subject A subject is defined as any entity that request access to an object For instance subject are often end users which request to access a specific resource through a User Interface But subjects can really be anything like a remote computer or a local program Principal A principal is a defining characteristic of a subject that can be uniquely identified like an identifier a name a social security number a language etc User A user is a specific kind of subject that is defined by principals usually referring to a human operator like a name or a user identifier Identification Identification is the process of uniquely tracking a subject across its interactions with the system Authentication Authentication is the process of verifying the subject identity by validating a proof of identity This is usually done by submitting a principal identifying the subject like a user identifier and a proof of identity that the system understands and trusts such as a password a certificate or any other mean Authorization Authorization is the process of determining an access policy for a subject This is done by compiling all granted rights into an access policy Access control Access control is the process of verifying the authorizations of a subject relative to an object It enforces the policy that is used to determine who has access to what Model Seed provides a security meta model that is easy to understand yet powerful enough for the most complex applications This meta model revolves around three main concepts permissions roles and subject It allows to define a fine grained and modular security policy Permissions Permissions are the most atomic elements of a security policy They describe concrete actions and represent what can be done in an application A well formed permission statement describes one or more resource s and what actions are possible when a subject interacts with those resources Consider the following examples of permissions Open a file Print a document Access the products Web resource Delete an order CRUD actions can frequently be found in permissions but any meaningful verb can be used The fundamental idea is that a permission should combine a resource description with an action description callout info Permission statements reflect behavior actions associated with resource types only They do not reflect who is able to perform such behavior Defining who which subject can do what which permission is done by assigning permission to subjects callout Simple usage The simplest expression of a permission is a single term String printDocument deleteDocument viewDocument These permissions represent the ability to print delete or view a document This very basic form of permission requires to be granted one by one or with a wildcard which will grant all the permissions of the application This may work in the simplest applications but it is not recommended The multi level permissions should be preferred Multi level Instead of expressing the permission as a single term a multi level permission can be used document print document delete document view The colon is a special character that is used to delimit the different parts of a multi level permission There are no enforced requirements on how a multi level permission should be organized but it is recommended to go from the most general to the most specific from left to right Also there is no limit to the number of parts Multiple values Each part can contain multiple values separated by commas document print view When assigning this permission to a subject this grants the ability to print and view documents All values To grant all permissions of a specific level use the wildcard character document view The first permission when assigned to a subject allow to do any action on documents meaning that any permission check of the document XXX pattern will be granted The second permission grants the view action on all application resources meaning that any permission check of the XXX view pattern will be granted Instance level checks The identifier of a specific instance can be used at the end of a permission document print doc273 This permission allows to print the document identified by the doc273 identifier Missing parts Missing parts in permissions imply that the user has access to all values corresponding to that part printer print This permission is equivalent to printer print Note that you can only leave off parts from the end of the permission Roles A Role is a named entity that typically represents a set of behaviors or responsibilities Those behaviors translate to things you can or can t do with an application Roles are typically assigned to subject like user accounts so by association subjects can do the things attributed to various roles There are two kinds of roles that can be used Implicit roles nothing is explicitly expressed in the application to assign permissions to implicit roles The allowed behavior is implicitly derived from the role name only For instance the admin role can do any administration task and those administration task are protected by a checking if the subject has the admin role This kind of role while superficially simpler is strongly discouraged Adding removing or redefining such roles later in the life of an application will be difficult costly and may lead to holes in the security model Explicit roles they are expressed as a named collection of actual permissions In this form the allowed behavior is explicitly defined and the code only contains specific permission checks which directly relates to the code behavior Altering the security model later in the life of an application will be easy and won t require to change existing code with the potential security implications This kind of role is recommended Subjects Subjects represent the entity which executes actions on the application The most common type of subject is the User type which represents a human operator interacting with the application Subjects are allowed to perform certain actions in your application through their association with roles or direct permissions Assigning roles and permissions to subjects is done through a Realm implementation Realms A realm implementation role is to translate a specific data model like an LDAP directory or a set of database tables into a security policy expressed with the security meta model described above Seed provides several predefined realms The ConfigurationRealm which computes the security policy from specific properties in the application configuration The X509CertificateRealm which computes the security policy from an X509 certificate The LdapRealm which computes the security policy from requests to a configured LDAP directory This realm is available in the LDAP add on addons ldap callout info Custom realms can be implemented to compute any data model into an enforceable security policy callout Configuration Beyond defining the security model of the application the security infrastructure must be configured Realm configuration A Realm is a component that can access specific security data such as users roles and permissions The Realm translates this specific data into a format that is understood by the security engine There is usually a 1 to 1 relation between a realm and a datasource such as an LDAP directory a set of relational tables or configuration properties callout info Most of the security datasources usually store both authentication and authorization data so a realm can perform both the authentication and authorization tasks callout To specify the realm s to enable use the following configuration property ini org seedstack seed security realms list of realms to use The realm name correspond to the simple name of the Java class that implements the realm For instance to enable the LDAP realm which is implemented in the Java class use the following configuration ini org seedstack seed security realms LdapRealm If the property is not specified the default realm is ConfigurationRealm callout info Note that you can specify multiple realms In that case the realms are tried in sequence and if at least one realm successfully authenticates the subject the overall attempt is considered successful If none authenticate successfully the attempt fails The data from all the successful realms are merged callout Configuration realm This realm relies on the application configuration to authenticate subject and retrieve their roles It is mainly intended to be used for testing purposes To declare subjects called users in this realm use the following configuration ini org seedstack seed security users user1 password role1 role2 user2 password role3 This will define two subjects user1 and user2 with their respective passwords and roles X509 realm This realm which is intended to be used in a Web context uses the certificates authorized by the Web server when an SSL connection is in use It stores the certificates in the user principals as well as the UID declared in the certificate It also uses the CN of the issuer of the certificates to define the basic roles of the user LDAP realm Check the LDAP add on documentation addons ldap Role permission resolver There is a role permission resolver component per Realm It resolves the Permissions assigned to a Role and provides them to the Realm To attach a role permission resolver to a Realm use the following configuration ini org seedstack seed security role permission resolver ConfigurationRolePermissionResolver Where corresponds to the name of the Realm this role permission resolver is mapped to The value corresponds to the simple name of the implementing Java class When no resolver is specified the configuration based role permission resolver is used Configuration based role permission This role permission resolver uses the application configuration to do resolution You can assign permissions to roles with the following configuration ini org seedstack seed security permissions role1 permission1a permission1b permission2a permission2b role2 permission3 permission4a permission4b role3 permission5 role4 permission6 This configuration assign permissions listed in values to their respective roles as keys This is the default role permission resolver Role mapping Optionally roles provided by realms can be mapped to application specific roles To do this a role mapping component should be defined in configuration ini org seedstack seed security role mapping ConfigurationRoleMapping Where corresponds to the name of the Realm this role mapping component is mapped to The value corresponds to the simple name of the implementing Java class When no mapping is specified the configuration based role mapping is used callout info When no role mapping is specified the roles provided by realms are directly used as application roles callout Configuration based role mapping This role mapping uses the application configuration to do the mapping ini org seedstack seed security roles role1 ORG APP ROLE1 ORG GLOBAL ADMIN role2 ORG APP ROLE2 role3 ORG APP location ROLE3 role4 This configuration defines the following mappings Application role role1 is attributed to the subject when the realm provides ORG APP ROLE1 OR ORG GLOBAL ADMIN Application role role2 is attributed to the subject when the realm provides ORG APP ROLE2 Application role role3 is attributed to the subject when the realm provides ORG APP FR ROLE3 where FR is converted into a security scope As such a scoped role3 is attributed to the subject which is only valid in FR location Application role role4 is attributed to every subject authenticated Example The following example is based on the defaults a ConfigurationRealm a ConfigurationRolePermissionResolver and a ConfigurationRoleMapping Their declaration is optional but present here for clarity You may want to replace each by a more suitable component especially the ConfigurationRealm which uses the configuration as its users repository ini org seedstack seed security realms ConfigurationRealm ConfigurationRealm role mapping ConfigurationRoleMapping ConfigurationRealm role permission resolver ConfigurationRolePermissionResolver org seedstack seed security users admin password1 APP ADMIN user1 password2 APP FR MANAGER APP UK MANAGER user2 password3 APP BASIC org seedstack seed security roles admin APP ADMIN manager APP ADMIN APP location MANAGER normal APP ADMIN APP BASIC guest org seedstack seed security permissions admin users clear cache invalidate manager users delete users create normal users list Note that Application roles admin manager normal and guest are attributed to a subject if it has at least one of the corresponding realm roles APP ADMIN APP FR MANAGER APP UK MANAGER APP BASIC For instance having the APP ADMIN realm role is enough to have the manager application role Subject user1 will only have the users delete and users create permissions on FR and UK locations Subject admin will have the users delete and users create permissions everywhere no location restriction The guest application role will be attributed to every identified subject Usage Access policy enforcement is achieved by using the Seed security API to protect specific sections of the application code Any code can be secured although restrictions may apply in some cases Enforcement strategy It is recommended to follow a well defined strategy in placing security checks in application code Failing to do so may lead to unexpected security holes as one missing or incomplete check may be enough to compromise the entire application Any well thought out strategy will do but you can consider applying one of the following or both Entry point security This strategy consists in only securing the code that allow to interact with the application This includes REST resources servlets and filters Web Services administrative commands etc Any applicative code can theoretically only be reached through one of these entry points so this strategy may be enough for most applications In depth security This strategy consists in independently securing each application behavior regardless of its depth in the call hierarchy This includes all the entry points of the previous strategy as well as services repositories finders etc It ensures that no behavior can be executed without the appropriate authorizations regardless how it is accessed This strategy provides higher security especially in applications with a lot of entry points or when entry points are often modified but is costlier to implement This cost can be mitigated by limiting the checks to critical application behavior only Annotation based checks There are two annotations that checks for authorizations before allowing method execution RequiresRoles which checks that the current subject has one or more role s before allowing to execute the method RequiresPermissions which checks that the current subject has one or more permission s before allowing to execute the method When the security check fails an exception of type is thrown callout warning Note that these annotation based security checks are implemented with method interception and are subject to its limitations concepts dependency injection method interception callout Examples java RequiresRoles administrator public void deleteUser User user This method is executed only if current subject has role administrator When not an AuthorizationException is thrown RequiresPermissions account create public void createAccount Account account This method is executed only if current subject has permission account create When not an AuthorizationException is thrown Programmatic checks If annotation based security checks cannot be used or if an programmatic style is preferred the facade can be used It provides various methods to explicitly check for current subject authorizations It is more versatile than annotation based checks and it is required when checking dynamically generated authorizations To use it simply inject it where needed Inject private SecuritySupport securitySupport To check if the current subject if any is authenticated if securitySupport isAuthenticated To check if the current subject if any has a specific role if securitySupport hasRole jedi To check if the current subject if any has a specific permission if securitySupport isPermitted jediCouncil attend callout info There are multiple variations for each of these methods and many more possibilities Please refer to the javadoc seed org seedstack seed security api SecuritySupport html for more information callout Other checks Seed security can provide additional ways to verify security depending on the technology used to access the application For instance in a Web application HTTP requests can be filtered to execute security tasks or checks For more information about applying HTTP security filtering refer to this documentation web security Access subject principals Note that SecuritySupport provides access to current subject Principals Get current subject id securitySupport getSimplePrincipalByName Principals IDENTITY getValue Get current subject first name if any securitySupport getSimplePrincipalByName Principals FIRST_NAME getValue Extension As Seed security is based on Apache Shiro http shiro apache org it can be extended by adding existing Shiro components or by writing your own components Seed also provides SPI to extend its own security features Creating a Realm You can create a custom Realm by following these steps 1 Create a class that implements or extends an existing Shiro realm 2 Use the realm class simple name as the realm name in the application configuration Creating a RolePermissionResolver You can create a custom Role Permission resolver by following these steps 1 Create a class that implements 2 Declare you want to use it on a realm in your properties Creating a RoleMapping You can create a custom Role mapping by following these steps 1 Create a class that implements 2 Declare you want to use it on a realm in your properties Testing Testing the security model and its implementation is crucial to ensure effective security This can be easily done with Seed through specific integration tests For a general overview of integration testing please check this documentation testing Configuration You can choose to fully emulate your security infrastructure for instance by using an LDAP test directory instead of the real one The main benefit of this approach is that it tests the security effectiveness as closely as possible to the real environment A simpler but still adequate approach is to override the security realm configuration to use a ConfigurationRealm and define test users in application configuration ini org seedstack seed security users testUser1 password role1 role2 testUser2 password role1 testUser3 password role3 For more information about the Configuration realm refer to this section configuration realm For more information on how to override the configuration for testing refer to this documentation override Subject authentication To authenticate a subject before a test method is executed use the annotation RunWith SeedITRunner class public class MyITWithSecurity Inject private SecuritySupport securitySupport Inject private MySecuredService mySecuredService Test expected AuthorizationException WithUser id testUser1 password password public void unprivileged_user_cannot_access_secured_service mySecuredService securedMethod fail securedMethod shouldn t have been called Test WithUser id testUser3 password password public void admin_user_is_allowed_to_access_secured_service mySecuredService securedMethod Data security The goal of the security on data is to protect the data exposed by an application It has the ability to obfuscate any attribute of any object that does not pass the security restriction defined on it For instance an account number 79927391338710 can be transformed into 799273 10 Restriction annotation This annotation can be applied on any class attribute The field value will be obfuscated when data security will be applied public class MySecuredPojo Restriction value hasRole manager obfuscation AccountObfuscationHandler class private String accountNumber The value of the annotation is a security expression see this section security expressions for more details If it evaluates to false against the current Subject the field will be obfuscated according to the DataObfuscationHandler specified see this section dataobfuscationhandler for more details The default obfuscation handler nullifies the field Data security service The security on data can be applied by using the DataSecurityService as follows Inject private DataSecurityService dataSecurityService dataSecurityService secure myDto This service will go recursively through the object fields and look for restrictions Each restriction that evaluates to f alse against the current Subject will trigger the obfuscation of its associated field Secured annotation You can add a Secured annotation on any method parameter to automatically apply data security on it You can also apply the Secured annotation directly on the method to apply data security on the return value Secured public SecuredPojo1 securedMethod Secured SecuredPojo2 securedPojo2 Every method annotated with Secured or with the annotation applied to at least one of its parameters will be intercepted and the relevant objects will be secured Note that the usual interception limitations docs seed concepts dependency injection method interception apply callout warning Please note that the data security interceptor will inspect the whole object graph starting from the secured object so you may encounter some performance penalty depending on its size It shouldn t be a problem for typical use callout Security expressions Security expressions are strings that respect the Unified Expression Language UEL https uel java net syntax The following methods are available hasRole String role Returns true if the current subject has the specified role false otherwise hasOneRole String roles Returns true if the current subject has at least one of the specified roles false otherwise hasAllRoles String roles Returns true if the current subject has all the specified roles false otherwise hasRole String role String scopes Returns true if the current subject has the specified role for all the specified scopes false otherwise hasPermission String permission Returns true if the current subject has the specified permission false otherwise hasOnePermission String permissions Returns true if the current subject has at least one of the specified permissions false otherwise hasAllPermissions String permissions Returns true if the current subject has all the specified permissions false otherwise hasPermission String permission String scopes Returns true if the current subject has the specified permission on the specified scopes false otherwise Examples plain hasRole manager hasPermission salary view hasAllPermissions salary view salary update hasPermission users manage FR More resources on EL Oracle tutorial http docs oracle com javaee 6 tutorial doc gjddd html Unified Expression Language https uel java net DataObfuscationHandler The goal of a DataObfuscationHandler is to obfuscate data with a specific algorithm For instance it could take a name eg Doe and return an anonymised name D This would be implemented as follows This code DataObfuscationHandler takes a code String eg Doe and obfuscate it into D public static class NameObfuscationHandler implements DataObfuscationHandler Override public String obfuscate String data String result if data null data length 0 result data charAt 0 result result toUpperCase return result Custom annotations Custom restriction annotations can be defined and registered with data security by defining a DataSecurityHandler Start with defining a custom annotation Retention RetentionPolicy RUNTIME Target ElementType FIELD public interface MyRestriction String expression Todo todo default Todo Nullify public enum Todo Hide Round Nullify Then define a DataSecurityHandler which handles the MyRestriction annotation public class MyDataSecurityHandler implements DataSecurityHandler Override public Object securityExpression MyRestriction annotation return annotation expression Override public Class extends DataObfuscationHandler securityObfuscationHandler MyRestriction annotation if annotation todo equals Todo Round Uses the rounding obfuscation handler defined below return RoundingObfuscationHandler class if annotation todo equals Todo Hide Uses the name obfuscation handler defined in the previous section return NameObfuscationHandler class return null public static class RoundingObfuscationHandler implements DataObfuscationHandler Override public Integer obfuscate Integer data Integer result 0 if data null result int Math ceil data 1000 1000 return result Then you can apply the annotation on a POJO public class MyPojo private String firstName MyRestriction expression 1 2 todo Todo Hide private String name MyRestriction expression hasRole manager todo Todo Round private Integer salary MyRestriction expression false private String password public MyPojo String name String firstName String password Integer salary this name name this firstName firstName this password password this salary salary","summary":"Seed provides application security through a powerful security model, which is equally easy to configure and to enforce.\nIt takes charge of the following tasks:\n\nIdentification (provides the identity of a subject),Authentication (verifies the subject identity),Authorization (defines which roles and...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Seed manual","icon":"fa fa-book","path":"manual"}},{"title":"Testing","tags":["integration","unit","test","arquillian","web"],"href":"/docs/seed/manual/testing","content":"Seed offers various tools to facilitate the writing of your tests in the seed testing module notably a JUnit test runner for integration testing This runner handles kernel startup and shutdown as well as injection of test classes It can also detect and activate Seed test plugins which augment the test behavior For instance the Seed security test plugin can login a predefined user based on an annotation To use Seed testing tools add the seed testing module in your test classpath Supported test typologies Seed testing tools are based upon the popular JUnit http junit org testing framework Unit tests The purpose of unit tests is to take a small and testable part of a program isolate it from any dependency injection databases network file system by mocking them and check whether it behaves exactly as expected The main goal is to validate code quality and reliability Seed doesn t help much when writing unit tests beyond packaging a few high quality test libraries such as AssertJ http joel costigliola github io assertj or Mockito http mockito org Integration tests The purpose of integration tests is to pick multiple components together and test them as a whole Integration tests can range from a testing a simple operation involving two classes to an entire application setup with all its dependencies databases file system network Their main goal is to detect issues appearing when components interact with each other Integration tests can be used to validate technical behavior such as the correct operation of a group of components or can extend beyond to verify the global program behavior in regard to functional expectations In this latter case it is often useful to supplement Seed testing tools with a framework for Behavior Driven Development BDD like JBehave http jbehave org Simple integration tests When a Web container is not required you can simply use the JUnit runner on your test class Alternatively you can also extend the class public class MyComponentIT extends AbstractSeedIT Inject MyService myService Test public void my_service_is_injectable Assertions assertThat myService isNotNull In this example The test class itself is instantiated by Seed injector and benefit from dependency injection and AOP interception A different kernel is used for each test class All test methods within a test class are invoked in the context of its kernel After all test methods are completed the kernel is shutdown This behavior can be altered manually or automatically by test plugins callout tips Simple integration tests run faster than Web integration tests are simpler to maintain They should be preferred when Web testing is not necessary and be supplemented with the minimal amount of Web integration tests callout Altering kernel mode Testing with security Testing command line applications Web integration tests Seed provides an Arquillian http arquillian org integration for Web application testing These kind of integration tests allow to programmatically define the deployed Web archive WAR and test it either from server side or from client side You can use the runner directly on your test class Alternatively you can extend the class public class MyComponentIT extends AbstractSeedWebIT To specify the deployed artifact declare a public static method annotated with that returns a class public class RestIT extends AbstractSeedWebIT Inject MyService myService Deployment public static WebArchive createDeployment return ShrinkWrap create WebArchive class addAsResource my conf props META INF configuration my conf props Test public void my_service_is_injectable Assertions assertThat myService isNotNull RunAsClient Test public void my_rest_resource_is_working ArquillianResource URL baseURL expect statusCode 200 when get baseURL toString rest my resource In this example The test class itself is NOT instantiated by Seed injector and as such cannot benefit from AOP interception It benefits from dependency injection though The kernel is started via the Web application listener automatically registered no need for a web xml file although one can be specified A unique kernel is used for all test methods This behavior cannot be altered The first test method named my_service_is_injectable is a server side test It can test if injected dependencies like a service of the Web application here are working correctly The second test method named my_rest_resource_is_working is a client side test It is executed in a separate thread and can invoke the deployed Web application through the URL provided by the org jboss arquillian test api ArquillianResource annotated parameter callout info Apache Tomcat http tomcat apache org is the default test server configured You can override this choice by specifying a custom arquillian xml file at the root of the classpath Arquillian provides many more features than described in this section For more information about Arquillian visit the official website http arquillian org callout Maven settings It is often useful to separate integration tests and unit tests into different source folders If you use Maven your can do so by adding the following configuration to your project root pom xml src it resources src test resources org apache maven plugins maven failsafe plugin execute integration tests integration test integration test verify integration tests verify verify org codehaus mojo build helper maven plugin add it sources generate test sources add test source src it java","summary":"Seed offers various tools to facilitate the writing of your tests in the seed-testing module, notably a JUnit test runner\nfor integration testing. This runner handles kernel startup and shutdown as well as injection of test classes. It can also\ndetect and activate Seed test plugins which augment the...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Seed manual","icon":"fa fa-book","path":"manual"}},{"title":"Transactions","tags":["local","jta","propagation","rollback","commit","demarcation"],"href":"/docs/seed/manual/transactions","content":"Seed transaction management allows interactions between the application code and one or more external resource s to be done transactionally ie in an all or nothing paradigm It is used in conjunction with other supports handling external resources such as persistence or messaging For more detail about transactions refer to this wikipedia page http en wikipedia org wiki Transaction_processing Dependency To enable transactions in your project add the seed transaction module to your classpath Note that this dependency is rarely explicitly required as it is transitively provided by any transaction capable add on like JPA persistence JMS Transaction manager The transaction manager is responsible for detecting transaction boundaries in the application code and wrap them with an interceptor This interceptor will then automatically create commit or rollback and release a transaction when the transactional code is invoked The behavior of the transaction manager is heavily customizable depending on your business requirement Configuration A Seed application can have only one transaction manager The transaction manager is specified with following configuration property org seedstack seed transaction transaction manager fully qualified name of TransactionManagerClass Local transaction manager The local transaction manager manages transactions within the application It cannot handle global transactions managed by an external transaction monitor like a J2EE Web server and doesn t support spanning transactions over multiple resources However it is very lightweight and adequate for most common applications uses This is the default transaction manager org seedstack seed transaction transaction manager org seedstack seed transaction internal LocalTransactionManager JTA transaction manager The JTA transaction manager integrates code demarcated with Seed transactions with any external JTA compliant transaction monitor such as ones found in J2EE Web servers To use it just specify the following configuration property org seedstack seed transaction transaction manager org seedstack seed transaction internal JtaTransactionManager Some supports may need additional configuration to be able to participate in a JTA transaction Transaction metadata Transactions have several attributes that define their behavior and outcome Propagation determines if a new transaction should be started and or how an existing transaction should be handled if any Possible values are REQUIRED use existing transaction or create a new one if none exists It is the default value REQUIRES_NEW create a new transaction and suspend the previous one if any exists MANDATORY throw an exception if no existing transaction is found SUPPORTS execute code outside any transaction if no existing transaction is found NOT_SUPPORTED execute code outside any transaction and suspend the current transaction if one exists NEVER execute code outside any transaction and throw an exception if an existing transaction is found Rollback behavior is defined a list of exception classes triggering a rollback if thrown from transactional code default is java lang Exception a list of exception classes that will NOT trigger a rollback if thrown from transactional code default value is empty readOnly attribute determines if a transaction is read only or not rollbackOnParticipationFailure attribute determines if a participating method should mark the transaction as rollback only if an error occurs The transaction handler will interact with the transacted resource s Resource identifier is required when multiple resources are handled by the same transaction handler These attributes are called transaction metadata and default values can be overridden explicitly or by inferred values from transaction metadata resolvers The explicitly specified values always take precedence over the automatically inferred ones which in turn always take precedence over the default ones Demarcation via annotation Transaction metadata can be explicitly specified through annotation and associated annotations for each type of transactional resource These annotations can be placed on methods classes interfaces and other annotations The search for the annotation starts for all methods of any Seed managed class using the following order The method and any annotation on this method The declaring class and any annotation on this class Any superclass or interface up in the hierarchy with the following sub order for each class interface The overridden method and any annotation on this method The class interface and any annotation on this class If no annotation is found when the top of the class hierarchy is reached the method is not transactional and not intercepted at all Automatic metadata resolution Transaction metadata resolvers are means of automatically determining transaction metadata for a specific context A transaction metadata resolver must implement interface and provide a default constructor They are scanned and registered at application startup and queried in no predefined order at the beginning of method interception Since they are queried inside the transaction interceptor an explicit transaction demarcation has to be present in the first place They cannot add behavior to not demarcated code Resolving The resolve method is called on each resolver with the intercepted method as parameter Its return is Return is either an instance of with the inferred attributes set ot null when nothing can be inferred inferred attributes set Seed provides a built in always active resolver which automatically associate the transaction handler if only one is available In this case it is not necessary to explicitly specify the corresponding transaction handler Other Seed modules can register their own resolvers that will infer more transaction metadata for specific contexts For instance the JMS add on can automatically detect the transacted resource when the annotation is used inside a JMS listener More documentation is available in modules where this is applicable Remember that an explicitly specified annotation will always override any automatically resolved metadata Examples With an explicit JMS resource Transactional JmsConnection connection1 public void send String stringMessage throws JMSException Destination queue session createQueue queue1 TextMessage message1 session createTextMessage message1 setText stringMessage MessageProducer producer session createProducer queue producer send message1 With an explicit JPA resource Inject Item1Repository item1Repository Transactional JpaUnit unit1 public void save throws Exception Item1 item1 new Item1 item1 setName item1Name item1Repository save item1 With an implicit resource Inject Item1Repository item1Repository Transactional public void save throws Exception Item1 item1 new Item1 item1 setName item1Name item1Repository save item1 JPA resource is assumed since it is the only resource available JpaUnit is assumed since only one is defined","summary":"Seed transaction management allows interactions between the application code and one or more external resource(s) to be\ndone transactionally (ie. in an all-or-nothing paradigm). It is used in conjunction with other supports handling external \nresources such as persistence or messaging. For more...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Seed manual","icon":"fa fa-book","path":"manual"}},{"title":"Web","tags":["servlet","security","url","filter","static","resource","mime","cors","websocket"],"href":"/docs/seed/manual/web","content":"Seed has great support for Web applications whether by using its lightweight embedded Web server or in more classical environments when using an external Web application server Seed provides tight integration with the Java Servlet specification along with support for HTTP security WebSockets Cross Origin Resource Sharing CORS or advanced static resources serving To enable Web support in your project add the seed web core module to your classpath callout info When deploying a Seed application in a standalone Web container the required minimum Servlet compliance level is 2 5 though some features require a Servlet 3 0 compliance level All the features are available with the embedded Web server callout Security When running in a Servlet environment Web you might want to secure access to the application URLs by specifying filtering patterns To enable this feature add the seed web security module to your project This module depends upon the seed security core module A servlet filter is automatically added on and as such has the ability to intercept all application URLs You can then define its interception behavior by specifying a list or URL patterns with their associated chains of security filters URL patterns Declaring URL patterns for security interception is done in configuration by prefixing patterns with org seedstack seed security urls This can be easily done in a Props file by defining a section org seedstack seed security urls some path specific filter1 filter2 some path filter3 filter4 filter5 other path filter6 fallbackFilter The patterns at the left of the equal sign are Ant style path expressions https ant apache org manual dirtasks html patterns relative to your Web application s context root The order matters as the first pattern to match the incoming request is applied and subsequent patterns are ignored This allows to define a catch all default pattern at the end that will apply if no above filters matched When a pattern is matched the filters at the right of the equal sign are applied in sequence Filters Filters can be used for various task such as Authentication form basic Authorization verify some permission role Other security checks or tasks You can directly use built in filters or define custom ones Built in filters Various built in filters are directly available by specifying their names and eventual parameters in the filter chain anon immediately allows access to the path without performing security checks of any kind unless you add other filters after it in the chain authc authentifies the subject using the request params username and password This can be used for form authentication authcBasic triggers and checks a Basic authentication cert extracts the certificates found by the JEE server and provides them to a X509CertificateRealm You can specify the optional parameter to allow the request even if certificate authentication fails cert optional logout logouts the current Subject Note that it will clear the subject session and will invalidate the corresponding security caches Note that basic authentication credentials are kept by user agents like browsers meaning that authentication will automatically happen again during the next request noSessionCreation will prevent the creation of a security session perms checks for the permission specified as a parameter Only allows access if the current subject has the specified permission Multiple permissions can be specified with commas perms users delete cache invalidate for instance port requires the request to be on the specified port port 8080 for instance rest similar to the perms filter but appends a CRUD verb derived from the HTTP method to the specified permission s For instance rest users will check the following permissions depending on the HTTP verb DELETE checks for the users delete permission GET checks for the users read permission HEAD checks for the users read permission OPTIONS checks for the users read permission POST checks for the users create permission PUT checks for the users update permission TRACE checks for the users read permission roles checks that the subject has the specified role s Only allows access if current subject has all the specified roles Multiple roles can be specified with commas roles manager admin for instance ssl Only allows access if the request is on port 443 and ServletRequest isSecure returns true user Only allows access if the user is identified Custom filters You can define you own custom security filters by creating a class implementing and annotating it with The annotation value will define the name of the filter that can be used in filter chains As an example consider a filter that always returns HTTP response code 418 SecurityFilter teapot public class TeapotFilter implements Filter Override public void init FilterConfig filterConfig throws ServletException Override public void doFilter ServletRequest request ServletResponse response FilterChain chain throws IOException ServletException HttpServletResponse response sendError 418 Override public void destroy You can use it in filter chains like this ini org seedstack seed security urls teapot teapot When a subject access the teapot URL an HTTP response code 418 will be returned To create advanced security filters you can extend existing Shiro security filters or use them as models Example Consider the following example ini org seedstack seed security urls resources anon rest users ssl authcBasic rest users rest authcBasic roles normal authcBasic Note that Anything served under resource can be accessed anonymously The rest users resource can only be accessed by authenticated subjects in HTTPS with the users action permission where action is dependent upon the HTTP method used see the rest filter definition for details Anything served under rest can only be accessed by authenticated subjects with the normal application role All others URLs can only be accessed by authenticated subjects In this example authentication is handled with the Basic Authentication scheme Servlets and Filters You can register a servlet and its mappings automatically by annotating your servlet class with WebServlet value myservlet initParams WebInitParam name param value value name my servlet public class MyServlet extends HttpServlet Similarly you can register a filter and its mappings automatically by annotating your servlet class with WebFilter value myfilter initParams WebInitParam name param value value name my filter public class MyFilter extends HttpFilter Static resources Seed provides automatic static resource serving from the classpath and the document root with some benefits over the container default resource serving Automatic serving of pre minified and or pre gzipped versions of resources On the fly gzipping of resources Cache friendly Emulation of servlet 3 0 serving from classpath when not available callout info Static resource serving is enabled by default It has a low priority Docroot resources always have precedence over classpath resources If a file under document root leads to the same resulting path as in classpath then the document root file have priority like robots txt in above example callout Default behavior The default behavior is to serve resources located under the document root folder and if not found under the META INF resources classpath location on the path For example consider the following folder tree docroot index html robots txt META INF resources robots txt lib jquery js jquery min js jquery min js gz The default behavior is to serve index html robots txt and jquery js on the following paths robots txt index html lib jquery js The jquery js file will be served as a minified and gzipped version without the overhead of on the fly gzipping since a pre gzipped version is already available callout info Docroot resources always have precedence over classpath resources If a file under document root leads to the same resulting path as in classpath then the document root file have priority like robots txt in above example callout Configuration Resources are always served on with a low priority The default serving path can be altered For example org seedstack seed web resources path my custom resource path The serving paths then are updated by appending my custom resource path to the document root base path and the META INF resources classpath location thus serving from respective following paths docroot my custom resource path for document root based resources META INF resources my custom resource path for classpath based resources Note that specifying an empty resource path would mean that resources are served directly under the application context root In that case the webapp must be dedicated to serving web resources since it will not be able to register additional servlets will be reserved for web resources Minification and gzip support The file extension is determined from the requested URL as the characters sequence after the last dot of the hierarchical part For instance js extension would be retrieved from plain http myapplication resources lib jquery js If minification support is enabled and a file with a min prefixed extension is found then it is used instead of the originally requested file In below example the last file would be served plain resources lib jquery js resources lib jquery min js If gzip support is enabled and the browser accepts gzip encoding and a file with a gzip suffixed extension is found then it is used instead of the originally requested file or instead of the minified file determined in the previous step For instance in below example the last file would be served plain resources lib jquery js resources lib jquery min js resources lib jquery js gzip If no gzipped version has been found but on the fly gzip support is enabled the resource will be gzipped in memory for serving To control the minification and gzip behavior use the following properties org seedstack seed web resources minification support true false org seedstack seed web resources gzip support true false org seedstack seed web resources gzip on the fly true false MIME types The following MIME types are automatically derived from extensions Mime typeExtensions text htmlhtml htm HTML HTM text plaintxt text TXT TEXT text javascriptjs JS text csscss less CSS LESS image gifgif GIF image jpegjpeg jpg jpe JPEG JPG JPE image pngpng PNG image vnd microsoft iconico ICO application pdfpdf PDF application jsonjson JSON application font woffwoff WOFF application vnd ms fontobjecteot EOT font truetypettf TTF font opentypeotf OTF Caching Resource information is determined by calls to classloader getResource for classpath locations and by calls to File canRead for docroot locations The number of these calls per resource lookup can increase when Using multiple locations classpath or docroot based in which case the lookup logic is invoked for each location Using minification and gzip support in which case the lookup logic itself is more costly trying to find the resource in the following order gzipped minified version gzipped version minified version normal version A built in cache is used to improve the lookup performance of resources that were served at least one time You can alter the cache properties as follows below example with default values ini org seedstack seed web resources cache max size 8192 org seedstack seed web resources cache concurrency 32 org seedstack seed web resources cache initial size 2048 If you don t specify the initial size configuration property it will be set at max size 4 CORS Cross Origin Resource Sharing CORS is supported through a Java filter and can be enabled in any Seed application callout info Seed integrates the CORS filter from dzhuvinov software http software dzhuvinov com cors filter html There is no need to install and configure the filter manually it is automatically registered by Seed All filter options can be specified through configuration properties callout Configuration To enable CORS support just add the following configuration to your application ini org seedstack seed web cors enabled true Filter properties The CORS filter allows to alter its default behavior with various parameters The filter documentation enumerates all configuration parameters Seed can transform any configuration property prefixed with org seedstack seed web cors property to the corresponding filter parameter For instance to specify the recognized verbs you can use the following configuration ini org seedstack seed web cors property supportedMethods GET POST HEAD OPTIONS PUT DELETE This configuration property is automatically translated to the cors supportedMethods filter parameter found in the documentation Note that the escaping of the commas is required to inhibit Seed from parsing this value as a list callout info Please refer to this page of the filter documentation http software dzhuvinov com cors filter configuration html for a complete list of configuration parameters callout WebSockets Seed also integrates the Java API for WebSocket JSR 356 allowing server and client endpoints to be injected WebSocket support requires Java 7 to work Server endpoints No specific configuration is required for server endpoint Just declare a standard JSR 356 endpoint ServerEndpoint value chat public class ChatEndpoint Logging private Logger logger Inject EchoService echoService OnOpen public void onOpen Session session logger info Connected session getId OnMessage public void message String message Session client throws IOException EncodeException for Session peer client getOpenSessions peer getBasicRemote sendText echoService echo message OnClose public void onClose Session session CloseReason closeReason logger info String format Session s close because of s session getId closeReason OnError public void onError Session session Throwable t logger error t getMessage t In this example the endpoint receives a message and then broadcast it to all clients Client endpoints Unlike server endpoints client endpoints have to explicitly specify a SeedClientEndpointConfigurator in order to be managed by Seed ClientEndpoint configurator SeedClientEndpointConfigurator class public class ChatClientEndpoint1 public static final String TEXT Client1 joins public static CountDownLatch latch public static String response OnOpen public void onOpen Session session try session getBasicRemote sendText TEXT catch IOException ioe ioe printStackTrace OnMessage public void processMessage String message response message latch countDown Testing You can test WebSocket endpoints with Seed Web integration testing testing Here is an example which tests two client endpoints public class WebSocketIT extends AbstractSeedWebIT Logging private Logger logger Inject ChatClientEndpoint1 chatClientEndpoint1 Inject ChatClientEndpoint2 chatClientEndpoint2 Deployment public static WebArchive createDeployment return ShrinkWrap create WebArchive class setWebXML WEB INF web xml Test RunAsClient public void communication_is_working ArquillianResource URL baseUrl throws Exception ChatClientEndpoint1 latch new CountDownLatch 1 final Session session1 connectToServer baseUrl chatClientEndpoint1 assertNotNull session1 assertTrue ChatClientEndpoint1 latch await 2 TimeUnit SECONDS assertEquals echo ChatClientEndpoint1 TEXT ChatClientEndpoint1 response ChatClientEndpoint1 latch new CountDownLatch 1 ChatClientEndpoint2 latch new CountDownLatch 1 final Session session2 connectToServer baseUrl chatClientEndpoint2 assertNotNull session2 assertTrue ChatClientEndpoint1 latch await 2 TimeUnit SECONDS assertTrue ChatClientEndpoint2 latch await 2 TimeUnit SECONDS assertEquals echo ChatClientEndpoint2 TEXT ChatClientEndpoint1 response assertEquals echo ChatClientEndpoint2 TEXT ChatClientEndpoint2 response private Session connectToServer URL baseUrl Object endpoint try WebSocketContainer container ContainerProvider getWebSocketContainer URI uri new URI ws baseUrl getHost baseUrl getPort baseUrl getPath chat return container connectToServer endpoint uri catch Exception e logger error e getMessage e fail","summary":"Seed has great support for Web applications whether by using its lightweight embedded Web server or in more classical\nenvironments, when using an external Web application server. Seed provides tight integration with the Java Servlet \nspecification along with support for HTTP security, WebSockets...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Seed manual","icon":"fa fa-book","path":"manual"}},{"title":"Generate goal","tags":["maven","plugin","project","generation","archetype"],"href":"/docs/seed/maven-plugin/generate","content":"To create a SeedStack project from scratch you can use generate goal from the SeedStack Maven Plugin This goal is invoked from the command line Parameters Parameters should be given as system properties DparameterName parameterValue Name Type Mandatory Description groupId String Yes The group identifier of your generated project Required artifactId String Yes The artifact identifier of your generated project Required version String No The version of your generated project Defaults to 1 0 0 SNAPSHOT type String No Specifies the archetype type to use for project generation Needed if archetypeArtifactId is not specified explicitly No default value Available types are web rest domain and batch allowSnapshots Boolean No Allow to use archetype snapshots Defaults to false archetypeGroupId String No Allow to explicitly specify the archetype group identifier Defaults to com inetpsa fnd tools archetypeArtifactId String No Allow to explicitly specify the archetype artifact identifier Needed if type is not specified Defaults to seed type archetype archetypeVersion String No Allow to explicitly specify the archetype version Defaults to latest release version available or to the latest snapshot available if allowSnapshots is also specified Examples Interactive mode mvn org seedstack seedstack maven plugin generate Batch mode mvn org seedstack seedstack maven plugin generate DgroupId org myorganization DartifactId myproject Dtype web The type property can be any of the archetype names provided by the distribution i e web rest domain","summary":"To create a SeedStack project from scratch you can use generate goal from the SeedStack Maven Plugin.\nThis goal is invoked from the command line.\n\nParameters\n\nParameters should be given as system properties (-DparameterName=parameterValue):\n\n<table class="table table-striped table-bordered...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Maven plugin","icon":"fa fa-cogs","path":"maven-plugin"}},{"title":"Overview","tags":["maven","plugin"],"href":"/docs/seed/maven-plugin/","content":"The SeedStack Maven plugin provides goals to manage SeedStack based artifacts To invoke the plugin use the following command line mvn org seedstack seedstack maven plugin callout info Tip If you add or already have the groupId org seedstack in the list of your maven settings xml file you can use a shorter command mvn seedstack More information about Maven plugin prefix mapping here http maven apache org guides introduction introduction to plugin prefix mapping html callout","summary":"The SeedStack Maven plugin provides goals to manage SeedStack-based artifacts. To invoke the plugin, use the following \ncommand line:\n\nmvn org.seedstack:seedstack-maven-plugin:<goal>\n\n\nTip: If you add (or already have) the groupId org.seedstack in the <pluginGroups&gt...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Maven plugin","icon":"fa fa-cogs","path":"maven-plugin"}},{"title":"Package goal","tags":["capsule","packaging","jar","standalone","maven","plugin"],"href":"/docs/seed/maven-plugin/package","content":"The package goal packages any self executable SeedStack application in a Capsule http www capsule io A Capsule is a way of packaging and running any application with all its dependencies from a unique plain executable JAR callout info Self executable SeedStack application are applications that contains one and only one implementation of the interface in their classpath like the one provided by the seed cli module for command line application or the seed web undertow module for embedded Web applications callout Parameters Parameters should be given as system properties DparameterName parameterValue Name Type Mandatory Description capsuleVersion String No The capsule version to be used If not given the latest version discoverable is automatically used light No If this parameter is specified no value is necessary a lightweight Capsule will be built instead of a standalone one A lightweight Capsule will download its dependencies through Maven the first time it is run capsuleVersion String No The capsule version to be usedThe string of all arguments used to run the Seed application allowSnapshots No If specified the Capsule will allow SNAPSHOT dependencies to be used Examples Standalone Capsule A standalone Capsule packs all its dependencies and is completely self contained It is the default mode of operation To build such a Capsule use the following command mvn org seedstack seedstack maven plugin package Lightweight Capsule A lightweight Capsule rely on Maven to download its dependencies the first time it is run To build such a Capsule use the following command mvn org seedstack seedstack maven plugin package Dlight callout warning Note that you will need a fully configured Maven environment on the machine you want to the run a lightweight Capsule on It is NOT recommended for production environment as it introduce a potential variability at execution time should a dependency contents change for instance callout Running a capsule To run a capsule you simply execute it as a plain executable JAR java jvm args jar my capsule jar args You can specify any argument to the JVM or to the program as usual callout tips A lot of options can be specified to alter the default behavior of the Capsule itself Please refer to the Capsule user guide http www capsule io user guide for more information callout","summary":"The package goal packages any self-executable SeedStack application in a Capsule.\nA Capsule is a way of packaging and running any application with all its dependencies from a unique plain executable JAR.\n\n\nSelf-executable SeedStack application are applications that contains one...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Maven plugin","icon":"fa fa-cogs","path":"maven-plugin"}},{"title":"Run goal","tags":["maven","plugin","running","executable"],"href":"/docs/seed/maven-plugin/run","content":"The run goal runs any self executable SeedStack application directly from the command line callout info Self executable SeedStack application are applications that contains one and only one implementation of the interface in their classpath like the one provided by the seed cli module for command line application or the seed web undertow module for embedded Web applications callout Parameters Parameters should be given as system properties DparameterName parameterValue Name Type Mandatory Description args String No The string of all arguments used to run the Seed application Required Examples Web application By running the following command on a SeedStack application containing the seed web undertow dependency like the catalog micro service sample https github com seedstack catalog microservice sample you will startup the application with its embedded Undertow Web server http undertow io mvn org seedstack seedstack maven plugin run CLI application By running the following command on a SeedStack application containing the seed cli dependency like the batch sample https github com seedstack samples tree master batch you will startup the application with the corresponding arguments mvn seedstack run Dargs run job job helloWorldJob callout info Note that a SeedStack CLI application needs at least one in the classpath which name must be specified as an argument In this example we assume that the SeedStack Spring bridge add on http seedstack org addons spring bridge batch run job command line handler is also present in the classpath callout","summary":"The run goal runs any self-executable SeedStack application directly from the command line.\n\n\nSelf-executable SeedStack application are applications that contains one and only one implementation of the \ninterface...","zone":{"path":"/docs/seed","label":"Java framework","logo":"seed-logo.svg"},"section":{"label":"Maven plugin","icon":"fa fa-cogs","path":"maven-plugin"}},{"title":"Introduction","tags":["masterpage","configuration","fragment","manifest","index"],"href":"/docs/w20/","content":"W20 is a web solution designed to allow developers to quickly and simply create enterprise grade Single Page Application SPA It is server agnostic which means it can work with any HTTP capable server technology In fact it can even work without any server Benefits W20 provides a modular programming model for web applications allowing entire parts of web frontend to be reused across applications These parts are called fragments and can be published on any HTTP server as static resources Creating a frontend application with W20 becomes as easy as choosing the fragments you want to load and how you want them to be configured from a single configuration file In fact W20 itself is distributed as several fragments which are aside from its core all optional Organization of an application A W20 application is a Single Page Application SPA composed of A master page usually index html but can be dynamically generated It is the entry point of the application A configuration file usually w20 app json but can be dynamically generated One or more fragment s A fragment is a bundle of web resources described by a JSON manifest which must be accessible by HTTP from the browser docroot index html w20 app json fragments fragment1 fragment1 w20 json fragment2 fragment2 w20 json The master page A single page application is a web application that fits on a single web page called the master page usually index html Assuming you keep your static resources in a bower_components directory a sample code of a minimalist master page in W20 would be Application title Things worth noticing The data w20 app attribute on the html tag that will load the configuration of your W20 application The tag where we reference RequireJS http requirejs org and instruct it to load W20 A W20 application is also an AngularJS http angularjs org application Therefore you should add a tag with the data ng view attribute This will include rendered templates into the master page The configuration file The configuration file w20 app json is where you set up your application As mentioned earlier a W20 application is basically composed of a set of fragments a fragment is a bundle of web resources All are optional except one the core fragment of W20 thus it has to be referenced in the w20 app json This is done by specifying the path to its configuration file _a k a_ the fragment manifest bower_components w20 w20 core w20 json The fragments An important concept in W20 is the fragment A W20 application is composed of one or more fragment s A fragment is a bundle of web resources templates css javascript Each one is intended to serve a purpose and can be reused across applications For example W20 provides an optional fragment with native AngularJS implementations of UI components such as _datagrid_ and _combo boxes_ Fragment manifest To reference web resources and how they are to be configured each fragment has its own manifest file located at the root of the fragment The only mandatory property is the fragment unique identifier id fragment identifier By convention the manifest file is called after the fragment identifier and suffixed by w20 json In this example the fragment manifest would be fragment identifier w20 json Fragment modules Now suppose we want to use the fragment discussed above but only the _datagrid_ component For that W20 offers a finer granularity to configure your application Within a single fragment there can be several units called modules which are loaded only if you decide to reference them in your application configuration That way you can load a fragment without being forced to load all of its resources The sample code below shows how to declare a fragment module id fragment identifier modules module1 path fragment identifier modules module1 autoload true false configSchema Things worth noticing fragment identifier is used by W20 as a placeholder to target the fragment path This ensures paths are always relative to the fragment manifest location It is particularly useful if the fragment is intended to be used across applications The path attribute is mandatory for RequireJS to load the module when it is required by the application Fragments modules are AMD compliant http requirejs org docs whyamd html amd If a configuration JSON schema is provided for a specific module in the fragment manifest the configuration specified here will be validated against it How it works The master page is the one and only entry point of your web application By adding the following tag in it two things happen 1 RequireJS is loaded 2 Once RequireJS is loaded it loads bower_components w20 modules w20 js notice there is no extension in the when pointing to the w20 js 3 w20 js is the core implementation of W20 Once loaded it will automatically parse your application configuration file w20 app json to detect which fragments to load detect which modules to load for each fragment validate configuration for each fragment and module w20 app json against its schema fragment identifier w20 json load AMD modules using RequireJS load the home view from the application module of the W20 core fragment into the master page Start a new project Thanks to the W20 application generator provided by Seedstack you can have a running web application in minutes The following steps will guide you through the process 1 Install Node js https nodejs org which bundles npm https www npmjs com 2 Install Yeoman http yeoman io Bower http bower io Grunt http gruntjs com globally using npm npm install g yo bower grunt cli 3 Install the generator w20 npm install g generator w20 4 Create a directory for your project cd into it and launch the generator with Yeoman yo w20 5 Choose among W20 optional fragments which ones you want to use 6 Run your static server with Grunt grunt connect 7 Open your application in a web browser and that s it Next start reading the manual","summary":"W20 is a web solution designed to allow developers to quickly and simply create enterprise-grade Single Page\nApplication (SPA). It is server agnostic which means it can work with any HTTP capable server technology. In fact,\nit can even work without any server.\n\nBenefits\n\nW20 provides a modular...","zone":{"path":"/docs/w20","label":"Web framework","logo":"w20-logo.svg"},"section":{"label":"Introduction","icon":"fa fa-file-text","path":""}},{"title":"Culture","tags":["i18n","locale","date","time","format","localization","internationalization","culture"],"href":"/docs/w20/manual/culture","content":"W20 provides an extensive culture support through the jQuery Globalize library It provides the developer tools to internationalize a W20 application which can then be localized via fragment manifests As AngularJS also provides internalization support W20 attempts to convert the active Globalize culture definition to an AngularJS locale on a best effort basis This automatic conversion has limits so it is recommended to stick to the W20 functions and services for internationalization Cultures Cultures are defined as a combination of the language and the country speaking it Each culture is given a unique code that is a combination of an ISO 639 two letter lowercase culture code for the language and a two letter uppercase code for the country or region For example en US is the culture code for English in the United States Only one culture can be active at a time in the application but you can format values in any culture supported by the application without switching the active one This module handles Textual internationalization Date and time formatting Currency formatting Number formatting W20 supports about 350 cultures but can also be extended to custom defined ones Here is the list of out of the box supported cultures Supported cultures af ZA af am ET am ar AE ar BH ar DZ ar EG ar IQ ar JO ar KW ar LB ar LY ar MA ar OM ar QA ar SA ar SY ar TN ar YE ar arn CL arn as IN as az Cyrl AZ az Cyrl az Latn AZ az Latn az ba RU ba be BY be bg BG bg bn BD bn IN bn bo CN bo br FR br bs Cyrl BA bs Cyrl bs Latn BA bs Latn bs ca ES ca co FR co cs CZ cs cy GB cy da DK da de AT de CH de DE de LI de LU de dsb DE dsb dv MV dv el GR el en 029 en AU en BZ en CA en GB en IE en IN en JM en MY en NZ en PH en SG en TT en US en ZA en ZW es AR es BO es CL es CO es CR es DO es EC es ES es GT es HN es MX es NI es PA es PE es PR es PY es SV es US es UY es VE es et EE et eu ES eu fa IR fa fi FI fi fil PH fil fo FO fo fr BE fr CA fr CH fr FR fr LU fr MC fr fy NL fy ga IE ga gd GB gd gl ES gl gsw FR gsw gu IN gu ha Latn NG ha Latn ha he IL he hi IN hi hr BA hr HR hr hsb DE hsb hu HU hu hy AM hy id ID id ig NG ig ii CN ii is IS is it CH it IT it iu Cans CA iu Cans iu Latn CA iu Latn iu ja JP ja ka GE ka kk KZ kk kl GL kl km KH km kn IN kn ko KR ko kok IN kok ky KG ky lb LU lb lo LA lo lt LT lt lv LV lv mi NZ mi mk MK mk ml IN ml mn Cyrl mn MN mn Mong CN mn Mong mn moh CA moh mr IN mr ms BN ms MY ms mt MT mt nb NO nb ne NP ne nl BE nl NL nl nn NO nn no nso ZA nso oc FR oc or IN or pa IN pa pl PL pl prs AF prs ps AF ps pt BR pt PT pt qut GT qut quz BO quz EC quz PE quz rm CH rm ro RO ro ru RU ru rw RW rw sa IN sa sah RU sah se FI se NO se SE se si LK si sk SK sk sl SI sl sma NO sma SE sma smj NO smj SE smj smn FI smn sms FI sms sq AL sq sr Cyrl BA sr Cyrl CS sr Cyrl ME sr Cyrl RS sr Cyrl sr Latn BA sr Latn CS sr Latn ME sr Latn RS sr Latn sr sv FI sv SE sv sw KE sw syr SY syr ta IN ta te IN te tg Cyrl TJ tg Cyrl tg th TH th tk TM tk tn ZA tn tr TR tr tt RU tt tzm Latn DZ tzm Latn tzm ug CN ug uk UA uk ur PK ur uz Cyrl UZ uz Cyrl uz Latn UZ uz Latn uz vi VN vi wo SN wo xh ZA xh yo NG yo zh CHS zh CHT zh CN zh Hans zh Hant zh HK zh MO zh SG zh TW zh zu ZA zu Configuration The culture module of w20 core can be configured with the following attribute available array of string which list the available culture in the application default string which is the culture name of the default culture It defaults to en Example path w20 core w20 json culture available en fr default en Fragment declaration The i18n section of a fragment manifest allows to declare culture localization bundles i18n rest i18n bundle language en i18n en bundle 1 json i18n en bundle 2 json fr FR i18n fr FR bundle 1 json i18n fr FR bundle 1 json Bundles modules will be loaded as a text dependency and parsed as JSON The empty string culture code can be used to point to remote bundle In that case two placeholders can be used in the URL The language placeholder will be replaced by the actual language code The culture placeholder will be replaced by the actual culture code Dynamic bundles will always be loaded for any language If no keys are available for a particular language an empty object can be returned Formatting Numbers and dates can be formatted in various ways by using formatting patterns Number formatting When formatting a number the main purpose is to convert the number into a human readable string using the culture s standard grouping and decimal rules The rules between cultures can vary a lot For example in some cultures the grouping of numbers is done unevenly In the te IN culture Telugu in India groups have 3 digits and then 2 digits The number 1000000 one million is written as 10 00 000 Some cultures do not group numbers at all There are four main types of number formatting n for number d for decimal digits p for percentage c for currency Even within the same culture the formatting rules can vary between these four types of numbers For example the expected number of decimal places may differ from the number format to the currency format Each format token may also be followed by a number The number determines how many decimal places to display for all the format types except decimal for which it means the minimum number of digits to display zero padding it if necessary Also note that the way negative numbers are represented in each culture can vary such as what the negative sign is and whether the negative sign appears before or after the number This is especially apparent with currency formatting where many cultures use parentheses instead of a negative sign For instance in the en US culture 123 45 formatted with n will give 123 45 123 45 formatted with n0 will give 123 123 45 formatted with n1 will give 123 5 123 45 formatted with d will give 123 12 formatted with d3 will give 012 123 45 formatted with c will give 123 45 123 45 formatted with c0 will give 123 123 45 formatted with c1 will give 123 5 123 45 formatted with c will give 123 45 0 12345 formatted with p will give 12 35 0 12345 formatted with p0 will give 12 0 12345 formatted with p4 will give 12 3450 Parsing also accepts any of these formats Date formatting Date formatting varies wildly by culture not just in the spelling of month and day names and the date separator but by the expected order of the various date components whether to use a 12 or 24 hour clock and how months and days are abbreviated Many cultures even include genitive month names which are different from the typical names and are used only in certain cases Also each culture has a set of standard or typical formats For example in en US when displaying a date in its fullest form it looks like Saturday November 05 1955 Note the non abbreviated day and month name the zero padded date and four digit year Format Meaning en US f Long Date Short Time dddd MMMM dd yyyy h mm tt F Long Date Long Time dddd MMMM dd yyyy h mm ss tt t Short Time h mm tt T Long Time h mm ss tt d Short Date M d yyyy D Long Date dddd MMMM dd yyyy Y Month Year MMMM yyyy M Month Day MMMM dd In addition to these standard formats there is the S format This is a sortable format that is identical in every culture yyyy MM dd T HH mm ss When more specific control is needed over the formatting you may use any format you wish by specifying the following custom tokens Token Meaning Example d Day of month no leading zero 5 dd Day of month leading zero 05 ddd Day name abbreviated Sat dddd Day name full Saturday M Month of year no leading zero 9 MM Month of year leading zero 09 MMM Month name abbreviated Sep MMMM Month name full September yy Year two digits 55 yyyy Year four digits 1955 literal Literal Text of the clock Single Quote o clock m Minutes no leading zero 9 mm Minutes leading zero 09 h Hours 12 hour time no leading zero 6 hh Hours 12 hour time leading zero 06 H Hours 24 hour time no leading zero 5 5am 15 3pm HH Hours 24 hour time leading zero 05 5am 15 3pm s Seconds no leading zero 9 ss Seconds leading zero 09 f Deciseconds 1 ff Centiseconds 11 fff Milliseconds 111 t AM PM indicator first letter A or P tt AM PM indicator full AM or PM z Timezone offset hours only no leading zero 8 zz Timezone offset hours only leading zero 08 zzz Timezone offset full hours minutes 08 00 g or gg Era name A D","summary":"W20 provides an extensive culture support through the jQuery Globalize library. It provides the developer tools to \ninternationalize a W20 application which can then be localized via fragment manifests. As AngularJS\nalso provides internalization support, W20 attempts to convert the active Globalize...","zone":{"path":"/docs/w20","label":"Web framework","logo":"w20-logo.svg"},"section":{"label":"W20 manual","icon":"fa fa-book","path":"manual"}},{"title":"Hypermedia","tags":["hypermedia","rest","link","api","resource","json"],"href":"/docs/w20/manual/hypermedia","content":"Hypermedia is a powerful aspect of the REST architectural style A client application can consume and navigate through REST resources via structured links relations Navigation through APIs resemble web navigation from a web page it is possible to follow links to new documents In the same way hypermedia provides a mechanism to interact with remote data with navigation and discovery in mind For an overview of this concept please refer to the documentation of the Java framework Restful API docs seed manual rest designing restful api Hypermedia module To enable the hypermedia module declare it in the core fragment configuration json hypermedia Available configuration for this module is provided below along with short introductions to the hypermedia formats supported JSON HOME The MIME type application json home http tools ietf org html draft nottingham json home 03 specify a document map of resources that can serve as entry points for clients into an hypermedia api Json home sample catalog and product json resources catalog href api products product href template api product name href vars name api doc param name In this scenario a client can enter a commercial api by requesting the json home document which will provide it with two relations catalog with an URI defined in the href property which when queried could for instance return a list of available products in the catalog product with an URI template https tools ietf org html rfc6570 defined in the href template property which uses the name of a product as a criteria for the query Note that since we are using an URI template the property is href template instead of href Now how should this parameter be used Whether by implicit knowledge or through documentation for parameters that can be provided in a href vars property This allows client to discover the usability of an api by querying the URL at this location More information can be provided in a json home document such as hints for available actions on the resource and or accepted format We advice you to take a look at the specification for an exhaustive documentation of the json home document type Configuring Json home endpoints In your hypermedia module declaration of the core fragment specify the api endpoint which exposes your json home resources with the api property json api myFirstApi http domain port mySecondApi You can specify a full absolute url starting with the http https protocol or an absolute url starting with In the last case the domain and port from which the application is served will be used as the hostname of the api Using aliases You can use alias for your api endpoint to refer to a previously declared api json api namedAlias http domain port myApi namedAlias There is one default alias home which resolve to json api home home HomeService The HomeService allows you to interact with the declared api endpoint s All endpoint declared in the manifest are automatically registered To access an api use the following declaration js homeService is the property used to reference the api URL The service has 3 methods enter api parameters actions options Provide a modified resource object configured from a registered home resource It signature is the same as the resource service of AngularJS but instead of providing a url as the first parameter you provide the name of the wanted relation provided in the Json home document Another important difference is that only the get method is available by default on the returned object since it is used only for retrieving entry point resources js homeService myApi enter catalog get function products register jsonHomeResource Programmatically register a new resource The resource should respect the format for a Json home document resource js homeService myApi register someNewResource href some url getDefinition resourceNAme Return the definition of the resource js homeService myApi getDefinition someNewResource href some url HAL Hypertext Application Language W20 provide support for application hal json http stateless co hal_specification html resources If Json home document constitute a map of the available entry points to the api HAL is the format for these entry points and any subsequent resources obtained by following the links provided in these resources Check the example below HAL sample querying products json currentPage 1 totalProduct 20 _links self href api products page 1 next href api products page 2 find href api products q templated true _embedded products name myProduct _links self href api product myProduct _embedded related name productRelatedToMyProduct _links self href api product myProduct related HAL document must validate against the JSON specification and contains two important recognizable fields _links which is mandatory and must contain at the very least a self property which reference the resource itself Additional links constitute the actual power of hypermedia they provide additional resources in the form of named actions resources In this example two actions are available going to the next page by following the next links or finding a product through the find links This last one uses URI template to define the available query parameter _embedded is not mandatory but allow to provide embedded resources directly in the response In this example we embedded a list of products with one element Each embedded resources respect itself the HAL specification so it must contain a _links with a reference to itself and optional embedded resources Usage When a resource is served with the application hal json MIME type the hypermedia module will intercept the response and return a resource object augmented with two additional methods links link parameters actions options This method has the same signature as resource but will use the name of the links instead of the url Suppose we return the HAL document above when querying the catalog api We can get the next page by following the next link js homeService myApi enter catalog get function products var nextProductPage products links next get If the links method is called without parameter it returns a list of the available links on the resource embedded name If the resource contains embedded items they can be accessed with this method Suppose we return the HAL document above when querying the catalog api We can get the embedded items with the following declaration js homeService myApi enter catalog get function products var embeddedProducts products embedded products console info embeddedProducts name myProduct var relatedProducts embeddedProducts embedded related 0 links self get the last line will GET api product myProduct related Note Although we used the HomeService in these example to start querying the api it is not an obligation Provided that a resource is served with the MIME type application hal json we could have used a simple resource object to start querying the api with a url Manual interception By default if the hypermedia module is configured and a resource is served with the MIME type application hal json the response will automatically be intercepted and processed according to what we said above If you want to disable this behavior and intercept response manually you need to set the interceptAll property to false in the hypermedia module configuration json hypermedia interceptAll false To do a manual interception you then need to inject the HypermediaRestAdapter and use it as follow js HypermediaRestAdapter process response data then function processedResponse Additional configuration json hypermedia api key value pair of api endpoint name and url interceptAll true default Intercept all hal json response automatically linksKey _links default Rename the links key linksHrefKey href default Rename the href key linksSelfLinkName self default Rename self link embeddedKey _embedded default Rename embedded key embeddedNewKey embedded default Rename the embedded function resourcesKey links default Rename the links function","summary":"Hypermedia is a powerful aspect of the REST architectural style. A client application can consume and navigate through \nREST resources via structured links relations. Navigation through APIs resemble web navigation: from a web page it is \npossible to follow links to new documents. In the same way...","zone":{"path":"/docs/w20","label":"Web framework","logo":"w20-logo.svg"},"section":{"label":"W20 manual","icon":"fa fa-book","path":"manual"}},{"title":"Basics","tags":["configuration","fragment","manifest","lifecycle","module","startup","angular"],"href":"/docs/w20/manual/","content":"This manual will provide you with a deeper understanding of the fundamentals of W20 Fragments and configuration W20 and its applications are organized around the idea of fragments What is a fragment A W20 application is made of several fragments that brings different concerns to the application A fragment is a collection of web resources JavaScript AMD modules http en wikipedia org wiki Asynchronous_module_definition stylesheets HTML templates that often but not necessarily depends on each other The dependency between modules inside a fragment is orchestrated by the use of the RequireJS http requirejs org library Think of a fragment as a coherent set of resources linked together for the purpose of organization and reusability By including and configuring a fragment you can bring the corresponding aspect and or asset to your web application without having to worry about the intrinsic details of the fragment itself Inside a fragment the module dependency system guarantees that the dependencies of a module will be loaded before the module itself This is especially important for large applications that often require an important number of JavaScript modules Fragments vs modules When we talk about a module we refer to a JavaScript AMD module as used in the RequireJS library That is to say thing shortly a js file whose content is wrapped in a define call AMD modules are explained in greater detail further down A fragment on the other hand is a collection of modules It is described by a manifest which exposes configuration properties When you include and configure a fragment in your application you can generally choose which modules to activate inside of it Fragment manifest Each fragment contains a JSON manifest that serves as a descriptor for the fragment configuration possibilities The fragment manifest has two main goals 1 To expose the available modules of the fragment and their available configuration options It is important to understand that the fragment manifest does not configure the fragment It exposes what configuration will be possible according to a configuration schema In the next section we will see how to actually configure the fragment when you declare it inside your application manifest 2 To allow the declaration of additional RequireJS configuration On application start each RequireJS configuration of each fragments if present are merged together The properties of a fragment manifest are id a mandatory string with no space which identifies the fragment No fragment with the same id can be included at the same time in an application name an optional name for the fragment description an optional description of the fragment requireConfig an optional object with the properties of a RequireJS configuration object In the example below we add a simple RequireJS configuration for module mapping this allow to map a module to a name which can be used for creating aliases or for module substitution For an exhaustive list and description of the RequireJS configuration options please have a look at its API http requirejs org docs api html Remember that this configuration will be merged with all the other declared fragment configuration on application start id demo fragment requireConfig map mappedModule path to module to map modules an optional object whose keys are the name of the exposed modules of the fragment The value of those keys is an object with the module path and the configuration schema The configuration schema contains the name of the configuration properties available for the module In the example below we expose a module demoModule inside a fragment with id demo fragment and a configuration property named demoConfig of type string for the module demoModule id demo fragment modules demoModule path demo fragment modules demoModule autoload true configSchema title Demo module configuration type object additionalProperties false properties demoConfig description A description of the demoConfig property type string There is a few additional things to note in this last example In the path property we used the fragment id enclosed in curly braces demo fragment This alias is automatically registered based on the fragment id and points to the location of the fragment manifest it is a RequireJS mapping You can and should for reusability consideration use this alias in all other fragments and in the application to refer to the fragment location The autoload attribute specify if the module should be loaded automatically or only if required by another module By required by another module we refer to the AMD definition and the dependency management between modules as used in RequireJS through the use of a define or require call If not specified the module will not be autoloaded The type property of the demoConfig option has been specified as a string This means that when the property will be given its value in the application manifest passing a type other than a string will raise an error The other type available are object array boolean and number The additionalProperties property of the configuration schema specify if additional properties can be given when configuring this module in the application manifest In this example trying to configure any other property than a demoConfig one for this module in the application manifest will raise an error callout info The configuration schema is optional You can simply declare the module along with its path and eventually ask for it to be autoloaded false if not specified This is often the case when you simply want to include a module that has no particular configuration in your business fragment callout W20 is packaged and distributed as multiple fragments Your application will then be composed of those fragments and your own business fragments Now that we have a better understanding of the notion of fragment we can proceed to the configuration step in which we actually include and configure those fragments in our application Configuration Application configuration happens in an application manifest This manifest must be named w20 app json because in the absence of a remote manifest the framework will fall back to looking for a JSON file with this name at the application root The role of the application manifest is to reference fragments through their manifest URL and configure them specifically for the application Fragment declaration To include a fragment in your application specify the path of the fragment manifest as a key bower_components w20 w20 core w20 json The w20 core fragment will be loaded with all its modules whose autoload property is set to true An alias w20 core is now pointing to bower_components w20 the location of the fragment manifest callout info bower_components is the default name of the folder in which Bower http bower io installs the web dependencies Bower is one of the most popular package manager for web application It should be installed to ease application development and or use the w20 application generator W20 fragments are available in the Bower registry http bower io search q w20 and will be installed to the bower_components folder if you choose this way of installation callout Fragment configuration Declaring a fragment like above can sometimes be enough Autoloaded modules will be available and that may be sufficient However most of the time you will configure the fragment s modules according to your need or because an explicit configuration value is required To configure the modules of the fragment add a modules section bower_components w20 w20 core w20 json modules application id my app In the above configuration the application module of w20 core will be configured with the corresponding object defining the unique identifier of the application in this case This module is normally defined as automatically loaded so this definition will only serve to configure it To load a module that is not automatically loaded without configuration just specify it with an empty object bower_components w20 w20 core w20 json modules application id my app bower_components other fragment other fragment w20 json modules my module In the example above my module will be loaded without any configuration If it was not declared and the module was not set to be autoloaded my module would not be loaded on application start even if it belongs to the other fragment fragment callout info If a configuration JSON schema is provided for a specific module in the fragment manifest the configuration specified here will be validated against it Also if a default configuration is provided for a specific module in the fragment manifest the configuration specified here will be merged with it overriding it If no default configuration is provided the configuration is provided as is to the module callout Summary fragments overview img fragments png Masterpage W20 uses AngularJS https angularjs org as a core framework for application development Thus its applications are Single Page Application SPA https en wikipedia org wiki Single page_application Only one HTML page is served with an outermost html doctype and a root tag This page is called the masterpage The masterpage serves two roles 1 Instruct the browser to load the RequireJS library with the w20 loader as the main module The w20 loader is a module of the core fragment and referenced in the main attribute of the script which loads RequireJS and who will take care of bootstrapping the application A w20 app attribute is mandatory on the root element of the masterpage Application loading is explained in further details in the following section 2 Declare the unique ng view element of the application which will include view templates View change is handled through client side routing which associates an URL to a template This template is rendered in the ng view tag Application title callout info You can notice that HTML attributes that are not part of the HTML specification such as w20 app or ng view are prefixed with data This allow to keep templates valid against HTML validator by defining those attributes as custom attributes https developer mozilla org en US docs Web HTML Global_attributes data callout callout warning Note that the w20 module is referenced without the js extension It is a common mistake to include the js extension while referring to module but this is not accepted by RequireJS The module file name is w20 js but it must be referenced by w20 only callout Additional configuration can be provided The w20 app attribute can be provided with the URL of the application manifest as the value In that case a request is made for retrieving the remote configuration Without any value provided the w20 loader will look for a w20 app json at the same level as the masterpage The w20 app version attribute when provided a value will append this value as an extra query string to URLs of resources This is useful for cache busting The w20 timeout attribute specify the number of seconds to wait before giving up on loading a script Setting it to 0 disables the timeout The default if not specified is 7 seconds The w20 cors with credentials attribute accept a boolean that specify if whether or not cross site Access Control requests should be made using credentials such as cookies or authorization headers By default the value is false Core fragment The core fragment of W20 is the most important fragment of the framework and the only one that is mandatory It provides the fundamental aspect of the framework mainly An AMD http en wikipedia org wiki Asynchronous_module_definition infrastructure through RequireJS http requirejs org An MVC runtime through AngularJS https angularjs org Application loading and initialization through the w20 module referenced in the masterpage A permission model which enables to reflect backend security Extensive culture support Support for HATEOAS No CSS framework is provided in the core fragment to let you free of this choice However you can simply add an appropriate fragment of W20 to bring frameworks such as Twitter Bootstrap http getbootstrap com w20 bootstrap 3 or Angular Material https material angularjs org latest w20 material For additional information please consult the UI http seedstack org docs w20 manual ui section The rest of this manual will focus mainly on the core fragment Additional fragments documentation can be found in the corresponding section of the documentation The core fragment provides the w20 module which is responsible for application initialization Let s look at how a W20 application load itself Application loading Once RequireJS is loaded the w20 module becomes the entry point of a W20 application as the main module Think of it as a fragment loader Its initialization sequence is as follow 1 Loading and parsing of the application configuration w20 app json or remote configuration 2 Loading and parsing of all the declared fragment manifests 3 Computing of a global RequireJS configuration along with the list of all modules to load 4 Loading of all modules needed at startup time at once 5 Initialization of each loaded modules through their lifecycle callbacks pre run post The last phase should be a little bit unclear at this point because we did not introduce modules lifecycle yet We included it here to give you the full initialization sequence for future reference Modules are documented in the next section Modules AMD JavaScript logic in W20 are defined in AMD modules An AMD module is defined using the global function define exposed by RequireJS AMD module can be named but it is strongly recommended that you use anonymous AMD modules each one living in its own JavaScript file They have the following form define 1 list of the dependencies of this module function 2 list of injected dependencies in the same order as 1 3 module factory function body private scope of the module return 4 public signature of the module that can be injected when requested as a dependency of another module Let us expand a little bit on each part of this module definition 1 The list of dependencies is composed of path to dependencies of this module which are often themselves AMD modules The path can be an absolute path or a map key if a RequireJS mapping has been defined Remember that fragments manifest location are automatically aliased by their fragment id enclosed in curly braces This means that you can reference a W20 fragment or your own one as a dependency like this define w20 core modules application your fragment modules your module Please note that modules are referenced without their js extension callout info Third party libraries location are also aliased For instance AngularJS distribution location is aliased by angular This means that you can reference a dependency to angular js with angular angular callout 2 The last parameter to the define function is the factory function Its parameters are the public value returned by the dependencies defined in 1 in the same order That is if we take the example above the public value of the application module as first argument and the public value of your module as second argument 3 The body of the factory function constitute the private part of the module This part is not available to other modules 4 The return value of a module is the public part it exposes to the world The value of this return will be what will be injected in other modules factory function if that module is a dependency of them define w20 core modules application yourFragment modules yourModule function applicationPublic yourModulePublic var privateValue I am a private string return publicValue I am a public string Now if we suppose the module above to be named demo js inside a fragment with id example if this module is defined as a dependency of another the last one can access the publicValue property of the object define example modules demo function demo console info demo publicValue I am a public string Module configuration To access the configuration of a module it needs to depend on the module module This special module is used to retrieve the module id its location and the value of its configuration options those declared in the application manifest If we suppose a module sample with the following configuration some fragment path some fragment w20 json modules sample prop Value of property one The configuration is retrieved inside the sample module like this define module function module var config module module config console log config prop Value of property The statement module module config is the idiomatic way of safely retrieving the module configuration Lifecycle callbacks In the Application loading section we have seen that the initialization sequence ended with each loaded modules going through their lifecycle callbacks Actually this is only the case for modules that declares lifecycle callbacks If a module does not declare any lifecycle callback then it is simply loaded Lifecycle callbacks happens when all fragments have been collected and the RequireJS configuration has been merged There are 3 lifecycle callbacks which runs in the order pre run and post All of them are optional It is guaranteed that every modules will run their pre callback before any other modules run their run callback It is guaranteed that every modules will run their run callback before any other modules run their post callback A module dependency will have its callback called before the module requiring it To integrate a module into the lifecycle management of the application you must add the following code to the public signature of the module i e the return value of the factory function return lifecycle pre function modules fragments callback run function modules fragments callback post function modules fragments callback You can omit the unsupported callbacks for instance just leaving the pre one If the loader recognize one or more lifecycle callbacks they will be invoked during W20 initialization with the following arguments modules is an array of all public modules definitions fragments an array of all loaded fragment manifests callback is a function that MUST be called to notify the loader that any processing in this phase is done for this module including asynchronous processing If a module do not call its callback the whole initialization process is blocked for a specified amount of time After that it is cancelled and a timeout error message is displayed Lifecycle callbacks are useful hooks for application initialization The pre callback for instance will run before AngularJS initialization the subject of the next section AngularJS initialization Before AngularJS initialization it is guaranteed that All AMD modules needed at startup are loaded Their factory functions have been run in the correct order Their pre lifecycle callbacks have been run and all modules have notified the loader that they have finished loading their asynchronous resources if any AngularJS initialization is done explicitly with the angular bootstrap function on the document element It occurs in the run lifecycle callback of the application module From this moment AngularJS initialize normally you can read more about the initialization process here https docs angularjs org guide bootstrap AngularJS modules AMD vs AngularJS modules AngularJS modules https docs angularjs org guide module are not to be confused with AMD modules We said at the begining of this guide that when we refer to a module it is an AMD module We will continue to do so and use the term AngularJS module to refer to the notion of module in AngularJS From the AMD point of view AngularJS modules have no meaning However AngularJS modules are fundamental for structuring an application correctly What is an AngularJS module AngularJS modules allow to register services factories controllers directives providers and other concepts such as configuration or run block AngularJS modules are also fundamental for unit testing Each AngularJS module can only be loaded once per injector Usually an AngularJS app has only one injector and AngularJS modules are only loaded once Each test has its own injector and AngularJS modules are loaded multiple times AngularJS module dependencies Wait a minute Did we not already talk about dependencies between modules Yes we did We talked of dependencies between AMD modules But AngularJs modules can also list other AngularJS modules as their dependencies Depending on an AngularJS module implies that the required AngularJS module needs to be loaded before the requiring AngularJS module is loaded firstModule js define angular angular function angular var firstAngularModule angular module first secondModule js define angular angular firstModule function angular var secondAngularModule angular module second first In the example above the dependency between AngularJS modules is declared as an array in the second argument to the angular module function AngularJS maintains an injector with a list of names and corresponding objects An entry is added to the injector when a component is created and the object is returned whenever it is referenced using the registered name How does that fit with the dependency system between AMD modules It is important to remember that the purpose of AMD modules and AngularJS modules is totally different The dependency injection system built into AngularJS deals with the objects needed in a component while dependency management in RequireJS deals with JavaScript files In other word if an AngularJS modules depends on another AngularJS modules this means that they must be loaded in the correct order The secondModule depend on the firstModule to be loaded first AngularJS modules and W20 To correctly initialize AngularJS the application module must know all the top level declared AngularJS modules To expose them properly you must add the following code to the public signature of modules that declare AngularJS modules return angularModules angularModule1 angularModule2 All angularModules arrays of AMD public signature modules are concatenated and the resulting array is passed to the angular bootstrap function callout info Note that you don t need to add the transitive AngularJS modules callout Integration with SeedStack backend While the web framework is compatible with any backend technology using the REST architecture integration with a SeedStack backend provide additional benefits such as Masterpage templating and generation Configuration variable Default manifest configuration Configuration options available from Props Properties format Automatic activation of fragments bundled in JAR This bridge between SeedStack front and back end is provided by the W20 bridge addon http seedstack org addons w20 bridge","summary":"This manual will provide you with a deeper understanding of the fundamentals of W20.\n\nFragments and configuration\n\nW20 and its applications are organized around the idea of fragments. \n\nWhat is a fragment ?\n\nA W20 application is made of several fragments that brings different concerns to the...","zone":{"path":"/docs/w20","label":"Web framework","logo":"w20-logo.svg"},"section":{"label":"W20 manual","icon":"fa fa-book","path":"manual"}},{"title":"Routing","tags":["route","template","path","view"],"href":"/docs/w20/manual/routing","content":"Routing AngularJS provides powerful routing capabilities which consists in a matching between a URL and a route definition This route definition specifies the contents and behavior of the view that will be displayed inside the HTML tag containing the ngView attribute To learn more about AngularJS routing please check this documentation https docs angularjs org api ngRoute provider routeProvider Fragment declared routes Although the AngularJS programmatic way of defining the application routing can be used unaltered in any W20 application a simpler declarative way of defining the routing is available It is done through the routes section of fragment manifests routes route1 route2 The application module will process the routes section of all fragments and register the valid routes in the AngularJS routing system The two components of a W20 route definition are The route paths which are specified by the keys of the routes object To ensure route uniqueness in an application the fragment identifier is used as a route path prefix For example if the fragment identifier is fragment1 the full route path registered in AngularJS routing for route1 is fragment1 route1 The route definitions which are specified as an object for each route path Every options of the AngularJS route object can be configured the most common one being the templateUrl and the controller associated to the view routes route1 templateUrl fragment id views route1Template html controller route1Controller Route types A route definition should contain a type attribute If it is not present a route type of view is assumed which is a standard AngularJS route Two route types are available out of the box A view route is a standard AngularJS route which is minimally processed by W20 If it contains a templateUrl its value is resolved into a full URL by the RequireJS function toUrl As such every fragment alias like fragment1 is resolved A sandbox route type is a W20 specific route type which encapsulate the page denoted by the url attribute into an iframe It is useful to add any pre existing HTML pages into a W20 application such as legacy application screens The url attribute is resolved into a full URL by the RequireJS function toUrl Any custom route type can be registered by using the registerRouteHandler function of the application module public definition define w20 core modules application function application application registerRouteHandler myCustomType function route analyze and transform the route object here return route The handler will be invoked for each detected route of type myCustomType It is required that the returned route object is a valid AngularJS route definition Additional route metadata Additional attributes can be attached to route definition and will be ignored by AngularJS When retrieving the route through the AngularJS route service these attributes will be preserved allow for further processing during the execution of the application W20 route metadata W20 adds a limited set of attributes on all routes type the type attribute is automatically added if not present with the view value path the full path of the route category the category of the route which can be used to classify the routes for navigation is added with a default value of __top i18n the i18n key for the route name is added with a default value of application view normalized route path Path normalization consists of replacing slashes with dots As such the fragment1 route1 fragments will have a default i18n key of application view fragment1 route1 resolve a resolve object will be added to check for route security and for any additional custom check defined by the check attribute on the route definition which must reference by name a custom check function registered with AngularJS injector through a module value myCheck function checkFn and returning a promise The routing is suspended until the promise is resolved or rejected Custom metadata Any additional metadata can be added to the route for custom purposes but be aware to not interfere with W20 route metadata as any custom attribute of the same name will be overwritten before any custom route handler is called","summary":"Routing\n\nAngularJS provides powerful routing capabilities which consists in a matching between a URL and \na route definition. This route definition specifies the contents and behavior of the view that will be displayed inside the \nHTML tag containing the ngView attribute. To learn more about...","zone":{"path":"/docs/w20","label":"Web framework","logo":"w20-logo.svg"},"section":{"label":"W20 manual","icon":"fa fa-book","path":"manual"}},{"title":"Security","tags":["permission","authentication","authorization","role"],"href":"/docs/w20/manual/security","content":"W20 applications can be integrated with security backends to authenticate users and display views that are consistent with the backend security model callout danger Before going into details it is crucial to understand that a client side Web application such as a W20 one can almost never provide effective security It is only a frontend that will reflect the security enforced in the backend but there is value in providing a consistent experience between what is possible in the UI and what is allowed by the backend and W20 provides such an integration callout The security model Subject and principals The subject is the security term which refers to a security centric view of an application user It always have an identifier A particular W20 application instance can only have zero or one subject connected at a time Principals are key value pairs associated to a subject and provide additional metadata about it like its default culture its full name its avatar etc Security providers Security providers are the bridge between the backend and the W20 security model Authentication operations are done through security providers Simple authentication provider W20 provides a SimpleAuthenticationProvider which is configured with two URL an authentication URL which will be requested with a GET upon authentication and a DELETE upon deauthentication an authorization URL which will be requested with a GET upon successful authentication to retrieve subject authorizations The credentials will be passed in clear as query parameters upon authentication so it is recommended that this provider is only used in the case of basic authentication https tools ietf org html rfc2617 where credentials can be omitted as they are directly handled by the browser Realms Realms allow a W20 application to use several security backends at once Security operations involving the backend s like authentication will be done on all security realms The multiple responses are checked for coherence they must all refer to the same subject id for instance and are partially aggregated Subject identity like its identifier type and principals are merged as one definition Subject authorizations are kept separate to avoid mixing backend security models Permissions W20 security model is permission based Permissions are arrays of strings which denote a specific right to do something in the application admin restart admin database wipe users list create read update users details printers lp457 print Permission names are completely arbitrary and developer defined but it is recommended to start from the least specific term like a functional area of the application or a use case to the most specific term like an action or an entity identifier Roles Roles are simply collections of permissions and although they can be checked for explicitly it is not recommended for the application security model maintainability The recommendation is to design the permissions such as they express the intent of the associated use case or user action and to check for these permissions only It is guaranteed that as long as the user action exists in the code the permission will remain semantically valid whereas how it is given can change throughout application life Attributes Attributes can be attached to roles and checked for during a permission or role check It is mainly used to restrict a role scope to a geographic region or an organisational branch for instance Configuration The security module can be configured with the following options autoLogin will automatically trigger an authentication upon application startup In this case security providers will be called without credentials They can ask for credentials at this points or let the browser handle credential entry as it is the case in basic authentication for instance redirectAfterLogin will redirect to the specified route path after a successful login redirectAfterLogout will redirect to the specified route path after a logout roleMapping will allow to map multiple backend roles to uniquely named unified frontend roles Role mapping W20 security allows to map several backend roles to a unified frontend role which can then be used for display or filtering purpose It can be done through the roleMapping configuration attribute roleMapping UNIFIED_ROLE realm1 SOME_BACKEND_ROLE realm2 OTHER_BACKEND_ROLE This configuration enables to view the two backend roles defined from two different realms as one frontend role called UNIFIED_ROLE If only one security realm is declared in the application all backend roles of this realm will automatically be mapped to unified roles of the same name Fragment declaration Security providers can be registered programatically with the authentication service but can also be declared in a fragment manifest security provider Simple config authentication authorizations This will register a security realm with the name of the fragment identifier using the SimpleSecurityProvider service as the security provider configured with the config section Security services Authentication service The authentication service can be used to alter the currently connected subject authenticate a new subject with its credentials and define it as the globally active subject deauthenticate the currently active subject refresh the currently active subject The authentication service can also be used to query identity information about the subject such as its identifier or its principals Authorization service The authorization service can be used to verify specific authorizations on the currently active subject and on a specific realm if the subject has a specific role with possibly specific attributes if the subject has a specific permission with possibly specific attributes It can also be used to query the list of roles although it is limited to the unified roles Security expression service Security expressions are a simple and effective way of checking the authentication and authorization status of the currently active subject They are regular AngularJS expressions which can be evaluated in a specific context Four operations are available hasPermission realm permission attributes which checks a permission for the currently active subject hasRole realm role attributes which checks if the currently active subject has a specific role isAuthenticated which checks if there is a currently active subject principal name which returns the value of a specific principal The result of the security expression is evaluated as a boolean Security directive The w20Security directive allows to evaluate a security expression in a view and display the element only if it evaluates to true Role filtering W20 security can narrow the authorizations of the currently active subject by setting up filters role filter narrows the authorizations to the specified roles Any permission or role not allowed by the filter will be denied until this filter is cancelled attribute filter narrows the authorizations on which the specified attribute values are attached Any permission or role which don t have the specified attribute values will be denied until this filter is cancelled Filtering is limited to unified roles","summary":"W20 applications can be integrated with security backends to authenticate users and display views that are consistent with\nthe backend security model. \n\n\nBefore going into details, it is crucial to understand that a client-side Web application such as a W20 one can almost...","zone":{"path":"/docs/w20","label":"Web framework","logo":"w20-logo.svg"},"section":{"label":"W20 manual","icon":"fa fa-book","path":"manual"}},{"title":"Testing","tags":["test","unit","integration"],"href":"/docs/w20/manual/testing","content":"As your application grows it becomes harder to assert that all your features are still working correctly Whether you are doing some refactoring upgrading a library version or adding new features you want a mechanism to assert that thing are working correctly and protect yourself from regression Testing Unit tests The web framework does not enforce a particular runner or test suite for unit testing but we found that a good combination is Karma http karma runner github io 0 13 index html as the runner and Jasmine http jasmine github io 2 0 introduction html as the test suite language This is probably the most popular combination for running tests and the one that the AngularJS team uses Recommended lecture are Karma documentation http karma runner github io 0 13 index html Jasmine documentation http jasmine github io 2 0 introduction html AngularJS guide on unit testing https docs angularjs org guide unit testing Installation and configuration If you used the generator w20 required packages will already be installed in your node_modules folder If you want to start from scratch first install NodeJS https nodejs org en create a directory for your app if you do not already have one cd into it and use the following command npm install karma karma cli karma jasmine karma phantomjs launcher karma requirejs You will need to configure a karma conf js file at your project root to instruct Karma You can use the following guide http karma runner github io 0 12 intro configuration html to configure every options in cli mode Please have a look at the Karma documentation http karma runner github io 0 12 intro configuration html for a complete description of the options The end result should look something like this module exports function config use strict config set frameworks jasmine requirejs files test main js pattern fragment js included false pattern bower_components included false port 9876 colors true logLevel INFO browsers PhantomJS This file instruct Karma about the file patterns to be served when running the tests As you can see we will served the business modules of the fragment located in the fragment folder along with the web dependencies of the bower_components callout info The PhantomJS browser will be used for loading the application PhantomJS is a headless browser It can run the application without rendering the HTML pages which we do not need since we are only interested in testing the application logic This is useful for executing tests in an environment which does not support graphical interface such as a CI server for instance callout Since we are using RequireJS we will need a main module for the tests This module will be declared in a test main js file var tests for var file in window __karma__ files if spec js test file tests push file window w20 configuration base bower_components w20 w20 core w20 json modules application id w20 test home test vars components path base bower_components deps tests callback window __karma__ start requirejs config paths angular mocks base bower_components angular mocks fragment base fragment shim angular mocks angular mocks angular angular requirejs base bower_components w20 modules w20 js There is a lot going on in the test main js file and we will explain what this configuration does This module is the main entry point to the application under test 1 Loaded files are listed in the global variable window _karma_ files We add all the spec js files in a list those files corresponding to the unit test modules we will write one soon 2 We configure the application programmatically by editing the w20 global variable configuration property Normally the loader will create this configuration by reading and parsing an application manifest but we can edit it directly for the need of bootstrapping a test environment We declare the core fragment and configure the application module Because Karma will serve files from base we need to specify the path to our web components by default the components path is mapped to bower_components but here we need to remap it to base bower_components This is possible using the vars property We add the unit test modules to the dependencies by using the deps property and allow the start of Karma once the configuration has been processed using the callback property 3 Some additional RequireJS configuration are necessary to remap the angular mocks module and the business fragment alias to suit Karma base path 4 Finally we start the application by requiring explicitely the w20 module Writing unit tests We are ready to start unit testing a module We will take the example of a simple AngularJS controller defined in fragment modules module to test js define angular angular function angular use strict var module angular module moduleToTest module controller ControllerToTest scope function scope scope greeting Hello World return angularModules moduleToTest This module does not do anything fancy We declare an AngularJS module moduleToTest and a controller with a scope property The spec unit test module for this module will be located in fragment specs module to test spec js define angular angular angular mocks angular mocks fragment modules module to test function angular use strict describe The module to test function var scope beforeEach angular mock module moduleToTest beforeEach inject function rootScope controller scope rootScope new controller ControllerToTest scope scope it says hello world function expect scope greeting toEqual Hello World 1 A test suite begins with a call to the global Jasmine function describe with two parameters a string and a function The string is the title of the suite usually what is under test The function body implements the suite 2 The beforeEach function executes before each unit test Here we register a mocked version of the module moduleToTest This will allow us later to request the controller declared on this module without having to worry about the dependency of this module 3 We also request that before each test the scope variable be initialized with a new scope The controller service allow us to retrieve our controller and provide it its dependency Our newly created scope with rootScope new will be passed to the constructor through dependency injection 4 Finally the unit test can be written A unit test in Jasmine takes the form of it statement which reads like a sentence describing the expected result of the test","summary":"As your application grows it becomes harder to assert that all your features are still working correctly. \nWhether you are doing some refactoring, upgrading a library version or adding new features, you want \na mechanism to assert that thing are working correctly and protect yourself from regression...","zone":{"path":"/docs/w20","label":"Web framework","logo":"w20-logo.svg"},"section":{"label":"W20 manual","icon":"fa fa-book","path":"manual"}},{"title":"UI","tags":["css","display","content","navigation","menu","bookmark"],"href":"/docs/w20/manual/ui","content":"The user interface can be customized with the graphical framework of your choice along with services which helps in areas such as navigation display and theming UI Framework Application can use any CSS frameworks or your own custom styling Two popular frameworks Twitter Bootstrap http getbootstrap com and Angular Material https material angularjs org latest are available through dedicated fragments To include these framework in the application declare the fragment that you want in your application manifest bower_components w20 bootstrap 3 w20 bootstrap 3 w20 json bower_components w20 material w20 material w20 json The CSS framework loaded can be identified in the application logic by requiring the css framework modules css framework module and evaluating its name property define css framework modules css framework function cssFramework console log cssFramework name bootstrap 3 Services Additionally several services are available for different areas of the user interface DisplayService The DisplayService assists in presentation and positioning It can request and exit fullscreen as well as registering callback for dynamic CSS classes Fullscreen mode The enterFullScreen and exitFullScreen methods will request fullscreen mode according to the type of browser in use Webkit browsers behave differently from MS browsers for instance These methods allows to abstract the request of the fullscreen mode for every browser Dynamic positioning The following CSS classes can have dynamic values w20 top shift padding padding top w20 top shift margin margin top w20 top shift top w20 right shift padding padding right w20 right shift margin margin right w20 right shift right w20 bottom shift padding padding bottom w20 bottom shift margin margin bottom w20 bottom shift bottom w20 left shift padding padding left w20 left shift margin margin left w20 left shift left Whenever a function return a b c d is registered through the registerContentShiftCallback fn method the value of theses classes is summed with the value of a b c and d a increment the value of w20 top shift padding w20 top shift margin w20 top shift b increment the value of w20 right shift padding w20 right shift margin w20 right shift c increment the value of w20 bottom shift padding w20 bottom shift margin w20 bottom shift d increment the value of w20 left shift padding w20 left shift margin w20 left shift You can compute the shift in value by calling computeContentShift The registerContentShiftCallback fn will automatically call the computeContentShift function but you might need to compute it again later if you used variables in the shift values for instance module controller ExempleController DisplayService EventService function displayService eventService var show true function showElement return show 100 0 50 0 0 displayService registerContentShiftCallback showElement eventService on SomeEvent function show show displayService computeContentShift In the example above initially The w20 top shift padding w20 top shift margin w20 top shift classes will have their value set to 100px The w20 right shift padding w20 right shift margin w20 right shift classes will have their value set to 50px the remaining one will have their value set to 0 When SomeEvent happen The w20 top shift padding w20 top shift margin w20 top shift classes will have their value set to 0 The w20 right shift padding w20 right shift margin w20 right shift classes will have their value set to 50px The remaining one will have their value set to 0 NavigationService The NavigationService is mostly used internally to compute a hierarchical routes tree useful for displaying a menu of routes ordered by categories You can call the routeTree method to retrieve the routes tree of the application For an exhaustive description of the API please consult the JSdoc MenuService The MenuService enable user to register custom action and section in themes actions are element of the topbar sections are element of the sidebar Note that some themes only allow actions Registering actions sections Before an action or section is added it needs to be a member of an action type or section type To register a new action section type use the registerActionType type config or registerSectionType type config methods of the service This is used to register the login and culture dropdown type action of themes for instance menuService registerActionType w20 login templateUrl css framework templates action login html showFn function return authenticationService isAuthentifiable menuService registerActionType w20 culture templateUrl css framework templates action culture html showFn function return cultureService availableCultures length 0 The showFn property specify on which condition should the action section be shown Adding actions sections To actually include an action or section use the addAction name type configExtension or addSection name type configExtension methods of the service menuService addAction login w20 login sortKey 100 The methods takes as argument the name of the action the type of the action and a configuration object which extends the registered type configuration The sortKey property allow to order actions sections Bookmark service The BookmarkService allow to store routes bookmarks Use the addBookmark name route method with a name and an angular route object to store one Use the getBookmark name or getAllBookmarks methods to retrieve bookmarks Additional methods are described in the API documentation","summary":"The user interface can be customized with the graphical framework of your choice along with services which helps in areas such as\nnavigation, display and theming.\n\nUI Framework\n\nApplication can use any CSS frameworks or your own custom styling. Two popular frameworks, Twitter Bootstrap\nand Angular...","zone":{"path":"/docs/w20","label":"Web framework","logo":"w20-logo.svg"},"section":{"label":"W20 manual","icon":"fa fa-book","path":"manual"}},{"title":"Distribution","href":"/getting-started/distribution/","content":"SeedStack modular design involves a lot of small modules that focus on a particular technology or scope This enables you to cherry pick the modules you really need for your projects and not more It also allows us to update components independently in their own lifecycle without disruption to other parts of the stack Usually managing projects with numerous dependent modules each with their own lifecycle can be a complex task Not so much with the SeedStack distribution which automatically handles the dependency management for you The main benefits of using the distribution over manual management of dependencies are All component versions are managed so you won t need to worry about it for any SeedStack dependency Components that are part of a distribution are tested and validated together The distribution provides composite dependencies which regroups components that are frequently used together The distribution provides the corresponding project archetypes and code generators Using a distribution in your project is almost always the recommended way to go It has no additional cost in build time Composite dependencies can sometimes add unwanted dependencies but they can be easily excluded or you can choose to not use the composites at all while still having the benefits of dependency management callout info Each organization can create its own tailored distribution s which can include cherry picked SeedStack components along with the organization private components and extensions to the stack We provide a reference Open Source distribution that can be used as is or as a base for customization This page is only about the reference distribution For more information about creating your own distribution please check this page create your own callout Dependency management To benefit from the dependency management of the distribution just add the following dependency management snippet to your root pom xml org seedstack seedstack bom pom import All components under org seedstack group identifiers are managed Composite dependencies Composites are POM type dependencies that can be added to your various project modules They regroup multiple modules that a frequently used together and often necessary in SeedStack application To add a composite dependency to one of your modules add the following dependency snippet org seedstack composite pom There are several types of composites targeted for different needs The domain composite is intended for use as a dependency to standalone domain modules The rest composite is intended for use as a dependency to REST micro services without UI The web composite is intended for use as a dependency to classic Web applications The batch composite is intended for use as a dependency to standalone batch jobs callout tips It is recommended to only use one composite per project module Note that you can add any additional dependency you may require such as add ons besides the composite callout Archetypes and generators The distribution also contains archetypes for different patterns They provide an easy way to start developping java web applications batches implement domains and rest modules","summary":"SeedStack modular design involves a lot of small modules that focus on a particular technology or scope. This enables you\nto cherry-pick the modules you really need for your projects and not more. It also allows us to update components \nindependently, in their own lifecycle, without disruption to...","zone":{"path":"/docs/getting-started","label":"Getting started","logo":"getting-started-logo.svg"},"section":{"label":"Distribution","icon":"fa fa-gift","path":"distribution"}},{"title":"Introduction","href":"/getting-started/","content":"SeedStack is a comprehensive software development stack aimed at application or service creation It addresses both backend and frontend needs in a modular yet seamless solution It means that you can cherry pick the components or choose to take advantage of the full stack for maximum development speed SeedStack is strongly opinionated and as such not an ubiquitous solution for every need Its main focus is on helping you to build better applications or services ones that will be valuable assets in the long run and that you can evolve and maintain as long as needed It does so by providing A highly modular architecture Integration of a wide range of curated technologies Easy to use building blocks SeedStack is designed with enterprise class requirements in mind High modularity powerful configuration advanced security self monitoring or side channel administrative commands are typical examples of such features They are easy to configure if you need them and won t get in your way if you don t In fact SeedStack high modularity allows you to only include the features you really need for each project SeedStack is customizable and extensible at multiple levels Beyond configuring and extending each component you can tailor the whole stack to your personal or organization needs The concept of distribution allows you to create a custom solution with its own component choices conventions and templates that you can then apply to all your organization projects We provide a reference Open Source distribution for common needs but massive gains can be found by creating your own proprietary or not especially if your organization is mid sized or large Composition SeedStack is made of three major frameworks The Java framework also known as Seed is the foundation of the application or service backend Its role is to provide access to a range of technologies from application code The Web framework also known as W20 is the foundation of the application Web frontend if any At its core it seamlessly integrates RequireJS and AngularJS to enable the creation of composite Web frontends It also provides a complete Bootstrap based UI solution The Business framework is the foundation of your business code Based on the Domain Driven Design methodology it implements all its concepts as read to use building blocks It also provides various services often needed around business code Stack diagram img stack svg Modularity is at the heart of SeedStack so you can tailor the solution to your exact needs by adding only the relevant components Components are mostly independent of each other and although there are dependencies between some of them they are kept to a minimum callout info There are two main technologies found in SeedStack Java components which are distributed as Maven artifacts on Maven Central http search maven org HTML CSS JS components which are distributed with Bower http bower io search These components are also repackaged as Maven artifacts if Bower is unavailable in your environment callout","summary":"SeedStack is a comprehensive software development stack aimed at application or service creation. It addresses both\nbackend and frontend needs in a modular yet seamless solution. It means that you can cherry-pick the components or\nchoose to take advantage of the full stack for maximum development...","zone":{"path":"/docs/getting-started","label":"Getting started","logo":"getting-started-logo.svg"},"section":{"label":"Introduction","icon":"fa fa-file-text","path":""}},{"title":"Java batch project","href":"/getting-started/project-templates/batch","content":"Creation To create a Java batch project project from scratch execute the following command mvn org seedstack seedstack maven plugin generate Dtype batch This will invoke the generate goal of the SeedStack maven plugin which will select the latest version of the SeedStack distribution and use its batch Maven archetype The process is interactive and will ask you a few questions about the project to be created Result If the creation process is successful you should see a unique module similar to the following plain mybatch Contain the domain layer if not in its own module the applicative layer the batch definition along with the related infrastructure and configuration","summary":"...\n\nCreation\n\nTo create a Java batch project project from scratch, execute the following command:\n\nmvn org.seedstack:seedstack-maven-plugin:generate -Dtype=batch\n\nThis will invoke the generate goal of the SeedStack maven plugin which will select the latest version\nof the SeedStack distribution and...","zone":{"path":"/docs/getting-started","label":"Getting started","logo":"getting-started-logo.svg"},"section":{"label":"Project templates","icon":"fa fa-cubes","path":"project-templates"}},{"title":"Reusable domain project","href":"/getting-started/project-templates/domain","content":"If you are using the business framework docs business you can choose to write your domain in its own module for reuse and modularity purposes In that case each domain e g each business context should go in its own project Creation To create a reusable domain project project from scratch execute the following command mvn org seedstack seedstack maven plugin generate Dtype domain This will invoke the generate goal of the SeedStack maven plugin which will select the latest version of the SeedStack distribution and use its domain Maven archetype http search maven org browse 7C1573518700 The process is interactive and will ask you a few questions about the project to be created Result If the creation process is successful you should see a unique module like the following plain mydomain Contains a domain layer on its own No application logic nor any infrastructure should be placed here","summary":"If you are using the business framework you can choose to write your domain in its own module for \nreuse and modularity purposes. In that case, each domain (e.g. each business context) should go in its own project.\n\nCreation\n\nTo create a reusable domain project project from scratch, execute the...","zone":{"path":"/docs/getting-started","label":"Getting started","logo":"getting-started-logo.svg"},"section":{"label":"Project templates","icon":"fa fa-cubes","path":"project-templates"}},{"title":"Project types","href":"/getting-started/project-templates/","content":"SeedStack based projects can be created from scratch but we propose a number of predefined project templates in the SeedStack reference distribution that can be generated from Maven archetypes https maven apache org guides introduction introduction to archetypes html or Yeoman generators http yeoman io We recommend that you use these project templates especially if you are new to SeedStack as they provide several benefits They are immediately executable and deployable after generation They follow best practices providing clean code organization and good modularity They are easy to use and provide fast onboarding Reference project templates The following project templates are available from the reference distribution Java Web application webapp template backend frontend Java RESTful service rest template backend only Batch job batch template backend only Reusable business domain domain template reusable component W20 Single Page Applications w20 template frontend only callout info Note that SeedStack is designed with extension in mind so you can design your own project types and provide archetypes and code generators for them in a custom distribution distribution create your own callout Project structure Each project template has its own layout adapted to the Java modules When creating a project from a reference template the The following directory structure is recommended for all Java modules plain src it for integration tests if any java resources main java org myorganization resources META INF configuration location of the module configuration files if any test for unit tests java resources pom xml Inner structure of Web fragments Browser only Web application are based upon the notion of W20 fragments which regroups various resources needed to provide one or more feature s The following structure is recommended for all W20 fragments plain i18n Localization files if any modules JS modules templates HTML templates specs Tests mocks Mocks for tests my fragment w20 json fragment manifest callout info You can learn more about fragments here docs w20 concepts fragment callout","summary":"SeedStack-based projects can be created from scratch but we propose a number of predefined project templates in the SeedStack\nreference distribution that can be generated from Maven archetypes\nor Yeoman generators. We recommend that you use these project templates, especially if you are\nnew to...","zone":{"path":"/docs/getting-started","label":"Getting started","logo":"getting-started-logo.svg"},"section":{"label":"Project templates","icon":"fa fa-cubes","path":"project-templates"}},{"title":"Java RESTful project","href":"/getting-started/project-templates/rest","content":"A Java RESTful project is a minimalist mono module project which produces a WAR artifact It can rely on one or more reusable domains domain and or embed its own business logic This type of project is intended for lightweight RESTful projects like micro services Creation To create a Java RESTful project from scratch execute the following command mvn org seedstack seedstack maven plugin generate Dtype rest This will invoke the generate goal of the SeedStack maven plugin which will select the latest version of the SeedStack distribution and use its REST Maven archetype http search maven org browse 7C 1094006884 The process is interactive and will ask you a few questions about the project to be created Result If the creation process is successful you should see a unique module like the following plain myservice Contains the REST APIs and optionally the business logic behind them This logic is often offloaded in reusable domain s","summary":"A Java RESTful project is a minimalist mono-module project which produces a WAR artifact. It can rely on one or more\nreusable domains and/or embed its own business logic. This type of project is intended for lightweight\nRESTful projects like micro-services. \n\nCreation\n\nTo create a Java RESTful...","zone":{"path":"/docs/getting-started","label":"Getting started","logo":"getting-started-logo.svg"},"section":{"label":"Project templates","icon":"fa fa-cubes","path":"project-templates"}},{"title":"Browser-only W20 project","href":"/getting-started/project-templates/w20","content":"If you need to create a browser only Single Page Application you can use the Web framework docs w20 independently from other SeedStack components This type of application can invoke backend s written with any technology through REST APIs This type of application is composed of static files only which are best served by specialized infrastructure like an optimized Web server or even a Content Delivery Network CDN They can also be served as a part of a backend application Creation Result If the process is successful you should see a structure similar to the following plain bower_components Dependencies go here fragments Application fragments go here one per directory bower json index html Application master page w20 app json Application configuration","summary":"If you need to create a browser-only Single Page Application, you can use the Web framework independently from\nother SeedStack components. This type of application can invoke backend(s) written with any technology through REST\nAPIs. \n\nThis type of application is composed of static files only which...","zone":{"path":"/docs/getting-started","label":"Getting started","logo":"getting-started-logo.svg"},"section":{"label":"Project templates","icon":"fa fa-cubes","path":"project-templates"}},{"title":"Java classic Web project","href":"/getting-started/project-templates/webapp","content":"A Java Web application project is a typical WAR style project It has an application module of JAR type containing application logic and possibly business domain logic if not separated to another module It also has a Web module of WAR type containing Web related code It is deployed as a standard WAR Creation To create a Java Web application project from scratch execute the following command mvn org seedstack seedstack maven plugin generate Dtype web This will invoke the generate goal of the SeedStack maven plugin which will select the latest version of the SeedStack distribution and use it Web Maven archetype http search maven org browse 7C1221480962 The process is interactive and will ask you a few questions about the project to be created Result If the creation process is successful you should see a structure similar to the following plain myapp Maven parent module used to regroup common pom xml configuration All dependency management should go here myapp app Contains the domain if not in its own module the application logic along with the related infrastructure and configuration myapp web Contains the Web interfaces code REST resources representations May contain multiple interfaces REST API Web Services for instance May contain additional resources needed by those interfaces like static Web resources","summary":"A Java Web application project is a typical WAR-style project. It has an application module of JAR type, containing \napplication logic and possibly business domain logic if not separated to another module. It also has a Web module of\nWAR type, containing Web-related code. It is deployed as a...","zone":{"path":"/docs/getting-started","label":"Getting started","logo":"getting-started-logo.svg"},"section":{"label":"Project templates","icon":"fa fa-cubes","path":"project-templates"}},{"title":"Tutorial","href":"/getting-started/tutorial/","content":"Welcome to the SeedStack 15 minutes tutorial It is intended to walk you through the most interesting features of SeedStack by making you build a simple Web application from scratch callout info SeedStack can be used for any type of project and provides templates for several predefined project types project types This tutorial is focused on a classic Web application project project types webapp callout Create the project The first step is to create the Web application using the latest project template plain mvn org seedstack seedstack maven plugin generate Dtype web The generator will ask you a few questions below are the recommended answers Project group id org myorg Project artifact id my app This will create a my app project in the current directory with the following layout plain my app root module app web First build The just created project is immediately buildable Go into the root module directory my app and run the following command plain mvn clean install If it is the first time you build a SeedStack project on your computer it could take a little time to download all dependencies First run You can now run the project using the pre configured Maven Jetty plugin Go into the web module directory my app web directory and run the following command plain mvn jetty run If the log showed Seed Web application started you can display the Web UI by pointing your Browser of choice at http localhost 8080 http localhost 8080 You can now import the project in your IDE if desired callout info If you don t import the project in a development environment that handles the compile deploy run cycle remember to rebuild the whole project after each modification and before restarting the jetty plugin You can do so by Killing the currently running Jetty server by hitting Ctrl C Going into the root project directory my app and execute the mvn clean install command Going into the web project directory my app web and execute the mvn jetty run command callout","summary":"Welcome to the SeedStack 15-minutes tutorial! It is intended to walk you through the most interesting features\nof SeedStack, by making you build a simple Web application from scratch.\n\n\nSeedStack can be used for any type of project and provides templates for several predefined...","zone":{"path":"/docs/getting-started","label":"Getting started","logo":"getting-started-logo.svg"},"section":{"label":"Tutorial","icon":"fa fa-graduation-cap","path":"tutorial"}},{"title":"Glossary","href":"/glossary","content":"Anemic domain model An anti pattern where the domain objects have hardly any behavior Frequently they are just data holders with getter setter access and the logic completely lives in services on top of the domain objects This is contrary to the essence of object oriented design which is to combine data and behavior together This anti pattern is really a procedural design in disguise It has the cost of a good domain model but none of the benefits Read more about it here http martinfowler com bliki AnemicDomainModel html Bounded context A bounded context is a pattern of the aspect of the DDD which is about dealing with large models and teams Large models are divided into different bounded contexts and are being explicit about their interrelationships CQRS The Command Query Responsibility Segregation CQRS pattern is a notion that a different model can be used to update information command model than the model used for reading information query model Domain A sphere of knowledge influence or activity The subject area to which the user applies a program is the domain of the software The domain is completely agnostic of the application logic Domain Driven Design An approach to the development of complex software adding on OOP to allow designers to concentrate on Business concerns rather than infrastructure ones Model An abstraction eg class diagram mind map plain text that describes a domain and can be used to solve problems related to that domain Principal In a security context a principal is a defining characteristic of a subject that can be uniquely identified like an identifier a name a social security number a language etc SPI Service Provider Interface SPI is an API intended to be implemented or extended by a third party It can be used to enable framework extension and replaceable components SeedStack provides numerous SPI allowing the developer to extend its capabilities and behaviors when needed In SeedStack all SPI live in a specific subpackage named spi Strategic design Strategic Design is a set of principles for maintaining model integrity distillation of the Domain Model and working with multiple models Ubiquitous Language Common rigorous language build up between developers and domain experts This language should be based on the Domain Model used in the software It should evolve as the team s understanding of the domain grows Value object Objects holding related values and defined by them They have no identity meaning that two value objects holding the same values are equals They should be immutable","summary":"Anemic domain model\n\nAn anti-pattern where the domain objects have hardly any behavior. Frequently they are just data holders with\ngetter/setter access and the logic completely lives in services on top of the domain objects. This is contrary to the \nessence of object-oriented design which is to...","zone":{"path":"/docs/glossary","label":"Glossary","logo":"glossary-logo.svg"},"section":{"path":""}},{"title":"AngularJS dependency injection","href":"/guides/angularjs-dependency-injection/","content":"Dependency injection in AngularJS is supremely useful and the key to making easily testable components This article explains how AngularJS dependency injection system works The Provider provide The provide service is responsible for telling Angular how to create new injectable things these things are called services Services are defined by things called providers which is what you re creating when you use provide Defining a provider is done via the provider method on the provide service and you can get hold of the provide service by asking for it to be injected into an application s config function An example might be something like this myMod config function provide provide provider greeting function this get function return function name alert Hello name Here we ve defined a new provider for a service called greeting we can inject a variable named greeting into any injectable function like controllers more on that later and Angular will call the provider s get function in order to return a new instance of the service In this case the thing that will be injected is a function that takes a name parameter and alerts a message based on the name We might use it like this myMod controller MainController function scope greeting scope onClick function greeting Ford Prefect Now here s the trick factory service and value are all just shortcuts to define various parts of a provider that is they provide a means of defining a provider without having to type all that stuff out For example you could write that exact same provider just like this myMod config function provide provide factory greeting function return function name alert Hello name It s important to understand so I ll rephrase under the hood AngularJS is calling the exact same code that we wrote above the provide provider version for us There is literally 100 no difference in the two versions value works just the same way if whatever we would return from our get function aka our factory function is always exactly the same we can write even less code using value For example since we always return the same function for our greeting service we can use value to define it too myMod config function provide provide value greeting function name alert Hello name Again this is 100 identical to the other two methods we ve used to define this function it s just a way to save some typing Now you probably noticed this annoying myMod config function provide thing I ve been using Since defining new providers via any of the given methods above is so common AngularJS exposes the provider methods directly on the module object to save even more typing var myMod angular module myModule myMod provider greeting myMod factory greeting myMod value greeting These all do the same thing as the more verbose app config versions we used previously The one injectable I ve skipped so far is constant For now it s easy enough to say that it works just like value We ll see there s one difference later To review all these pieces of code are doing the exact same thing myMod provider greeting function this get function return function name alert Hello name myMod factory greeting function return function name alert Hello name myMod value greeting function name alert Hello name The Injector injector The injector is responsible for actually creating instances of our services using the code we provided via provide no pun intended Any time you write a function that takes injected arguments you re seeing the injector at work Each AngularJS application has a single injector that gets created when the application first starts you can get a hold of it by injecting injector into any injectable function yes injector knows how to inject itself Once you have injector you can get an instance of a defined service by calling get on it with the name of the service For example var greeting injector get greeting greeting Ford Prefect The injector is also responsible for injecting services into functions for example you can magically inject services into any function you have using the injector s invoke method var myFunction function greeting greeting Ford Prefect injector invoke myFunction Its worth noting that the injector will only create an instance of a service once It then caches whatever the provider returns by the service s name the next time you ask for the service you ll actually get the exact same object So it stands to reason that you can inject services into any function that is called with injector invoke This includes controller definition functions directive definition functions filter definition functions the get methods of providers aka the factory definition functions Since constants and values always return a static value they are not invoked via the injector and thus you cannot inject them with anything Configuring Providers You may be wondering why anyone would bother to set up a full fledged provider with the provide method if factory value etc are so much easier The answer is that providers allow a lot of configuration We ve already mentioned that when you create a service via the provider or any of the shortcuts Angular gives you you create a new provider that defines how that service is constructed What I didn t mention is that these providers can be injected into config sections of your application so you can interact with them First Angular runs your application in two phases the config and run phases The config phase as we ve seen is where you can set up any providers as necessary This is also where directives controllers filters and the like get set up The run phase as you might guess is where Angular actually compiles your DOM and starts up your app You can add additional code to be run in these phases with the myMod config and myMod run functions each take a function to run during that specific phase As we saw in the first section these functions are injectable we injected the built in provide service in our very first code sample However what s worth noting is that during the config phase only providers can be injected with the exception of the services in the AUTO module provide and injector For example the following is not allowed myMod config function greeting WON T WORK greeting is an instance of a service Only providers for services can be injected in config blocks What you do have access to are any providers for services you ve made myMod config function greetingProvider a ok There is one important exception constants since they cannot be changed are allowed to be injected inside config blocks this is how they differ from values They are accessed by their name alone no Provider suffix necessary Whenever you defined a provider for a service that provider gets named serviceProvider where service is the name of the service Now we can use the power of providers to do some more complicated stuff myMod provider greeting function var text Hello this setText function value text value this get function return function name alert text name myMod config function greetingProvider greetingProvider setText Howdy there myMod run function greeting greeting Ford Prefect Now we have a function on our provider called setText that we can use to customize our alert we can get access to this provider in a config block to call this method and customize the service When we finally run our app we can grab the greeting service and try it out to see that our customization took effect Since this is a more complex example here s a working demonstration http jsfiddle net BinaryMuse 9GjYg http jsfiddle net BinaryMuse 9GjYg Controllers controller You can inject things into controllers but you can t inject controllers into things That s because controllers aren t created via the provider Instead there is a built in Angular service called controller that is responsible for setting up your controllers When you call myMod controller you re actually accessing this service s provider just like in the last section For example when you define a controller like this myMod controller MainController function scope What you re actually doing is this myMod config function controllerProvider controllerProvider register MainController function scope Later when Angular needs to create an instance of your controller it uses the controller service which in turn uses the injector to invoke your controller function so it gets its dependencies injected too Filters and Directives filter and directive work exactly the same way as controller filter uses a service called filter and its provider filterProvider while directive uses a service called compile and its provider compileProvider Some links filter http docs angularjs org api ng filter http docs angularjs org api ng filter filterProvider http docs angularjs org api ng filterProvider http docs angularjs org api ng filterProvider compile http docs angularjs org api ng compile http docs angularjs org api ng compile compileProvider http docs angularjs org api ng compileProvider http docs angularjs org api ng compileProvider As per the other examples myMod filter and myMod directive are shortcuts to configuring these services Summary So to summarize any function that gets called with injector invoke can be injected into This includes but is not limited to controller directive factory filter provider get when defining provider as an object provider function when defining provider as a constructor function service The provider creates new services that can be injected into things This includes constant factory provider service value That said built in services like controller and filter can be injected and you can use those service to get hold of the new filters and controllers you defined with those methods even though the things you defined aren t by themselves able to be injected into things Other than that any injector invoked function can be injected with any provider provided service there is no restriction other than the config and run differences listed herein Source article Article copied from https github com angular angular js wiki Understanding Dependency Injection https github com angular angular js wiki Understanding Dependency Injection","summary":"Dependency injection in AngularJS is supremely useful, and the key to making easily testable components. This article \nexplains how AngularJS dependency injection system works.\n\nThe Provider ($provide)\n\nThe $provide service is responsible for telling Angular how to create new injectable things...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"AngularJS dependency injection","path":"angularjs-dependency-injection"}},{"title":"AngularJS directive design","href":"/guides/angularjs-directive-design/","content":"AngularJS is a web application framework that makes creating complicated web applications much simpler One of its best features is the ability to create directives or reusable web components It gives you the ability to create new HTML tags and attributes which can dynamically display content in response to data changes as well as update the data when appropriate They re a big productivity booster because they let you wrap up a complicated interaction with the DOM in a nice reusable package Making directives can be confusing at first It doesn t take long to realize that directives are useful and the ones that are bundled with AngularJS are well designed but making directives can feel overwhelming at first The Angular team has done a good job making directives extremely powerful and flexible but all that power comes with some complexity Specifically it s difficult to understand how to create a directive that responds to data changes updates data responds to events or exposes events Basically it boils down to this How do I talk to a directive This article aims to explain and simplify some of the most common problems you will run in to when creating directives Directive design principles Directives make our lives easier when you can reuse them without needing to read or edit the source code Then we can forget how they work and just remember what they do If you re coming from a view centric framework you may be tempted to separate your application into view like directive chunks For example if you want to display a list of users you might create a directive that reads scope users and prints them all out The user list directive works I mean look how DRY it is However contrast it with ng repeat which handles only the repetition Which one could be used in more places What if you need to display users differently in two places A good directive only does one job ng repeat is better than user list because it does only one job It only does the repetition part so you can reuse it many more situations It s job is easy to understand Instead of making one directive that solves everything split it up into several focused directives and glue them together A good directive is not application specific Directives are more widely useful the fewer assumptions they make about your application A directive that allows the user to say which property to observe like ng model is more useful than one that assumes that scope users exists As a general rule if your directive could be useful in a completely different application it s more likely to be well designed and useful even if you never publish it That s enough theory for now Let s dive in to some specific examples of common ways you can interact with directives How to display bindings The first thing to learn is how to make a directive that respects a binding the ones with double curly braces For example let s make a directive that displays a photo and a caption The first step in any directive design is to choose the names of the attributes that will make up your interface I ve chosen to use photo src for the image src and caption for the text Be careful not to use names that other directives use like ng src unless you know how they work Secondly decide if you want to support only attributes and class names or elements too In this case we decide we want photo to be an element Note that I did not give the directive the whole photo object It s better design to allow the directive to work with any data structure To read a binding use attrs observe This will call your callback any time the binding changes We then use element to make changes to the DOM app directive photo function return required to make it work as an element restrict E replace with this html template replace true observe and manipulate the DOM link function scope element attrs attrs observe caption function value element find figcaption text value attribute names change to camel case attrs observe photoSrc function value element find img attr src value Alternatively if your component has its own template you can do all of this with an isolate scope app directive photo function return restrict E templateUrl photo html replace true pass these two names from attrs into the template scope scope caption photoSrc HTML caption How to read and write data Some directives need to write data too like ng model Let s make a button toggle directive This directive will automatically set its toggle state based on some boolean in the scope and when clicked it will set the boolean When passing data this way you don t use curly braces you use an Expression An Expression is any JS code that would run if it were on the scope Use expressions whenever you need to write data or when passing in an Object or Array into the directive instead of a string Show Details First we use on the scope settings to make scope toggle available within our directive Anywhere in our directive scope toggle reads and writes to whatever the user set in the attribute app directive toggle function return scope toggle link function scope element attrs Next we use scope watch which calls your function whenever the expression changes We ll add and remove the active css class whenever it changes scope watch toggle function value element toggleClass active value Finally let s listen to the jQuery click event and update the scope We need to use scope apply any time we respond to changes from outside of Angular element click function scope apply function scope toggle scope toggle How to expose events Sometimes you want to allow a controller to respond to events from within a directive like ng click Let s make a scroll directive that can call a function whenever a user scrolls that element In addition let s expose the scroll offset too Similar to the toggle button we map whatever function they specify in the attribute to scroll in our directive s scope app directive scroll function return scope scroll link function scope element attrs We ll use jQuery s scroll event to get what we need We still need to call scope apply here because even though it calls the handler either way the handler on the controller might set data element scroll function scope apply function var offset element scrollTop scope scroll offset offset Notice that we don t pass the offset in as the first parameter we pass a hash of available parameters and make them available to the expression onScroll offset that they passed in to the attribute This is much more flexible than passing parameters directly because they can pass other scope variables into their functions like the current item in an ng repeat How to have HTML content Directives can have html content by default but the minute you specify a template the content is replaced by the template Let s make a modal component a popup window with a close button and we would like to set the body as html Some contents Put whatever you want in here Our modal is more than just one element though When we make the template we include everything we need then we put a special ng transclude directive in the div that is supposed to take back over and get all the contents Close Modal Wiring things up is pretty simple Just set transclude true to get this to work app directive modal function return restrict E templateUrl modal html replace true transclude true You can combine this with any of the other techniques in this article to make something more complicated How to respond to events Sometimes you might want to call a function on your directive in response to an event in your scope For example you might want to close the open modal if the user hits the escape key This is almost always an indication that you are stuck on events when you should be thinking about data flow Controllers don t just contain data they hold view state too It s totally fine to have a windowShown boolean on your controller and use ng show or pass a boolean into your directive as described above There are cases where it does make sense to use scope on in a directive but for beginners try to think about the problem in terms of changing state instead Things get much easier in Angular if you focus on data and state instead of events More Information There is a lot more to directives This article doesn t nearly cover everything they can do Please visit the directive documentation http docs angularjs org guide directive page for more information Source article Article copied from http seanhess github io 2013 10 14 angularjs directive design html http seanhess github io 2013 10 14 angularjs directive design html","summary":"AngularJS is a web application framework that makes creating complicated web applications much simpler. One of its best\nfeatures is the ability to create directives, or reusable web components. It gives you the ability to create new HTML\ntags and attributes, which can dynamically display content in...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"AngularJS directive design","path":"angularjs-directive-design"}},{"title":"Aggregate design","href":"/guides/ddd-pitfalls-and-tips/aggregate-design/","content":"Most business domains have very interconnected Entities sometimes up to the point where there is always a path going from any Entity to any other We can try to minimize the number of associations in our design and this is a good practice but it can lead to a translation loss between business and software In a typical object model it is difficult to clearly see the boundaries of a change This is particularly acute in systems with concurrent access such as Web applications callout info It is difficult to guarantee the consistency of changes to objects in a model with complex associations and no clear boundaries between objects Considering every object as independent from each other is not a valid approach but on the other side refreshing every object because of a change is not practical A balanced solution must be found callout To help us with this delicate problem the Aggregate pattern can be applied It is a cluster of associated objects that are considered as a unit for the purpose of data changes Each Aggregate has root and a boundary which determines what is inside the Aggregate The Aggregate root is a specific Entity contained in the Aggregate It is the only entry point of the Aggregate meaning that it is the only Aggregate Entity that client objects can hold references to Other objects of the Aggregate are only accessible through the context of the Aggregate root Characteristics The following rules apply to Aggregates The Aggregate root has a global identity and is responsible for checking invariants within the Aggregate Non root Entities inside the Aggregate have a local identity that is only unique within the Aggregate Code outside the Aggregate can only hold references to the Aggregate root The root can hand references to internal entities but they must only use them transiently and not hold to the reference Value Objects can be handed without any concern because they are immutable and side effect free Only Aggregate roots can be loaded directly from the persistence All other objects must be found by traversal of associations Any change within the Aggregate boundary must satisfy all the Aggregate invariants Typologies There are almost infinite ways to design a model for a specific business domain Each of these ways will have its own characteristics in terms of performance consistency simplicity etc Good Aggregate design is crucial to build a system that will have the desired qualities Consistency must be ensured at the Aggregate level This means that an Aggregate root is responsible to check that business invariants i e business rules that must be valid at all times are satisfied This also means that a properly designed system modifies only one Aggregate instance per transaction in all cases This may sound strict but it should be a goal to strive for in most cases This is the main reason behind modeling with Aggregates Consider the following aggregate typologies aggregate typologies img aggregate typologies png The left topology is not expressive in terms of business and could often lead to glorified database editors The right topology is an object graph which is too big to scale well when modified concurrently The middle typology is the one to strive for but it is often difficult to get it right on first try Try to use Value Objects where possible to limit the complexity associated to dealing with entities Aggregate design is an iterative process where Aggregates may start relatively big and then refined iteration after iteration as measure as business domain knowledge is gained callout info Aggregates should be designed with a consistency boundaries in mind meaning that a change i e a transaction should only impact one Aggregate instance if possible callout References As we saw above references between Aggregates should always be done through the Aggregate roots But there is another rule that must be obeyed only reference other Aggregates through their identities instead of a direct reference This will help tremendously in limiting the scope of persistence operations remember that we don t want to change more than one aggregate instance at the time Model navigation is not completely prevented by only referencing identities A Repository or Domain Service could be used to lookup needed objects ahead of invoking the Aggregate behavior Those objects would be handed as parameters to the operation An Application Service can encapsulate this logic Only using reference by identity may limit the ability to serve complex User Interface views where multiple calls to repositories may be needed One solution is to use theta joins https en wikipedia org wiki Relational_algebra CE B8 join_and_equijoin to assemble referentially associated Aggregates in a single join query Consistency If immediate consistency or transactional consistency should be applied when changing one Aggregate one cannot expect this to be the case for changes that spans multiple Aggregates In this case eventual consistency can be applied instead where consistency will be attained after a specified amount of time Technical mechanisms such as event processing batch processing or other update mechanisms can be used to this effect But the invariants applied within an Aggregate must always be satisfied with the completion of each transaction Developers are usually reticent to depart from the idea that the model should be consistent at all times But often the business rules are not that strict and eventual consistency can be used without breaking them It is something that need to be discussed with domain experts This not always possible however Performance Performance is one of the top reasons why we would like to break those rules especially the one which states that Aggregates should only reference other Aggregates by identity It is especially apparent in systems where the persistence mechanism is not as versatile as we would like and imposes its constraints upon queries that can be made or not If the system is required to provide a lot of complex and different sets of data to the end user while being able to be changed transactionally consider using a read model that is different from the domain model and is optimized to answer those data sets Such a read model could even be implemented with another persistence technology like full text indexing kept in sync with domain events docs business manual event It may be worth the cost If only a few queries must be specifically optimized it could be best to hold direct object references to other Aggregates This must be well considered before being attempted in the light of potential performance trade offs this could incur to other parts of the system This should be viewed as a strong indication that they may be some issues with Aggregate boundaries and only used as a last resort","summary":"Most business domains have very interconnected Entities, sometimes up to the point where there is always a path going \nfrom any Entity to any other. We can try to minimize the number of associations in our design, and this is a good practice\nbut it can lead to a translation loss between business and...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"DDD pitfalls and tips","path":"ddd-pitfalls-and-tips/aggregate-design"}},{"title":"Anemic Domain Model","href":"/guides/ddd-pitfalls-and-tips/anemic-domain-model","content":"An Anemic Domain Model is something that can be found a lot of projects and astonishingly is often viewed as a good practice But as you may already have deduced from its name it doesn t sound like something desirable and certainly not in DDD oriented software And indeed it isn t An Anemic Domain Model is the result of having all or almost all the behavior of the Domain in separate classes often called Services that are directly changing the internal state of entities through setters In that case the entities are merely a data model often projected from a relational model through an ORM with no behavior at all To recognize if your software suffers from the Anemic Domain Model anti pattern consider the following questions Do all the classes of your model have mostly public getters and setters and no or almost no business logic Do the classes that use your model contain the business logic of the system If you answered No to both questions no worry your project doesn t seem to suffer this problem If you answered Yes to both questions read on we will analyze the situation As you may have guessed there is no other valid answer combination Disadvantages of an Anemic Domain Model The main disadvantage of an Anemic Domain Model is that it costs you the same as a Rich Domain Model to build and you get little to no benefit in return The encapsulation OOP principle which is very important to create and maintain complex systems is violated You allow any code to change your model internal state without any sanity check and as such cannot ensure that the model is in a correct and valid state The model is a lot less expressive since all behavior has been stripped out of it The model is completely untestable because we cannot ensure that the model doesn t get invalid at some point Business logic is wholly implemented in a procedural style separate layer which mixes domain logic and application logic The greatest irony comes when you still use an Object Relational mapping with its often heavy associated cost and finally end up with procedures altering data holders Put bluntly this is simply bad design Bad example Consider a Customer class which only has public getters and setters for a few attributes Then consider the following example service that is client of an Anemic Domain Model public class CustomerServiceImpl implements CustomerService Inject private Repository customerRepository Inject private Factory customerFactory Transactional public void saveCustomer String id String firstName String lastName String street String city String postalCode String String phone String email Customer customer customerRepository load id if customer null customer customerFactory create customerId customerRepository persist customer customer setFirstName firstName customer setLastName lastName customer setStreet street customer setCity city customer setPostCode postalCode customer setPhone phone if email null customer setEmail email customerRepository save customer This service operation can be used in dozen of different business circumstances like changing its address updating its phone number or even creating a new customer This may seem awesome at first sight but this method can work in various invalid ways and the model cannot prevent it It also has a number of additional problems No business intention is revealed by the saveCustomer interface The Customer domain object is just a data holder not an object Even if the service operation contains additional validation logic and checks it cannot be guaranteed that there is no other badly implemented service which will potentially corrupt the model Refactoring to goodness The first thing we could do is to create intention revealing operations on the Customer class itself that draw their names from the and implement business behavior in them public class Customer public void changePersonalName String firstName String lastName public void relocateTo PostalAddress newPostalAddress public void changeTelephone Telephone newTelephone public void disconnectTelephone public void changeEmail EmailAddress newEmailAddress We can immediately see that the business intentions are clearly apparent here and that additional behavior linked to these intentions can now be easily implemented and enforced in the Customer class itself This logic is testable and those tests will ensure that Customer objects will behave correctly Furthermore we can now ensure that no Customer object can be used invalidly by its clients This is perhaps not the best design for a Customer but as it reveals its intentions and capabilities this design can then be improved upon instead of being kept implicit and dependent of its callers Note that in our quest of expressiveness we also introduced some Value Objects like Telephone PostalAddress or EmailAddress which will contain additional encapsulated business logic about them The service will also be refactored to reflect explicit business intentions public class CustomerServiceImpl implements CustomerService Inject private Repository customerRepository Transactional public void changeCustomerName String customerId String newFirstName String newLastName Customer customer customerRepository load customerId if customer null throw new IllegalStateException Customer doesn t exist customer changePersonalName newFirstName newLastName Now this method can only be used in a well defined business case that everyone can understand by reading the code The terms coming from the Ubiquitous Language are now clearly apparent and as they are shared across the team including business experts there is little to no possible misunderstanding about what this really does callout info The result is a software design that not only is fully functional and correct but also directly relates to and reflect business knowledge callout","summary":"An Anemic Domain Model is something that can be found a lot of projects and, astonishingly, is often viewed as a good \npractice. But as you may already have deduced from its name, it doesn't sound like something desirable and certainly not \nin DDD-oriented software.\n\nAnd indeed it isn't. An...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"DDD pitfalls and tips","path":"ddd-pitfalls-and-tips"}},{"title":"Behavior and services","href":"/guides/ddd-pitfalls-and-tips/behavior-and-services","content":"Sometimes behavior doesn t fit into Entities or Value Objects Pure operations may exist in the domain and should therefore be modeled as such Domain Driven Design propose the Service pattern to model these operations It is important to strike a balance between modeling all behavior inside objects and modeling all behavior as Services Complex operations can easily muddle the conceptual clarity of simple objects and when applying on many different domain objects at once blur the responsibility between them On the other hand using Services exclusively can lead to an Anemic Domain Model anemic domain model which is equally something to avoid Characteristics A domain Service should have the following characteristics The operation relates to a domain concept that don t fit naturally in an Entity or a Value Object The interface is defined by other elements of the model parameters and returns values are domain model objects The operation is stateless Stateless operation doesn t mean that the Service cannot change the system global state In fact it can have side effects such as persisting an object But it doesn t maintain a state on its own that could affect its behavior Other types of services There are other types of Services as well addressing different purposes in the system Application Services orchestrate domain operations to realize the system use cases Interface Service contain presentation logic Infrastructure Services encapsulate technical operations These types of Services also model stateless operations but in other parts layers of the application","summary":"Sometimes behavior doesn't fit into Entities or Value Objects. Pure operations may exist in the domain and should therefore\nbe modeled as such. Domain-Driven-Design propose the Service pattern to model these operations. \n\nIt is important to strike a balance between modeling all behavior inside...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"DDD pitfalls and tips","path":"ddd-pitfalls-and-tips"}},{"title":"Entities and Value Objects","href":"/guides/ddd-pitfalls-and-tips/entities-and-value-objects","content":"Modeling business concepts with objects may seem very intuitive at first sight but there are a lot of difficulties awaiting us in the details To clarify the meaning of model elements and propose a set of design practices Domain Driven Design defines three patterns that express the model Entities Value Objects and Services This chapter will focus on Entities and Value Objects leaving Services for their own chapter behavior and services Entities An object having a specific identity and defined primarily by it is called an Entity We model a domain concept as an Entity when its individuality is primordial and it must be distinguished from other objects in the system There is a notion of continuity in Entities as they can change drastically throughout their lifecycle yet they remain uniquely identified Entities don t need to be tied to an identifiable real world concept as their name could imply They can be anything that need to be tracked in the system regardless of their attributes Identity When designing an Entity the focus should be put first on its primary attributes and behaviors that contribute to its identity There is a tendency especially for DDD beginners to focus on data and define all the attributes of a domain object This should be delayed until all the aspects of the Entity identity have been considered and settled One should first consider how the identity is obtained User provided identity The user could input one or more unique values into the application to be used as an identity which in turn should ensure that they have the required qualities Correctness The provided values should adequately identify the Entity without ambiguity Uniqueness The provided values should be unique among all the entities of the same type Immutable Most of the time the identity must be immutable because the cost of changing an identity may be very high Application generated identity The application could internally generate an identity using an algorithm that provide unique values The Business framework provides an API that can delegate the identity generation to any specified implementation at Entity creation This is called early identity generation because identity is assigned before the Entity can be used in the application This requires the Entity identity attribute to be annotated with Identity public class MyEntity extends BaseEntity Identity handler SequenceHandler class private Long id other attributes and methods The factory method which create the entity must be annotated with Create Create MyEntity createMyEntity return new MyEntity Here the specified handler class SequenceHandler is an interface so configuration is required to specify the qualifier of the implementation it could be oracle sequence for instance and the additional implementation properties like a sequence name For more information refer to the documentation docs business manual factory identity callout info This mechanism can be used to delegate the identity generation to a specific technology without tainting your domain by keeping the handler implementation in the infrastructure But it also can be used to simply reuse a pure domain generation logic across multiple Entity types callout Persistence generated identity The application waits until a persistence mechanism affects an identity to the persisted Entity This is called late identity generation and is less than ideal because an Entity won t have any identity and as such will be invalid until it is persisted It is strongly recommended to use the business framework identity generation mechanism instead which can delegate the generation to the persistence without compromising entity validity Externally generated identity Another like another application has already an identity or a list of identities which the user can choose from This is the most complex identity creation strategy as it involves one or more external systems The Business framework identity generation mechanism can help by allowing to encapsulate this complex logic into a custom IdentityHandler Surrogate identity It is sometimes necessary to define a surrogate identity mainly for certain persistence mechanisms that do not deal with complex identities In this case we need to use two identities one for the persistence tool which should be hidden from the rest of the domain and one for the domain which is used throughout the system The surrogate identity can often be hidden by using a private or protected visibility as most persistence tools are able to deal with it callout warn A surrogate identity is not something desirable and should only be used in last resort callout Equality Entity equality should always be based on the comparison of the type and the identity only The Business framework BaseEntity base class already implements this equality mechanism If you choose to implement the Entity interface directly or just annotate you class with DomainEntity instead be sure to implement compliant equals and hashCode methods Value Objects An object that don t have a conceptual identity but is just describing some characteristics of a thing is called a Value Object Because the most visible objects in a model are usually Entities there is a natural tendency to assign an identity to every domain object But this tendency should be refrained Here are the main characteristics of a Value Object It measures quantifies or describes a thing in the domain It is immutable meaning that its state cannot be changed after creation It describes a conceptual whole Its attributes are related to each other and are all participating to the description This means that all the required values should be assigned upon creation i e in the constructor It is comparable to others using value equality Its behavior is side effect free Example As an example consider the following class public class MonetaryValue private final BigDecimal amount private final String currency public MonetaryValue BigDecimal amount String currency this amount amount this currency currency behavior methods A monetary value consists at least in an amount of money and the currency this amount is expressed in These two attributes cannot be separated without losing the meaning of this domain object Moreover if a thing would be worth 1000 we would not expect it to have these two separate attributes as it would muddle the model and its client would have to know when and how to use amount and currency together It would be vastly better to describe the worth as a whole and only have an attribute of type MonetaryValue especially if it can provide additional behavior to manipulate it Immutability One of the most important constraint of a Value Object is immutability The object state cannot change after it has been created When a change is required a new instance of the Value Object is created either from scratch or derived from an existing instance In this latter case the object itself can provide methods to derive itself public MonetaryValue add MonetaryValue other if currency equals other currency throw new IllegalArgumentException Cannot add two monetary values of different currency return new MonetaryValue amount add other amount currency This method is said to be side effect free as it produces an output but without modifying its own state This kind of design allows to share any Value Object by reference throughout the system improving performance without compromising model integrity Simple value as Value Object Very often we resort to primitive data types and Strings to describe a lot of the model attributes This is sound when these attributes are secondary to the model But when considering attributes of first importance they are better modeled as Value Objects with only one attribute For instance an email could be modeled as a String but it would be able to provide a real meaning to it nor any behavior Moreover it would leak a vague concept in the model client code instead of a clear valid and useful one callout info Since identities are of crucial importance in the model they can be modeled as Value Objects with great success callout Equality Value Object equality should always be based on the comparison of the type and the attributes values The Business framework BaseValueObject already implement this equality mechanism If you choose to implement the ValueObject interface directly or just annotate you class with DomainValueObject instead be sure to implement compliant equals and hashCode methods Persistence Persisting Value Objects as part of referencing Entities can pose its challenges especially with relational databases and ORM Simple references When an entity holds a reference to a Value Object there is basically two choices The Value Object can be serialized in a format such as JSON or XML to a column of the Entity table The inability to execute queries referring to the contents of the Value Object can pose problem though The Value Object attributes can be stored independently as columns of the holding Entity table by using a mechanism such as JPA Embeddable Embedded This is the preferred way because it preserves the ability to query the Value Object attributes In this case whatever the method the persistence of Value Objects is clean and optimized No persistence store specifics leaks in the model Collections Persisting a collection of Value Objects hold by an Entity is more difficult Like in the single Value Object case the whole collection can still be serialized in a specific column although column size problems can arise in addition to the inability to query the collection contents This mechanism may also require custom ORM code to handle the serialization deserialization process An alternative would to treat such Value Objects as Entities in the data model by giving them an identity and their own table It would be crucial to hide this persistence only identity from the rest of the domain and the system by using visibility restrictions private attribute or other techniques","summary":"Modeling business concepts with objects may seem very intuitive at first sight but there are a lot of difficulties \nawaiting us in the details. To clarify the meaning of model elements and propose a set of design practices, Domain-Driven\nDesign defines three patterns that express the model: Entities...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"DDD pitfalls and tips","path":"ddd-pitfalls-and-tips"}},{"title":"Introduction","href":"/guides/ddd-pitfalls-and-tips/","content":"Domain Driven Design is focused on creating high quality software that not only meet the users needs but also is designed to deliver true business value Software that is not merely working but has the potential to accompany the business strategic initiatives and provide a clear competitive advantage Software that can be evolved throughout the years to remain a valuable asset instead of being a recurring cost It does so by addressing both the strategic needs of the business and the tactical ways of translating them into real software that works This guide doesn t even try to address the strategic side of DDD but is focused on the common mistakes and their solution your can face when implementing DDD in your project Examples of such mistakes and their solution are presented based on the SeedStack business framework Contents of this guide This guide is mainly intended for beginners that should know about these pitfalls in order to recognize and avoid them before it s too late But it can also be of valuable help to more seasoned developers The following topics are addressed The Anemic Domain Model Fowler Anemic is viewed by many as an anti pattern of Domain Modeling and will prevent you to get all the benefits from Domain Driven Design We will look at its disadvantages and how to recognize it An example will show how to refactor an Anemic Domain Model into a Rich Domain Model The duality of Entities and Value Objects will be explored What are their respective characteristics when to use which and how to manage identities Aggregate design is a particularly difficult topic especially for beginners We will review various criteria which can help in achieving the right granularity and de coupling level In relation to the Anemic Domain Model topic we will focus on the behavior of the domain When behavior should go into Entities VO or segregated into Services what are the characteristics of a good service Beyond the Domain live its clients like the Application layer We will look at how they can effectively use the domain while being kept thin Tactical patterns As a reference the main DDD tactical patterns and their relations are summarized on the following diagram tactical patterns img all domain png References Fowler Anemic Fowler Martin 2003 http www martinfowler com bliki AnemicDomainModel html http www martinfowler com bliki AnemicDomainModel html","summary":"Domain-Driven Design is focused on creating high-quality software that not only meet the users needs, but also is designed\nto deliver true business value. Software that is not merely working but has the potential to accompany the business\nstrategic initiatives and provide a clear competitive...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"DDD pitfalls and tips","path":"ddd-pitfalls-and-tips"}},{"title":"Frontend testing","href":"/guides/frontend-testing/","content":"As your application grows it becomes harder to assert that all your features are still working correctly Whether you are doing some refactoring upgrading a library version or adding new features you would want a mechanism to protect yourself from regression Testing is well known for Java EE server side application but your front end web application also deserves unit testing especially when complex logic are involved Unit testing as the name implies is about testing individual units of code Unit tests try to answer questions such as Did I think about the logic correctly or Does the sort function order the list in the right order W20 itself is agnostic of the testing framework and the test runner but you may have good results with respectively Jasmine and Karma Writing unit tests Instead of repeating in a less complete way what the documentation on Jasmine Jasmine http jasmine github io 2 1 introduction html and AngularJS http docs angularjs org guide dev_guide unit testing have to offer on testing we are going to follow an example and see how we can test our individual unit of code The code to test We will use the example of a small CRUD application for managing users The code that we will test consists of a service UsersService that retrieve users and an angular controller which holds some functions addUser loadUsers and clearUsers module factory UsersService resource function resource return usersResource resource require toUrl fragmentRoot data users json module controller UserController scope UsersService function scope usersService var userId 0 var Users usersService usersResource User array initialization scope users This function add the current entered user to the user array scope addUser function scope users push id userId toString firstName scope firstName lastName scope lastName This function loads users from a resource scope loadUsers function Users query function result for var i 0 i userId userId result i maxid scope users result This function clears the user array scope clearUsers function scope users We can now start writing some tests in our user test js file Unit test structure A test suite begins with a call to the global Jasmine function describe with two parameters a string and a function The string is a name or title for a spec suite usually what is under test The function is a block of code that implements the suite describe A suite function it contains spec with an expectation function expect true toBe true Specs are defined by calling the global Jasmine function it which like describe takes a string and a function The string is a title for this spec and the function is the spec or test A spec contains one or more expectations that test the state of the code under test An expectation in Jasmine is an assertion that can be either true or false A spec with all true expectations is a passing spec A spec with one or more expectations that evaluate to false is a failing spec describe A suite of spec function var a it is a spec and variable a should be true function a true expect a toBe true Jasmine also provides the global beforeEach and afterEach functions As the name implies the beforeEach function is called once before each spec in the describe is run and the afterEach function is called once after each spec describe A spec with setup and tear down function var foo beforeEach function foo 0 foo 1 afterEach function foo 0 it is just a function so it can contain any code function expect foo toEqual 1 it can have more than one expectation function expect foo toEqual 1 expect true toEqual true Example With those basic concepts we can now start writing some tests for our code sample Before writing the test suite we want to get our hand on the service and controller inside our test file We do this by using the beforeEach function define angular angular angular mocks angular mocks my fragment modules user function angular var userController scope beforeEach function Load the user module which contains the service and controller module user inject services that will allow us to get our hands on the required components we want to unit test inject function injector controller rootScope Create an object serviceMock with a property usersResource We do this so that later on we can use it as a spy for call on the UsersService usersResource query serviceMock usersResource Get a new child scope from the root scope which will served in our specs scope rootScope new Get the UserController and map its scope dependency to the one defined above and its UsersService dependency as the serviceMock we defined above userController controller UserController scope scope UsersService serviceMock We now have all our components ready for our test suite Remember that a test suite is defined with describe describe the user controller function Inside of this test suite we can write our specs Check that initialization is correct it should have empty users collection when initialized function assert that scope users exists expect scope users toBeDefined assert it is empty expect scope users length toEqual 0 Unit test the adduser method it should be able to add items to the users collection function scope firstName Robert scope lastName SMITH scope addUser expect scope users length toEqual 1 expect scope users toContain id 1 firstName Robert lastName SMITH Unit test the clearUsers method it should be able to clear the users collection function scope users push id 1 firstName Robert lastName SMITH expect scope users length toEqual 1 scope clearUsers expect scope users length toEqual 0 Unit test the loadUsers method it should be able to load data to the users collection function We are going to turn query into a dummy function The andCallFake specify what the call to query should do We created a spy Then we test it with loadUsers serviceMock usersResource query jasmine createSpy andCallFake function callback callback id 1 firstName Robert lastName SMITH loadUsers will trigger a call to usersService usersResource query which is mocked by serviceMock usersResource query scope loadUsers expect scope users length toEqual 1 expect scope users toContain id 1 firstName Robert lastName SMITH scope firstName Anna scope lastName O HARA scope addUser expect scope users length toEqual 2 expect scope users toContain id 1 firstName Robert lastName SMITH id 2 firstName Anna lastName O HARA Full code To conclude here is the entire user test js file define angular angular angular mocks angular mocks my fragment modules user function angular var userController scope beforeEach function module user inject function injector controller rootScope serviceMock usersResource scope rootScope new userController controller UserController scope scope UsersService serviceMock describe the user controller function it should have empty users collection when initialized function expect scope users toBeDefined expect scope users length toEqual 0 it should be able to add items to the users collection function scope firstName Robert scope lastName SMITH scope addUser expect scope users length toEqual 1 expect scope users toContain id 1 firstName Robert lastName SMITH it should be able to clear the users collection function scope users push id 1 firstName Robert lastName SMITH expect scope users length toEqual 1 scope clearUsers expect scope users length toEqual 0 it should be able to load data to the users collection function serviceMock usersResource query jasmine createSpy andCallFake function callback callback id 1 firstName Robert lastName SMITH scope loadUsers expect scope users length toEqual 1 expect scope users toContain id 1 firstName Robert lastName SMITH scope firstName Anna scope lastName O HARA scope addUser expect scope users length toEqual 2 expect scope users toContain id 1 firstName Robert lastName SMITH id 2 firstName Anna lastName O HARA","summary":"As your application grows it becomes harder to assert that all your features are still working correctly. Whether you are\ndoing some refactoring, upgrading a library version or adding new features, you would want a mechanism to protect yourself\nfrom regression. Testing is well known for Java EE...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"Frontend testing","path":"frontend-testing"}},{"title":"Introduction","href":"/guides/make-configurable-application/","content":"Configuration is a crucial part of an application that can be difficult to get right It encompasses multiple aspects like logging internal configuration or externalisation and should be treated with the same care that code Configuration files Unified configuration Seed provides an unified configuration that is consolidated from multiple classpath locations and is available throughout the whole application This configuration is sourced from two kind of files Props files with the props extension placed under META INF configuration Properties files with the properties extension placed under META INF configuration If possible every configurable value should be placed in the unified configuration preferably in props files because of their better expressiveness Some of these files can then be externalized if necessary Since the unified configuration is aggregated from all classpath locations one can only externalize necessary values not whole files Other configuration files All other files are NOT participating in this unified configuration but can still be needed to configure various components like the LDAP component or the logging subsystem for instance These files can also be externalized if necessary but are outside of Seed control so they cannot be aggregated It means that they must be externalized a whole file at a time JNDI Another aspect of application configuration is the use of JNDI resources which can be provided by the runtime environment and configured administratively The JNDI name is used inside the application as an alias to an externally defined resource About this guide This guide will help you define which configuration aspects should be externalized and which shouldn t and the best practices for each one","summary":"Configuration is a crucial part of an application that can be difficult to get right. It encompasses multiple aspects,\nlike logging, internal configuration or externalisation and should be treated with the same care that code.\n\nConfiguration files\n\nUnified configuration\n\nSeed provides an unified...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"Make a configurable application","path":"make-configurable-application"}},{"title":"Logging","href":"/guides/make-configurable-application/logging","content":"Logging configuration is a very good candidate for externalisation since it will allow to change the log level of various components after deployment and even when the application is running if configured properly Logging configuration is often centralized in one file which can be wholly externalised without any risks Logging is a purely technical aspect of applications and can be entirely managed by the people in charge of the runtime environment Note that Seed applications are using the SLF4J logging API but are not usually dependant of a specific implementation Nonetheless we recommend using the Logback implementation because of its powerful configuration options and good runtime performance Logback The recommended SLF4J implementation for Seed applications is Logback It is mainly configurable through an XML file named logback xml that must present in the classpath in the default package e g as a top level resource callout info We strongly recommend that you include Seed default configuration for Logback by adding the following line in your logback xml file callout To properly externalise your logback xml file you have three options Add a logback xml file in a directory that will be added to the classpath BEFORE other classpath entries and as such will override any internal version of the file This option is RECOMMENDED in production Exclude logback xml from being packaged in the application As such the application will only log if you add a logback xml file to the classpath whatever the position of this classpath entry The main drawback is that the application won t log anything without an external logback configuration file so it is NOT RECOMMENDED in production Set the system property logback configurationFile to the path of the logback xml file This will override any classpath version of the file This property also accepts a classpath resource path if you want to place your file elsewhere in the classpath or to an accessible URL While this option can be useful for testing purposes and temporary overrides it is NOT RECOMMENDED in production callout warning Be sure that you have no logback test xml file in your main classpath or it will be picked by Logback instead of the logback xml file It can happen if you placed the test file in the main sources of your project instead of keeping it in the test folders callout You can find the full documentation about Logback configuration here http logback qos ch manual configuration html","summary":"Logging configuration is a very good candidate for externalisation, since it will allow to change the log level of\nvarious components after deployment and even when the application is running if configured properly. Logging configuration\nis often centralized in one file which can be wholly...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"Make a configurable application","path":"make-configurable-application"}},{"title":"Other resources","href":"/guides/make-configurable-application/other-resources","content":"Although props files can be used to externalise a lot an application configuration you will often need to externalise additional resources as well This section will lead you to a better understanding of all frequently encountered resources and if they need to be externalised callout info If you need to externalise props files please have a look at this page props instead callout JPA persistence xml Seed JPA persistence support allows you to completely avoid persistence xml usage and use classpath scanning instead to discover JPA entities But you can still use the explicit persistence xml file if you wish This file is located in the META INF directory of the classpath This file is purely internal to the application and shouldn t be externalised at all To externalise the database configuration you have two options Configure JPA to retrieve the data source through JNDI using a well defined name You can find more information on JPA JNDI configuration here addons jpa datasource via jndi It is strongly discouraged to externalise the JNDI name of the data source since this name can be used internally by the application The JPA unit name s shouldn t be externalised at all Use the Seed unified configuration to specify the data source properties Those can then be externalised using the props externalisation mechanism described here props","summary":"Although props files can be used to externalise a lot an application configuration, you will often need to externalise\nadditional resources as well. This section will lead you to a better understanding of all frequently encountered resources\nand if they need to be externalised. \n\n{{% callout info...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"Make a configurable application","path":"make-configurable-application"}},{"title":"Props and properties","href":"/guides/make-configurable-application/props","content":"Props files are the recommended way to specify key value pairs for the Seed unified configuration Properties files can also be used as a compatible alternative but with far less expressive power Full props documentation is available here docs seed manual core configuration Location To be recognized by Seed props files must end with the props extension and be located under the META INF configuration location in the classpath For a JAR file it means having at least this top level inner directory structure archive jar the JAR file META INF configuration props put all relevant props files here The same directory structure should be used when adding a filesystem directory in the classpath The added directory must contain this directory structure local directory the local directory added to the classpath META INF configuration props put all relevant props files here callout info Please note that when multiple files with the same name and in the same classpath location META INF configuration in this case are present only one file is visible from Java code which one depending on the classpath entries order To avoid this situation please be sure to name each props files differently denoting its purpose in the same for instance you can name them org myorganization myproject security props and org myorganization myproject app props and both of them will be picked It is sometimes desirable to use this characteristic to override a whole props file In that case be sure to put the location with the overriding file BEFORE the location with the overridden file callout Props files content You can use sections to help you write smaller props files A section is a brackets enclosed key name on its own line Every line after it will be prefixed with the section name To revert back to the global section without prefix use the empty section syntax Another trick of props files is that you can use macros Macros are enclosed key names which are replaced by the corresponding value if found anywhere in the unified configuration even if in another file of another classpath location The macros can be used to externalize only a part of a value to another key value pair located elsewhere System properties Props files can use system properties directly using the sys name of system property syntax This can be used to externalize values or parts of values as something that can be changed at every execution of the application by just passing a different Dname of system property value argument to the JVM The system property variable lookup is case sensitive The JVM has several predefined system properties http docs oracle com javase tutorial essential environment sysprop html which can also be used It is notably useful for defining paths using platform dependent separator or use the home or the temporary directory Environment variables Props files can also use environment variables directly using the env NAME_OF_ENV_VARIABLE syntax Please note that the environment variable lookup is case sensitive Externalisation As a best practice we recommend to use a controlled externalisation of application configuration It must be seen as a contract between the application and its runtime environment and as such between the people that own each To establish this contract you can follow this process For each props configuration file asks yourself if it needs to be externalised at all If some keys or some value parts need to be externalised only externalise those using macros replace the entire value or the part of the value by a macro referencing a key that you will externalise By limiting the configuration externalisation to the necessary parts you will improve the encapsulation and the modularity of your application You can view it as providing well defined setters for your internal configuration instead of making everything public If some keys or some value parts are better suited for externalisation via system properties or environment variables use the mechanisms described above to achieve this goal You will end with One or more internal configuration props file s Exactly one externalisation file per environment containing only the externalised key value pairs Optionally some system properties or environment variables that should be defined in the environment callout info As an alternative to the per environment externalisation files you can use a unique props externalisation file valued through a deployment specific process callout","summary":"Props files are the recommended way to specify key/value pairs for the Seed unified configuration. Properties files can\nalso be used as a compatible alternative but with far less expressive power. Full props documentation is available \nhere.\n\nLocation\n\nTo be recognized by Seed, props files must end...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"Make a configurable application","path":"make-configurable-application"}},{"title":"Storage","href":"/guides/make-configurable-application/storage","content":"Seed defines a default local directory that can be used by applications for persistent file storage without bothering about its location It helps keeping application files under one parent directory that can be reconfigured at will The contents of this directory depends on the enabled Seed supports some supports are using this folder internally and of the application usage Seed usage Shell support If the shell support is configured to auto generate an SSH key on first connection as it is by default it will store its auto generated SSH key in the shell sub directory of the application storage Application usage Applications can request a subdirectory inside the Seed storage directory for any purpose It is the responsibility of the application to manage this subdirectory and its contents Location Default location of the Seed storage directory is in the home directory of the user used to start the application home seed appId this directory is named after the application identifier This is a quite usual location in UNIX and Windows systems and is adequate for light storage needs To accommodate heavier needs or for any other reason this location can be changed to any local directory by setting the org seedstack seed core storage configuration property org seedstack seed core application id prd00 core storage users prd00 data seed callout info If you have multiple Seed applications running on the same server be sure to have set a unique identifier for each It will avoid any storage directory collision if you uses the default location If you specify the location manually be sure to specify a different location for each application storage directories cannot be shared between Seed instances In all cases each application MUST have a different identifier callout callout info Note that this value can be externalised as any configuration value see this page props for more details callout","summary":"Seed defines a default local directory that can be used by applications for persistent file storage without bothering\nabout its location. It helps keeping application files under one parent directory that can be reconfigured at will. The\ncontents of this directory depends on the enabled Seed...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"Make a configurable application","path":"make-configurable-application"}},{"title":"Using SeedStack development snapshots","href":"/guides/using-snapshots/","content":"Sometimes there is a need to use a development version of a SeedStack component in your project for testing purposes SeedStack Java components are available as Maven dependencies at the following locations Releases are available on Bintray https bintray com seedstack jars JCenter https bintray com bintray jcenter and Maven central http search maven org Development snapshots are available on JFrog OSS Artifactory https oss jfrog org artifactory webapp artifacts browse simple General oss snapshot local org seedstack Proxy configuration In the case where you are behind a corporate proxy you must configure Maven to go through the proxy You can do so by following this documentation https maven apache org guides mini guide proxies html Configuring Maven for SeedStack snapshots You can configure access to SeedStack snapshots located on JFrog OSS Artifactory You can do this either specifically for a project or globally in your system wide Maven settings Project specific To access snapshots you need to add the following repository definitions to your project POM ojo libs snapshot ojo snapshots https oss jfrog org artifactory libs snapshot false true ojo libs snapshot ojo snapshots https oss jfrog org artifactory libs snapshot false true callout info Note that the section is only needed if you want use development snapshots of SeedStack Maven plugin http seedstack org docs seed maven plugin callout System wide configuration Update your Maven settings xml file which is located by default under m2 settings xml with the following profile ojo snapshots ojo libs snapshot ojo snapshots https oss jfrog org artifactory libs snapshot false true ojo libs snapshot ojo snapshots https oss jfrog org artifactory libs snapshot false true callout info Similarly to project specific configuration the section is only needed if you want use development snapshots of SeedStack Maven plugin http seedstack org docs seed maven plugin callout You can activate the ojo snapshots profile on demand or choose to always enable it by adding the following section to your settings xml file ojo snapshots","summary":"Sometimes there is a need to use a development version of a SeedStack component in your project, for testing purposes.\nSeedStack Java components are available as Maven dependencies at the following locations:\n\nReleases are available on Bintray, JCenter\nand Maven central.Development snapshots are...","zone":{"path":"/guides","label":"Guides","logo":"guides-logo.svg"},"section":{"label":"Using SeedStack development snapshots","path":"using-snapshots"}},{"title":"15.11.1 release notes","tags":["release"],"href":"/posts/15-11-1-release-notes","content":"We are happy to announce the release of SeedStack 15 11 1 an incremental update of SeedStack 15 11 Changes Validation The validation add on http seedstack org addons validation has been improved to better conform with the Bean Validation specification The custom ValidationService is deprecated and should be replaced by the class Validator which can be injected or obtained through the injectable ValidatorFactory JDBC JPA JMS Minor fixes of error messages which referenced outdated information I18n The i18n add on http seedstack org addons i18n performance has been vastly improved both for translation initial loading and during heavy use better caching implementation The translations of the add on itself have been moved to static files in its W20 frontend instead of being automatically populated backend keys The CSV import throwing exceptions has been fixed Beware that this version uses a different database mapping which is incompatible with tables from previous versions The upgrade procedure is Export your keys and translations to a CSV file with your current version Drop old i18n tables Upgrade to the latest i18n version and let it recreate the tables Import your keys and translation A detailed blog post will soon be published with the procedure details W20 bridge The W20 bridge add on http seedstack org addons w20 bridge contains minor fixes and the latest version of W20 and it add ons The main evolution of W20 is the upgrade to AngularJS 1 4 8 and Bootstrap 3 3 6 New features JAX RS 2 The version 2 of JAX RS standard has been integrated in the Java framework through the Jersey 2 library You can now benefits of all the improvements of the JAX RS 2 specification such as Bean validation of parameters and return values The ability to group parameters in reusable BeanParam classes Asynchronous resources The JAX RS 2 specification is backwards compatible with JAX RS 1 so you can easily upgrade by replacing your seed rest jersey1 dependency with seed rest jersey2 The configuration options are unchanged except if you happened to have specified custom Jersey properties In that case replace them with their Jersey 2 equivalent https jersey java net documentation latest appendix properties html Swagger A new Swagger http swagger io add on has been released and can be used to expose JSON information about your application API This can be used by Swagger clients to display and document your REST API automatically Some devices like API management tools can also autoconfigure themselves by using this Swagger description To enable the Swagger add on simply add it to your project dependencies The Swagger description will then be available on http myserver org swagger json for the JSON format http myserver org swagger yaml for the YAML format Component versions Updated components are highlighted in bold characters Base poms 2 3 0 https github com seedstack poms releases tag v2 3 0 seed 2 2 0 https github com seedstack seed releases tag v2 2 0 business 2 2 0 https github com seedstack business releases tag v2 2 0 w20 2 2 0 https github com seedstack w20 releases tag v2 2 0 Add ons audit addon 2 1 0 monitoring addon 2 1 0 elasticsearch addon 2 1 0 i18n addon 2 2 0 https github com seedstack i18n addon releases tag v2 2 0 io addon 2 1 0 javamail addon 2 1 0 jcache addon 2 1 0 jdbc addon 2 1 2 https github com seedstack jdbc addon releases tag v2 1 2 jms addon 2 1 1 https github com seedstack jms addon releases tag v2 1 1 jpa addon 2 1 2 https github com seedstack jpa addon releases tag v2 1 2 ldap addon 2 1 0 mongodb addon 1 0 0 neo4j addon 1 0 0 redis addon 1 0 0 scheduling addon 2 1 0 solr addon 1 0 0 spring bridge addon 2 2 0 swagger addon 1 0 0 https github com seedstack swagger addon releases tag v1 0 0 new validation addon 2 2 0 https github com seedstack validation addon releases tag v2 2 0 w20 bridge addon 2 2 0 https github com seedstack w20 bridge addon releases tag v2 2 0 web services addon 2 1 1 w20 extras 2 1 1 https github com seedstack w20 extras releases tag v2 1 1 w20 dataviz 2 1 1 https github com seedstack w20 dataviz releases tag v2 1 1 w20 material 2 1 3 https github com seedstack w20 material releases tag v2 1 3 w20 components 2 2 0 https github com seedstack w20 components releases tag v2 2 0 w20 bootstrap 2 2 1 2 https github com seedstack w20 bootstrap 2 releases tag v2 1 2 w20 bootstrap 3 2 1 2 https github com seedstack w20 bootstrap 3 releases tag v2 1 2 Themes w20 simple theme 3 1 1 https github com seedstack w20 simple theme releases tag v3 1 1 w20 business theme 1 1 3 https github com seedstack w20 business theme releases tag v1 1 3","summary":"We are happy to announce the release of SeedStack 15.11.1, an incremental update of SeedStack 15.11.\n\nChanges\n\nValidation\n\nThe validation add-on has been improved to better conform with the Bean\nValidation specification. The custom ValidationService is deprecated and should be replaced by the class...","zone":{"path":"/posts","label":"Posts","logo":"blog-logo.svg"},"section":{"path":""}},{"title":"15.11.2 release notes","tags":["release"],"href":"/posts/15-11-2-release-notes","content":"We are happy to announce the release of SeedStack 15 11 2 the second incremental update of SeedStack 15 11 Fixes This mainly fixes the MongoDB Neo4J Redis and Solr add ons which were not released correctly and therefore not usable at all A minor fix is also present in W20 Component versions Updated components are highlighted in bold characters with a link to the detailed change log Base poms 2 3 0 seed 2 2 0 business 2 2 0 w20 2 2 1 https github com seedstack w20 releases tag v2 2 1 Add ons audit addon 2 1 0 monitoring addon 2 1 0 elasticsearch addon 2 1 0 i18n addon 2 2 0 io addon 2 1 0 javamail addon 2 1 0 jcache addon 2 1 0 jdbc addon 2 1 2 jms addon 2 1 1 jpa addon 2 1 2 ldap addon 2 1 0 mongodb addon 1 0 1 https github com seedstack mongodb addon releases tag v1 0 1 neo4j addon 1 0 1 https github com seedstack neo4j addon releases tag v1 0 1 redis addon 1 0 1 https github com seedstack redis addon releases tag v1 0 1 scheduling addon 2 1 0 solr addon 1 0 1 https github com seedstack solr addon releases tag v1 0 1 spring bridge addon 2 2 0 swagger addon 1 0 0 validation addon 2 2 0 w20 bridge addon 2 2 1 https github com seedstack w20 bridge addon releases tag v2 2 1 web services addon 2 1 1 w20 extras 2 1 1 w20 dataviz 2 1 1 w20 material 2 1 4 https github com seedstack w20 material releases tag v2 1 4 w20 components 2 2 0 w20 bootstrap 2 2 1 2 w20 bootstrap 3 2 1 2 Themes w20 simple theme 3 1 1 w20 business theme 1 1 3","summary":"We are happy to announce the release of SeedStack 15.11.2, the second incremental update of SeedStack 15.11.\n\nFixes\n\nThis mainly fixes the MongoDB, Neo4J, Redis and Solr add-ons which were not released correctly and therefore not\nusable at all. A minor fix is also present in W20.\n\nComponent versions...","zone":{"path":"/posts","label":"Posts","logo":"blog-logo.svg"},"section":{"path":""}},{"title":"15.11 release notes","tags":["release"],"href":"/posts/15-11-release-notes","content":"We are happy to announce the release of SeedStack 15 11 codenamed Hibiscus This new version comes with a new add on architecture and several new features like business framework improvements a full featured cryptography module and support for several NoSQL technologies Automatic upgrade The vast majority of upgrade tasks can be carried on by our automatic upgrade tool To automatically upgrade your project download the tool executable available here https github com seedstack tools releases go to your project root directory and execute the following command line plain seed t https raw githubusercontent com seedstack distribution master upgrades 15 7 to 15 11 upgrade toml fix Note that a small amount of tasks cannot be done automatically by the upgrade tool and must be applied manually The rest of this post describes all changes made by the tool but also details the eventual changes you need to apply Changes Add on architecture A lot of modules have been extracted as add ons As such the foundation frameworks are lighter and simpler to understand The full list of available add ons is available here addons Click on the add on title to access its documentation callout info The refactoring into add ons doesn t induce any behavior breaking change These changes are automatically done by the upgrade tool but some cleanup may be required Some previous dependencies have been merged into a unique dependency and the tool is currently unable to eliminate the leftover duplicates Please check your POM files for duplicate dependencies Don t forget that some dependencies can be duplicated through inheritance Business framework JPA specific classes have been moved to the JPA add on As such the tool will convert any business jpa dependency into a jpa add on dependency If you did not also have the business core dependency in the first place it will be missing add it manually if you re in that case callout Simplified packaging We have also simplified our package naming conventions All the APIs of a module are under the package org seedstack modulename For instance org seedstack jpa for the JPA add on or org seedstack business for the business framework The api sub package has been merged into the module top level package When an SPI is provided it is still located under org seedstack modulename spi Finally all internal classes are located under org seedstack modulename internal No compatibility is guaranteed for internal classes so your code should never rely on them callout info The simplified packaging doesn t induce any behavior breaking change These changes are automatically done by the upgrade tool callout callout tips As the package layout is simpler we decided to aggregate the Javadoc for the whole distribution foundation frameworks and official add ons into a unique aggregated Javadoc javadoc callout Simplified configuration The configuration prefixes have also been updated to reflect these changes This ini org seedstack seed persistence jpa units org seedstack seed persistence jdbc datasources Becomes ini org seedstack jpa units org seedstack jdbc datasources callout info These changes are automatically done by the upgrade tool but some cleanup may be required If a part of a key is defined as a section the upgrade tool may not recognize it ini org seedstack seed persistence jpa units jdbc datasources In this case as the keys are broken apart the tool cannot recognize the whole key and will not replace it Please review your configuration files for any occurence of this case callout Dependency management To avoid leaking dependency management in your projects we have removed it all from SeedStack modules Of course the distribution BOM still exists but importing it will not manage dependencies outside the SeedStack itself In the same reduction spirit we have removed a lot of libraries bring by Seed If you rely on some of them for your project add their version explicitly in your pom xml file Dependency reduction To reduce the footprint of SeedStack we removed dependencies that were not strictly necessary Please add the required one s back to your pom xml Compile scope plain commons beanutils commons beanutils 1 8 3 org json json 20140107 commons lang commons lang 2 6 Test scope plain commons io commons io 2 4 pl pragmatists JUnitParams 1 0 3 org easytesting fest reflect 1 4 1 org json json 20140107 org jukito jukito 1 1 org hamcrest hamcrest core 1 3 org hamcrest hamcrest library 1 3 org powermock powermock core 1 6 2 org powermock powermock api mockito 1 6 2 org powermock powermock module junit4 1 6 2 org skyscreamer jsonassert 1 2 3 W20 fragments refactoring The W20 framework has been further modularized Every fragment has become an addon to the exception of the core fragment which is mandatory The w20 ui fragment has been removed and its rich components UI Grid and UI Select have been moved to a new w20 components fragment Its CSS framework independent code has been merged into w20 core Bootstrap 3 and UI Bootstrap have been moved to a new w20 bootstrap 3 fragment The w20 components fragment is new and contains the UI Grid and UI Select rich components previously found in the w20 ui fragment The w20 bootstrap 3 fragment is new and contains the Bootstrap 3 CSS framework with its corresponding UI Bootstrap helper The w20 bootstrap 2 fragment is new and contains the Bootstrap 2 CSS framework with its corresponding UI Bootstrap helper The w20 material fragment is new and contains the Angular Material CSS framework This allows to use alternative CSS frameworks with W20 such as the older Bootstrap 2 for compatibility purposes or Angular Material https material angularjs org to easily implement material design https www google com design spec material design introduction html Bootstrap 4 support will be introduced as a fragment when released For w20 bridge addon user it is necessary to include the additional fragments which was all previously distributed by the w20 bridge web artifact For instance this is the declaration necessary for including the w20 core w20 dataviz w20 bootstrap 3 and w20 business theme fragments in maven org seedstack addons w20 w20 bridge web org seedstack addons w20 w20 bridge web dataviz org seedstack addons w20 w20 bridge web bootstrap 3 org seedstack addons w20 w20 bridge web business theme New features Cryptography Seed provides a new cryptography module docs seed manual crypto which allow you to easily configure and use keystores It also provides a simpler API to encrypt and decrypt data Domain registry A domain registry has been added to the Business framework It allows to dynamically retrieve a domain object instance This is particularly useful when you have multiple implementations for the same interface and you need to programatically choose a specific implementation The is often the case for policies For instance if you want to choose a tax policy according the user s locale you can do it as follows java TaxPolicy taxPolicy domainRegistry getPolicy TaxPolicy class userLocale A static equivalent would be limited to an hard coded locale value java Inject Named fr TaxPolicy taxPolicy callout tips This new registry can be used for factories policies repositories and services callout Spring managed JPA transactions When using the Spring bridge add on you can now let Spring manage the JPA transactions across framework boundaries In this case Seed code will be injected with a Spring managed JPA entity manager instead of the Seed managed one This is particularly useful in Spring batch jobs where there are clear performance benefits to let Spring batch manage the transactions More information about this feature here addons spring bridge transactions NoSQL add ons Three new add ons are now provided to use popular NoSQL databases MongoDB add on addons mongodb Redis add on addons redis Neo4J add on addons neo4j Solr add on A Solr add on addons solr is now provided to access Solr indexing servers Component versions Base poms 2 1 1 seed 2 1 0 business 2 1 0 w20 2 1 1 Add ons audit addon 2 1 0 monitoring addon 2 1 0 elasticsearch addon 2 1 0 i18n addon 2 1 0 io addon 2 1 0 javamail addon 2 1 0 jcache addon 2 1 0 jdbc addon 2 1 1 jms addon 2 1 0 jpa addon 2 1 1 ldap addon 2 1 0 mongodb addon 1 0 0 neo4j addon 1 0 0 redis addon 1 0 0 scheduling addon 2 1 0 solr addon 1 0 0 spring bridge addon 2 2 0 validation addon 2 1 0 w20 bridge addon 2 1 1 web services addon 2 1 1 w20 extras 2 1 0 w20 dataviz 2 1 0 w20 material 2 1 1 w20 components 2 1 1 w20 bootstrap 2 2 1 1 w20 bootstrap 3 2 1 1 Themes w20 simple theme 3 1 0 w20 business theme 1 1 0","summary":"We are happy to announce the release of SeedStack 15.11, codenamed "Hibiscus". This new version comes with a new \nadd-on architecture and several new features like business framework improvements, a full-featured cryptography \nmodule and support for several NoSQL technologies.\n\nAutomatic...","zone":{"path":"/posts","label":"Posts","logo":"blog-logo.svg"},"section":{"path":""}},{"title":"I18n-addon 2.1.1","tags":["release","i18n"],"href":"/posts/i18n-2.1.1-release-notes","content":"The 2 1 1 version of the i18n add on has been released with fixes and minor new features This version will be integrated in an upcoming distribution version but for now you have to define this dependency management manually in your parent POM org seedstack addons i18n i18n specs 2 1 1 org seedstack addons i18n i18n rest 2 1 1 org seedstack addons i18n i18n core 2 1 1 org seedstack addons i18n i18n web 2 1 1 Fixes Regional locales fixes First we have fixed the localization issues which appeared when regional locales like es AR were used This was due to a mismatch between standard locale codes es AR and Java locale codes es AR It is now possible to use regional locales without any issue but you will have to alter your i18n data replace underscores _ by dashes in the locale codes Import fixes The CSV import feature has also been fixed It is now possible to import multiple translation files New features Mixing frontend and backend translations By default when a translation is missing for a given locale the i18n addon doesn t return a translation to the frontend In this case W20 fallback to the default locale This can be useful as it maximize the amount of translated keys even if some translations are missing in a language but it can lead to pages with mixed languages To avoid this mix a strict mode can now be enabled When it is enabled the i18n add on will the return the key name between brackets for the missing translations You can enable it by add the following configuration org seedstack i18n allow missing translation false In that case the W20 frontend will display the untranslated keys between brackets instead of fallback to the default language making it easier to spot the lacking translations Custom locales Declaring custom locales previously required specifying three properties It is now simpler as you just have to declare one org seedstack i18n additional locales br FR ca ES The names of the custom locales will be automatically derived from the codes","summary":"The 2.1.1 version of the i18n add-on has been released with fixes and minor new features. This version will be integrated\nin an upcoming distribution version but for now you have to define this dependency management manually in your parent\nPOM:\n\n<dependency>\n    <groupId>org.seedstack...","zone":{"path":"/posts","label":"Posts","logo":"blog-logo.svg"},"section":{"path":""}},{"title":"I18n-addon 2.2.0","tags":["release","i18n"],"href":"/posts/i18n-2.2.0-release-notes","content":"The 2 2 0 version of the i18n add on has been released with fixes and improved performance This version will be integrated in an upcoming distribution version but for now you have to define this dependency management manually in your parent POM org seedstack addons i18n i18n specs 2 2 0 org seedstack addons i18n i18n rest 2 2 0 org seedstack addons i18n i18n core 2 2 0 org seedstack addons i18n i18n web 2 2 0 Fixes CSV import will no longer add null translations no more NullPointerException on import Changes Performance The translation mechanism has been rewritten in order to provide vastly better performance on the first load and in subsequent uses However this refactoring had some impact on the database model So in order to upgrade to this new version you will have to backup your data using the CSV import export Then regenerate the SQL schema with the new structure You can use JPA to generate it for you or you can use the following scripts https github com seedstack i18n addon tree master scripts Addon translations The i18n addon UI has always been internationalized But it doesn t make sense to pollute your translations with translations comming from the addon itself That is why we decided to move all the addon translations into json files using the W20 i18n mechanism Documentation The documentation http seedstack org addons i18n has also been rewritten in order to be more simple and straightforward","summary":"The 2.2.0 version of the i18n add-on has been released with fixes and improved performance. This version will be integrated\nin an upcoming distribution version but for now you have to define this dependency management manually in your parent\nPOM:\n\n<dependency>\n    <groupId>org.seedstack...","zone":{"path":"/posts","label":"Posts","logo":"blog-logo.svg"},"section":{"path":""}},{"title":"Welcome to SeedStack","href":"/posts/welcome-to-seedstack","content":"Welcome to SeedStack an Open Source enterprise class development stack for building modern and robust applications SeedStack has been derived from a PSA Peugeot Citro n http www psa peugeot citroen com internal development stack It was fully created in house starting at the beginning of 2013 and is now used by more than 40 projects with more than 20 projects in production","summary":"Welcome to SeedStack, an Open-Source enterprise-class development stack for building modern and robust applications.\nSeedStack has been derived from a PSA Peugeot Citroën internal development\nstack. \n\nIt was fully created in-house, starting at the beginning of 2013, and is now used by more than 4...","zone":{"path":"/posts","label":"Posts","logo":"blog-logo.svg"},"section":{"path":""}},{"title":"Build","href":"/project/build","content":"callout info All compatibility tests have been done with docker containers callout SeedStack is automatically tested against several runtime environment which are listed on this page with the corresponding results Tested Features JPA with persistence xml file JPA with Seed configuration in a props file so without persistence xml Basic REST test Other tests and other application servers will be added in the future Application Servers as build Notes as notes","summary":"\n\nAll compatibility tests have been done with docker containers.\n\n\nSeedStack is automatically tested against several runtime environment which are listed on this page with the...","zone":{"path":"/project","label":"Project","logo":"project-logo.svg"},"section":{"label":"Build","icon":"fa fa-cogs","path":""}},{"title":"Overview","href":"/project/community/","content":"SeedStack has just arrived on the Open Source scene Nonetheless we already have the tools to let people discuss about SeedStack file issues ask for help and simply discover the stack together IRC The seedstack irc chat freenode net seedstack IRC on the Freenode community is intended to chat with the SeedStack team and other users Mailing list You can ask for support on the Google Group https groups google com forum forum seedstack or directly on the mailing list by sending an email to seedstack googlegroups com mailto seedstack googlegroups com callout info Note that you must already belong to the group to be able to participate To join go to the Google Group https groups google com forum forum seedstack and click the Join button callout StackOverflow If you have any question or problem please use StackOverflow http stackoverflow com and make sure to tag your question with seedstack Twitter You can follow seedstack https twitter com intent follow screen_name seedstack to stay in touch or simply share your experience with SeedStack or by tweeting about it using the seedstack hashtag","summary":"SeedStack has just arrived on the Open-Source scene. Nonetheless we already have the tools to let people discuss about\nSeedStack, file issues, ask for help and simply discover the stack together.\n\nIRC\n\nThe #seedstack IRC on the Freenode community is intended to chat with the SeedStack \nteam and...","zone":{"path":"/project","label":"Project","logo":"project-logo.svg"},"section":{"label":"Community","icon":"fa fa-community","path":"community"}},{"title":"Project members","href":"/project/community/members","content":"Core team The core team is composed of full time dedicated members member Adrien LAUER https avatars2 githubusercontent com u 2498919 v 3 https github com adrienlauer https twitter com adrienlauer Software engineer with 10 years of experience he worked on various Java projects at PSA Peugeot Citro n before creating the W20 Web framework in 2011 He joined the SeedStack team in 2013 at the beginning of the project Since then he has actively contributed to define and implement the whole solution member member Kavi RAMYEAD https avatars0 githubusercontent com u 5616469 v 3 https github com kavi87 Software frontend developer he worked on various Java web projects He joined the SeedStack team in the end of 2013 Since then he mainly works on the front end framework W20 and on the productivity tools member member Marius MATEI https avatars2 githubusercontent com u 3427528 v 3 https github com cmmatei https twitter com C_M_Matei Marius Matei is the SeedStack Program Manager He contributed on various Java web applications as Senior software architect IT Manager or Team Leader before building the SeedStack team and putting on the rails the SeedStack enterprise software project member member Pierre THIROUIN https avatars3 githubusercontent com u 2495124 v 3 https github com pith https twitter com pierrethirouin Software developer for Infotel he worked on various Java projects in the industry and banking sectors He joined the SeedStack team in the end of 2013 Since then he mainly works on the Java and Business frameworks plus some tooling and SeedStack functions member member Thierry BOUVET https avatars2 githubusercontent com u 12045960 v 3 https github com tbouvet Software engineer with 15 years of experience he worked on various Java projects at PSA Peugeot Citro n before joining SeedStack team He has actively contributed to define implement the whole solution He actively contributes to improve SeedStack usage and development performance member Active members Active members are frequently contributing to SeedStack member po JEMBA https avatars2 githubusercontent com u 887400 v 3 https github com ejemba member member Redouane LOULOU https avatars2 githubusercontent com u 9444088 v 3 https github com red1l member member Tuan DO CAO https avatars0 githubusercontent com u 8062405 v 3 https github com notoon member member Yves DAUTREMAY https avatars3 githubusercontent com u 3729195 v 3 https github com ydautremay member All contributors All contributors to SeedStack past and present are listed below Thanks to all of them for their time and effort callout info If you contributed to SeedStack code or documentation or want to you should appear in this list To register your name here please open a pull request on the seedstack repository https github com seedstack seedstack to update the CONTRIBUTORS file If relevant the AUTHORS file may be updated too callout","summary":"Core team\n\nThe core team is composed of full-time dedicated members.\n\n<ul class="list-unstyled team-v1">\n\n{{% member "Adrien LAUER" "https://avatars2.githubusercontent.com/u/2498919?v=3" "https://github.com/adrienlauer" "https://twitter.com...","zone":{"path":"/project","label":"Project","logo":"project-logo.svg"},"section":{"label":"Community","icon":"fa fa-community","path":"community"}},{"title":"Users","href":"/project/community/users","content":"user PSA Peugeot Citro n img clients psa svg France Car manufacturing http www psa peugeot citroen com Since the end of 2013 SeedStack is the foundation of all the new enterprise applications of PSA Peugeot Citro n More than 50 Java web information systems for different domains like vehicle trading research and development digital manufacturing quality billing and monitoring are based on SeedStack components Built first as a key lever for optimizing the PSA s application development costs the stack was consolidated for 2 years to ensure now the operational excellence of the IT projects portfolio from all the enterprise s domains More than 250 people shared their Java development experience since 2013 by using SeedStack user callout info If you use SeedStack and want to appear on this page please let us know by opening an issue on the Website repository https github com seedstack website callout","summary":"\nSince the end of 2013 SeedStack is the foundation of all the new enterprise applications of "PSA Peugeot Citroën&quot...","zone":{"path":"/project","label":"Project","logo":"project-logo.svg"},"section":{"label":"Community","icon":"fa fa-community","path":"community"}},{"title":"FAQ","href":"/project/faq","content":"Answers to common questions about SeedStack How is SeedStack licensed SeedStack code is licensed under the Mozilla Public License 2 0 https www mozilla org MPL 2 0 The documentation is licensed under the Creative Commons Share Alike 4 0 license http creativecommons org licenses by sa 4 0 Can I use the Web Framework without the Java Framework Yes the Web and Java frameworks are independent and can be used separately Various projects are already using W20 with other backend technologies such as PHP or even Perl How to get help for a SeedStack related problem If you have any question or problem please use StackOverflow http stackoverflow com and make sure to tag your question with seedstack You can also use the Google Group https groups google com forum forum seedstack or directly the mailing list via seedstack googlegroups com mailto seedstack googlegroups com We are available on the Freenode IRC community at seedstack irc freenode net seedstack Can I contribute to the project Sure We would love to accept contributions Here is a guide https github com seedstack seedstack blob master CONTRIBUTING md explaining how to contribute Your FAQ is weak It did not answer my question Open an issue https github com seedstack website issues on the website repository or ask us directly on IRC at seedstack irc freenode net seedstack or on the Google Group https groups google com forum forum seedstack","summary":"Answers to common questions about SeedStack.\n\nHow is SeedStack licensed ?\n\nSeedStack code is licensed under the Mozilla Public License 2.0. The documentation\nis licensed under the Creative Commons Share-Alike 4.0 license.\n\nCan I use the Web Framework without the Java Framework ?\n\nYes, the Web and...","zone":{"path":"/project","label":"Project","logo":"project-logo.svg"},"section":{"label":"FAQ","icon":"fa fa-comments-o","path":"faq"}},{"title":"Overview","href":"/project/","content":"This section is about the SeedStack project itself Find out more by browsing the menu sections above","summary":"This section is about the SeedStack project itself. Find out more by browsing the menu sections above.","zone":{"path":"/project","label":"Project","logo":"project-logo.svg"},"section":{"label":"Overview","icon":"fa fa-file-text","path":""}}]