You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by mm...@apache.org on 2020/03/16 15:56:12 UTC
[syncope] 26/36: [SYNCOPE-1545] Refactoring logging,
adding Keymaster support + Docker image
This is an automated email from the ASF dual-hosted git repository.
mmoayyed pushed a commit to branch SYNCOPE-1545
in repository https://gitbox.apache.org/repos/asf/syncope.git
commit 37251ffb31db59c23b783840d9ce1aeb39d500f7
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Wed Mar 4 16:15:16 2020 +0100
[SYNCOPE-1545] Refactoring logging, adding Keymaster support + Docker image
---
.../client/console/SyncopeConsoleApplication.java | 15 +-
.../client/console/SyncopeWebApplication.java | 20 --
.../client/enduser/SyncopeEnduserApplication.java | 13 ++
.../client/enduser/SyncopeWebApplication.java | 15 --
common/keymaster/client-api/pom.xml | 5 +
.../client/api/startstop/KeymasterStart.java | 11 +-
.../client/api/startstop/KeymasterStartStop.java | 12 +-
.../client/api/startstop/KeymasterStop.java | 14 +-
.../core/starter/SyncopeCoreApplication.java | 12 ++
...ncopeCoreStartup.java => SyncopeCoreStart.java} | 12 +-
docker/core/src/main/resources/log4j2.xml | 4 +
docker/pom.xml | 16 +-
.../docker-compose/docker-compose-all.yml | 18 +-
docker/wa/LICENSE | 202 +++++++++++++++++++++
docker/wa/NOTICE | 5 +
docker/wa/pom.xml | 177 ++++++++++++++++++
.../wa/src/main/resources/Dockerfile | 35 ++--
.../wa}/src/main/resources/application.properties | 2 +-
.../wa/src/main/resources/keymaster.properties | 27 +--
docker/wa/src/main/resources/log4j2.xml | 59 ++++++
.../wa/src/main/resources/startup.sh | 28 +--
.../wa/src/main/resources/wa.properties | 21 +--
.../syncope/core/logic/NetworkServiceLogic.java | 6 +-
fit/console-reference/pom.xml | 5 -
fit/enduser-reference/pom.xml | 5 -
fit/wa-reference/pom.xml | 159 +++++++++++++++-
.../src/main/resources/keymaster.properties | 27 +--
fit/wa-reference/src/main/resources/log4j2.xml | 148 +++++----------
.../wa-reference/src/main/resources/wa.properties | 21 +--
.../src/test/resources/hotswap-agent.properties | 25 +--
sra/pom.xml | 6 +
.../apache/syncope/sra/SyncopeSRAApplication.java | 13 ++
.../org/apache/syncope/sra/SyncopeSRAShutdown.java | 33 ----
.../apache/syncope/sra/SyncopeSRAStartStop.java | 40 ----
wa/pom.xml | 133 +++++++++++++-
.../apache/syncope/wa/SyncopeWAApplication.java | 17 ++
wa/src/main/resources/application.properties | 8 +-
wa/src/main/resources/log4j2.xml | 68 +++++++
wa/src/main/resources/static/images/favicon.png | Bin 0 -> 641 bytes
wa/src/main/resources/templates/layout.html | 4 +-
.../{application.properties => wa.properties} | 21 +--
.../java/org/apache/syncope/wa/SyncopeWATest.java | 158 ++++++++++++++++
.../apache/syncope/wa/ZookeeperTestingServer.java | 80 ++++++++
.../resources/keymaster.properties} | 27 +--
44 files changed, 1255 insertions(+), 472 deletions(-)
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
index 0175fe7..8e922cc 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
@@ -19,6 +19,7 @@
package org.apache.syncope.client.console;
import com.giffing.wicket.spring.boot.starter.web.config.WicketWebInitializerAutoConfig.WebSocketWicketWebInitializerAutoConfiguration;
+import org.apache.syncope.client.console.commons.AnyDirectoryPanelAdditionalActionLinksProvider;
import org.apache.syncope.client.console.commons.AnyDirectoryPanelAdditionalActionsProvider;
import org.apache.syncope.client.console.commons.AnyWizardBuilderAdditionalSteps;
import org.apache.syncope.client.console.commons.ExternalResourceProvider;
@@ -36,6 +37,9 @@ import org.apache.syncope.client.console.commons.StatusProvider;
import org.apache.syncope.client.console.commons.VirSchemaDetailsPanelProvider;
import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
import org.apache.syncope.client.console.init.MIMETypesLoader;
+import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
+import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStart;
+import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStop;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -44,7 +48,6 @@ import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConf
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
-import org.apache.syncope.client.console.commons.AnyDirectoryPanelAdditionalActionLinksProvider;
@SpringBootApplication(exclude = {
ErrorMvcAutoConfiguration.class,
@@ -61,6 +64,16 @@ public class SyncopeConsoleApplication extends SpringBootServletInitializer {
return super.configure(builder);
}
+ @Bean
+ public KeymasterStart keymasterStart() {
+ return new KeymasterStart(NetworkService.Type.CONSOLE);
+ }
+
+ @Bean
+ public KeymasterStop keymasterStop() {
+ return new KeymasterStop(NetworkService.Type.CONSOLE);
+ }
+
@ConditionalOnMissingBean(name = "classPathScanImplementationLookup")
@Bean
public ClassPathScanImplementationLookup classPathScanImplementationLookup() {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java
index bc01e4d..e015d03 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java
@@ -76,7 +76,6 @@ import org.apache.wicket.request.component.IRequestablePage;
import org.apache.wicket.request.cycle.IRequestCycleListener;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@@ -100,9 +99,6 @@ public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
@Autowired
private ServiceOps serviceOps;
- @Value("${service.discovery.address}")
- private String address;
-
private String anonymousUser;
private String anonymousKey;
@@ -179,13 +175,6 @@ public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
}
}
- private NetworkService getNetworkService() {
- NetworkService ns = new NetworkService();
- ns.setType(NetworkService.Type.CONSOLE);
- ns.setAddress(address);
- return ns;
- }
-
@Override
protected void init() {
super.init();
@@ -311,15 +300,6 @@ public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
if (getDebugSettings().isAjaxDebugModeEnabled()) {
getDebugSettings().setComponentPathAttributeName("syncope-path");
}
-
- serviceOps.register(getNetworkService());
- }
-
- @Override
- protected void onDestroy() {
- serviceOps.unregister(getNetworkService());
-
- super.onDestroy();
}
@Override
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
index 975a076..aaac232 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
@@ -21,6 +21,9 @@ package org.apache.syncope.client.enduser;
import com.giffing.wicket.spring.boot.starter.web.config.WicketWebInitializerAutoConfig.WebSocketWicketWebInitializerAutoConfiguration;
import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup;
import org.apache.syncope.client.enduser.init.MIMETypesLoader;
+import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
+import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStart;
+import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStop;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -45,6 +48,16 @@ public class SyncopeEnduserApplication extends SpringBootServletInitializer {
return super.configure(builder);
}
+ @Bean
+ public KeymasterStart keymasterStart() {
+ return new KeymasterStart(NetworkService.Type.ENDUSER);
+ }
+
+ @Bean
+ public KeymasterStop keymasterStop() {
+ return new KeymasterStop(NetworkService.Type.ENDUSER);
+ }
+
@ConditionalOnMissingBean(name = "classPathScanImplementationLookup")
@Bean
public ClassPathScanImplementationLookup classPathScanImplementationLookup() {
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
index edc4ae4..176fa39 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
@@ -83,7 +83,6 @@ import org.apache.wicket.util.lang.Args;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@@ -110,9 +109,6 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
@Autowired
private ServiceOps serviceOps;
- @Value("${service.discovery.address}")
- private String address;
-
private boolean useGZIPCompression;
private String adminUser;
@@ -148,13 +144,6 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
}
}
- private NetworkService getNetworkService() {
- NetworkService ns = new NetworkService();
- ns.setType(NetworkService.Type.ENDUSER);
- ns.setAddress(address);
- return ns;
- }
-
@Override
protected void init() {
super.init();
@@ -355,14 +344,10 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
if (getDebugSettings().isAjaxDebugModeEnabled()) {
getDebugSettings().setComponentPathAttributeName("syncope-path");
}
-
- serviceOps.register(getNetworkService());
}
@Override
protected void onDestroy() {
- serviceOps.unregister(getNetworkService());
-
if (customFormAttributesMonitor != null) {
try {
customFormAttributesMonitor.stop(0);
diff --git a/common/keymaster/client-api/pom.xml b/common/keymaster/client-api/pom.xml
index 5dcf5ad..37fdb6b 100644
--- a/common/keymaster/client-api/pom.xml
+++ b/common/keymaster/client-api/pom.xml
@@ -43,6 +43,11 @@ under the License.
<artifactId>syncope-common-idrepo-lib</artifactId>
<version>${project.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git a/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAStartup.java b/common/keymaster/client-api/src/main/java/org/apache/syncope/common/keymaster/client/api/startstop/KeymasterStart.java
similarity index 78%
rename from sra/src/main/java/org/apache/syncope/sra/SyncopeSRAStartup.java
rename to common/keymaster/client-api/src/main/java/org/apache/syncope/common/keymaster/client/api/startstop/KeymasterStart.java
index cbc7b59..f164865 100644
--- a/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAStartup.java
+++ b/common/keymaster/client-api/src/main/java/org/apache/syncope/common/keymaster/client/api/startstop/KeymasterStart.java
@@ -16,16 +16,19 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.syncope.sra;
+package org.apache.syncope.common.keymaster.client.api.startstop;
+import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
-import org.springframework.stereotype.Component;
-@Component
-public class SyncopeSRAStartup extends SyncopeSRAStartStop
+public class KeymasterStart extends KeymasterStartStop
implements ApplicationListener<ContextRefreshedEvent> {
+ public KeymasterStart(final NetworkService.Type networkServiceType) {
+ super(networkServiceType);
+ }
+
@Override
public void onApplicationEvent(final ContextRefreshedEvent event) {
serviceOps.register(getNetworkService());
diff --git a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreStartStop.java b/common/keymaster/client-api/src/main/java/org/apache/syncope/common/keymaster/client/api/startstop/KeymasterStartStop.java
similarity index 79%
rename from core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreStartStop.java
rename to common/keymaster/client-api/src/main/java/org/apache/syncope/common/keymaster/client/api/startstop/KeymasterStartStop.java
index 7f52923..29a161b 100644
--- a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreStartStop.java
+++ b/common/keymaster/client-api/src/main/java/org/apache/syncope/common/keymaster/client/api/startstop/KeymasterStartStop.java
@@ -16,24 +16,30 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.syncope.core.starter;
+package org.apache.syncope.common.keymaster.client.api.startstop;
import org.apache.syncope.common.keymaster.client.api.ServiceOps;
import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-abstract class SyncopeCoreStartStop {
+abstract class KeymasterStartStop {
@Autowired
protected ServiceOps serviceOps;
+ protected final NetworkService.Type networkServiceType;
+
+ protected KeymasterStartStop(final NetworkService.Type networkServiceType) {
+ this.networkServiceType = networkServiceType;
+ }
+
@Value("${service.discovery.address}")
private String address;
protected NetworkService getNetworkService() {
NetworkService ns = new NetworkService();
- ns.setType(NetworkService.Type.CORE);
+ ns.setType(networkServiceType);
ns.setAddress(address);
return ns;
}
diff --git a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreShutdown.java b/common/keymaster/client-api/src/main/java/org/apache/syncope/common/keymaster/client/api/startstop/KeymasterStop.java
similarity index 78%
rename from core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreShutdown.java
rename to common/keymaster/client-api/src/main/java/org/apache/syncope/common/keymaster/client/api/startstop/KeymasterStop.java
index 256607e..7851a39 100644
--- a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreShutdown.java
+++ b/common/keymaster/client-api/src/main/java/org/apache/syncope/common/keymaster/client/api/startstop/KeymasterStop.java
@@ -16,19 +16,19 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.syncope.core.starter;
+package org.apache.syncope.common.keymaster.client.api.startstop;
+import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
-import org.springframework.stereotype.Component;
-/**
- * Take care of cleanup actions needed by Syncope Core.
- */
-@Component
-public class SyncopeCoreShutdown extends SyncopeCoreStartStop
+public class KeymasterStop extends KeymasterStartStop
implements ApplicationListener<ContextClosedEvent> {
+ public KeymasterStop(final NetworkService.Type networkServiceType) {
+ super(networkServiceType);
+ }
+
@Override
public void onApplicationEvent(final ContextClosedEvent event) {
serviceOps.unregister(getNetworkService());
diff --git a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java b/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java
index 9c9aaf4..8902bec 100644
--- a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java
+++ b/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java
@@ -20,6 +20,8 @@ package org.apache.syncope.core.starter;
import java.io.IOException;
import org.apache.cxf.spring.boot.autoconfigure.openapi.OpenApiAutoConfiguration;
+import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
+import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStop;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -57,4 +59,14 @@ public class SyncopeCoreApplication extends SpringBootServletInitializer {
pspc.setIgnoreUnresolvablePlaceholders(true);
return pspc;
}
+
+ @Bean
+ public SyncopeCoreStart keymasterStart() {
+ return new SyncopeCoreStart();
+ }
+
+ @Bean
+ public KeymasterStop keymasterStop() {
+ return new KeymasterStop(NetworkService.Type.CORE);
+ }
}
diff --git a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreStartup.java b/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreStart.java
similarity index 89%
rename from core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreStartup.java
rename to core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreStart.java
index f93de92..515fa13 100644
--- a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreStartup.java
+++ b/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreStart.java
@@ -19,6 +19,8 @@
package org.apache.syncope.core.starter;
import java.util.Comparator;
+import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
+import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStart;
import org.apache.syncope.core.persistence.api.DomainHolder;
import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
import org.slf4j.Logger;
@@ -28,20 +30,22 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.Ordered;
-import org.springframework.stereotype.Component;
/**
* Take care of all initializations needed by Syncope Core to run up and safe.
*/
-@Component
-public class SyncopeCoreStartup extends SyncopeCoreStartStop
+public class SyncopeCoreStart extends KeymasterStart
implements ApplicationListener<ContextRefreshedEvent>, Ordered {
- private static final Logger LOG = LoggerFactory.getLogger(SyncopeCoreStartup.class);
+ private static final Logger LOG = LoggerFactory.getLogger(SyncopeCoreStart.class);
@Autowired
private DomainHolder domainHolder;
+ public SyncopeCoreStart() {
+ super(NetworkService.Type.CORE);
+ }
+
@Override
public int getOrder() {
return 0;
diff --git a/docker/core/src/main/resources/log4j2.xml b/docker/core/src/main/resources/log4j2.xml
index 1941154..063d123 100644
--- a/docker/core/src/main/resources/log4j2.xml
+++ b/docker/core/src/main/resources/log4j2.xml
@@ -108,6 +108,10 @@ under the License.
<appender-ref ref="console"/>
<appender-ref ref="main"/>
</asyncLogger>
+ <asyncLogger name="liquibase" additivity="false" level="ERROR">
+ <appender-ref ref="console"/>
+ <appender-ref ref="main"/>
+ </asyncLogger>
<asyncLogger name="org.apache.cocoon" additivity="false" level="ERROR">
<appender-ref ref="console"/>
<appender-ref ref="main"/>
diff --git a/docker/pom.xml b/docker/pom.xml
index db2f0d5..dd17d08 100644
--- a/docker/pom.xml
+++ b/docker/pom.xml
@@ -42,13 +42,6 @@ under the License.
<rootpom.basedir>${basedir}/..</rootpom.basedir>
</properties>
- <modules>
- <module>core</module>
- <module>console</module>
- <module>enduser</module>
- <module>sra</module>
- </modules>
-
<build>
<resources>
<resource>
@@ -120,5 +113,12 @@ under the License.
</build>
</profile>
</profiles>
-
+
+ <modules>
+ <module>core</module>
+ <module>console</module>
+ <module>enduser</module>
+ <module>sra</module>
+ <module>wa</module>
+ </modules>
</project>
diff --git a/docker/src/main/resources/docker-compose/docker-compose-all.yml b/docker/src/main/resources/docker-compose/docker-compose-all.yml
index e3a9c25..29d6918 100644
--- a/docker/src/main/resources/docker-compose/docker-compose-all.yml
+++ b/docker/src/main/resources/docker-compose/docker-compose-all.yml
@@ -24,7 +24,7 @@ version: '3.3'
services:
keymaster:
- image: zookeeper:3.4.14
+ image: zookeeper:3.5.6
restart: always
db:
@@ -84,13 +84,27 @@ services:
KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD:-}
SERVICE_DISCOVERY_ADDRESS: http://syncope-enduser:8080/syncope-enduser/
+ syncope-wa:
+ depends_on:
+ - syncope
+ - keymaster
+ image: apache/syncope-wa:${SYNCOPE_VERSION}
+ ports:
+ - "48080:8080"
+ restart: always
+ environment:
+ KEYMASTER_ADDRESS: keymaster:2181
+ KEYMASTER_USERNAME: ${KEYMASTER_USERNAME:-}
+ KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD:-}
+ SERVICE_DISCOVERY_ADDRESS: http://syncope-wa:8080/syncope-wa/
+
syncope-sra:
depends_on:
- syncope
- keymaster
image: apache/syncope-sra:${SYNCOPE_VERSION}
ports:
- - "48080:8080"
+ - "58080:8080"
restart: always
environment:
KEYMASTER_ADDRESS: keymaster:2181
diff --git a/docker/wa/LICENSE b/docker/wa/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/docker/wa/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/docker/wa/NOTICE b/docker/wa/NOTICE
new file mode 100644
index 0000000..3db7985
--- /dev/null
+++ b/docker/wa/NOTICE
@@ -0,0 +1,5 @@
+Apache Syncope
+Copyright 2012-2019 The Apache Software Foundation
+
+This product includes software developed by:
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/docker/wa/pom.xml b/docker/wa/pom.xml
new file mode 100644
index 0000000..13721b8
--- /dev/null
+++ b/docker/wa/pom.xml
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope</groupId>
+ <artifactId>syncope-docker</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Docker WA</name>
+ <description>Apache Syncope Docker WA</description>
+ <groupId>org.apache.syncope</groupId>
+ <artifactId>syncope-docker-wa</artifactId>
+ <packaging>war</packaging>
+
+ <properties>
+ <guava.version>28.2-jre</guava.version>
+ <opensaml.version>3.4.5</opensaml.version>
+ <bootstrap.version>4.4.1</bootstrap.version>
+ <slf4j.version>2.0.0-alpha1</slf4j.version>
+
+ <rootpom.basedir>${basedir}/../..</rootpom.basedir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-undertow</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope</groupId>
+ <artifactId>syncope-wa</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope.ext.self-keymaster</groupId>
+ <artifactId>syncope-ext-self-keymaster-client</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.common.keymaster</groupId>
+ <artifactId>syncope-common-keymaster-client-zookeeper</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <inherited>false</inherited>
+ <configuration>
+ <webXml>${basedir}/../../fit/wa-reference/src/main/webapp/WEB-INF/web.xml</webXml>
+ <webResources>
+ <resource>
+ <directory>${basedir}</directory>
+ <targetPath>META-INF</targetPath>
+ <includes>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ </includes>
+ </resource>
+ </webResources>
+ <outputDirectory>${project.build.outputDirectory}</outputDirectory>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <configuration>
+ <mainClass>org.apache.syncope.wa.SyncopeWAApplication</mainClass>
+ <layout>ZIP</layout>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.outputDirectory}</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>io.fabric8</groupId>
+ <artifactId>docker-maven-plugin</artifactId>
+ <configuration>
+ <verbose>true</verbose>
+ <images>
+ <image>
+ <name>apache/syncope-wa:%v</name>
+ <build>
+ <dockerFileDir>${project.build.outputDirectory}</dockerFileDir>
+ </build>
+ </image>
+ </images>
+ </configuration>
+ <executions>
+ <execution>
+ <id>remove-syncope-wa</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>remove</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>build-syncope-wa</id>
+ <phase>package</phase>
+ <goals>
+ <goal>build</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>apache-release</id>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <inherited>false</inherited>
+ <configuration>
+ <skipSource>true</skipSource>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+</project>
diff --git a/wa/src/main/resources/application.properties b/docker/wa/src/main/resources/Dockerfile
similarity index 53%
copy from wa/src/main/resources/application.properties
copy to docker/wa/src/main/resources/Dockerfile
index 487d11b..7edf8dc 100644
--- a/wa/src/main/resources/application.properties
+++ b/docker/wa/src/main/resources/Dockerfile
@@ -14,27 +14,26 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-spring.application.name=Apache Syncope ${syncope.version} WA
-spring.groovy.template.check-template-location=false
-spring.main.banner-mode=log
-server.port=8080
+# Cannot FROM adoptopenjdk/openjdk11-openj9:alpine-slim because it's headless, and fonts might be required
+FROM openjdk:11
+MAINTAINER dev@syncope.apache.org
-spring.http.encoding.charset=UTF-8
-spring.http.encoding.enabled=true
-spring.http.encoding.force=true
+RUN set -x
-server.servlet.contextPath=/syncope-wa
+RUN mkdir /opt/syncope
+RUN mkdir /opt/syncope/bin
+RUN mkdir /opt/syncope/conf
+RUN mkdir /opt/syncope/lib
+RUN mkdir /opt/syncope/log
-##
-# Allow configuration classes to override bean definitions from Spring Boot
-#
-spring.main.allow-bean-definition-overriding=true
-spring.main.lazy-initialization=false
+COPY *.properties /opt/syncope/conf/
+COPY log4j2.xml /opt/syncope/conf/
+
+COPY syncope-docker-wa-*war /opt/syncope/lib/syncope-wa.war
-service.discovery.address=http://localhost:8080/syncope-wa/
+COPY startup.sh /opt/syncope/bin
+RUN chmod 755 /opt/syncope/bin/startup.sh
+CMD ["/opt/syncope/bin/startup.sh"]
-# Conf directories
-conf.directory=${conf.directory}
-cas.standalone.configurationDirectory=${conf.directory}
-cas.authn.oidc.jwksFile=file:${conf.directory}/oidc.keystore
+EXPOSE 8080
diff --git a/wa/src/main/resources/application.properties b/docker/wa/src/main/resources/application.properties
similarity index 95%
copy from wa/src/main/resources/application.properties
copy to docker/wa/src/main/resources/application.properties
index 487d11b..254b399 100644
--- a/wa/src/main/resources/application.properties
+++ b/docker/wa/src/main/resources/application.properties
@@ -32,7 +32,7 @@ server.servlet.contextPath=/syncope-wa
spring.main.allow-bean-definition-overriding=true
spring.main.lazy-initialization=false
-service.discovery.address=http://localhost:8080/syncope-wa/
+service.discovery.address=${SERVICE_DISCOVERY_ADDRESS}
# Conf directories
conf.directory=${conf.directory}
diff --git a/wa/src/main/resources/application.properties b/docker/wa/src/main/resources/keymaster.properties
similarity index 52%
copy from wa/src/main/resources/application.properties
copy to docker/wa/src/main/resources/keymaster.properties
index 487d11b..14e8ca6 100644
--- a/wa/src/main/resources/application.properties
+++ b/docker/wa/src/main/resources/keymaster.properties
@@ -14,27 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-spring.application.name=Apache Syncope ${syncope.version} WA
-spring.groovy.template.check-template-location=false
-spring.main.banner-mode=log
-
-server.port=8080
-
-spring.http.encoding.charset=UTF-8
-spring.http.encoding.enabled=true
-spring.http.encoding.force=true
-
-server.servlet.contextPath=/syncope-wa
-
-##
-# Allow configuration classes to override bean definitions from Spring Boot
-#
-spring.main.allow-bean-definition-overriding=true
-spring.main.lazy-initialization=false
-
-service.discovery.address=http://localhost:8080/syncope-wa/
-
-# Conf directories
-conf.directory=${conf.directory}
-cas.standalone.configurationDirectory=${conf.directory}
-cas.authn.oidc.jwksFile=file:${conf.directory}/oidc.keystore
+keymaster.address=${KEYMASTER_ADDRESS}
+keymaster.username=${KEYMASTER_USERNAME}
+keymaster.password=${KEYMASTER_PASSWORD}
diff --git a/docker/wa/src/main/resources/log4j2.xml b/docker/wa/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..269180c
--- /dev/null
+++ b/docker/wa/src/main/resources/log4j2.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+-->
+<configuration status="WARN">
+
+ <appenders>
+
+ <Console name="console" target="SYSTEM_OUT" follow="true">
+ <PatternLayout pattern="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} %highlight{${LOG_LEVEL_PATTERN:-%5p}}{FATAL=red blink, ERROR=red, WARN=yellow bold, INFO=green, DEBUG=green bold, TRACE=blue} [%11.11t] %style{%-60.60c{60}}{cyan} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
+ </Console>
+
+ </appenders>
+
+ <loggers>
+
+ <asyncLogger name="org.apereo.cas" additivity="false" level="INFO">
+ <appender-ref ref="console"/>
+ </asyncLogger>
+ <asyncLogger name="org.apereo.inspektr.audit.support" additivity="false" level="INFO">
+ <appender-ref ref="console"/>
+ </asyncLogger>
+
+ <asyncLogger name="org.springframework" additivity="false" level="INFO">
+ <appender-ref ref="console"/>
+ </asyncLogger>
+
+ <asyncLogger name="org.apache.syncope.client.lib" additivity="false" level="OFF">
+ <appender-ref ref="console"/>
+ </asyncLogger>
+ <asyncLogger name="org.apache.syncope.wa" additivity="false" level="INFO">
+ <appender-ref ref="console"/>
+ </asyncLogger>
+
+ <asyncLogger name="org.apache.cxf" additivity="false" level="ERROR">
+ <appender-ref ref="console"/>
+ </asyncLogger>
+
+ <root level="INFO">
+ <appender-ref ref="console"/>
+ </root>
+
+ </loggers>
+</configuration>
diff --git a/wa/src/main/resources/application.properties b/docker/wa/src/main/resources/startup.sh
old mode 100644
new mode 100755
similarity index 52%
copy from wa/src/main/resources/application.properties
copy to docker/wa/src/main/resources/startup.sh
index 487d11b..68c70da
--- a/wa/src/main/resources/application.properties
+++ b/docker/wa/src/main/resources/startup.sh
@@ -1,3 +1,5 @@
+#!/bin/sh
+
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
@@ -14,27 +16,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-spring.application.name=Apache Syncope ${syncope.version} WA
-spring.groovy.template.check-template-location=false
-spring.main.banner-mode=log
-
-server.port=8080
-
-spring.http.encoding.charset=UTF-8
-spring.http.encoding.enabled=true
-spring.http.encoding.force=true
-
-server.servlet.contextPath=/syncope-wa
-
-##
-# Allow configuration classes to override bean definitions from Spring Boot
-#
-spring.main.allow-bean-definition-overriding=true
-spring.main.lazy-initialization=false
-
-service.discovery.address=http://localhost:8080/syncope-wa/
-# Conf directories
-conf.directory=${conf.directory}
-cas.standalone.configurationDirectory=${conf.directory}
-cas.authn.oidc.jwksFile=file:${conf.directory}/oidc.keystore
+export LOADER_PATH="/opt/syncope/conf,/opt/syncope/lib"
+java -Dfile.encoding=UTF-8 -server -Xms1536m -Xmx1536m -XX:NewSize=256m -XX:MaxNewSize=256m \
+ -XX:+DisableExplicitGC -Djava.security.egd=file:/dev/./urandom -jar /opt/syncope/lib/syncope-wa.war
diff --git a/wa/src/main/resources/application.properties b/docker/wa/src/main/resources/wa.properties
similarity index 64%
copy from wa/src/main/resources/application.properties
copy to docker/wa/src/main/resources/wa.properties
index 487d11b..a208075 100644
--- a/wa/src/main/resources/application.properties
+++ b/docker/wa/src/main/resources/wa.properties
@@ -14,25 +14,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-spring.application.name=Apache Syncope ${syncope.version} WA
-spring.groovy.template.check-template-location=false
-spring.main.banner-mode=log
+anonymousUser=${anonymousUser}
+anonymousKey=${anonymousKey}
-server.port=8080
-
-spring.http.encoding.charset=UTF-8
-spring.http.encoding.enabled=true
-spring.http.encoding.force=true
-
-server.servlet.contextPath=/syncope-wa
-
-##
-# Allow configuration classes to override bean definitions from Spring Boot
-#
-spring.main.allow-bean-definition-overriding=true
-spring.main.lazy-initialization=false
-
-service.discovery.address=http://localhost:8080/syncope-wa/
+useGZIPCompression=true
# Conf directories
conf.directory=${conf.directory}
diff --git a/ext/self-keymaster/logic/src/main/java/org/apache/syncope/core/logic/NetworkServiceLogic.java b/ext/self-keymaster/logic/src/main/java/org/apache/syncope/core/logic/NetworkServiceLogic.java
index d97af30..554cb29 100644
--- a/ext/self-keymaster/logic/src/main/java/org/apache/syncope/core/logic/NetworkServiceLogic.java
+++ b/ext/self-keymaster/logic/src/main/java/org/apache/syncope/core/logic/NetworkServiceLogic.java
@@ -43,8 +43,8 @@ public class NetworkServiceLogic extends AbstractTransactionalLogic<EntityTO> {
private SelfKeymasterEntityFactory entityFactory;
private static NetworkService toNetworkService(
- final NetworkService.Type serviceType,
- final NetworkServiceEntity service) {
+ final NetworkService.Type serviceType,
+ final NetworkServiceEntity service) {
NetworkService ns = new NetworkService();
ns.setType(serviceType);
@@ -84,7 +84,7 @@ public class NetworkServiceLogic extends AbstractTransactionalLogic<EntityTO> {
public void unregister(final NetworkService networkService) {
serviceDAO.findAll(networkService.getType()).stream().
filter(service -> service.getAddress().equals(networkService.getAddress())).
- findFirst().ifPresent(service -> serviceDAO.delete(service));
+ forEach(service -> serviceDAO.delete(service));
}
@Override
diff --git a/fit/console-reference/pom.xml b/fit/console-reference/pom.xml
index f80f55b..9e4fca4 100644
--- a/fit/console-reference/pom.xml
+++ b/fit/console-reference/pom.xml
@@ -56,11 +56,6 @@ under the License.
<artifactId>syncope-ext-self-keymaster-client</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>org.apache.syncope.common.keymaster</groupId>
- <artifactId>syncope-common-keymaster-client-zookeeper</artifactId>
- <version>${project.version}</version>
- </dependency>
<dependency>
<groupId>org.apache.syncope.ext.flowable</groupId>
diff --git a/fit/enduser-reference/pom.xml b/fit/enduser-reference/pom.xml
index 812478d..29c34fd 100644
--- a/fit/enduser-reference/pom.xml
+++ b/fit/enduser-reference/pom.xml
@@ -51,11 +51,6 @@ under the License.
<artifactId>syncope-ext-self-keymaster-client</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>org.apache.syncope.common.keymaster</groupId>
- <artifactId>syncope-common-keymaster-client-zookeeper</artifactId>
- <version>${project.version}</version>
- </dependency>
<dependency>
<groupId>org.apache.syncope.ext.flowable</groupId>
diff --git a/fit/wa-reference/pom.xml b/fit/wa-reference/pom.xml
index 7c08b20..e097196 100644
--- a/fit/wa-reference/pom.xml
+++ b/fit/wa-reference/pom.xml
@@ -50,6 +50,52 @@ under the License.
<artifactId>syncope-wa</artifactId>
<version>${project.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope.ext.self-keymaster</groupId>
+ <artifactId>syncope-ext-self-keymaster-client</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- TEST -->
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.fit</groupId>
+ <artifactId>syncope-fit-build-tools</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.fit</groupId>
+ <artifactId>syncope-fit-core-reference</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.fit</groupId>
+ <artifactId>syncope-fit-console-reference</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.fit</groupId>
+ <artifactId>syncope-fit-enduser-reference</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
@@ -66,9 +112,15 @@ under the License.
<downloadDir>${settings.localRepository}/org/codehaus/cargo/cargo-container-archives</downloadDir>
<extractDir>${project.build.directory}/cargo/extract</extractDir>
</zipUrlInstaller>
- <timeout>300000</timeout>
+ <timeout>600000</timeout>
<log>${cargo.log}</log>
<output>${cargo.output}</output>
+ <dependencies>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ </dependency>
+ </dependencies>
</container>
<configuration>
<properties>
@@ -79,6 +131,34 @@ under the License.
</configuration>
<deployables>
<deployable>
+ <groupId>org.apache.syncope.fit</groupId>
+ <artifactId>syncope-fit-build-tools</artifactId>
+ <type>war</type>
+ <properties>
+ <context>syncope-fit-build-tools</context>
+ </properties>
+ </deployable>
+ <deployable>
+ <location>${basedir}/../core-reference/target/syncope-fit-core-reference-${project.version}</location>
+ <pingURL>http://localhost:${cargo.servlet.port}/syncope/index.html</pingURL>
+ <pingTimeout>${cargo.deployable.ping.timeout}</pingTimeout>
+ <properties>
+ <context>syncope</context>
+ </properties>
+ </deployable>
+ <deployable>
+ <location>${basedir}/../console-reference/target/syncope-fit-console-reference-${project.version}</location>
+ <properties>
+ <context>syncope-console</context>
+ </properties>
+ </deployable>
+ <deployable>
+ <location>${basedir}/../enduser-reference/target/syncope-fit-enduser-reference-${project.version}</location>
+ <properties>
+ <context>syncope-enduser</context>
+ </properties>
+ </deployable>
+ <deployable>
<location>${project.build.directory}/${project.build.finalName}</location>
<properties>
<context>syncope-wa</context>
@@ -113,13 +193,6 @@ under the License.
<profiles>
<profile>
- <id>properties4cas</id>
- <activation>
- <activeByDefault>true</activeByDefault>
- </activation>
- </profile>
-
- <profile>
<id>skipTests</id>
</profile>
@@ -143,6 +216,7 @@ under the License.
<properties>
<cargo.jvmargs>
-Dspring.profiles.active=embedded
+ -Dwicket.core.settings.general.configuration-type=development
-Xdebug -Djaxb.debug=true -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n
-XX:+CMSClassUnloadingEnabled -XX:+UseG1GC -Xmx1024m -Xms512m</cargo.jvmargs>
</properties>
@@ -152,6 +226,73 @@ under the License.
</plugins>
</build>
</profile>
+
+ <!-- requires JAVA_HOME set to the latest JDK from https://github.com/TravaOpenJDK/trava-jdk-11-dcevm -->
+ <profile>
+ <id>hotswap</id>
+
+ <build>
+ <defaultGoal>clean verify cargo:run</defaultGoal>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <inherited>true</inherited>
+ <executions>
+ <execution>
+ <id>enableHotSwapForCoreAndConsoleAndEnduser</id>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <copy file="${basedir}/../core-reference/target/test-classes/hotswap-agent.properties"
+ tofile="${basedir}/../core-reference/target/syncope-fit-core-reference-${project.version}/WEB-INF/classes/hotswap-agent.properties"
+ overwrite="true"/>
+ <copy file="${basedir}/../console-reference/target/test-classes/hotswap-agent.properties"
+ tofile="${basedir}/../console-reference/target/syncope-fit-console-reference-${project.version}/WEB-INF/classes/hotswap-agent.properties"
+ overwrite="true"/>
+ <copy file="${basedir}/../enduser-reference/target/test-classes/hotswap-agent.properties"
+ tofile="${basedir}/../enduser-reference/target/syncope-fit-enduser-reference-${project.version}/WEB-INF/classes/hotswap-agent.properties"
+ overwrite="true"/>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.cargo</groupId>
+ <artifactId>cargo-maven2-plugin</artifactId>
+ <inherited>true</inherited>
+ <configuration>
+ <configuration>
+ <properties>
+ <cargo.jvmargs>
+ -Dspring.profiles.active=embedded
+ -Dwicket.core.settings.general.configuration-type=development
+ -javaagent:${java.home}/lib/hotswap/hotswap-agent.jar=autoHotswap=true,disablePlugin=Spring,disablePlugin=Hibernate,disablePlugin=CxfJAXRS
+ -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
+ -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -Xmx1024m -Xms512m</cargo.jvmargs>
+ </properties>
+ </configuration>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ <resources>
+ <resource>
+ <directory>src/test/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>hotswap-agent.properties</include>
+ </includes>
+ </resource>
+ </resources>
+ </build>
+ </profile>
<profile>
<id>apache-release</id>
@@ -172,7 +313,7 @@ under the License.
<configuration>
<skipSource>true</skipSource>
</configuration>
- </plugin>
+ </plugin>
</plugins>
</build>
</profile>
diff --git a/wa/src/main/resources/application.properties b/fit/wa-reference/src/main/resources/keymaster.properties
similarity index 52%
copy from wa/src/main/resources/application.properties
copy to fit/wa-reference/src/main/resources/keymaster.properties
index 487d11b..033fe3b 100644
--- a/wa/src/main/resources/application.properties
+++ b/fit/wa-reference/src/main/resources/keymaster.properties
@@ -14,27 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-spring.application.name=Apache Syncope ${syncope.version} WA
-spring.groovy.template.check-template-location=false
-spring.main.banner-mode=log
-
-server.port=8080
-
-spring.http.encoding.charset=UTF-8
-spring.http.encoding.enabled=true
-spring.http.encoding.force=true
-
-server.servlet.contextPath=/syncope-wa
-
-##
-# Allow configuration classes to override bean definitions from Spring Boot
-#
-spring.main.allow-bean-definition-overriding=true
-spring.main.lazy-initialization=false
-
-service.discovery.address=http://localhost:8080/syncope-wa/
-
-# Conf directories
-conf.directory=${conf.directory}
-cas.standalone.configurationDirectory=${conf.directory}
-cas.authn.oidc.jwksFile=file:${conf.directory}/oidc.keystore
+keymaster.address=http://localhost:9080/syncope/rest/keymaster
+keymaster.username=${anonymousUser}
+keymaster.password=${anonymousKey}
diff --git a/fit/wa-reference/src/main/resources/log4j2.xml b/fit/wa-reference/src/main/resources/log4j2.xml
index 08196df..e184c60 100644
--- a/fit/wa-reference/src/main/resources/log4j2.xml
+++ b/fit/wa-reference/src/main/resources/log4j2.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8" ?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -17,118 +17,52 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
-<!-- Specify the refresh internal in seconds. -->
-<Configuration monitorInterval="5" packages="org.apereo.cas.logging">
- <Properties>
- <Property name="baseDir">${log.directory}</Property>
- <Property name="cas.log.level">info</Property>
- <Property name="spring.webflow.log.level">warn</Property>
- <Property name="spring.security.log.level">info</Property>
- <Property name="spring.cloud.log.level">warn</Property>
- <Property name="spring.web.log.level">warn</Property>
- <Property name="spring.boot.log.level">warn</Property>
- <Property name="ldap.log.level">warn</Property>
- <Property name="pac4j.log.level">warn</Property>
- <Property name="opensaml.log.level">warn</Property>
- <Property name="hazelcast.log.level">warn</Property>
- </Properties>
- <Appenders>
- <RollingFile name="file" fileName="${baseDir}/wa.log" append="true"
- filePattern="${baseDir}/wa-%d{yyyy-MM-dd-HH}-%i.log">
- <PatternLayout pattern="%highlight{%d %p [%c] - <%m>%n}" />
- <Policies>
- <OnStartupTriggeringPolicy />
- <SizeBasedTriggeringPolicy size="10 MB"/>
- <TimeBasedTriggeringPolicy />
- </Policies>
- <DefaultRolloverStrategy max="5" compressionLevel="9">
- <Delete basePath="${baseDir}" maxDepth="2">
- <IfFileName glob="*/*.log.gz" />
- <IfLastModified age="7d" />
- </Delete>
- </DefaultRolloverStrategy>
- </RollingFile>
- <RollingFile name="auditlogfile" fileName="${baseDir}/wa-audit.log" append="true"
- filePattern="${baseDir}/wa-audit-%d{yyyy-MM-dd-HH}-%i.log">
- <PatternLayout pattern="%highlight{%d %p [%c] - %m%n}" />
+<configuration status="WARN">
+
+ <appenders>
+
+ <RollingRandomAccessFile name="main" fileName="${log.directory}/wa.log"
+ filePattern="${log.directory}/wa-%d{yyyy-MM-dd}.log.gz"
+ immediateFlush="false" append="true">
+ <PatternLayout>
+ <pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
+ </PatternLayout>
<Policies>
- <OnStartupTriggeringPolicy />
- <SizeBasedTriggeringPolicy size="10 MB"/>
- <TimeBasedTriggeringPolicy />
+ <TimeBasedTriggeringPolicy/>
+ <SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
- <DefaultRolloverStrategy max="5" compressionLevel="9">
- <Delete basePath="${baseDir}" maxDepth="2">
- <IfFileName glob="*/*.log.gz" />
- <IfLastModified age="7d" />
- </Delete>
- </DefaultRolloverStrategy>
- </RollingFile>
+ </RollingRandomAccessFile>
- <CasAppender name="casAudit">
- <AppenderRef ref="auditlogfile" />
- </CasAppender>
- <CasAppender name="casFile">
- <AppenderRef ref="file" />
- </CasAppender>
- </Appenders>
- <Loggers>
- <AsyncLogger name="org.apereo.cas" level="${sys:cas.log.level}" includeLocation="true" />
- <AsyncLogger name="org.apereo.cas.services" level="${sys:cas.log.level}" includeLocation="true" />
- <AsyncLogger name="org.apereo.spring" level="${sys:cas.log.level}" includeLocation="true" />
- <AsyncLogger name="org.apereo.services.persondir" level="${sys:cas.log.level}" includeLocation="true" />
- <AsyncLogger name="org.apereo.cas.web.flow" level="${sys:cas.log.level}" includeLocation="true" />
- <AsyncLogger name="org.apereo.cas.web.CasWebApplication" level="${sys:cas.log.level}" includeLocation="true"/>
+ </appenders>
- <AsyncLogger name="org.apereo.inspektr.audit.support" additivity="true" level="info" includeLocation="true">
- <AppenderRef ref="casAudit"/>
- </AsyncLogger>
+ <loggers>
- <AsyncLogger name="org.springframework.boot" level="${sys:spring.boot.log.level}" />
- <AsyncLogger name="org.springframework.boot.context.embedded" level="info" />
- <AsyncLogger name="org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration" level="${sys:spring.security.log.level}" />
- <AsyncLogger name="org.springframework.boot.autoconfigure.security" level="${sys:spring.security.log.level}" />
- <AsyncLogger name="org.springframework.boot.devtools" level="debug" />
-
- <AsyncLogger name="org.springframework" level="warn" includeLocation="true" />
- <AsyncLogger name="org.springframework.webflow" level="${sys:spring.webflow.log.level}" includeLocation="true"/>
- <AsyncLogger name="org.springframework.aop" level="warn" includeLocation="true" />
- <AsyncLogger name="org.springframework.session" level="warn" includeLocation="true"/>
- <AsyncLogger name="org.springframework.scheduling" level="info" includeLocation="true"/>
- <AsyncLogger name="org.springframework.cloud.vault" level="warn" includeLocation="true" />
- <AsyncLogger name="org.springframework.web.client" level="warn" includeLocation="true" />
- <AsyncLogger name="org.springframework.security" level="${sys:spring.security.log.level}" includeLocation="true"/>
- <AsyncLogger name="org.springframework.cloud" level="${sys:spring.cloud.log.level}" includeLocation="true"/>
- <AsyncLogger name="org.springframework.amqp" level="error" />
- <AsyncLogger name="org.springframework.integration" level="warn" includeLocation="true"/>
- <AsyncLogger name="org.springframework.messaging" level="warn" includeLocation="true"/>
- <AsyncLogger name="org.springframework.web" level="${sys:spring.web.log.level}" includeLocation="true"/>
- <AsyncLogger name="org.springframework.orm.jpa" level="warn" includeLocation="true"/>
- <AsyncLogger name="org.springframework.scheduling" level="warn" includeLocation="true"/>
- <AsyncLogger name="org.springframework.context.annotation" level="off" includeLocation="true"/>
- <AsyncLogger name="org.springframework.web.socket" level="warn" includeLocation="true"/>
- <AsyncLogger name="org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter" level="trace" includeLocation="true"/>
+ <asyncLogger name="org.apereo.cas" additivity="false" level="INFO">
+ <appender-ref ref="main"/>
+ </asyncLogger>
+ <asyncLogger name="org.apereo.inspektr.audit.support" additivity="false" level="INFO">
+ <appender-ref ref="main"/>
+ </asyncLogger>
- <AsyncLogger name="com.couchbase" level="warn" includeLocation="true" />
- <AsyncLogger name="org.apache" level="error" includeLocation="true"/>
- <AsyncLogger name="com.netflix" level="warn" includeLocation="true"/>
- <AsyncLogger name="org.quartz" level="warn" includeLocation="true"/>
- <AsyncLogger name="org.thymeleaf" level="warn" includeLocation="true"/>
- <AsyncLogger name="org.pac4j" level="${sys:pac4j.log.level}" includeLocation="true"/>
+ <asyncLogger name="org.springframework" additivity="false" level="INFO">
+ <appender-ref ref="main"/>
+ </asyncLogger>
- <AsyncLogger name="org.opensaml" level="${sys:opensaml.log.level}" includeLocation="true"/>
- <AsyncLogger name="PROTOCOL_MESSAGE" level="${sys:opensaml.log.level}" includeLocation="true" />
+ <asyncLogger name="org.apache.syncope.client.lib" additivity="false" level="OFF">
+ <appender-ref ref="main"/>
+ </asyncLogger>
+ <asyncLogger name="org.apache.syncope.wa" additivity="false" level="INFO">
+ <appender-ref ref="main"/>
+ </asyncLogger>
- <AsyncLogger name="net.sf.ehcache" level="warn" includeLocation="true"/>
- <AsyncLogger name="net.jradius" level="warn" includeLocation="true"/>
- <AsyncLogger name="org.openid4java" level="warn" includeLocation="true"/>
- <AsyncLogger name="org.ldaptive" level="${sys:ldap.log.level}" includeLocation="true"/>
- <AsyncLogger name="com.hazelcast" level="${sys:hazelcast.log.level}" includeLocation="true"/>
- <AsyncLogger name="org.jasig.spring" level="warn" includeLocation="true"/>
- <AsyncLogger name="org.apache.cxf" level="warn" includeLocation="true"/>
- <AsyncLogger name="org.apache.http" level="warn" includeLocation="true"/>
+ <asyncLogger name="org.apache.cxf" additivity="false" level="ERROR">
+ <appender-ref ref="main"/>
+ </asyncLogger>
- <AsyncRoot level="warn">
- <AppenderRef ref="casFile"/>
- </AsyncRoot>
- </Loggers>
-</Configuration>
+ <root level="INFO">
+ <appender-ref ref="main"/>
+ </root>
+
+ </loggers>
+
+</configuration>
diff --git a/wa/src/main/resources/application.properties b/fit/wa-reference/src/main/resources/wa.properties
similarity index 64%
copy from wa/src/main/resources/application.properties
copy to fit/wa-reference/src/main/resources/wa.properties
index 487d11b..a208075 100644
--- a/wa/src/main/resources/application.properties
+++ b/fit/wa-reference/src/main/resources/wa.properties
@@ -14,25 +14,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-spring.application.name=Apache Syncope ${syncope.version} WA
-spring.groovy.template.check-template-location=false
-spring.main.banner-mode=log
+anonymousUser=${anonymousUser}
+anonymousKey=${anonymousKey}
-server.port=8080
-
-spring.http.encoding.charset=UTF-8
-spring.http.encoding.enabled=true
-spring.http.encoding.force=true
-
-server.servlet.contextPath=/syncope-wa
-
-##
-# Allow configuration classes to override bean definitions from Spring Boot
-#
-spring.main.allow-bean-definition-overriding=true
-spring.main.lazy-initialization=false
-
-service.discovery.address=http://localhost:8080/syncope-wa/
+useGZIPCompression=true
# Conf directories
conf.directory=${conf.directory}
diff --git a/wa/src/main/resources/application.properties b/fit/wa-reference/src/test/resources/hotswap-agent.properties
similarity index 52%
copy from wa/src/main/resources/application.properties
copy to fit/wa-reference/src/test/resources/hotswap-agent.properties
index 487d11b..d0bf167 100644
--- a/wa/src/main/resources/application.properties
+++ b/fit/wa-reference/src/test/resources/hotswap-agent.properties
@@ -14,27 +14,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-spring.application.name=Apache Syncope ${syncope.version} WA
-spring.groovy.template.check-template-location=false
-spring.main.banner-mode=log
-server.port=8080
+LOGGER=error
-spring.http.encoding.charset=UTF-8
-spring.http.encoding.enabled=true
-spring.http.encoding.force=true
+autoHotswap=true
-server.servlet.contextPath=/syncope-wa
-
-##
-# Allow configuration classes to override bean definitions from Spring Boot
-#
-spring.main.allow-bean-definition-overriding=true
-spring.main.lazy-initialization=false
-
-service.discovery.address=http://localhost:8080/syncope-wa/
-
-# Conf directories
-conf.directory=${conf.directory}
-cas.standalone.configurationDirectory=${conf.directory}
-cas.authn.oidc.jwksFile=file:${conf.directory}/oidc.keystore
+extraClasspath=\
+${basedir}/../../wa/target/classes/org
diff --git a/sra/pom.xml b/sra/pom.xml
index 1139819..6644b0e 100644
--- a/sra/pom.xml
+++ b/sra/pom.xml
@@ -166,6 +166,7 @@ under the License.
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
+
<resource>
<directory>${basedir}/../src/main/resources</directory>
<filtering>true</filtering>
@@ -208,6 +209,11 @@ under the License.
<artifactId>cxf-rt-transports-http-netty-server</artifactId>
<scope>compile</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-devtools</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git a/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAApplication.java b/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAApplication.java
index 5a2e05e..3f56eb4 100644
--- a/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAApplication.java
+++ b/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAApplication.java
@@ -19,6 +19,9 @@
package org.apache.syncope.sra;
import java.util.Objects;
+import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
+import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStart;
+import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStop;
import org.apache.syncope.common.lib.types.IdRepoEntitlement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
@@ -62,6 +65,16 @@ public class SyncopeSRAApplication implements EnvironmentAware {
}
@Bean
+ public KeymasterStart keymasterStart() {
+ return new KeymasterStart(NetworkService.Type.SRA);
+ }
+
+ @Bean
+ public KeymasterStop keymasterStop() {
+ return new KeymasterStop(NetworkService.Type.SRA);
+ }
+
+ @Bean
public RouteLocator routes(final RouteLocatorBuilder builder) {
return () -> Flux.fromIterable(provider.fetch()).map(Route.AbstractBuilder::build);
}
diff --git a/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAShutdown.java b/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAShutdown.java
deleted file mode 100644
index 4ed772c..0000000
--- a/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAShutdown.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.syncope.sra;
-
-import org.springframework.context.ApplicationListener;
-import org.springframework.context.event.ContextClosedEvent;
-import org.springframework.stereotype.Component;
-
-@Component
-public class SyncopeSRAShutdown extends SyncopeSRAStartStop
- implements ApplicationListener<ContextClosedEvent> {
-
- @Override
- public void onApplicationEvent(final ContextClosedEvent event) {
- serviceOps.unregister(getNetworkService());
- }
-}
diff --git a/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAStartStop.java b/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAStartStop.java
deleted file mode 100644
index 926a608..0000000
--- a/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAStartStop.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.syncope.sra;
-
-import org.apache.syncope.common.keymaster.client.api.ServiceOps;
-import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-
-abstract class SyncopeSRAStartStop {
-
- @Autowired
- protected ServiceOps serviceOps;
-
- @Value("${service.discovery.address}")
- private String address;
-
- protected NetworkService getNetworkService() {
- NetworkService ns = new NetworkService();
- ns.setType(NetworkService.Type.SRA);
- ns.setAddress(address);
- return ns;
- }
-}
diff --git a/wa/pom.xml b/wa/pom.xml
index 2bdb8b0..13d69aa 100644
--- a/wa/pom.xml
+++ b/wa/pom.xml
@@ -43,6 +43,18 @@ under the License.
<dependencies>
<dependency>
+ <groupId>org.apache.syncope.common.keymaster</groupId>
+ <artifactId>syncope-common-keymaster-client-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope.client.am</groupId>
+ <artifactId>syncope-client-am-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
</dependency>
@@ -175,15 +187,30 @@ under the License.
</dependency>
<dependency>
+ <groupId>org.apache.syncope.common.keymaster</groupId>
+ <artifactId>syncope-common-keymaster-client-zookeeper</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-tomcat</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>org.junit.vintage</groupId>
- <artifactId>junit-vintage-engine</artifactId>
- </exclusion>
- </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter</artifactId>
+ <scope>test</scope>
</dependency>
</dependencies>
@@ -209,24 +236,105 @@ under the License.
</includes>
</resource>
</resources>
+
+ <testResources>
+ <testResource>
+ <directory>${basedir}/src/test/resources</directory>
+ <filtering>true</filtering>
+ </testResource>
+ </testResources>
</build>
<profiles>
<profile>
<id>debug</id>
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-undertow</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope.common.keymaster</groupId>
+ <artifactId>syncope-common-keymaster-client-zookeeper</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-test</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<build>
- <defaultGoal>clean package spring-boot:run</defaultGoal>
+ <defaultGoal>clean package io.fabric8:docker-maven-plugin:start spring-boot:run</defaultGoal>
<plugins>
<plugin>
+ <groupId>io.fabric8</groupId>
+ <artifactId>docker-maven-plugin</artifactId>
+ <configuration>
+ <images>
+ <image>
+ <name>zookeeper:${zookeeper.version}</name>
+ <run>
+ <ports>
+ <port>2181:2181</port>
+ </ports>
+ <volumes>
+ <bind>
+ <volume>${project.build.testOutputDirectory}/zoo.cfg:/conf/zoo.cfg</volume>
+ <volume>${project.build.testOutputDirectory}/java.env:/conf/java.env</volume>
+ <volume>${project.build.testOutputDirectory}/server-jaas.conf:/conf/server-jaas.conf</volume>
+ <volume>${project.build.testOutputDirectory}/client-jaas.conf:/conf/client-jaas.conf</volume>
+ </bind>
+ </volumes>
+ </run>
+ </image>
+ </images>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${basedir}/src/test/java</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>**/org/apache/syncope/wa/**Test.java</exclude>
+ <exclude>**/org/apache/syncope/wa/**Zookeeper*.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+
+ <plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
@@ -244,11 +352,16 @@ under the License.
<resources>
<resource>
<directory>${basedir}/src/test/resources</directory>
- <includes>
- <include>application-debug.properties</include>
- </includes>
+ <filtering>true</filtering>
</resource>
</resources>
+
+ <testResources>
+ <testResource>
+ <directory>${basedir}/../common/keymaster/client-zookeeper/src/main/resources</directory>
+ <filtering>true</filtering>
+ </testResource>
+ </testResources>
</build>
</profile>
diff --git a/wa/src/main/java/org/apache/syncope/wa/SyncopeWAApplication.java b/wa/src/main/java/org/apache/syncope/wa/SyncopeWAApplication.java
index 970d890..16d985d 100644
--- a/wa/src/main/java/org/apache/syncope/wa/SyncopeWAApplication.java
+++ b/wa/src/main/java/org/apache/syncope/wa/SyncopeWAApplication.java
@@ -19,6 +19,9 @@
package org.apache.syncope.wa;
import org.apache.commons.lang.StringUtils;
+import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
+import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStart;
+import org.apache.syncope.common.keymaster.client.api.startstop.KeymasterStop;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.util.AsciiArtUtils;
import org.apereo.cas.util.DateTimeUtils;
@@ -41,12 +44,16 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.context.annotation.PropertySource;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
+@PropertySource("classpath:wa.properties")
+@PropertySource(value = "file:${conf.directory}/wa.properties", ignoreResourceNotFound = true)
@SpringBootApplication(exclude = {
HibernateJpaAutoConfiguration.class,
JerseyAutoConfiguration.class,
@@ -84,4 +91,14 @@ public class SyncopeWAApplication extends SpringBootServletInitializer {
AsciiArtUtils.printAsciiArtReady(LOG, StringUtils.EMPTY);
LOG.info("Ready to process requests @ [{}]", DateTimeUtils.zonedDateTimeOf(event.getTimestamp()));
}
+
+ @Bean
+ public KeymasterStart keymasterStart() {
+ return new KeymasterStart(NetworkService.Type.WA);
+ }
+
+ @Bean
+ public KeymasterStop keymasterStop() {
+ return new KeymasterStop(NetworkService.Type.WA);
+ }
}
diff --git a/wa/src/main/resources/application.properties b/wa/src/main/resources/application.properties
index 487d11b..53ae4b0 100644
--- a/wa/src/main/resources/application.properties
+++ b/wa/src/main/resources/application.properties
@@ -26,6 +26,9 @@ spring.http.encoding.force=true
server.servlet.contextPath=/syncope-wa
+management.endpoints.web.exposure.include=health,loggers
+management.endpoint.health.show-details=always
+
##
# Allow configuration classes to override bean definitions from Spring Boot
#
@@ -33,8 +36,3 @@ spring.main.allow-bean-definition-overriding=true
spring.main.lazy-initialization=false
service.discovery.address=http://localhost:8080/syncope-wa/
-
-# Conf directories
-conf.directory=${conf.directory}
-cas.standalone.configurationDirectory=${conf.directory}
-cas.authn.oidc.jwksFile=file:${conf.directory}/oidc.keystore
diff --git a/wa/src/main/resources/log4j2.xml b/wa/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..e184c60
--- /dev/null
+++ b/wa/src/main/resources/log4j2.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+-->
+<configuration status="WARN">
+
+ <appenders>
+
+ <RollingRandomAccessFile name="main" fileName="${log.directory}/wa.log"
+ filePattern="${log.directory}/wa-%d{yyyy-MM-dd}.log.gz"
+ immediateFlush="false" append="true">
+ <PatternLayout>
+ <pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
+ </PatternLayout>
+ <Policies>
+ <TimeBasedTriggeringPolicy/>
+ <SizeBasedTriggeringPolicy size="250 MB"/>
+ </Policies>
+ </RollingRandomAccessFile>
+
+ </appenders>
+
+ <loggers>
+
+ <asyncLogger name="org.apereo.cas" additivity="false" level="INFO">
+ <appender-ref ref="main"/>
+ </asyncLogger>
+ <asyncLogger name="org.apereo.inspektr.audit.support" additivity="false" level="INFO">
+ <appender-ref ref="main"/>
+ </asyncLogger>
+
+ <asyncLogger name="org.springframework" additivity="false" level="INFO">
+ <appender-ref ref="main"/>
+ </asyncLogger>
+
+ <asyncLogger name="org.apache.syncope.client.lib" additivity="false" level="OFF">
+ <appender-ref ref="main"/>
+ </asyncLogger>
+ <asyncLogger name="org.apache.syncope.wa" additivity="false" level="INFO">
+ <appender-ref ref="main"/>
+ </asyncLogger>
+
+ <asyncLogger name="org.apache.cxf" additivity="false" level="ERROR">
+ <appender-ref ref="main"/>
+ </asyncLogger>
+
+ <root level="INFO">
+ <appender-ref ref="main"/>
+ </root>
+
+ </loggers>
+
+</configuration>
diff --git a/wa/src/main/resources/static/images/favicon.png b/wa/src/main/resources/static/images/favicon.png
new file mode 100644
index 0000000..aa2f3e2
Binary files /dev/null and b/wa/src/main/resources/static/images/favicon.png differ
diff --git a/wa/src/main/resources/templates/layout.html b/wa/src/main/resources/templates/layout.html
index 846f0d5..ad83fbc 100644
--- a/wa/src/main/resources/templates/layout.html
+++ b/wa/src/main/resources/templates/layout.html
@@ -24,7 +24,7 @@ under the License.
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
- <title layout:title-pattern="$CONTENT_TITLE - $LAYOUT_TITLE">Apache Syncope</title>
+ <title layout:title-pattern="$LAYOUT_TITLE">Apache Syncope</title>
<!--/* Core CAS CSS */-->
<link rel="stylesheet" type="text/css" href="../static/css/normalize.css" th:href="@{#{webjars.normalize.css}}" />
@@ -33,7 +33,7 @@ under the License.
<link rel="stylesheet" type="text/css" href="../static/css/mdi-font.css" th:href="@{#{webjars.mdi-font.css}}" />
<link rel="stylesheet" type="text/css" href="../static/css/cas.css" th:href="@{${#themes.code('cas.standard.css.file')}}"/>
- <link rel="icon" th:href="@{/favicon.ico}" type="image/x-icon"/>
+ <link rel="shortcut icon" th:href="@{'/images/favicon.png'}" type="image/png"/>
</head>
<body>
diff --git a/wa/src/main/resources/application.properties b/wa/src/main/resources/wa.properties
similarity index 64%
copy from wa/src/main/resources/application.properties
copy to wa/src/main/resources/wa.properties
index 487d11b..a208075 100644
--- a/wa/src/main/resources/application.properties
+++ b/wa/src/main/resources/wa.properties
@@ -14,25 +14,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-spring.application.name=Apache Syncope ${syncope.version} WA
-spring.groovy.template.check-template-location=false
-spring.main.banner-mode=log
+anonymousUser=${anonymousUser}
+anonymousKey=${anonymousKey}
-server.port=8080
-
-spring.http.encoding.charset=UTF-8
-spring.http.encoding.enabled=true
-spring.http.encoding.force=true
-
-server.servlet.contextPath=/syncope-wa
-
-##
-# Allow configuration classes to override bean definitions from Spring Boot
-#
-spring.main.allow-bean-definition-overriding=true
-spring.main.lazy-initialization=false
-
-service.discovery.address=http://localhost:8080/syncope-wa/
+useGZIPCompression=true
# Conf directories
conf.directory=${conf.directory}
diff --git a/wa/src/test/java/org/apache/syncope/wa/SyncopeWATest.java b/wa/src/test/java/org/apache/syncope/wa/SyncopeWATest.java
new file mode 100644
index 0000000..c4ed578
--- /dev/null
+++ b/wa/src/test/java/org/apache/syncope/wa/SyncopeWATest.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.syncope.wa;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+import javax.ws.rs.core.HttpHeaders;
+import org.apache.http.Consts;
+import org.apache.http.Header;
+import org.apache.http.HttpStatus;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.test.context.ContextConfiguration;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
+ "cas.authn.accept.users=mrossi::password"
+})
+@ContextConfiguration(initializers = ZookeeperTestingServer.class)
+public class SyncopeWATest {
+
+ @LocalServerPort
+ private int port;
+
+ private String getLoginURL() {
+ return "http://localhost:" + port + "/syncope-wa/login";
+ }
+
+ @Test
+ public void loginLogout() throws IOException {
+ CloseableHttpClient httpclient = HttpClients.createDefault();
+ HttpClientContext context = HttpClientContext.create();
+ context.setCookieStore(new BasicCookieStore());
+
+ // 1. first GET to fetch execution
+ HttpGet get = new HttpGet(getLoginURL());
+ get.addHeader(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE, "en-US,en;q=0.5"));
+ CloseableHttpResponse response = httpclient.execute(get, context);
+ assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
+
+ String responseBody = EntityUtils.toString(response.getEntity());
+ int begin = responseBody.indexOf("name=\"execution\" value=\"");
+ assertNotEquals(-1, begin);
+ int end = responseBody.indexOf("\"/><input type=\"hidden\" name=\"_eventId\"");
+ assertNotEquals(-1, end);
+
+ String execution = responseBody.substring(begin + 24, end);
+ assertNotNull(execution);
+
+ // 2. then POST to authenticate
+ List<NameValuePair> form = new ArrayList<>();
+ form.add(new BasicNameValuePair("_eventId", "submit"));
+ form.add(new BasicNameValuePair("execution", execution));
+ form.add(new BasicNameValuePair("username", "mrossi"));
+ form.add(new BasicNameValuePair("password", "password"));
+ form.add(new BasicNameValuePair("geolocation", ""));
+
+ HttpPost post = new HttpPost(getLoginURL());
+ post.addHeader(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE, "en-US,en;q=0.5"));
+ post.setEntity(new UrlEncodedFormEntity(form, Consts.UTF_8));
+ response = httpclient.execute(post, context);
+
+ // 3. check authentication results
+ assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
+
+ Header[] cookie = response.getHeaders("Set-Cookie");
+ assertNotNull(cookie);
+ assertTrue(cookie.length > 0);
+ assertEquals(1, Stream.of(cookie).filter(item -> item.getValue().startsWith("TGC")).count());
+
+ String body = EntityUtils.toString(response.getEntity());
+ assertTrue(body.contains("Log In Successful"));
+ assertTrue(body.contains("have successfully logged into the Central Authentication Service"));
+
+ // 4. logout
+ HttpGet logout = new HttpGet(getLoginURL().replace("login", "logout"));
+ logout.addHeader(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE, "en-US,en;q=0.5"));
+ response = httpclient.execute(logout, context);
+ assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
+
+ body = EntityUtils.toString(response.getEntity());
+ assertTrue(body.contains("Logout successful"));
+ assertTrue(body.contains("have successfully logged out of the Central Authentication Service"));
+ }
+
+ @Test
+ public void loginError() throws IOException {
+ CloseableHttpClient httpclient = HttpClients.createDefault();
+ HttpClientContext context = HttpClientContext.create();
+ context.setCookieStore(new BasicCookieStore());
+
+ // 1. first GET to fetch execution
+ HttpGet get = new HttpGet(getLoginURL());
+ get.addHeader(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE, "en-US,en;q=0.5"));
+ CloseableHttpResponse response = httpclient.execute(get, context);
+ assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
+
+ String responseBody = EntityUtils.toString(response.getEntity());
+ int begin = responseBody.indexOf("name=\"execution\" value=\"");
+ assertNotEquals(-1, begin);
+ int end = responseBody.indexOf("\"/><input type=\"hidden\" name=\"_eventId\"");
+ assertNotEquals(-1, end);
+
+ String execution = responseBody.substring(begin + 24, end);
+ assertNotNull(execution);
+
+ // 2. then POST to authenticate
+ List<NameValuePair> form = new ArrayList<>();
+ form.add(new BasicNameValuePair("_eventId", "submit"));
+ form.add(new BasicNameValuePair("execution", execution));
+ form.add(new BasicNameValuePair("username", "mrossi"));
+ form.add(new BasicNameValuePair("password", "WRONG"));
+ form.add(new BasicNameValuePair("geolocation", ""));
+
+ HttpPost post = new HttpPost(getLoginURL());
+ post.addHeader(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE, "en-US,en;q=0.5"));
+ post.setEntity(new UrlEncodedFormEntity(form, Consts.UTF_8));
+ response = httpclient.execute(post, context);
+
+ // 3. check authentication results
+ assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode());
+ }
+}
diff --git a/wa/src/test/java/org/apache/syncope/wa/ZookeeperTestingServer.java b/wa/src/test/java/org/apache/syncope/wa/ZookeeperTestingServer.java
new file mode 100644
index 0000000..956e6f3
--- /dev/null
+++ b/wa/src/test/java/org/apache/syncope/wa/ZookeeperTestingServer.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.syncope.wa;
+
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicReference;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import org.apache.curator.test.InstanceSpec;
+import org.apache.curator.test.TestingServer;
+import org.apache.zookeeper.server.auth.DigestLoginModule;
+import org.apache.zookeeper.server.auth.SASLAuthenticationProvider;
+import org.springframework.context.ApplicationContextInitializer;
+import org.springframework.context.ConfigurableApplicationContext;
+
+public class ZookeeperTestingServer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
+
+ @Override
+ public void initialize(final ConfigurableApplicationContext ctx) {
+ AtomicReference<String> username = new AtomicReference<>();
+ AtomicReference<String> password = new AtomicReference<>();
+ try (InputStream propStream = getClass().getResourceAsStream("/keymaster.properties")) {
+ Properties props = new Properties();
+ props.load(propStream);
+
+ username.set(props.getProperty("keymaster.username"));
+ password.set(props.getProperty("keymaster.password"));
+ } catch (Exception e) {
+ throw new IllegalStateException("Could not load /keymaster.properties", e);
+ }
+
+ Configuration.setConfiguration(new Configuration() {
+
+ private final AppConfigurationEntry[] entries = {
+ new AppConfigurationEntry(
+ DigestLoginModule.class.getName(),
+ AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+ Map.of(
+ "user_" + username.get(), password.get()
+ ))
+ };
+
+ @Override
+ public AppConfigurationEntry[] getAppConfigurationEntry(final String name) {
+ return entries;
+ }
+ });
+
+ Map<String, Object> customProperties = new HashMap<>();
+ customProperties.put("authProvider.1", SASLAuthenticationProvider.class.getName());
+ InstanceSpec spec = new InstanceSpec(null, 2181, -1, -1, true, 1, -1, -1, customProperties);
+
+ try {
+ new TestingServer(spec, true);
+ } catch (Exception e) {
+ fail(e);
+ }
+ }
+}
diff --git a/wa/src/main/resources/application.properties b/wa/src/test/resources/keymaster.properties
similarity index 52%
copy from wa/src/main/resources/application.properties
copy to wa/src/test/resources/keymaster.properties
index 487d11b..f374d8c 100644
--- a/wa/src/main/resources/application.properties
+++ b/wa/src/test/resources/keymaster.properties
@@ -14,27 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-spring.application.name=Apache Syncope ${syncope.version} WA
-spring.groovy.template.check-template-location=false
-spring.main.banner-mode=log
-
-server.port=8080
-
-spring.http.encoding.charset=UTF-8
-spring.http.encoding.enabled=true
-spring.http.encoding.force=true
-
-server.servlet.contextPath=/syncope-wa
-
-##
-# Allow configuration classes to override bean definitions from Spring Boot
-#
-spring.main.allow-bean-definition-overriding=true
-spring.main.lazy-initialization=false
-
-service.discovery.address=http://localhost:8080/syncope-wa/
-
-# Conf directories
-conf.directory=${conf.directory}
-cas.standalone.configurationDirectory=${conf.directory}
-cas.authn.oidc.jwksFile=file:${conf.directory}/oidc.keystore
+keymaster.address=127.0.0.1:2181
+keymaster.username=${anonymousUser}
+keymaster.password=${anonymousKey}