Commit 58cad31b authored by Anastasios Poimenidis's avatar Anastasios Poimenidis
Browse files

feat: allow port ranges and multiple protocols in host configuration

parent e6f1aea3
Loading
Loading
Loading
Loading
Loading
+2 −2
Changes for src/main/java/org/etsi/osl/hypo/api/fabric/clients/ZitiManagementClient.java: 2 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import org.etsi.osl.hypo.api.fabric.model.domain.identities.ZitiDomainIdentities
import org.etsi.osl.hypo.api.fabric.model.domain.identities.ZitiDomainIdentityResponse;
import org.etsi.osl.hypo.api.fabric.model.domain.identities.incoming.DomainIdentityRequest;
import org.etsi.osl.hypo.api.fabric.model.domain.identities.incoming.DomainIdentityUpdateRequest;
import org.etsi.osl.hypo.api.fabric.model.network.controller.ConfigsRequest;
import org.etsi.osl.hypo.api.fabric.model.network.controller.BaseConfigsRequest;
import org.etsi.osl.hypo.api.fabric.model.network.controller.ServicePoliciesRequest;

@RegisterRestClient
@@ -45,7 +45,7 @@ public interface ZitiManagementClient {

    @POST
    @Path("/edge/management/v1/configs")
    ZitiResponse configs(@HeaderParam("zt-session") String token, ConfigsRequest request);
    ZitiResponse configs(@HeaderParam("zt-session") String token, BaseConfigsRequest request);

    @DELETE
    @Path("/edge/management/v1/configs/{id}")
+7 −6
Changes for src/main/java/org/etsi/osl/hypo/api/fabric/entity/DomainConnectionData.java: 7 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -12,11 +12,13 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.PrePersist;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Size;
import java.util.List;
import java.util.UUID;
import lombok.Data;
import org.etsi.osl.hypo.api.fabric.model.domain.identities.PortRange;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

@Data
@Entity
@@ -66,10 +68,9 @@ public class DomainConnectionData {
    @Column(nullable = false)
    private String address;

    @Min(1)
    @Max(65535)
    @Column(nullable = false)
    private Integer port;
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(columnDefinition = "jsonb") // or "jsonb" on PostgreSQL
    private List<PortRange> portRanges;

    @Size(max = 40)
    @Column(nullable = false)
+22 −9
Changes for src/main/java/org/etsi/osl/hypo/api/fabric/kafka/handlers/SonataMessageHandler.java: 22 added lines, 9 removed lines.
Original line number Diff line number Diff line
@@ -9,9 +9,11 @@ import jakarta.enterprise.context.ApplicationScoped;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.eclipse.microprofile.reactive.messaging.Message;
import org.etsi.osl.hypo.api.fabric.entity.DomainConnectionData;
import org.etsi.osl.hypo.api.fabric.entity.DomainIdentityData;
@@ -20,6 +22,7 @@ import org.etsi.osl.hypo.api.fabric.exception.domain.connection.DomainConnection
import org.etsi.osl.hypo.api.fabric.kafka.FabricKafkaSonataProducer;
import org.etsi.osl.hypo.api.fabric.mapper.DomainConnectionMapper;
import org.etsi.osl.hypo.api.fabric.model.domain.connection.DomainConnectionRequest;
import org.etsi.osl.hypo.api.fabric.model.domain.identities.PortRange;
import org.etsi.osl.hypo.api.fabric.service.DomainConnectionsService;
import org.etsi.osl.hypo.api.fabric.service.DomainIdentityService;
import org.etsi.osl.hypo.api.fabric.utils.DomainConnectionCheckerService;
@@ -141,15 +144,27 @@ public class SonataMessageHandler {
                    DomainConnectionRequest domainConnectionRequest =
                            domainConnectionMapper.mapToDomainIdentity(
                                    fabricApiConnection, bindDomainIdentityData);
                    domainConnectionRequest.setProtocols(Set.of(protocol));

                    // loop for each port without a domain connection and try to establish it
                    for (Integer port : portsWithNoConnection) {
                        domainConnectionRequest.setPort(port);
                    List<PortRange> portRanges =
                            portsWithNoConnection.stream()
                                    .map(
                                            port -> {
                                                PortRange portRange = new PortRange();
                                                portRange.setLow(port);
                                                portRange.setHigh(port);
                                                return portRange;
                                            })
                                    .toList();

                    domainConnectionRequest.setPortRanges(portRanges);
                    try {
                        domainConnectionsService.createDomainConnection(
                                ztSession, domainConnectionRequest, networkController);
                            checkCreatedConnection(ipAddress, port, protocolName, serviceId);
                        portsWithNoConnection.forEach(
                                port -> checkCreatedConnection(ipAddress, port, protocolName, serviceId));

                    } catch (Exception e) {
                        logger.errorf(
                                FAILURE_DUE_TO_EXCEPTION_OF_TYPE_S_WITH_MESSAGE_S,
@@ -161,8 +176,6 @@ public class SonataMessageHandler {
                        // if a failure takes place, break out from the routine entirely
                        return;
                    }
                    }

                    sendCallbackMessageToSonata(request, Status.SUCCESS, null, FABRIC_API_CONNECTION_RESULT);
                },
                () -> {
@@ -260,14 +273,14 @@ public class SonataMessageHandler {
    private boolean checkAlreadyEstablishedConnectionForIpAndPort(
            String ipAddress, String protocol, Integer port, UUID serviceId) {

        if (StringUtils.isNotBlank(protocol) && StringUtils.equalsIgnoreCase(protocol, "TCP")) {
        if (StringUtils.isNotBlank(protocol) && Strings.CI.equals(protocol, "TCP")) {
            if (domainConnectionCheckerService.isTcpReachable(ipAddress, port, TIMEOUT_MILLIS)) {
                logger.infof(
                        "TCP connection for port %s, ipAddress %s , protocol %s and service id %s is already established",
                        port, ipAddress, protocol, serviceId);
                return true;
            }
        } else if (StringUtils.isNotBlank(protocol) && StringUtils.equalsIgnoreCase(protocol, "UDP")) {
        } else if (StringUtils.isNotBlank(protocol) && Strings.CI.equals(protocol, "UDP")) {
            if (domainConnectionCheckerService.isUdpReachable(ipAddress, port, TIMEOUT_MILLIS)) {
                logger.infof(
                        "UDP connection for port %s, ipAddress %s , protocol %s and service id %s is already established",
@@ -290,7 +303,7 @@ public class SonataMessageHandler {
            String ipAddress, Integer port, String protocol, UUID serviceId)
            throws DomainConnectionCreationFailureException {

        if (StringUtils.isNotBlank(protocol) && StringUtils.equalsIgnoreCase(protocol, "TCP")) {
        if (StringUtils.isNotBlank(protocol) && Strings.CI.equals(protocol, "TCP")) {

            boolean isTcpReachable =
                    domainConnectionCheckerService
@@ -307,7 +320,7 @@ public class SonataMessageHandler {
                logger.error(errorMessage);
                throw new DomainConnectionCreationFailureException(errorMessage);
            }
        } else if (StringUtils.isNotBlank(protocol) && StringUtils.equalsIgnoreCase(protocol, "UDP")) {
        } else if (StringUtils.isNotBlank(protocol) && Strings.CI.equals(protocol, "UDP")) {
            boolean isTcpReachable =
                    domainConnectionCheckerService
                            .pollUdpReachability(
+24 −2
Changes for src/main/java/org/etsi/osl/hypo/api/fabric/model/domain/connection/DomainConnectionRequest.java: 24 added lines, 2 removed lines.
Original line number Diff line number Diff line
package org.etsi.osl.hypo.api.fabric.model.domain.connection;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import lombok.Data;
import org.etsi.osl.hypo.api.fabric.model.domain.identities.PortRange;
import org.etsi.osl.hypo.core.common.fabric.management.ztc.host.Protocol;

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class DomainConnectionRequest {

    private String serviceOrderId;
@@ -12,6 +23,17 @@ public class DomainConnectionRequest {
    private String dialDomainIdentityRole;
    private String dialDomainIdentityId;
    private String address;
    private Integer port;
    private String protocol;
    private List<PortRange> portRanges;

    @JsonDeserialize(contentUsing = ProtocolDeserializer.class)
    private Set<Protocol> protocols;

    // Static nested deserializer that leverages the enum's existing getProtocol method
    public static class ProtocolDeserializer extends JsonDeserializer<Protocol> {
        @Override
        public Protocol deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            String value = p.getText();
            return (value == null) ? null : Protocol.getProtocol(value.trim());
        }
    }
}
+4 −0
Changes for src/main/java/org/etsi/osl/hypo/api/fabric/model/domain/identities/PortRange.java: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
package org.etsi.osl.hypo.api.fabric.model.domain.identities;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class PortRange {
    private int high;
    private int low;
Loading