All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fish.focus.uvms.plugins.ais.service.ExchangeService Maven / Gradle / Ivy

The newest version!
/*
Developed with the contribution of the European Commission - Directorate General for Maritime Affairs and Fisheries
© European Union, 2015-2016.

This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The IFDM Suite is free software: you can
redistribute it and/or modify it under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or any later version. The IFDM Suite is distributed in
the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a
copy of the GNU General Public License along with the IFDM Suite. If not, see .
 */
package fish.focus.uvms.plugins.ais.service;

import fish.focus.schema.exchange.module.v1.ExchangeModuleMethod;
import fish.focus.schema.exchange.movement.v1.MovementBaseType;
import fish.focus.schema.exchange.movement.v1.SetReportMovementType;
import fish.focus.schema.exchange.plugin.types.v1.PluginType;
import fish.focus.uvms.asset.client.model.AssetDTO;
import fish.focus.uvms.exchange.model.mapper.ExchangeModuleRequestMapper;
import fish.focus.uvms.plugins.ais.StartupBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.jms.Queue;
import javax.jms.*;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import java.time.Instant;
import java.util.*;

@Stateless
public class ExchangeService {

    private static final Logger LOG = LoggerFactory.getLogger(ExchangeService.class);

    private static final String NOP = "//NOP: {}";
    private static final String COULD_NOT_SEND_MOVEMENT = "couldn't send movement";

    private final Jsonb jsonb = JsonbBuilder.create();

    @Resource(mappedName = "java:/ConnectionFactory")
    private ConnectionFactory connectionFactory;

    @Resource(mappedName = "java:/jms/queue/UVMSExchangeEvent")
    private Queue exchangeQueue;

    @Resource(mappedName = "java:/jms/queue/UVMSPluginFailedReport")
    private Queue errorQueue;

    @Inject
    private StartupBean startupBean;

    private static void sendToErrorQueue(String movement, Session session, MessageProducer producer) {
        try {
            BytesMessage messageBytes = session.createBytesMessage();
            messageBytes.setStringProperty("source", "AIS");
            messageBytes.setStringProperty("type", "byte");
            messageBytes.writeBytes(movement.getBytes());
            producer.send(messageBytes);
        } catch (Exception e) {
            LOG.info(NOP, e.getLocalizedMessage());
        }
    }

    public boolean sendAssetUpdates(Collection assets) {
        boolean ok = true;
        if (assets == null || assets.isEmpty()) {
            return ok;
        }

        String json = jsonb.toJson(assets);
        LOG.trace(json);
        LOG.info("Sending {} ais assets updates to exchange as a json array", assets.size());

        try (Connection connection = connectionFactory.createConnection();
             Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
             MessageProducer producer = session.createProducer(exchangeQueue)
        ) {
            sendAsset(json, session, producer);
        } catch (JMSException e) {
            LOG.error(COULD_NOT_SEND_MOVEMENT);
            ok = false;
        }
        return ok;
    }

    private void sendAsset(String json, Session session, MessageProducer producer) {
        try {
            String text = ExchangeModuleRequestMapper.createReceiveAssetInformation(json, "AIS", PluginType.OTHER, "AIS Plugin");
            TextMessage message = session.createTextMessage();
            message.setStringProperty("FUNCTION", ExchangeModuleMethod.RECEIVE_ASSET_INFORMATION.toString());
            message.setText(text);
            producer.setDeliveryMode(DeliveryMode.PERSISTENT);
            producer.setPriority(3); //Lower prio for updating vessel info from AIS than default 4.
            producer.send(message);
        } catch (RuntimeException e) {
            LOG.error("Couldn't map movement to setreportmovementtype");
            sendToErrorQueueParsingError(json);
        } catch (Exception e) {
            LOG.info(NOP, e.getLocalizedMessage());
        }
    }

    public List sendMovements(Collection movements) {
        LOG.info("Sending {} positions to exchange", movements.size());
        List failedToSendMovements = new ArrayList<>();
        try (Connection connection = connectionFactory.createConnection();
             Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
             MessageProducer producer = session.createProducer(exchangeQueue)
        ) {
            producer.setDeliveryMode(DeliveryMode.PERSISTENT);
            // emit
            for (MovementBaseType movement : movements) {
                var failedToSendMovement = sendMovement(session, producer, movement);
                failedToSendMovement.ifPresent(failedToSendMovements::add);
            }
        } catch (JMSException e) {
            LOG.error(COULD_NOT_SEND_MOVEMENT);
        }
        return failedToSendMovements;
    }

    private Optional sendMovement(Session session, MessageProducer producer, MovementBaseType movement) {
        try {
            SetReportMovementType movementReport = getMovementReport(movement, startupBean.getRegisterClassName());
            String text = ExchangeModuleRequestMapper.createSetMovementReportRequest(movementReport, "AIS", null, Instant.now(), PluginType.OTHER, "AIS", null);
            TextMessage message = session.createTextMessage();
            message.setStringProperty("FUNCTION", ExchangeModuleMethod.SET_MOVEMENT_REPORT.value());
            message.setText(text);
            //AIS from SWE prio 3 from others prio 2
            if (movement.getFlagState() != null || "SWE".equalsIgnoreCase(movement.getFlagState())) {
                producer.setPriority(3);
            } else {
                producer.setPriority(2);
            }

            producer.send(message);
            startupBean.incrementAisIncoming();
        } catch (RuntimeException e) {
            LOG.error("Couldn't map movement to setreportmovementtype");
            sendToErrorQueueParsingError(movement.toString());
        } catch (JMSException e) {
            return Optional.of(movement);
        } catch (Exception e) {
            LOG.info(NOP, e.getLocalizedMessage());
        }
        return Optional.empty();
    }

    public void sendToErrorQueueParsingError(String movement) {
        try (Connection connection = connectionFactory.createConnection();
             Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
             MessageProducer producer = session.createProducer(errorQueue)) {
            producer.setDeliveryMode(DeliveryMode.PERSISTENT);

            sendToErrorQueue(movement, session, producer);
        } catch (JMSException e) {
            LOG.error(COULD_NOT_SEND_MOVEMENT);
        }
    }

    private SetReportMovementType getMovementReport(MovementBaseType movement, String pluginName) {
        SetReportMovementType report = new SetReportMovementType();
        report.setTimestamp(new Date());
        report.setPluginName(pluginName);
        report.setPluginType(PluginType.OTHER);
        report.setMovement(movement);
        return report;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy