HostingAsset-Hierarchie spec in enum HsHostingAssetType and generates PlantUML #72
@ -1,14 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
## HostingAsset Type Structure
|
## HostingAsset Type Structure
|
||||||
|
|
||||||
### packages Server, Webspace, Domain
|
### Domain
|
||||||
|
|
||||||
```plantuml
|
```plantuml
|
||||||
@startuml
|
@startuml
|
||||||
left to right direction
|
left to right direction
|
||||||
|
|
||||||
package Booking #99bcdb {
|
package Booking #feb28c {
|
||||||
entity BI_PRIVATE_CLOUD
|
entity BI_PRIVATE_CLOUD
|
||||||
entity BI_CLOUD_SERVER
|
entity BI_CLOUD_SERVER
|
||||||
entity BI_MANAGED_SERVER
|
entity BI_MANAGED_SERVER
|
||||||
@ -17,7 +15,16 @@ package Booking #99bcdb {
|
|||||||
entity BI_DOMAIN_EMAIL_SUBMISSION_SETUP
|
entity BI_DOMAIN_EMAIL_SUBMISSION_SETUP
|
||||||
}
|
}
|
||||||
|
|
||||||
package Hosting #white {
|
package Hosting #feb28c{
|
||||||
|
package Domain #99bcdb {
|
||||||
|
entity HA_DOMAIN_SETUP
|
||||||
|
entity HA_DOMAIN_DNS_SETUP
|
||||||
|
entity HA_DOMAIN_HTTP_SETUP
|
||||||
|
entity HA_DOMAIN_EMAIL_SUBMISSION_SETUP
|
||||||
|
entity HA_DOMAIN_EMAIL_MAILBOX_SETUP
|
||||||
|
entity HA_EMAIL_ADDRESS
|
||||||
|
}
|
||||||
|
|
||||||
package Server #99bcdb {
|
package Server #99bcdb {
|
||||||
entity HA_CLOUD_SERVER
|
entity HA_CLOUD_SERVER
|
||||||
entity HA_MANAGED_SERVER
|
entity HA_MANAGED_SERVER
|
||||||
@ -30,15 +37,6 @@ package Hosting #white {
|
|||||||
entity HA_EMAIL_ALIAS
|
entity HA_EMAIL_ALIAS
|
||||||
}
|
}
|
||||||
|
|
||||||
package Domain #99bcdb {
|
|
||||||
entity HA_DOMAIN_SETUP
|
|
||||||
entity HA_DOMAIN_DNS_SETUP
|
|
||||||
entity HA_DOMAIN_HTTP_SETUP
|
|
||||||
entity HA_DOMAIN_EMAIL_SUBMISSION_SETUP
|
|
||||||
entity HA_DOMAIN_EMAIL_MAILBOX_SETUP
|
|
||||||
entity HA_EMAIL_ADDRESS
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BI_CLOUD_SERVER *--> BI_PRIVATE_CLOUD
|
BI_CLOUD_SERVER *--> BI_PRIVATE_CLOUD
|
||||||
@ -50,18 +48,21 @@ HA_MANAGED_SERVER ==* BI_MANAGED_SERVER
|
|||||||
HA_MANAGED_WEBSPACE ==* BI_MANAGED_WEBSPACE
|
HA_MANAGED_WEBSPACE ==* BI_MANAGED_WEBSPACE
|
||||||
HA_MANAGED_WEBSPACE o..> HA_MANAGED_SERVER
|
HA_MANAGED_WEBSPACE o..> HA_MANAGED_SERVER
|
||||||
HA_UNIX_USER *==> HA_MANAGED_WEBSPACE
|
HA_UNIX_USER *==> HA_MANAGED_WEBSPACE
|
||||||
HA_DOMAIN_DNS_SETUP ==* BI_DOMAIN_DNS_SETUP
|
HA_DOMAIN_SETUP o..> HA_DOMAIN_SETUP
|
||||||
HA_DOMAIN_HTTP_SETUP *==> HA_MANAGED_WEBSPACE
|
HA_DOMAIN_DNS_SETUP *==> HA_DOMAIN_SETUP
|
||||||
|
HA_DOMAIN_HTTP_SETUP *==> HA_DOMAIN_SETUP
|
||||||
HA_DOMAIN_HTTP_SETUP o..> HA_UNIX_USER
|
HA_DOMAIN_HTTP_SETUP o..> HA_UNIX_USER
|
||||||
HA_DOMAIN_EMAIL_SUBMISSION_SETUP ==* BI_DOMAIN_EMAIL_SUBMISSION_SETUP
|
HA_DOMAIN_EMAIL_SUBMISSION_SETUP *==> HA_DOMAIN_SETUP
|
||||||
HA_DOMAIN_EMAIL_SUBMISSION_SETUP o..> HA_MANAGED_WEBSPACE
|
HA_DOMAIN_EMAIL_SUBMISSION_SETUP o..> HA_MANAGED_WEBSPACE
|
||||||
HA_DOMAIN_EMAIL_MAILBOX_SETUP *==> HA_MANAGED_WEBSPACE
|
HA_DOMAIN_EMAIL_MAILBOX_SETUP *==> HA_DOMAIN_SETUP
|
||||||
|
HA_DOMAIN_EMAIL_MAILBOX_SETUP o..> HA_MANAGED_WEBSPACE
|
||||||
HA_EMAIL_ALIAS *==> HA_MANAGED_WEBSPACE
|
HA_EMAIL_ALIAS *==> HA_MANAGED_WEBSPACE
|
||||||
HA_EMAIL_ADDRESS *==> HA_DOMAIN_EMAIL_MAILBOX_SETUP
|
HA_EMAIL_ADDRESS *==> HA_DOMAIN_EMAIL_MAILBOX_SETUP
|
||||||
HA_IP_NUMBER o..> HA_CLOUD_SERVER
|
HA_IP_NUMBER o..> HA_CLOUD_SERVER
|
||||||
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
||||||
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
||||||
package Legend {
|
|
||||||
|
package Legend #white {
|
||||||
SUB_ENTITY1 *--> REQUIRED_PARENT_ENTITY
|
SUB_ENTITY1 *--> REQUIRED_PARENT_ENTITY
|
||||||
SUB_ENTITY2 *..> OPTIONAL_PARENT_ENTITY
|
SUB_ENTITY2 *..> OPTIONAL_PARENT_ENTITY
|
||||||
ASSIGNED_ENTITY1 o--> REQUIRED_ASSIGNED_TO_ENTITY1
|
ASSIGNED_ENTITY1 o--> REQUIRED_ASSIGNED_TO_ENTITY1
|
||||||
@ -69,13 +70,13 @@ package Legend {
|
|||||||
}
|
}
|
||||||
Booking -down[hidden]->Legend
|
Booking -down[hidden]->Legend
|
||||||
```
|
```
|
||||||
### packages MariaDB, Server, Webspace
|
### MariaDB
|
||||||
|
|
||||||
```plantuml
|
```plantuml
|
||||||
@startuml
|
@startuml
|
||||||
left to right direction
|
left to right direction
|
||||||
|
|
||||||
package Booking #99bcdb {
|
package Booking #feb28c {
|
||||||
entity BI_PRIVATE_CLOUD
|
entity BI_PRIVATE_CLOUD
|
||||||
entity BI_CLOUD_SERVER
|
entity BI_CLOUD_SERVER
|
||||||
entity BI_MANAGED_SERVER
|
entity BI_MANAGED_SERVER
|
||||||
@ -84,7 +85,7 @@ package Booking #99bcdb {
|
|||||||
entity BI_DOMAIN_EMAIL_SUBMISSION_SETUP
|
entity BI_DOMAIN_EMAIL_SUBMISSION_SETUP
|
||||||
}
|
}
|
||||||
|
|
||||||
package Hosting #white {
|
package Hosting #feb28c{
|
||||||
package MariaDB #99bcdb {
|
package MariaDB #99bcdb {
|
||||||
entity HA_MARIADB_INSTANCE
|
entity HA_MARIADB_INSTANCE
|
||||||
entity HA_MARIADB_USER
|
entity HA_MARIADB_USER
|
||||||
@ -123,7 +124,8 @@ HA_MARIADB_DATABASE o..> HA_MARIADB_INSTANCE
|
|||||||
HA_IP_NUMBER o..> HA_CLOUD_SERVER
|
HA_IP_NUMBER o..> HA_CLOUD_SERVER
|
||||||
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
||||||
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
||||||
package Legend {
|
|
||||||
|
package Legend #white {
|
||||||
SUB_ENTITY1 *--> REQUIRED_PARENT_ENTITY
|
SUB_ENTITY1 *--> REQUIRED_PARENT_ENTITY
|
||||||
SUB_ENTITY2 *..> OPTIONAL_PARENT_ENTITY
|
SUB_ENTITY2 *..> OPTIONAL_PARENT_ENTITY
|
||||||
ASSIGNED_ENTITY1 o--> REQUIRED_ASSIGNED_TO_ENTITY1
|
ASSIGNED_ENTITY1 o--> REQUIRED_ASSIGNED_TO_ENTITY1
|
||||||
@ -131,13 +133,13 @@ package Legend {
|
|||||||
}
|
}
|
||||||
Booking -down[hidden]->Legend
|
Booking -down[hidden]->Legend
|
||||||
```
|
```
|
||||||
### packages Server, PostgreSQL, Webspace
|
### PostgreSQL
|
||||||
|
|
||||||
```plantuml
|
```plantuml
|
||||||
@startuml
|
@startuml
|
||||||
left to right direction
|
left to right direction
|
||||||
|
|
||||||
package Booking #99bcdb {
|
package Booking #feb28c {
|
||||||
entity BI_PRIVATE_CLOUD
|
entity BI_PRIVATE_CLOUD
|
||||||
entity BI_CLOUD_SERVER
|
entity BI_CLOUD_SERVER
|
||||||
entity BI_MANAGED_SERVER
|
entity BI_MANAGED_SERVER
|
||||||
@ -146,19 +148,19 @@ package Booking #99bcdb {
|
|||||||
entity BI_DOMAIN_EMAIL_SUBMISSION_SETUP
|
entity BI_DOMAIN_EMAIL_SUBMISSION_SETUP
|
||||||
}
|
}
|
||||||
|
|
||||||
package Hosting #white {
|
package Hosting #feb28c{
|
||||||
package Server #99bcdb {
|
|
||||||
entity HA_CLOUD_SERVER
|
|
||||||
entity HA_MANAGED_SERVER
|
|
||||||
entity HA_IP_NUMBER
|
|
||||||
}
|
|
||||||
|
|
||||||
package PostgreSQL #99bcdb {
|
package PostgreSQL #99bcdb {
|
||||||
entity HA_PGSQL_INSTANCE
|
entity HA_PGSQL_INSTANCE
|
||||||
entity HA_PGSQL_USER
|
entity HA_PGSQL_USER
|
||||||
entity HA_PGSQL_DATABASE
|
entity HA_PGSQL_DATABASE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
package Server #99bcdb {
|
||||||
|
entity HA_CLOUD_SERVER
|
||||||
|
entity HA_MANAGED_SERVER
|
||||||
|
entity HA_IP_NUMBER
|
||||||
|
}
|
||||||
|
|
||||||
package Webspace #99bcdb {
|
package Webspace #99bcdb {
|
||||||
entity HA_MANAGED_WEBSPACE
|
entity HA_MANAGED_WEBSPACE
|
||||||
entity HA_UNIX_USER
|
entity HA_UNIX_USER
|
||||||
@ -185,7 +187,8 @@ HA_PGSQL_DATABASE o..> HA_PGSQL_INSTANCE
|
|||||||
HA_IP_NUMBER o..> HA_CLOUD_SERVER
|
HA_IP_NUMBER o..> HA_CLOUD_SERVER
|
||||||
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
||||||
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
||||||
package Legend {
|
|
||||||
|
package Legend #white {
|
||||||
SUB_ENTITY1 *--> REQUIRED_PARENT_ENTITY
|
SUB_ENTITY1 *--> REQUIRED_PARENT_ENTITY
|
||||||
SUB_ENTITY2 *..> OPTIONAL_PARENT_ENTITY
|
SUB_ENTITY2 *..> OPTIONAL_PARENT_ENTITY
|
||||||
ASSIGNED_ENTITY1 o--> REQUIRED_ASSIGNED_TO_ENTITY1
|
ASSIGNED_ENTITY1 o--> REQUIRED_ASSIGNED_TO_ENTITY1
|
||||||
|
@ -203,6 +203,9 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject, Properti
|
|||||||
|
|
||||||
.switchOnColumn("type",
|
.switchOnColumn("type",
|
||||||
inCaseOf("DOMAIN_SETUP", then -> {
|
inCaseOf("DOMAIN_SETUP", then -> {
|
||||||
|
// grant(ADMIN).to(currentlyAssumedRole() // FIXME
|
||||||
|
// oder:
|
||||||
|
// via with.incomingSuperRole("bookingItem", ADMIN); (s.u.)
|
||||||
then.toRole(GLOBAL, GUEST).grantPermission(INSERT);
|
then.toRole(GLOBAL, GUEST).grantPermission(INSERT);
|
||||||
then.toRole(GLOBAL, ADMIN).grantPermission(SELECT); // TODO.spec: replace by a proper solution
|
then.toRole(GLOBAL, ADMIN).grantPermission(SELECT); // TODO.spec: replace by a proper solution
|
||||||
})
|
})
|
||||||
|
@ -5,6 +5,7 @@ import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||||
import net.hostsharing.hsadminng.hs.booking.item.Node;
|
import net.hostsharing.hsadminng.hs.booking.item.Node;
|
||||||
|
|
||||||
|
import javax.naming.NamingException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@ -16,11 +17,14 @@ import java.util.function.Function;
|
|||||||
|
|
||||||
import static java.util.Arrays.stream;
|
import static java.util.Arrays.stream;
|
||||||
import static java.util.stream.Collectors.joining;
|
import static java.util.stream.Collectors.joining;
|
||||||
|
import static java.util.stream.Collectors.toSet;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.EntityTypeRelation.*;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.EntityTypeRelation.*;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.RelationPolicy.OPTIONAL;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.RelationPolicy.OPTIONAL;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.RelationPolicy.REQUIRED;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.RelationPolicy.REQUIRED;
|
||||||
|
|
||||||
public enum HsHostingAssetType implements Node {
|
public enum HsHostingAssetType implements Node {
|
||||||
|
SAME_TYPE, // pseudo-type for recursive references
|
||||||
|
|
||||||
CLOUD_SERVER( // named e.g. vm1234
|
CLOUD_SERVER( // named e.g. vm1234
|
||||||
inGroup("Server"),
|
inGroup("Server"),
|
||||||
requires(HsBookingItemType.CLOUD_SERVER)),
|
requires(HsBookingItemType.CLOUD_SERVER)),
|
||||||
@ -38,28 +42,29 @@ public enum HsHostingAssetType implements Node {
|
|||||||
inGroup("Webspace"),
|
inGroup("Webspace"),
|
||||||
requiredParent(MANAGED_WEBSPACE)),
|
requiredParent(MANAGED_WEBSPACE)),
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
DOMAIN_SETUP( // named e.g. example.org
|
DOMAIN_SETUP( // named e.g. example.org
|
||||||
inGroup("Domain")
|
inGroup("Domain"),
|
||||||
|
optionalParent(SAME_TYPE)
|
||||||
),
|
),
|
||||||
|
|
||||||
DOMAIN_DNS_SETUP( // named e.g. example.org
|
DOMAIN_DNS_SETUP( // named e.g. example.org
|
||||||
inGroup("Domain"),
|
inGroup("Domain"),
|
||||||
requires(HsBookingItemType.DOMAIN_DNS_SETUP)),
|
requiredParent(DOMAIN_SETUP)),
|
||||||
|
|
||||||
DOMAIN_HTTP_SETUP( // named e.g. example.org
|
DOMAIN_HTTP_SETUP( // named e.g. example.org
|
||||||
inGroup("Domain"),
|
inGroup("Domain"),
|
||||||
requiredParent(MANAGED_WEBSPACE),
|
requiredParent(DOMAIN_SETUP),
|
||||||
assignedTo(UNIX_USER)),
|
assignedTo(UNIX_USER)),
|
||||||
|
|
||||||
DOMAIN_EMAIL_SUBMISSION_SETUP( // named e.g. example.org
|
DOMAIN_EMAIL_SUBMISSION_SETUP( // named e.g. example.org
|
||||||
inGroup("Domain"),
|
inGroup("Domain"),
|
||||||
requires(HsBookingItemType.DOMAIN_EMAIL_SUBMISSION_SETUP),
|
requiredParent(DOMAIN_SETUP),
|
||||||
optionallyAssignedTo(MANAGED_WEBSPACE)),
|
assignedTo(MANAGED_WEBSPACE)),
|
||||||
|
|
||||||
DOMAIN_EMAIL_MAILBOX_SETUP( // named e.g. example.org
|
DOMAIN_EMAIL_MAILBOX_SETUP( // named e.g. example.org
|
||||||
inGroup("Domain"),
|
inGroup("Domain"),
|
||||||
requiredParent(MANAGED_WEBSPACE)),
|
requiredParent(DOMAIN_SETUP),
|
||||||
|
assignedTo(MANAGED_WEBSPACE)),
|
||||||
|
|
||||||
// TODO.spec: SECURE_MX
|
// TODO.spec: SECURE_MX
|
||||||
|
|
||||||
@ -106,7 +111,7 @@ public enum HsHostingAssetType implements Node {
|
|||||||
assignedTo(MANAGED_WEBSPACE)
|
assignedTo(MANAGED_WEBSPACE)
|
||||||
);
|
);
|
||||||
|
|
||||||
final String groupName;
|
private final String groupName;
|
||||||
private final EntityTypeRelation<?, ?>[] relations;
|
private final EntityTypeRelation<?, ?>[] relations;
|
||||||
|
|
||||||
HsHostingAssetType(
|
HsHostingAssetType(
|
||||||
@ -117,6 +122,11 @@ public enum HsHostingAssetType implements Node {
|
|||||||
this.relations = relations;
|
this.relations = relations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HsHostingAssetType() {
|
||||||
|
this.groupName = null;
|
||||||
|
this.relations = null;
|
||||||
|
}
|
||||||
|
|
||||||
/// just syntactic sugar
|
/// just syntactic sugar
|
||||||
private static String inGroup(final String groupName) {
|
private static String inGroup(final String groupName) {
|
||||||
return groupName;
|
return groupName;
|
||||||
@ -124,50 +134,62 @@ public enum HsHostingAssetType implements Node {
|
|||||||
|
|
||||||
|
|
||||||
public RelationPolicy bookingItemPolicy() {
|
public RelationPolicy bookingItemPolicy() {
|
||||||
return stream(relations).filter(r -> r.relatedType == (Object) HsBookingItemType.class).findAny()
|
return stream(relations).filter(r -> r.relatedType instanceof HsBookingItemType)
|
||||||
.map(r -> r.relationType)
|
.map(r -> r.relationType)
|
||||||
|
.reduce(HsHostingAssetType::onlyASingleElementExpectedException)
|
||||||
.orElse(RelationPolicy.FORBIDDEN);
|
.orElse(RelationPolicy.FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HsBookingItemType bookingItemType() {
|
public HsBookingItemType bookingItemType() {
|
||||||
return stream(relations).filter(r -> r.relatedType == (Object) HsBookingItemType.class).findAny()
|
return stream(relations).filter(r -> r.relatedType instanceof HsBookingItemType)
|
||||||
.map(r -> HsBookingItemType.valueOf(r.relatedType.toString()))
|
.map(r -> HsBookingItemType.valueOf(r.relatedType.toString()))
|
||||||
|
.reduce(HsHostingAssetType::onlyASingleElementExpectedException)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RelationPolicy parentAssetPolicy() {
|
public RelationPolicy parentAssetPolicy() {
|
||||||
return stream(relations).filter(r -> r.relatedType == (Object) HsHostingAssetType.class).findAny()
|
return stream(relations).filter(r -> r.relatedType instanceof HsHostingAssetType)
|
||||||
.map(r -> r.relationType)
|
.map(r -> r.relationType)
|
||||||
|
.reduce(HsHostingAssetType::onlyASingleElementExpectedException)
|
||||||
.orElse(RelationPolicy.FORBIDDEN);
|
.orElse(RelationPolicy.FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HsHostingAssetType parentAssetType() {
|
public HsHostingAssetType parentAssetType() {
|
||||||
return stream(relations).filter(r -> r.relatedType == (Object) HsHostingAssetType.class).findAny()
|
return stream(relations).filter(r -> r.relatedType instanceof HsHostingAssetType)
|
||||||
.map(r -> HsHostingAssetType.valueOf(r.relatedType.toString()))
|
.map(r -> HsHostingAssetType.valueOf(r.relatedType.toString()))
|
||||||
|
.reduce(HsHostingAssetType::onlyASingleElementExpectedException)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RelationPolicy assignedToAssetPolicy() {
|
public RelationPolicy assignedToAssetPolicy() {
|
||||||
return stream(relations).filter(r -> r.relatedType == (Object) HsHostingAssetType.class).findAny()
|
return stream(relations).filter(r -> r.relatedType == (Object) HsHostingAssetType.class)
|
||||||
.map(r -> r.relationType)
|
.map(r -> r.relationType)
|
||||||
|
.reduce(HsHostingAssetType::onlyASingleElementExpectedException)
|
||||||
.orElse(RelationPolicy.FORBIDDEN);
|
.orElse(RelationPolicy.FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HsHostingAssetType assignedToAssetType() {
|
public HsHostingAssetType assignedToAssetType() {
|
||||||
return stream(relations).filter(r -> r.relatedType == (Object) HsHostingAssetType.class).findAny()
|
return stream(relations).filter(r -> r.relatedType == (Object) HsHostingAssetType.class)
|
||||||
.map(r -> HsHostingAssetType.valueOf(r.relatedType.toString()))
|
.map(r -> HsHostingAssetType.valueOf(r.relatedType.toString()))
|
||||||
|
.reduce(HsHostingAssetType::onlyASingleElementExpectedException)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static <X> X onlyASingleElementExpectedException(Object a, Object b) {
|
||||||
|
throw new IllegalStateException("Only a single element expected to match criteria.");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> edges() {
|
public List<String> edges() {
|
||||||
return stream(relations)
|
return stream(relations)
|
||||||
.map(r -> nodeName() + r.edge + r.relatedType.nodeName())
|
.map(r -> nodeName() + r.edge + resolveNode(r.relatedType).nodeName())
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Node resolveNode(final Node node) {
|
||||||
|
return node == SAME_TYPE ? this : node;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String nodeName() {
|
public String nodeName() {
|
||||||
return "HA_" + name();
|
return "HA_" + name();
|
||||||
@ -181,100 +203,107 @@ public enum HsHostingAssetType implements Node {
|
|||||||
return type == null ? null : type.name();
|
return type == null ? null : type.name();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void renderAsPlantUML(final Set<String> includedHostingGroups) throws IOException {
|
private static String renderAsPlantUML(final String caption, final Set<String> includedHostingGroups) {
|
||||||
final String bookingNodes = stream(HsBookingItemType.values())
|
final String bookingNodes = stream(HsBookingItemType.values())
|
||||||
.map(t -> " entity " + t.nodeName())
|
.map(t -> " entity " + t.nodeName())
|
||||||
.collect(joining("\n"));
|
.collect(joining("\n"));
|
||||||
final String hostingGroups = includedHostingGroups.stream()
|
final String hostingGroups = includedHostingGroups.stream().sorted()
|
||||||
.map(HsHostingAssetType::generateGroup)
|
.map(HsHostingAssetType::generateGroup)
|
||||||
.collect(joining("\n"));
|
.collect(joining("\n"));
|
||||||
final String hostingAssetNodes = stream(HsHostingAssetType.values())
|
final String hostingAssetNodes = stream(HsHostingAssetType.values())
|
||||||
.filter(a -> includedHostingGroups.contains(a.groupName))
|
.filter(t -> t.isInGroups(includedHostingGroups))
|
||||||
.map(a -> "entity "+a.nodeName())
|
.map(t -> "entity " + t.nodeName())
|
||||||
.collect(joining("\n"));
|
.collect(joining("\n"));
|
||||||
final String bookingItemEdges = stream(HsBookingItemType.values())
|
final String bookingItemEdges = stream(HsBookingItemType.values())
|
||||||
.map(HsBookingItemType::edges)
|
.map(HsBookingItemType::edges)
|
||||||
.flatMap(Collection::stream)
|
.flatMap(Collection::stream)
|
||||||
.collect(joining("\n"));
|
.collect(joining("\n"));
|
||||||
final String hostingAssetEdges = stream(HsHostingAssetType.values())
|
final String hostingAssetEdges = stream(HsHostingAssetType.values())
|
||||||
.filter(t -> includedHostingGroups.contains(t.groupName))
|
.filter(t -> t.isInGroups(includedHostingGroups))
|
||||||
.map(HsHostingAssetType::edges)
|
.map(HsHostingAssetType::edges)
|
||||||
.flatMap(Collection::stream)
|
.flatMap(Collection::stream)
|
||||||
.collect(joining("\n"));
|
.collect(joining("\n"));
|
||||||
Files.writeString(
|
return """
|
||||||
Path.of("doc/hs-hosting-asset-type-structure.md"),
|
|
||||||
|
### %{caption}
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
left to right direction
|
||||||
|
|
||||||
|
package Booking #feb28c {
|
||||||
|
%{bookingNodes}
|
||||||
|
}
|
||||||
|
|
||||||
|
package Hosting #feb28c{
|
||||||
|
%{hostingGroups}
|
||||||
|
}
|
||||||
|
|
||||||
|
%{bookingItemEdges}
|
||||||
|
|
||||||
|
%{hostingAssetEdges}
|
||||||
|
|
||||||
|
package Legend #white {
|
||||||
|
SUB_ENTITY1 *--> REQUIRED_PARENT_ENTITY
|
||||||
|
SUB_ENTITY2 *..> OPTIONAL_PARENT_ENTITY
|
||||||
|
ASSIGNED_ENTITY1 o--> REQUIRED_ASSIGNED_TO_ENTITY1
|
||||||
|
ASSIGNED_ENTITY2 o..> OPTIONAL_ASSIGNED_TO_ENTITY2
|
||||||
|
}
|
||||||
|
Booking -down[hidden]->Legend
|
||||||
|
```
|
||||||
"""
|
"""
|
||||||
### packages %{packages}
|
.replace("%{caption}", caption)
|
||||||
|
.replace("%{bookingNodes}", bookingNodes)
|
||||||
|
.replace("%{hostingGroups}", hostingGroups)
|
||||||
|
.replace("%{hostingAssetNodeStyles}", hostingAssetNodes)
|
||||||
|
.replace("%{bookingItemEdges}", bookingItemEdges)
|
||||||
|
.replace("%{hostingAssetEdges}", hostingAssetEdges);
|
||||||
|
}
|
||||||
|
|
||||||
```plantuml
|
private boolean isInGroups(final Set<String> assetGroups) {
|
||||||
@startuml
|
return groupName != null && assetGroups.contains(groupName);
|
||||||
left to right direction
|
|
||||||
|
|
||||||
package Booking #99bcdb {
|
|
||||||
%{bookingNodes}
|
|
||||||
}
|
|
||||||
|
|
||||||
package Hosting #white {
|
|
||||||
%{hostingGroups}
|
|
||||||
}
|
|
||||||
|
|
||||||
%{bookingItemEdges}
|
|
||||||
|
|
||||||
%{hostingAssetEdges}
|
|
||||||
package Legend {
|
|
||||||
SUB_ENTITY1 *--> REQUIRED_PARENT_ENTITY
|
|
||||||
SUB_ENTITY2 *..> OPTIONAL_PARENT_ENTITY
|
|
||||||
ASSIGNED_ENTITY1 o--> REQUIRED_ASSIGNED_TO_ENTITY1
|
|
||||||
ASSIGNED_ENTITY2 o..> OPTIONAL_ASSIGNED_TO_ENTITY2
|
|
||||||
}
|
|
||||||
Booking -down[hidden]->Legend
|
|
||||||
```
|
|
||||||
"""
|
|
||||||
.replace("%{packages}", String.join(", ", includedHostingGroups))
|
|
||||||
.replace("%{bookingNodes}", bookingNodes)
|
|
||||||
.replace("%{hostingGroups}", hostingGroups)
|
|
||||||
.replace("%{hostingAssetNodeStyles}", hostingAssetNodes)
|
|
||||||
.replace("%{bookingItemEdges}", bookingItemEdges)
|
|
||||||
.replace("%{hostingAssetEdges}", hostingAssetEdges),
|
|
||||||
StandardOpenOption.APPEND);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String generateGroup(final String group) {
|
private static String generateGroup(final String group) {
|
||||||
return " package " + group + " #99bcdb {\n"
|
return " package " + group + " #99bcdb {\n"
|
||||||
+ stream(HsHostingAssetType.values())
|
+ stream(HsHostingAssetType.values())
|
||||||
.filter(t -> t.groupName.equals(group))
|
.filter(t -> group.equals(t.groupName))
|
||||||
.map(t -> " entity " + t.nodeName())
|
.map(t -> " entity " + t.nodeName())
|
||||||
.collect(joining(" \n"))
|
.collect(joining("\n"))
|
||||||
+ "\n }\n";
|
+ "\n }\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(final String[] args) throws IOException {
|
static String renderAsEmbeddedPlantUml() {
|
||||||
|
|
||||||
Files.writeString(
|
|
||||||
Path.of("doc/hs-hosting-asset-type-structure.md"),
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
|
final var markdown = new StringBuilder("""
|
||||||
## HostingAsset Type Structure
|
## HostingAsset Type Structure
|
||||||
|
|
||||||
""",
|
""");
|
||||||
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
|
||||||
|
|
||||||
// renderAsPlantUML(stream(HsHostingAssetType.values())
|
// rendering all types in a single diagram is currently ignored
|
||||||
// .map(t -> t.groupName)
|
renderAsPlantUML("Domain", stream(HsHostingAssetType.values())
|
||||||
// .collect(toSet()));
|
.filter(t -> t.groupName != null)
|
||||||
|
.map(t -> t.groupName)
|
||||||
|
.collect(toSet()));
|
||||||
|
|
||||||
renderAsPlantUML(Set.of("Domain", "Webspace", "Server"));
|
markdown.append(renderAsPlantUML("Domain", Set.of("Domain", "Webspace", "Server")))
|
||||||
renderAsPlantUML(Set.of("MariaDB", "Webspace", "Server"));
|
.append(renderAsPlantUML("MariaDB", Set.of("MariaDB", "Webspace", "Server")))
|
||||||
renderAsPlantUML(Set.of("PostgreSQL", "Webspace", "Server"));
|
.append(renderAsPlantUML("PostgreSQL", Set.of("PostgreSQL", "Webspace", "Server")));
|
||||||
|
|
||||||
|
markdown.append("""
|
||||||
|
|
||||||
|
This code generated was by %{this}.main, do not amend manually.
|
||||||
|
"""
|
||||||
|
.replace("%{this}", HsHostingAssetType.class.getSimpleName()));
|
||||||
|
|
||||||
|
return markdown.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(final String[] args) throws IOException, NamingException {
|
||||||
Files.writeString(
|
Files.writeString(
|
||||||
Path.of("doc/hs-hosting-asset-type-structure.md"),
|
Path.of("doc/hs-hosting-asset-type-structure.md"),
|
||||||
"""
|
renderAsEmbeddedPlantUml(),
|
||||||
This code generated was by %{this}.main, do not amend manually.
|
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||||
"""
|
|
||||||
.replace("%{this}", HsHostingAssetType.class.getSimpleName()),
|
|
||||||
StandardOpenOption.APPEND);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum RelationPolicy {
|
public enum RelationPolicy {
|
||||||
@ -285,27 +314,23 @@ public enum HsHostingAssetType implements Node {
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
class EntityTypeRelation<E, T extends Node> {
|
class EntityTypeRelation<E, T extends Node> {
|
||||||
final HsHostingAssetType.RelationPolicy relationType;
|
final HsHostingAssetType.RelationPolicy relationType;
|
||||||
private final Function<HsHostingAssetEntity, E> getter;
|
final Function<HsHostingAssetEntity, E> getter;
|
||||||
final T relatedType;
|
final T relatedType;
|
||||||
final String edge;
|
final String edge;
|
||||||
|
|
||||||
static EntityTypeRelation<HsBookingItemEntity, HsBookingItemType> requires(final HsBookingItemType bookingItemType) {
|
static EntityTypeRelation<HsBookingItemEntity, HsBookingItemType> requires(final HsBookingItemType bookingItemType) {
|
||||||
return new EntityTypeRelation<>(REQUIRED, HsHostingAssetEntity::getBookingItem, bookingItemType, " ==* ");
|
return new EntityTypeRelation<>(REQUIRED, HsHostingAssetEntity::getBookingItem, bookingItemType, " *==> ");
|
||||||
}
|
}
|
||||||
|
|
||||||
static EntityTypeRelation<HsHostingAssetEntity, HsHostingAssetType> optionalParent(final HsHostingAssetType hostingAssetType) {
|
static EntityTypeRelation<HsHostingAssetEntity, HsHostingAssetType> optionalParent(final HsHostingAssetType hostingAssetType) {
|
||||||
return new EntityTypeRelation<>(OPTIONAL, null, hostingAssetType, " o..> ");
|
return new EntityTypeRelation<>(OPTIONAL, HsHostingAssetEntity::getParentAsset, hostingAssetType, " o..> ");
|
||||||
}
|
}
|
||||||
|
|
||||||
static EntityTypeRelation<HsHostingAssetEntity, HsHostingAssetType> requiredParent(final HsHostingAssetType hostingAssetType) {
|
static EntityTypeRelation<HsHostingAssetEntity, HsHostingAssetType> requiredParent(final HsHostingAssetType hostingAssetType) {
|
||||||
return new EntityTypeRelation<>(REQUIRED, null, hostingAssetType, " *==> ");
|
return new EntityTypeRelation<>(REQUIRED, HsHostingAssetEntity::getParentAsset, hostingAssetType, " *==> ");
|
||||||
}
|
}
|
||||||
|
|
||||||
static EntityTypeRelation<HsHostingAssetEntity, HsHostingAssetType> assignedTo(final HsHostingAssetType hostingAssetType) {
|
static EntityTypeRelation<HsHostingAssetEntity, HsHostingAssetType> assignedTo(final HsHostingAssetType hostingAssetType) {
|
||||||
return new EntityTypeRelation<>(REQUIRED, null, hostingAssetType, " o..> ");
|
return new EntityTypeRelation<>(REQUIRED, HsHostingAssetEntity::getAssignedToAsset, hostingAssetType, " o..> ");
|
||||||
}
|
|
||||||
|
|
||||||
static EntityTypeRelation<HsHostingAssetEntity, HsHostingAssetType> optionallyAssignedTo(final HsHostingAssetType hostingAssetType) {
|
|
||||||
return new EntityTypeRelation<>(OPTIONAL, null, hostingAssetType, " o..> ");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
|
||||||
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
||||||
|
|
||||||
class HsCloudServerHostingAssetValidator extends HsHostingAssetEntityValidator {
|
class HsCloudServerHostingAssetValidator extends HsHostingAssetEntityValidator {
|
||||||
|
|
||||||
HsCloudServerHostingAssetValidator() {
|
HsCloudServerHostingAssetValidator() {
|
||||||
super(
|
super(
|
||||||
HsHostingAssetType.CLOUD_SERVER,
|
CLOUD_SERVER,
|
||||||
AlarmContact.isOptional(),
|
AlarmContact.isOptional(),
|
||||||
NO_EXTRA_PROPERTIES);
|
NO_EXTRA_PROPERTIES);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
|||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SETUP;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SETUP;
|
||||||
@ -20,6 +21,36 @@ class HsDomainSetupHostingAssetValidator extends HsHostingAssetEntityValidator {
|
|||||||
this.identifierPattern = Pattern.compile(DOMAIN_NAME_REGEX);
|
this.identifierPattern = Pattern.compile(DOMAIN_NAME_REGEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> validateEntity(final HsHostingAssetEntity assetEntity) {
|
||||||
|
// TODO.impl: for newly created entities, check the permission of setting up a domain
|
||||||
|
//
|
||||||
|
// reject, if the domain is any of these:
|
||||||
|
// hostsharing.com|net|org|coop, // just to be on the safe side
|
||||||
|
// [^.}+, // top-level-domain
|
||||||
|
// co.uk, org.uk, gov.uk, ac.uk, sch.uk,
|
||||||
|
// com.au, net.au, org.au, edu.au, gov.au, asn.au, id.au,
|
||||||
|
// co.jp, ne.jp, or.jp, ac.jp, go.jp,
|
||||||
|
// com.cn, net.cn, org.cn, gov.cn, edu.cn, ac.cn,
|
||||||
|
// com.br, net.br, org.br, gov.br, edu.br, mil.br, art.br,
|
||||||
|
// co.in, net.in, org.in, gen.in, firm.in, ind.in,
|
||||||
|
// com.mx, net.mx, org.mx, gob.mx, edu.mx,
|
||||||
|
// gov.it, edu.it,
|
||||||
|
// co.nz, net.nz, org.nz, govt.nz, ac.nz, school.nz, geek.nz, kiwi.nz,
|
||||||
|
// co.kr, ne.kr, or.kr, go.kr, re.kr, pe.kr
|
||||||
|
//
|
||||||
|
// allow if
|
||||||
|
// - user has Admin/Agent-role for all its sub-domains and the direct parent-Domain which are set up at at Hostsharing
|
||||||
|
// - domain has DNS zone with TXT record approval
|
||||||
|
// - parent-domain has DNS zone with TXT record approval
|
||||||
|
// - dom
|
||||||
|
//
|
||||||
|
// TXT-Record check:
|
||||||
|
// new InitialDirContext().getAttributes("dns:_netblocks.google.com", new String[] { "TXT"}).get("TXT").getAll();
|
||||||
|
|
||||||
|
return super.validateEntity(assetEntity);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||||
return identifierPattern;
|
return identifierPattern;
|
||||||
|
@ -190,20 +190,6 @@ public abstract class HsHostingAssetEntityValidator extends HsEntityValidator<Hs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ParentAssetReferenceValidation extends ReferenceValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
|
||||||
|
|
||||||
ParentAssetReferenceValidation(final HsHostingAssetType.RelationPolicy policy, final HsHostingAssetType parentAssetType) {
|
|
||||||
super(policy, parentAssetType, HsHostingAssetEntity::getParentAsset, HsHostingAssetEntity::getType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class AssignedToAssetReferenceValidation extends ReferenceValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
|
||||||
|
|
||||||
AssignedToAssetReferenceValidation(final HsHostingAssetType.RelationPolicy policy, final HsHostingAssetType assignedToAssetType) {
|
|
||||||
super(policy, assignedToAssetType, HsHostingAssetEntity::getAssignedToAsset, HsHostingAssetEntity::getType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class AlarmContact extends ReferenceValidator<HsOfficeContactEntity, Enum<?>> {
|
static class AlarmContact extends ReferenceValidator<HsOfficeContactEntity, Enum<?>> {
|
||||||
|
|
||||||
AlarmContact(final HsHostingAssetType.RelationPolicy policy) {
|
AlarmContact(final HsHostingAssetType.RelationPolicy policy) {
|
||||||
|
@ -20,6 +20,7 @@ public class HsHostingAssetEntityValidatorRegistry {
|
|||||||
register(MANAGED_WEBSPACE, new HsManagedWebspaceHostingAssetValidator());
|
register(MANAGED_WEBSPACE, new HsManagedWebspaceHostingAssetValidator());
|
||||||
register(UNIX_USER, new HsUnixUserHostingAssetValidator());
|
register(UNIX_USER, new HsUnixUserHostingAssetValidator());
|
||||||
register(EMAIL_ALIAS, new HsEMailAliasHostingAssetValidator());
|
register(EMAIL_ALIAS, new HsEMailAliasHostingAssetValidator());
|
||||||
|
register(DOMAIN_SETUP, new HsDomainSetupHostingAssetValidator());
|
||||||
register(DOMAIN_DNS_SETUP, new HsDomainDnsSetupHostingAssetValidator());
|
register(DOMAIN_DNS_SETUP, new HsDomainDnsSetupHostingAssetValidator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,12 +4,12 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
|||||||
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
||||||
|
|
||||||
class HsManagedWebspaceHostingAssetValidator extends HsHostingAssetEntityValidator {
|
class HsManagedWebspaceHostingAssetValidator extends HsHostingAssetEntityValidator {
|
||||||
public HsManagedWebspaceHostingAssetValidator() {
|
public HsManagedWebspaceHostingAssetValidator() {
|
||||||
super(
|
super(
|
||||||
MANAGED_SERVER,
|
MANAGED_WEBSPACE,
|
||||||
AlarmContact.isOptional(), // hostmaster alert address is implicitly added
|
AlarmContact.isOptional(), // hostmaster alert address is implicitly added
|
||||||
NO_EXTRA_PROPERTIES);
|
NO_EXTRA_PROPERTIES);
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ class HsUnixUserHostingAssetValidator extends HsHostingAssetEntityValidator {
|
|||||||
|
|
||||||
HsUnixUserHostingAssetValidator() {
|
HsUnixUserHostingAssetValidator() {
|
||||||
super(
|
super(
|
||||||
HsHostingAssetType.DOMAIN_DNS_SETUP,
|
HsHostingAssetType.UNIX_USER,
|
||||||
AlarmContact.isOptional(),
|
AlarmContact.isOptional(),
|
||||||
|
|
||||||
integerProperty("SSD hard quota").unit("GB").maxFrom("SSD").optional(),
|
integerProperty("SSD hard quota").unit("GB").maxFrom("SSD").optional(),
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.validation;
|
package net.hostsharing.hsadminng.hs.validation;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -18,7 +19,7 @@ public abstract class HsEntityValidator<E extends PropertiesProvider> {
|
|||||||
|
|
||||||
public final ValidatableProperty<?, ?>[] propertyValidators;
|
public final ValidatableProperty<?, ?>[] propertyValidators;
|
||||||
|
|
||||||
public HsEntityValidator(final ValidatableProperty<?, ?>... validators) {
|
public <T extends Enum <T>> HsEntityValidator(final ValidatableProperty<?, ?>... validators) {
|
||||||
propertyValidators = validators;
|
propertyValidators = validators;
|
||||||
stream(propertyValidators).forEach(p -> p.deferredInit(propertyValidators));
|
stream(propertyValidators).forEach(p -> p.deferredInit(propertyValidators));
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
||||||
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SETUP;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
|
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
|
||||||
@ -165,8 +166,9 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
context("person-SmithPeter@example.com");
|
context("person-SmithPeter@example.com");
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(em, () -> {
|
||||||
final var newAsset = HsHostingAssetEntity.builder()
|
final var newAsset = HsHostingAssetEntity.builder()
|
||||||
.caption("some new domain setup")
|
.type(DOMAIN_SETUP)
|
||||||
.identifier("example.org")
|
.identifier("example.org")
|
||||||
|
.caption("some new domain setup")
|
||||||
.build();
|
.build();
|
||||||
return toCleanup(assetRepo.save(newAsset));
|
return toCleanup(assetRepo.save(newAsset));
|
||||||
});
|
});
|
||||||
@ -181,7 +183,6 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatAssetIsPersisted(final HsHostingAssetEntity saved) {
|
private void assertThatAssetIsPersisted(final HsHostingAssetEntity saved) {
|
||||||
final var context =
|
|
||||||
attempt(em, () -> {
|
attempt(em, () -> {
|
||||||
final var found = assetRepo.findByUuid(saved.getUuid());
|
final var found = assetRepo.findByUuid(saved.getUuid());
|
||||||
assertThat(found).isNotEmpty().map(HsHostingAssetEntity::toString).get().isEqualTo(saved.toString());
|
assertThat(found).isNotEmpty().map(HsHostingAssetEntity::toString).get().isEqualTo(saved.toString());
|
||||||
|
@ -0,0 +1,219 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class HsHostingAssetTypeUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void generatedPlantUML() {
|
||||||
|
final var result = HsHostingAssetType.renderAsEmbeddedPlantUml();
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo("""
|
||||||
|
## HostingAsset Type Structure
|
||||||
|
|
||||||
|
|
||||||
|
### Domain
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
left to right direction
|
||||||
|
|
||||||
|
package Booking #feb28c {
|
||||||
|
entity BI_PRIVATE_CLOUD
|
||||||
|
entity BI_CLOUD_SERVER
|
||||||
|
entity BI_MANAGED_SERVER
|
||||||
|
entity BI_MANAGED_WEBSPACE
|
||||||
|
entity BI_DOMAIN_DNS_SETUP
|
||||||
|
entity BI_DOMAIN_EMAIL_SUBMISSION_SETUP
|
||||||
|
}
|
||||||
|
|
||||||
|
package Hosting #feb28c{
|
||||||
|
package Domain #99bcdb {
|
||||||
|
entity HA_DOMAIN_SETUP
|
||||||
|
entity HA_DOMAIN_DNS_SETUP
|
||||||
|
entity HA_DOMAIN_HTTP_SETUP
|
||||||
|
entity HA_DOMAIN_EMAIL_SUBMISSION_SETUP
|
||||||
|
entity HA_DOMAIN_EMAIL_MAILBOX_SETUP
|
||||||
|
entity HA_EMAIL_ADDRESS
|
||||||
|
}
|
||||||
|
|
||||||
|
package Server #99bcdb {
|
||||||
|
entity HA_CLOUD_SERVER
|
||||||
|
entity HA_MANAGED_SERVER
|
||||||
|
entity HA_IP_NUMBER
|
||||||
|
}
|
||||||
|
|
||||||
|
package Webspace #99bcdb {
|
||||||
|
entity HA_MANAGED_WEBSPACE
|
||||||
|
entity HA_UNIX_USER
|
||||||
|
entity HA_EMAIL_ALIAS
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BI_CLOUD_SERVER *--> BI_PRIVATE_CLOUD
|
||||||
|
BI_MANAGED_SERVER *--> BI_PRIVATE_CLOUD
|
||||||
|
BI_MANAGED_WEBSPACE *--> BI_MANAGED_SERVER
|
||||||
|
|
||||||
|
HA_CLOUD_SERVER *==> BI_CLOUD_SERVER
|
||||||
|
HA_MANAGED_SERVER *==> BI_MANAGED_SERVER
|
||||||
|
HA_MANAGED_WEBSPACE *==> BI_MANAGED_WEBSPACE
|
||||||
|
HA_MANAGED_WEBSPACE o..> HA_MANAGED_SERVER
|
||||||
|
HA_UNIX_USER *==> HA_MANAGED_WEBSPACE
|
||||||
|
HA_DOMAIN_SETUP o..> HA_DOMAIN_SETUP
|
||||||
|
HA_DOMAIN_DNS_SETUP *==> HA_DOMAIN_SETUP
|
||||||
|
HA_DOMAIN_HTTP_SETUP *==> HA_DOMAIN_SETUP
|
||||||
|
HA_DOMAIN_HTTP_SETUP o..> HA_UNIX_USER
|
||||||
|
HA_DOMAIN_EMAIL_SUBMISSION_SETUP *==> HA_DOMAIN_SETUP
|
||||||
|
HA_DOMAIN_EMAIL_SUBMISSION_SETUP o..> HA_MANAGED_WEBSPACE
|
||||||
|
HA_DOMAIN_EMAIL_MAILBOX_SETUP *==> HA_DOMAIN_SETUP
|
||||||
|
HA_DOMAIN_EMAIL_MAILBOX_SETUP o..> HA_MANAGED_WEBSPACE
|
||||||
|
HA_EMAIL_ALIAS *==> HA_MANAGED_WEBSPACE
|
||||||
|
HA_EMAIL_ADDRESS *==> HA_DOMAIN_EMAIL_MAILBOX_SETUP
|
||||||
|
HA_IP_NUMBER o..> HA_CLOUD_SERVER
|
||||||
|
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
||||||
|
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
||||||
|
|
||||||
|
package Legend #white {
|
||||||
|
SUB_ENTITY1 *--> REQUIRED_PARENT_ENTITY
|
||||||
|
SUB_ENTITY2 *..> OPTIONAL_PARENT_ENTITY
|
||||||
|
ASSIGNED_ENTITY1 o--> REQUIRED_ASSIGNED_TO_ENTITY1
|
||||||
|
ASSIGNED_ENTITY2 o..> OPTIONAL_ASSIGNED_TO_ENTITY2
|
||||||
|
}
|
||||||
|
Booking -down[hidden]->Legend
|
||||||
|
```
|
||||||
|
|
||||||
|
### MariaDB
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
left to right direction
|
||||||
|
|
||||||
|
package Booking #feb28c {
|
||||||
|
entity BI_PRIVATE_CLOUD
|
||||||
|
entity BI_CLOUD_SERVER
|
||||||
|
entity BI_MANAGED_SERVER
|
||||||
|
entity BI_MANAGED_WEBSPACE
|
||||||
|
entity BI_DOMAIN_DNS_SETUP
|
||||||
|
entity BI_DOMAIN_EMAIL_SUBMISSION_SETUP
|
||||||
|
}
|
||||||
|
|
||||||
|
package Hosting #feb28c{
|
||||||
|
package MariaDB #99bcdb {
|
||||||
|
entity HA_MARIADB_INSTANCE
|
||||||
|
entity HA_MARIADB_USER
|
||||||
|
entity HA_MARIADB_DATABASE
|
||||||
|
}
|
||||||
|
|
||||||
|
package Server #99bcdb {
|
||||||
|
entity HA_CLOUD_SERVER
|
||||||
|
entity HA_MANAGED_SERVER
|
||||||
|
entity HA_IP_NUMBER
|
||||||
|
}
|
||||||
|
|
||||||
|
package Webspace #99bcdb {
|
||||||
|
entity HA_MANAGED_WEBSPACE
|
||||||
|
entity HA_UNIX_USER
|
||||||
|
entity HA_EMAIL_ALIAS
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BI_CLOUD_SERVER *--> BI_PRIVATE_CLOUD
|
||||||
|
BI_MANAGED_SERVER *--> BI_PRIVATE_CLOUD
|
||||||
|
BI_MANAGED_WEBSPACE *--> BI_MANAGED_SERVER
|
||||||
|
|
||||||
|
HA_CLOUD_SERVER *==> BI_CLOUD_SERVER
|
||||||
|
HA_MANAGED_SERVER *==> BI_MANAGED_SERVER
|
||||||
|
HA_MANAGED_WEBSPACE *==> BI_MANAGED_WEBSPACE
|
||||||
|
HA_MANAGED_WEBSPACE o..> HA_MANAGED_SERVER
|
||||||
|
HA_UNIX_USER *==> HA_MANAGED_WEBSPACE
|
||||||
|
HA_EMAIL_ALIAS *==> HA_MANAGED_WEBSPACE
|
||||||
|
HA_MARIADB_INSTANCE *==> HA_MANAGED_SERVER
|
||||||
|
HA_MARIADB_USER *==> HA_MARIADB_INSTANCE
|
||||||
|
HA_MARIADB_USER o..> HA_MANAGED_WEBSPACE
|
||||||
|
HA_MARIADB_DATABASE *==> HA_MANAGED_WEBSPACE
|
||||||
|
HA_MARIADB_DATABASE o..> HA_MARIADB_INSTANCE
|
||||||
|
HA_IP_NUMBER o..> HA_CLOUD_SERVER
|
||||||
|
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
||||||
|
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
||||||
|
|
||||||
|
package Legend #white {
|
||||||
|
SUB_ENTITY1 *--> REQUIRED_PARENT_ENTITY
|
||||||
|
SUB_ENTITY2 *..> OPTIONAL_PARENT_ENTITY
|
||||||
|
ASSIGNED_ENTITY1 o--> REQUIRED_ASSIGNED_TO_ENTITY1
|
||||||
|
ASSIGNED_ENTITY2 o..> OPTIONAL_ASSIGNED_TO_ENTITY2
|
||||||
|
}
|
||||||
|
Booking -down[hidden]->Legend
|
||||||
|
```
|
||||||
|
|
||||||
|
### PostgreSQL
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
left to right direction
|
||||||
|
|
||||||
|
package Booking #feb28c {
|
||||||
|
entity BI_PRIVATE_CLOUD
|
||||||
|
entity BI_CLOUD_SERVER
|
||||||
|
entity BI_MANAGED_SERVER
|
||||||
|
entity BI_MANAGED_WEBSPACE
|
||||||
|
entity BI_DOMAIN_DNS_SETUP
|
||||||
|
entity BI_DOMAIN_EMAIL_SUBMISSION_SETUP
|
||||||
|
}
|
||||||
|
|
||||||
|
package Hosting #feb28c{
|
||||||
|
package PostgreSQL #99bcdb {
|
||||||
|
entity HA_PGSQL_INSTANCE
|
||||||
|
entity HA_PGSQL_USER
|
||||||
|
entity HA_PGSQL_DATABASE
|
||||||
|
}
|
||||||
|
|
||||||
|
package Server #99bcdb {
|
||||||
|
entity HA_CLOUD_SERVER
|
||||||
|
entity HA_MANAGED_SERVER
|
||||||
|
entity HA_IP_NUMBER
|
||||||
|
}
|
||||||
|
|
||||||
|
package Webspace #99bcdb {
|
||||||
|
entity HA_MANAGED_WEBSPACE
|
||||||
|
entity HA_UNIX_USER
|
||||||
|
entity HA_EMAIL_ALIAS
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BI_CLOUD_SERVER *--> BI_PRIVATE_CLOUD
|
||||||
|
BI_MANAGED_SERVER *--> BI_PRIVATE_CLOUD
|
||||||
|
BI_MANAGED_WEBSPACE *--> BI_MANAGED_SERVER
|
||||||
|
|
||||||
|
HA_CLOUD_SERVER *==> BI_CLOUD_SERVER
|
||||||
|
HA_MANAGED_SERVER *==> BI_MANAGED_SERVER
|
||||||
|
HA_MANAGED_WEBSPACE *==> BI_MANAGED_WEBSPACE
|
||||||
|
HA_MANAGED_WEBSPACE o..> HA_MANAGED_SERVER
|
||||||
|
HA_UNIX_USER *==> HA_MANAGED_WEBSPACE
|
||||||
|
HA_EMAIL_ALIAS *==> HA_MANAGED_WEBSPACE
|
||||||
|
HA_PGSQL_INSTANCE *==> HA_MANAGED_SERVER
|
||||||
|
HA_PGSQL_USER *==> HA_PGSQL_INSTANCE
|
||||||
|
HA_PGSQL_USER o..> HA_MANAGED_WEBSPACE
|
||||||
|
HA_PGSQL_DATABASE *==> HA_MANAGED_WEBSPACE
|
||||||
|
HA_PGSQL_DATABASE o..> HA_PGSQL_INSTANCE
|
||||||
|
HA_IP_NUMBER o..> HA_CLOUD_SERVER
|
||||||
|
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
||||||
|
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
||||||
|
|
||||||
|
package Legend #white {
|
||||||
|
SUB_ENTITY1 *--> REQUIRED_PARENT_ENTITY
|
||||||
|
SUB_ENTITY2 *..> OPTIONAL_PARENT_ENTITY
|
||||||
|
ASSIGNED_ENTITY1 o--> REQUIRED_ASSIGNED_TO_ENTITY1
|
||||||
|
ASSIGNED_ENTITY2 o..> OPTIONAL_ASSIGNED_TO_ENTITY2
|
||||||
|
}
|
||||||
|
Booking -down[hidden]->Legend
|
||||||
|
```
|
||||||
|
|
||||||
|
This code generated was by HsHostingAssetType.main, do not amend manually.
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_DNS_SETUP;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_DNS_SETUP;
|
||||||
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SETUP;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator.RR_COMMENT;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator.RR_COMMENT;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator.RR_RECORD_DATA;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator.RR_RECORD_DATA;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator.RR_RECORD_TYPE;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator.RR_RECORD_TYPE;
|
||||||
@ -22,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
class HsDomainDnsSetupHostingAssetValidatorUnitTest {
|
||||||
|
|
||||||
static final HsHostingAssetEntity validDomainSetupEntity = HsHostingAssetEntity.builder()
|
static final HsHostingAssetEntity validDomainSetupEntity = HsHostingAssetEntity.builder()
|
||||||
|
.type(DOMAIN_SETUP)
|
||||||
.identifier("example.org")
|
.identifier("example.org")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ class HsHostingAssetEntityValidatorRegistryUnitTest {
|
|||||||
HsHostingAssetType.MANAGED_WEBSPACE,
|
HsHostingAssetType.MANAGED_WEBSPACE,
|
||||||
HsHostingAssetType.UNIX_USER,
|
HsHostingAssetType.UNIX_USER,
|
||||||
HsHostingAssetType.EMAIL_ALIAS,
|
HsHostingAssetType.EMAIL_ALIAS,
|
||||||
|
HsHostingAssetType.DOMAIN_SETUP,
|
||||||
HsHostingAssetType.DOMAIN_DNS_SETUP
|
HsHostingAssetType.DOMAIN_DNS_SETUP
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user