Skip to content

Commit

Permalink
Feature/mgr 138 (#31)
Browse files Browse the repository at this point in the history
* MGR-138 
* Cherry-picked MGR-139 from 1.20.x

Co-authored-by: Matthias Müller <Matthias.Mueller@aiticon.com>
  • Loading branch information
dheuvels and Matthias Müller committed Aug 18, 2022
1 parent 5672027 commit 3df93ec
Show file tree
Hide file tree
Showing 18 changed files with 533 additions and 62 deletions.
6 changes: 6 additions & 0 deletions application-home/conf/datasources/ds-sites.xml
Expand Up @@ -128,6 +128,9 @@
<field name="host" type="text">
<label>host</label>
</field>
<field name="hostAliases" type="longtext" binding="hostAliases">
<label>hostAliases</label>
</field>
<field name="domain" type="text">
<label>domain</label>
</field>
Expand Down Expand Up @@ -158,6 +161,9 @@
<field name="host" type="text">
<label>host</label>
</field>
<field name="hostAliases" type="longtext" binding="hostAliases">
<label>hostAliases</label>
</field>
<field name="domain" type="text">
<label>domain</label>
</field>
Expand Down
7 changes: 5 additions & 2 deletions application-home/dictionary/manager-messages.properties
Expand Up @@ -118,7 +118,8 @@ hitCount=Hits
heap.max=Heap max.
heap.used=Heap used
heap.usedPercent=Percentage
host=Host
host=Hostname
hostAliases=Hostname aliases (one per line)
hostName=Host name
id=ID
install.latestrelease=Install latest release
Expand Down Expand Up @@ -350,7 +351,9 @@ site.deleted=Site has been deleted.
site.domain.exists=A different site with this domain already exists!
site.edit=Site {0}
site.grant=Grant access to sites
site.host.exists=A different site with this host already exists!
site.host.exists=Hostname overlaps with hostnames of site "{0}"!
site.hostalias.exists=Hostname aliases overlap with hostnames of site "{0}"!
site.hostalias.invalid=Hostname alias "{0}" is not a valid hostname.
site.name.exists=A different site with this name already exists!
site.not.exists=Site does not exist.
site.properties=Site properties
Expand Down
7 changes: 5 additions & 2 deletions application-home/dictionary/manager-messages_de.properties
Expand Up @@ -88,7 +88,8 @@ group=Gruppe
groups=Gruppen
hidden=Versteckt
hitCount=Zugriffe
host=Host
host=Hostname
hostAliases=Host Alias-Namen (einer pro Zeile)
id=ID
install.latestrelease=Neustes Release installieren
install.latestsnapshot=Neuste Snapshot installieren
Expand Down Expand Up @@ -291,7 +292,9 @@ site.deleted=Site wurde gelöscht.
site.domain.exists=Eine andere Seite mit dieser Domäne existiert bereits!
site.edit=Site {0}
site.grant=Zugriff für Sites erlauben
site.host.exists=Eine andere Seite mit diesem Host existiert bereits!
site.host.exists=Dieser Hostname wird bereits als Name von der Seite "{0}" benutzt!
site.hostalias.exists=Einer der Alias Hostnamen wird bereits als Name von der Seite "{0}" benutzt!
site.hostalias.invalid=Alias Hostname "{0}" ist kein valider Hostname.
site.name.exists=Eine andere Seite mit diesem Namen existiert bereits!
site.not.exists=Die angeforderte Site existiert nicht.
site.properties=Site Einstellungen
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -21,7 +21,7 @@
<parent>
<groupId>org.appng</groupId>
<artifactId>appng-application-parent</artifactId>
<version>1.23.0</version>
<version>1.24.6-SNAPSHOT</version>
</parent>

<scm>
Expand Down
39 changes: 38 additions & 1 deletion src/main/java/org/appng/application/manager/form/SiteForm.java
Expand Up @@ -15,17 +15,31 @@
*/
package org.appng.application.manager.form;

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.validation.Valid;

import org.appng.api.Environment;
import org.appng.api.FieldProcessor;
import org.appng.api.FormValidator;
import org.appng.api.Options;
import org.appng.api.Request;
import org.appng.api.model.Application;
import org.appng.api.model.Site;
import org.appng.application.manager.MessageConstants;
import org.appng.core.domain.SiteImpl;
import org.appng.core.domain.ValidationPatterns;

/**
* Bindclass used for creating/updating a {@link SiteImpl}.
*
* @author Matthias Müller
*
*/
public class SiteForm {
public class SiteForm implements FormValidator {

private SiteImpl site;
private String template;
Expand Down Expand Up @@ -55,4 +69,27 @@ public void setTemplate(String template) {
this.template = template;
}

public String getHostAliases() {
return String.join(System.lineSeparator(), site.getHostAliases());
}

public void setHostAliases(String hostAliases) {
Set<String> hostnames = new HashSet<String>();
Pattern splitPattern = Pattern.compile("^[ \t]*(.+?)[ \t]*$", Pattern.MULTILINE);
Matcher splitMatcher = splitPattern.matcher(hostAliases);
while (splitMatcher.find()) {
hostnames.add(splitMatcher.group(1));
}
site.setHostAliases(hostnames);
}

public void validate(Site site, Application application, Environment environment, Options options, Request request,
FieldProcessor fp) {
for (String name : this.site.getHostAliases()) {
if (!Pattern.matches(ValidationPatterns.HOST_PATTERN, name))
fp.addErrorMessage(fp.getField("hostAliases"),
request.getMessage(MessageConstants.SITE_HOSTALIAS_INVALID, name));
}
}

}
Expand Up @@ -1085,8 +1085,20 @@ private void checkSite(Request request, Site site, FieldProcessor fp, Site curre
if (fp.hasField("site.name") && !siteRepository.isUnique(site.getId(), "name", site.getName())) {
fp.addErrorMessage(fp.getField("site.name"), request.getMessage(MessageConstants.SITE_NAME_EXISTS));
}
if (!siteRepository.isUnique(site.getId(), "host", site.getHost())) {
fp.addErrorMessage(fp.getField("site.host"), request.getMessage(MessageConstants.SITE_HOST_EXISTS));
Set<String> hostnames = new HashSet<String>(site.getHostAliases());
hostnames.add(site.getHost());
List<SiteImpl> hostOverlapSites = siteRepository.findSitesForHostNames(hostnames);
for (SiteImpl ovlpSite : hostOverlapSites) {
if (site.getId() == ovlpSite.getId())
continue;
else {
if (ovlpSite.getHost().equals(site.getHost()) || ovlpSite.getHostAliases().contains(site.getHost()))
fp.addErrorMessage(fp.getField("site.host"),
request.getMessage(MessageConstants.SITE_HOST_EXISTS, ovlpSite.getName()));
else
fp.addErrorMessage(fp.getField("hostAliases"),
request.getMessage(MessageConstants.SITE_HOSTALIAS_EXISTS, ovlpSite.getName()));
}
}
if (!siteRepository.isUnique(site.getId(), "domain", site.getDomain())) {
fp.addErrorMessage(fp.getField("site.domain"), request.getMessage(MessageConstants.SITE_DOMAIN_EXISTS));
Expand Down
79 changes: 54 additions & 25 deletions src/test/java/org/appng/application/manager/business/SitesTest.java
Expand Up @@ -17,6 +17,8 @@

import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

import org.appng.api.FieldProcessor;
Expand Down Expand Up @@ -49,35 +51,16 @@ public class SitesTest extends AbstractTest {

private static final String SITE_EVENT = "siteEvent";

@Override
protected void mockSite(GenericApplicationContext applicationContext) {
if (null == site) {
site = Mockito.mock(SiteImpl.class);
}
Mockito.when(site.getName()).thenReturn("localhost");
Mockito.when(site.getState()).thenReturn(SiteState.STARTED);
Mockito.when(site.getDomain()).thenReturn("localhost");
Mockito.when(site.getHost()).thenReturn("localhost");
Mockito.when(site.getApplication("appng-manager")).thenReturn(application);
org.appng.api.support.SiteClassLoader siteClassLoader = new org.appng.api.support.SiteClassLoader(new URL[0],
this.getClass().getClassLoader(), site.getName());
Mockito.when(site.getSiteClassLoader()).thenReturn(siteClassLoader);
List<Property> siteProperties = getSiteProperties("platform.site.localhost.");
Mockito.when(site.getProperties()).thenReturn(new PropertyHolder("platform.site.localhost.", siteProperties));
if (null != applicationContext) {
applicationContext.addBeanFactoryPostProcessor(pp -> pp.registerSingleton("site", site));
}
}

@Test
public void testCreateSite() throws Exception {
public void testCreateSite01() throws Exception {
propertyRepository.save(new PropertyImpl("platform." + Platform.Property.MESSAGING_ENABLED, null, "false"));

SiteImpl siteToCreate = new SiteImpl();
SiteForm siteForm = new SiteForm(siteToCreate);
siteToCreate.setName("localhost");
siteToCreate.setHost("localhost");
siteToCreate.setDomain("localhost");
siteToCreate.setName("site1");
siteToCreate.setHost("hostname1.domain.tld");
siteToCreate.setHostAliases(new HashSet<>(Arrays.asList("doppeltes", "lottchen")));
siteToCreate.setDomain("https://hostname1.domain.tld");
siteToCreate.setActive(true);

// prepares using appNG >= 1.19.1
Expand All @@ -96,9 +79,55 @@ public void testCreateSite() throws Exception {
}

@Test
public void testCreateSiteValidationFail() throws Exception {
public void testCreateSite02ValidationFail() throws Exception {
SiteImpl siteToCreate = new SiteImpl();
SiteForm siteForm = new SiteForm(siteToCreate);
CallableAction callableAction = getAction(SITE_EVENT, "create").withParam(FORM_ACTION, "create")
.getCallableAction(siteForm);
callableAction.perform();
validate(callableAction.getAction());
}

@Test
public void testCreateSite03NameDuplicateFail() throws Exception {
SiteImpl siteToCreate = new SiteImpl();
SiteForm siteForm = new SiteForm(siteToCreate);
siteToCreate.setName("site1");
siteToCreate.setHost("other-hostname.domain.tld");
siteToCreate.setDomain("https://other-hostname.domain.tld");
siteToCreate.setActive(true);

CallableAction callableAction = getAction(SITE_EVENT, "create").withParam(FORM_ACTION, "create")
.getCallableAction(siteForm);
callableAction.perform();
validate(callableAction.getAction());
}

@Test
public void testCreateSite04HostDuplicateFail() throws Exception {
SiteImpl siteToCreate = new SiteImpl();
SiteForm siteForm = new SiteForm(siteToCreate);
siteToCreate.setName("other-site");
siteToCreate.setHost("lottchen");
siteToCreate.setDomain("https://other-hostname.domain.tld");
siteToCreate.setActive(true);

CallableAction callableAction = getAction(SITE_EVENT, "create").withParam(FORM_ACTION, "create")
.getCallableAction(siteForm);
callableAction.perform();
validate(callableAction.getAction());
}

@Test
public void testCreateSite05AliasDuplicateFail() throws Exception {
SiteImpl siteToCreate = new SiteImpl();
SiteForm siteForm = new SiteForm(siteToCreate);
siteToCreate.setName("other-site");
siteToCreate.setHost("other-hostname.domain.tld");
siteToCreate.setHostAliases(new HashSet<>(Arrays.asList("", "hostname1.domain.tld")));
siteToCreate.setDomain("https://other-hostname.domain.tld");
siteToCreate.setActive(true);

CallableAction callableAction = getAction(SITE_EVENT, "create").withParam(FORM_ACTION, "create")
.getCallableAction(siteForm);
callableAction.perform();
Expand Down
28 changes: 26 additions & 2 deletions src/test/resources/xml/DataBaseConnectionsTest-testMigrations.xml
Expand Up @@ -33,8 +33,8 @@
</meta-data>
</config>
<data paginate="false">
<resultset chunk="0" chunkname="migrations" chunksize="16" nextchunk="0" previouschunk="0" firstchunk="0"
lastchunk="0" hits="16">
<resultset chunk="0" chunkname="migrations" chunksize="17" nextchunk="0" previouschunk="0" firstchunk="0"
lastchunk="0" hits="17">
<result>
<field name="installedRank" type="int">
<value></value>
Expand Down Expand Up @@ -419,6 +419,30 @@
<icon type="class">led_orange</icon>
</field>
</result>
<result>
<field name="installedRank" type="int">
<value></value>
</field>
<field name="installedOn" type="date">
<value></value>
</field>
<field name="version.version" type="text">
<value>4.4</value>
</field>
<field name="description" type="text">
<value>add table site hostnames</value>
</field>
<field name="checksum" type="text">
<value>368748984</value>
</field>
<field name="installedBy" type="text">
<value></value>
</field>
<field name="state" type="image">
<value>PENDING</value>
<icon type="class">led_orange</icon>
</field>
</result>
</resultset>
</data>
</datasource>
4 changes: 2 additions & 2 deletions src/test/resources/xml/PlatformEventsTest-testShowAll.xml
Expand Up @@ -24,7 +24,7 @@
<label id="application">Application</label>
</field>
<field name="origin" type="text" binding="origin">
<label id="host">Host</label>
<label id="host">Hostname</label>
</field>
<field name="hostName" type="text" binding="hostName">
<label id="hostName">Host name</label>
Expand Down Expand Up @@ -70,7 +70,7 @@
<option value="" name="" />
</selection>
<selection id="eH" type="select">
<title id="host">Host</title>
<title id="host">Hostname</title>
<option value="" name="" />
</selection>
<selection id="eN" type="select">
Expand Down
Expand Up @@ -25,7 +25,7 @@
</validation>
</field>
<field name="host" type="text" binding="site.host">
<label id="host">Host</label>
<label id="host">Hostname</label>
<validation>
<notNull>
<message ref="site.host" class="ERROR" code="{validation.notNull}">Field must not be empty</message>
Expand All @@ -37,6 +37,9 @@
</pattern>
</validation>
</field>
<field name="hostAliases" type="longtext" binding="hostAliases">
<label id="hostAliases">Hostname aliases (one per line)</label>
</field>
<field name="domain" type="text" binding="site.domain">
<label id="domain">Domain</label>
<validation>
Expand Down Expand Up @@ -85,6 +88,9 @@
<field name="host" type="text">
<value></value>
</field>
<field name="hostAliases" type="longtext">
<value></value>
</field>
<field name="domain" type="text">
<value></value>
</field>
Expand Down
Expand Up @@ -28,7 +28,7 @@
</messages>
</field>
<field name="host" type="text" binding="site.host">
<label id="host">Host</label>
<label id="host">Hostname</label>
<validation>
<notNull>
<message ref="site.host" class="ERROR" code="{validation.notNull}">Field must not be empty</message>
Expand All @@ -43,6 +43,9 @@
<message ref="site.host" class="ERROR" code="{validation.notNull}">Field must not be empty</message>
</messages>
</field>
<field name="hostAliases" type="longtext" binding="hostAliases">
<label id="hostAliases">Hostname aliases (one per line)</label>
</field>
<field name="domain" type="text" binding="site.domain">
<label id="domain">Domain</label>
<validation>
Expand Down Expand Up @@ -92,6 +95,9 @@
<field name="host" type="text">
<value></value>
</field>
<field name="hostAliases" type="longtext">
<value></value>
</field>
<field name="domain" type="text">
<value></value>
</field>
Expand Down

0 comments on commit 3df93ec

Please sign in to comment.