<commit_before>/**
 * Licensed to the Austrian Association for Software Tool Integration (AASTI)
 * under one or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership. The AASTI licenses this file to you 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.openengsb.ports.jms;

import java.util.HashMap;

import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.openengsb.core.common.remote.FilterChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.SimpleMessageListenerContainer;

public class JMSIncomingPort {

    private static final Logger LOGGER = LoggerFactory.getLogger(JMSIncomingPort.class);

    private static final String RECEIVE = "receive";

    private static final String DISABLE_ENCRYPTION = "org.openengsb.jms.noencrypt";

    private JMSTemplateFactory factory;

    private ConnectionFactory connectionFactory;

    private SimpleMessageListenerContainer simpleMessageListenerContainer;

    private FilterChain filterChain;

    /*
     * TODO OPENENGSB-1575 this property is kind of a hack and should be replaced by proper dynamic port configuration
     */
    private FilterChain unsecureFilterChain;

    public void start() {
        simpleMessageListenerContainer = createListenerContainer(RECEIVE, new MessageListener() {
            @Override
            public void onMessage(Message message) {
                LOGGER.trace("JMS-message recieved. Checking if the type is supported");
                if (message instanceof TextMessage) {
                    LOGGER.trace("parsing as TextMessage");
                    TextMessage textMessage = (TextMessage) message;
                    String textContent;
                    try {
                        textContent = textMessage.getText();
                    } catch (JMSException e) {
                        throw new RuntimeException(e);
                    }
                    HashMap<String, Object> metadata = new HashMap<String, Object>();
                    String result;
                    try {
                        LOGGER.debug("starting filterchain for incoming message");
                        result = (String) getFilterChainToUse().filter(textContent, metadata);
                    } catch (Exception e) {
                        LOGGER.error("an error occured when processing the filterchain", e);
                        String callId = (String) metadata.get("callId");
                        if (callId != null) {
                            LOGGER.info("callId could be extracted. Sending Exception-response to remote caller ({})",
                                callId);
                            new JmsTemplate(connectionFactory).convertAndSend(callId, ExceptionUtils.getStackTrace(e));
                        }
                        return;
                    }
                    String callId = (String) metadata.get("callId");
                    LOGGER.debug("filterchain processed OK, sending result to answer-queue ({})", callId);
                    if (metadata.containsKey("answer")) {
                        new JmsTemplate(connectionFactory).convertAndSend(callId, result);
                    }
                }
            }

        });
        simpleMessageListenerContainer.start();
    }

    private SimpleMessageListenerContainer createListenerContainer(String destination, MessageListener listener) {
        SimpleMessageListenerContainer messageListenerContainer = factory.createMessageListenerContainer();
        messageListenerContainer.setConnectionFactory(connectionFactory);
        messageListenerContainer.setDestinationName(destination);<commit_msg>[OPENENGSB-2134] Remove error antipattern from jms receive code<commit_after>/**
 * Licensed to the Austrian Association for Software Tool Integration (AASTI)
 * under one or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership. The AASTI licenses this file to you 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.openengsb.ports.jms;

import java.util.HashMap;

import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.openengsb.core.common.remote.FilterChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.SimpleMessageListenerContainer;

public class JMSIncomingPort {

    private static final Logger LOGGER = LoggerFactory.getLogger(JMSIncomingPort.class);

    private static final String RECEIVE = "receive";

    private static final String DISABLE_ENCRYPTION = "org.openengsb.jms.noencrypt";

    private JMSTemplateFactory factory;

    private ConnectionFactory connectionFactory;

    private SimpleMessageListenerContainer simpleMessageListenerContainer;

    private FilterChain filterChain;

    /*
     * TODO OPENENGSB-1575 this property is kind of a hack and should be replaced by proper dynamic port configuration
     */
    private FilterChain unsecureFilterChain;

    public void start() {
        simpleMessageListenerContainer = createListenerContainer(RECEIVE, new MessageListener() {
            @Override
            public void onMessage(Message message) {
                LOGGER.trace("JMS-message recieved. Checking if the type is supported");
                if (!(message instanceof TextMessage)) {
                    LOGGER.debug("Received JMS-message is not type of text message.");
                    return;
                }
                LOGGER.trace("Received a text message and start parsing");
                TextMessage textMessage = (TextMessage) message;
                String textContent = extractTextFromMessage(textMessage);
                HashMap<String, Object> metadata = new HashMap<String, Object>();
                String result;
                try {
                    LOGGER.debug("starting filterchain for incoming message");
                    result = (String) getFilterChainToUse().filter(textContent, metadata);
                } catch (Exception e) {
                    handleJmsReplyException(metadata, e);
                    return;
                }
                String callId = (String) metadata.get("callId");
                LOGGER.debug("filterchain processed OK, sending result to answer-queue ({})", callId);
                if (metadata.containsKey("answer")) {
                    new JmsTemplate(connectionFactory).convertAndSend(callId, result);
                }
            }

            private void handleJmsReplyException(HashMap<String, Object> metadata, Exception e) {
                LOGGER.error("an error occured when processing the filterchain", e);
                String callId = (String) metadata.get("callId");
                if (callId != null) {
                    LOGGER.info("callId could be extracted. Sending Exception-response to remote caller ({})",
                        callId);
                    new JmsTemplate(connectionFactory).convertAndSend(callId, ExceptionUtils.getStackTrace(e));
                }
            }

            private String extractTextFromMessage(TextMessage textMessage) {
                try {
                    return textMessage.getText();
                } catch (JMSException e) {
                    throw new RuntimeException(e);
                }
            }

        });
        simpleMessageListenerContainer.start();
    }

    private SimpleMessageListenerContainer createListenerContainer(String destination, MessageListener listener) {
        SimpleMessageListenerContainer messageListenerContainer = factory.createMessageListenerContainer();
        messageListenerContainer.setConnectionFactory(connectionFactory);
        messageListenerContainer.setDestinationName(destination);
{'fraction_non_alphanumeric': 0.07274094767379392, 'fraction_numerical': 0.002578704201138928, 'mean_word_length': 2.543205177007994, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1089210', 'n_tokens_mistral': 2187, 'n_tokens_neox': 2098, 'n_words': 667}