Commit 872beaea authored by Konstantinos Poulakakis's avatar Konstantinos Poulakakis
Browse files

refactor: change the Add , Delete , Update ztp services . Add exception...

refactor: change the Add , Delete , Update ztp services . Add exception handling for external services and remove unnecessary device==null exception handling. Create an internal exception handling mechanism for all the uni failures.
parent 265a2f46
Loading
Loading
Loading
Loading
+72 −96
Original line number Diff line number Diff line
@@ -23,12 +23,12 @@ import org.etsi.tfs.ztp.context.ContextService;
import org.etsi.tfs.ztp.context.model.Device;
import org.etsi.tfs.ztp.context.model.DeviceConfig;
import org.etsi.tfs.ztp.device.DeviceService;
import org.etsi.tfs.ztp.exception.ExternalServiceFailureException;
import org.jboss.logging.Logger;

@ApplicationScoped
public class ZtpServiceImpl implements ZtpService {
    private static final Logger LOGGER = Logger.getLogger(ZtpServiceImpl.class);
    // private static final String MESSAGE = "Retrieved %s";

    private final DeviceService deviceService;
    private final ContextService contextService;
@@ -41,128 +41,104 @@ public class ZtpServiceImpl implements ZtpService {

    @Override
    public Uni<Device> addDevice(String deviceId) {
        final var deserializedDeviceUni = contextService.getDevice(deviceId);

        deserializedDeviceUni
        return contextService
                .getDevice(deviceId)
                .onFailure()
                .recoverWithNull()
                .subscribe()
                .with(
                .transform(failure -> new ExternalServiceFailureException(failure.getMessage()))
                .onItem()
                .transformToUni(
                        device -> {
                            final var id = deviceId;

                            if (device == null) {
                                LOGGER.warnf("%s is null. Ignoring...", device);
                                return;
                            }

                            if (device.isEnabled()) {
                                LOGGER.warnf("%s has already been enabled. Ignoring...", device);
                                return;
                                return Uni.createFrom().failure(new Exception("Device is already enabled"));
                            } else {
                                return addDeviceTo(device, deviceId);
                            }
                        });
    }

                            // LOGGER.infof(MESSAGE, device);

                            final var initialConfiguration =
                                    deviceService.getInitialConfiguration(device.getDeviceId());

    public Uni<Device> addDeviceTo(Device device, String deviceId) {
        LOGGER.infof("Enabling device with ID [%s]", deviceId);
        device.enableDevice();
                            LOGGER.infof("Enabled device [%s]", id);

                            initialConfiguration
                                    .subscribe()
                                    .with(
        final Uni<DeviceConfig> initialConfiguration = deviceService.getInitialConfiguration(deviceId);

        return initialConfiguration
                .onItem()
                .transformToUni(
                        deviceConfig -> {
                            device.setDeviceConfiguration(deviceConfig);
                                                final var configuredDeviceIdUni = deviceService.configureDevice(device);

                                                configuredDeviceIdUni
                                                        .subscribe()
                                                        .with(
                                                                configuredDeviceId ->
                            LOGGER.infof(
                                                                                "Device [%s] has been successfully enabled and configured with %s.\n",
                                                                                id, deviceConfig));
                                    "Configuring device with ID [%s] with initial configuration %s",
                                    deviceId, deviceConfig);
                            return deviceService
                                    .configureDevice(device)
                                    .map(
                                            configuredDeviceId -> {
                                                LOGGER.infof(
                                                        "Device with ID [%s] has been successfully enabled and configured.",
                                                        deviceId);
                                                return device;
                                            });
                        });

        return deserializedDeviceUni;
    }

    @Override
    public Uni<Device> deleteDevice(String deviceId) {
        final var deserializedDeviceUni = contextService.getDevice(deviceId);

        deserializedDeviceUni
        return contextService
                .getDevice(deviceId)
                .onFailure()
                .recoverWithNull()
                .subscribe()
                .with(
                .transform(failure -> new ExternalServiceFailureException(failure.getMessage()))
                .onItem()
                .transformToUni(
                        device -> {
                            final var id = deviceId;

                            if (device == null) {
                                LOGGER.warnf("%s is null. Ignoring...", device);
                                return;
                            }

                            if (device.isDisabled()) {
                                LOGGER.warnf("%s has already been disabled. Ignoring...", device);
                                return;
                            }

                                LOGGER.warnf("Device with ID %s has already been disabled. Ignoring...", deviceId);
                                return Uni.createFrom().nullItem();
                            } else {
                                LOGGER.infof("Disabling device with ID [%s]", deviceId);
                                device.disableDevice();
                            LOGGER.infof("Disabled device [%s]", id);

                            // LOGGER.infof(MESSAGE, device);

                            final var empty = deviceService.deleteDevice(device.getDeviceId());

                            empty
                                    .subscribe()
                                    .with(
                                            emptyMessage ->
                                                    LOGGER.infof("Device [%s] has been successfully deleted.\n", id));
                                return deviceService
                                        .deleteDevice(deviceId)
                                        .onItem()
                                        .transform(
                                                emptyMessage -> {
                                                    LOGGER.infof(
                                                            "Device with ID [%s] has been successfully deleted.", deviceId);
                                                    return device;
                                                });
                            }
                        });

        return deserializedDeviceUni;
    }

    @Override
    public Uni<Device> updateDevice(String deviceId, DeviceConfig deviceConfig) {
        final var deserializedDeviceUni = contextService.getDevice(deviceId);

        deserializedDeviceUni
        return contextService
                .getDevice(deviceId)
                .onFailure()
                .recoverWithNull()
                .subscribe()
                .with(
                .transform(failure -> new ExternalServiceFailureException(failure.getMessage()))
                .onItem()
                .transformToUni(
                        device -> {
                            final var id = deviceId;

                            if (device == null) {
                                LOGGER.warnf("%s is null. Ignoring...", device);
                                return;
                            }

                            if (!device.isEnabled()) {
                                LOGGER.warnf("Cannot update disabled device %s. Ignoring...", device);
                                return;
                            }

                            // LOGGER.infof(MESSAGE, device);
                                LOGGER.warnf("Cannot update disabled device %s. Ignoring...", deviceId);
                                return Uni.createFrom().nullItem();
                            } else {
                                LOGGER.infof("Updating configuration of device with ID [%s]", deviceId);
                                device.setDeviceConfiguration(deviceConfig);
                            final var updatedDeviceIdUni = deviceService.configureDevice(device);

                            updatedDeviceIdUni
                                    .subscribe()
                                    .with(
                                            configuredDeviceId ->
                                return deviceService
                                        .configureDevice(device)
                                        .onItem()
                                        .transform(
                                                configuredDeviceId -> {
                                                    LOGGER.infof(
                                                            "Device [%s] has been successfully updated with %s.\n",
                                                            id, deviceConfig));
                                                            "Device with ID [%s] has been successfully updated with %s.",
                                                            deviceId, deviceConfig);
                                                    return device;
                                                });
                            }
                        });

        return deserializedDeviceUni;
    }
}
+28 −0
Original line number Diff line number Diff line
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.etsi.tfs.ztp.exception;

public class ExternalServiceFailureException extends RuntimeException {

