From 389e3a6a73020cb3ad9471defd95ffbd84be0811 Mon Sep 17 00:00:00 2001 From: jomu Date: Thu, 15 Nov 2018 10:54:34 +0100 Subject: [PATCH] optimized startup sequence --- account-ui/pom.xml | 1 + .../account/web/ApplicationController.java | 59 --------- .../account/web/ApplicationProducer.java | 67 ---------- .../application/boundary/StartupBean.java | 71 +++++++++++ .../control/ApplicationController.java | 116 ++++++++++++++++++ .../src/main/resources/buildInfo.properties | 3 +- .../account/entity/AccountEntity.java | 1 + .../config/boundary/ConfigService.java | 5 +- 8 files changed, 195 insertions(+), 128 deletions(-) delete mode 100644 account-ui/src/main/java/de/muehlencord/shared/account/web/ApplicationController.java delete mode 100644 account-ui/src/main/java/de/muehlencord/shared/account/web/ApplicationProducer.java create mode 100644 account-ui/src/main/java/de/muehlencord/shared/account/web/business/application/boundary/StartupBean.java create mode 100644 account-ui/src/main/java/de/muehlencord/shared/account/web/business/application/control/ApplicationController.java diff --git a/account-ui/pom.xml b/account-ui/pom.xml index bcae1a2..3522df6 100644 --- a/account-ui/pom.xml +++ b/account-ui/pom.xml @@ -17,6 +17,7 @@ UTF-8 ${maven.build.timestamp} + 143a2bd3-7e0b-4162-a76e-3031331c7dfe 10 10 diff --git a/account-ui/src/main/java/de/muehlencord/shared/account/web/ApplicationController.java b/account-ui/src/main/java/de/muehlencord/shared/account/web/ApplicationController.java deleted file mode 100644 index 084d3a4..0000000 --- a/account-ui/src/main/java/de/muehlencord/shared/account/web/ApplicationController.java +++ /dev/null @@ -1,59 +0,0 @@ -package de.muehlencord.shared.account.web; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; -import javax.annotation.PostConstruct; -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Named; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author joern.muehlencord - */ -@Named(value = "applicationController") -@ApplicationScoped -public class ApplicationController { - - private final static Logger LOGGER = LoggerFactory.getLogger(ApplicationController.class.getName()); - - private String version; - private String buildDate; - - @PostConstruct - public void init() { - InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("buildInfo.properties"); - if (in == null) { - return; - } - - Properties props = new Properties(); - try { - props.load(in); - - version = props.getProperty("build.version"); - buildDate = props.getProperty("build.timestamp"); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("buildInfo.properties read successfully"); - } - - } catch (IOException ex) { - LOGGER.error("Cannot find buildInfo.properties. ", ex); - version = "??"; - buildDate = "??"; - } - - } - - /* *** getter / setter *** */ - public String getVersion() { - return version; - } - - public String getBuildDate() { - return buildDate; - } -} diff --git a/account-ui/src/main/java/de/muehlencord/shared/account/web/ApplicationProducer.java b/account-ui/src/main/java/de/muehlencord/shared/account/web/ApplicationProducer.java deleted file mode 100644 index f6c4239..0000000 --- a/account-ui/src/main/java/de/muehlencord/shared/account/web/ApplicationProducer.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2018 Joern Muehlencord . - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package de.muehlencord.shared.account.web; - -import de.muehlencord.shared.account.business.application.boundary.ApplicationService; -import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; -import java.util.UUID; -import javax.annotation.PostConstruct; -import javax.ejb.EJB; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Produces; -import javax.inject.Named; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author Joern Muehlencord - */ -@Named("applicationProdiucer") -@ApplicationScoped -public class ApplicationProducer { - - private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationProducer.class); - - @EJB - ApplicationService applicationService; - - private ApplicationEntity application = null; - - @PostConstruct - public void init() { - String id = "143a2bd3-7e0b-4162-a76e-3031331c7dfe"; // TODO load from properties file - this.application = applicationService.findById(UUID.fromString(id)); - if (application == null) { - LOGGER.error("Could not find application with id "); - } else { - LOGGER.info("Found application {} for id{}", application.getApplicationName(), id); - } - } - - /** - * needs to return link to "Account UI" and not to current selected - * application TODO: ensure only Account UI can call functions where - * appliction can be handed in all other applications need to call the - * function which use the injected application - */ - @Produces - public ApplicationEntity getApplication() { - return application; - - } - -} diff --git a/account-ui/src/main/java/de/muehlencord/shared/account/web/business/application/boundary/StartupBean.java b/account-ui/src/main/java/de/muehlencord/shared/account/web/business/application/boundary/StartupBean.java new file mode 100644 index 0000000..a3005dd --- /dev/null +++ b/account-ui/src/main/java/de/muehlencord/shared/account/web/business/application/boundary/StartupBean.java @@ -0,0 +1,71 @@ +/* + * Copyright 2018 Joern Muehlencord . + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.muehlencord.shared.account.web.business.application.boundary; + +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import de.muehlencord.shared.account.business.config.boundary.ConfigService; +import de.muehlencord.shared.account.business.config.entity.ConfigException; +import javax.annotation.PreDestroy; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.Initialized; +import javax.enterprise.event.Observes; +import javax.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Joern Muehlencord + */ +@ApplicationScoped +public class StartupBean { + + private static final Logger LOGGER = LoggerFactory.getLogger(StartupBean.class); + + @Inject + ConfigService configService; + + @Inject + ApplicationEntity application; + + public void init(@Observes @Initialized(ApplicationScoped.class) Object init) { + try { + LOGGER.info("Starting application {}", application.getApplicationName()); + String instanceName = configService.getConfigValue("base.instance", "Development System", true); + LOGGER.info("instanceName={}", instanceName); + + // ensure maxFailedLogins is available + configService.getConfigValue("account.maxFailedLogins", "5", true); + + LOGGER.info("Application startup complete"); + } catch (ConfigException ex) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(ex.toString(), ex); + } else { + LOGGER.error(ex.toString()); + } + } + } + + @PreDestroy + public void shutdown() { + LOGGER.info("Shutting down application {}", application.getApplicationName()); + + + LOGGER.info("Application shutdown complete"); + } + +} diff --git a/account-ui/src/main/java/de/muehlencord/shared/account/web/business/application/control/ApplicationController.java b/account-ui/src/main/java/de/muehlencord/shared/account/web/business/application/control/ApplicationController.java new file mode 100644 index 0000000..a3154f6 --- /dev/null +++ b/account-ui/src/main/java/de/muehlencord/shared/account/web/business/application/control/ApplicationController.java @@ -0,0 +1,116 @@ +/* + * Copyright 2018 Joern Muehlencord . + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.muehlencord.shared.account.web.business.application.control; + +import de.muehlencord.shared.account.business.application.boundary.ApplicationService; +import de.muehlencord.shared.account.business.application.entity.ApplicationEntity; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import java.util.UUID; +import javax.annotation.PostConstruct; +import javax.ejb.EJB; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; +import javax.inject.Named; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Joern Muehlencord + */ +@Named("applicationController") +@ApplicationScoped +public class ApplicationController { + + private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationController.class); + + @EJB + ApplicationService applicationService; + + private String version; + private String buildDate; + private UUID uuid; + private ApplicationEntity application = null; + + @PostConstruct + public void readBuildInfoProperties() { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Trying to read buildInfo.properties"); + } + InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("buildInfo.properties"); + if (in == null) { + return; + } + Properties props = new Properties(); + try { + props.load(in); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("properties read from buildInfo.properties"); + } + + version = props.getProperty("build.version"); + buildDate = props.getProperty("build.timestamp"); + uuid = UUID.fromString(props.getProperty("application.uuid")); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("buildInfo.properties parsed successfully"); + } + + } catch (IOException ex) { + LOGGER.error("Cannot find buildInfo.properties. ", ex); + version = "??"; + buildDate = "??"; + uuid = null; + LOGGER.error("Application id not readable, application will not be able to run"); + } + + if (uuid != null) { + this.application = applicationService.findById(uuid); + if (application == null) { + LOGGER.error("Could not find application with id "); + } else { + LOGGER.info("Found application {} with id {}", application.getApplicationName(), uuid.toString()); + } + } + } + + /** + * needs to return link to "Account UI" and not to current selected + * application TODO: ensure only Account UI can call functions where + * appliction can be handed in - all other applications need to call the + * function which use the injected application + */ + @Produces + public ApplicationEntity getApplication() { + return application; + + } + + public String getVersion() { + return version; + } + + public String getBuildDate() { + return buildDate; + } + + public UUID getApplicationId() { + return uuid; + } + +} diff --git a/account-ui/src/main/resources/buildInfo.properties b/account-ui/src/main/resources/buildInfo.properties index 37404b0..d0f10ae 100644 --- a/account-ui/src/main/resources/buildInfo.properties +++ b/account-ui/src/main/resources/buildInfo.properties @@ -1,2 +1,3 @@ build.version=${project.version} -build.timestamp=${timestamp} \ No newline at end of file +build.timestamp=${timestamp} +application.uuid=${applicationUuid} \ No newline at end of file diff --git a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountEntity.java b/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountEntity.java index e697ad8..735b4a9 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountEntity.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/account/entity/AccountEntity.java @@ -38,6 +38,7 @@ import org.hibernate.annotations.Type; @XmlRootElement @NamedQueries({ @NamedQuery(name = "AccountEntity.findAll", query = "SELECT a FROM AccountEntity a ORDER by a.lastname, a.firstname"), + @NamedQuery(name = "AccountEntity.findByUsername", query = "SELECT a FROM AccountEntity a WHERE a.username = :username"), @NamedQuery(name = "AccountEntity.findByStatus", query = "SELECT a FROM AccountEntity a WHERE a.status = :status"), @NamedQuery(name = "AccountEntity.findByCreatedOn", query = "SELECT a FROM AccountEntity a WHERE a.createdOn = :createdOn"), @NamedQuery(name = "AccountEntity.findByCreatedBy", query = "SELECT a FROM AccountEntity a WHERE a.createdBy = :createdBy"), diff --git a/account/src/main/java/de/muehlencord/shared/account/business/config/boundary/ConfigService.java b/account/src/main/java/de/muehlencord/shared/account/business/config/boundary/ConfigService.java index 0dd223d..4ae98fb 100644 --- a/account/src/main/java/de/muehlencord/shared/account/business/config/boundary/ConfigService.java +++ b/account/src/main/java/de/muehlencord/shared/account/business/config/boundary/ConfigService.java @@ -9,7 +9,6 @@ import de.muehlencord.shared.account.business.config.entity.ConfigException; import java.io.Serializable; import java.util.List; import java.util.Optional; -import javax.annotation.PostConstruct; import javax.ejb.Lock; import javax.ejb.LockType; import javax.ejb.Singleton; @@ -81,6 +80,8 @@ public class ConfigService implements Serializable { return getConfigValue(configKey, defaultValue, false); } + @Transactional + @Lock(LockType.WRITE) public String getConfigValue(String configKey, String defaultValue, boolean storeDefaultValue) throws ConfigException { // get configValue as usual String configValue = getConfigValue(configKey); @@ -121,6 +122,8 @@ public class ConfigService implements Serializable { } } + @Transactional + @Lock(LockType.WRITE) public String getConfigValue(String configKey, String defaultValue, boolean storeDefaultValue, Account account, boolean fallbackToSystem) throws ConfigException { String configValue = getConfigValue(configKey, account, fallbackToSystem);