    public ExternalServiceFailureException(String message, Exception e) {
        super(message, e);
    }

    public ExternalServiceFailureException(String message) {
        super(message);
    }
}
+57 −0
Original line number Diff line number Diff line
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.etsi.tfs.ztp.exception;

import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import io.quarkus.grpc.ExceptionHandlerProvider;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class GeneralExceptionHandler implements ExceptionHandlerProvider {
    @Override
    public <ReqT, RespT> io.quarkus.grpc.ExceptionHandler<ReqT, RespT> createHandler(
            ServerCall.Listener<ReqT> listener, ServerCall<ReqT, RespT> serverCall, Metadata metadata) {
        return new HelloExceptionHandler<>(listener, serverCall, metadata);
    }

    @Override
    public Throwable transform(Throwable t) {
        if (t instanceof ExternalServiceFailureException) {
            return new StatusRuntimeException(Status.INTERNAL.withDescription(t.getMessage()));
        } else {
            return ExceptionHandlerProvider.toStatusException(t, true);
        }
    }

    private static class HelloExceptionHandler<A, B> extends io.quarkus.grpc.ExceptionHandler<A, B> {
        public HelloExceptionHandler(
                ServerCall.Listener<A> listener, ServerCall<A, B> call, Metadata metadata) {
            super(listener, call, metadata);
        }

        @Override
        protected void handleException(Throwable t, ServerCall<A, B> call, Metadata metadata) {
            StatusRuntimeException sre =
                    (StatusRuntimeException) ExceptionHandlerProvider.toStatusException(t, true);
            Metadata trailers = sre.getTrailers() != null ? sre.getTrailers() : metadata;
            call.close(sre.getStatus(), trailers);
        }
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -15,6 +15,11 @@
ztp:
  should-subscribe-to-context-component: true
quarkus:
  package:
    type: mutable-jar
  live-reload:
    password: 1234
    url: http://0.0.0.0:8080
  banner:
    path: teraflow-ztp-banner.txt
  grpc: