<commit_before>/*******************************************************************************
 * Copyright (C) 2017 Push Technology Ltd.
 *
 * 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 com.pushtechnology.adapters.rest.adapter;

import static java.util.stream.Collectors.toList;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ScheduledExecutorService;

import javax.net.ssl.SSLContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.pushtechnology.adapters.rest.model.latest.DiffusionConfig;
import com.pushtechnology.adapters.rest.model.latest.Model;
import com.pushtechnology.adapters.rest.model.latest.ServiceConfig;
import com.pushtechnology.adapters.rest.polling.EndpointClientImpl;
import com.pushtechnology.adapters.rest.polling.HttpClientFactory;
import com.pushtechnology.adapters.rest.polling.ServiceSessionFactoryImpl;
import com.pushtechnology.adapters.rest.publication.PublishingClientImpl;
import com.pushtechnology.adapters.rest.session.management.DiffusionSessionFactory;
import com.pushtechnology.adapters.rest.session.management.EventedSessionListener;
import com.pushtechnology.adapters.rest.session.management.SSLContextFactory;
import com.pushtechnology.adapters.rest.session.management.SessionLossHandler;
import com.pushtechnology.adapters.rest.session.management.SessionLostListener;
import com.pushtechnology.adapters.rest.topic.management.TopicManagementClientImpl;
import com.pushtechnology.diffusion.client.session.Session;
import com.pushtechnology.diffusion.client.session.SessionFactory;

import net.jcip.annotations.GuardedBy;

/**
 * The REST Adapter.
 *
 * @author <NAME> 07/10/2017
 */
public final class InternalRESTAdapter implements RESTAdapterListener, AutoCloseable {
    private static final Logger LOG = LoggerFactory.getLogger(InternalRESTAdapter.class);
    private final ScheduledExecutorService executor;
    private final SessionLossHandler sessionLossHandler;
    private final ServiceListener serviceListener;

    private final EventedSessionListener eventedSessionListener = new EventedSessionListener();
    private final HttpClientFactory httpClientFactory;
    private final ServiceManager serviceManager = new ServiceManager();
    private final SSLContextFactory sslContextFactory = new SSLContextFactory();
    private final DiffusionSessionFactory sessionFactory;
    private final Runnable shutdownHandler;
    @GuardedBy("this")
    private Model currentModel;
    @GuardedBy("this")
    private EndpointClientImpl endpointClient;
    @GuardedBy("this")
    private SSLContext sslContext;
    @GuardedBy("this")
    private TopicManagementClientImpl topicManagementClient;
    @GuardedBy("this")
    private PublishingClientImpl publishingClient;
    @GuardedBy("this")
    private State state = State.STANDBY;
    @GuardedBy("this")
    private Session diffusionSession;

    /**
     * Constructor.
     */
    public InternalRESTAdapter(
        ScheduledExecutorService executor,
        SessionFactory sessions,
        HttpClientFactory httpClientFactory,
        ServiceListener serviceListener,
        SessionLossHandler sessionLossHandler,
        Runnable shutdownHandler) {

        this.executor = executor;
        this.sessionLossHandler = sessionLossHandler;
        this.serviceListener = serviceListener;
        this.httpClientFactory = httpClientFactory;
        sessionFactory = new DiffusionSessionFactory(sessions);
        this.shutdownHandler = shutdownHandler;
    }

    @Override
    public synchronized void onReconfiguration(Model model) {
        LOG.warn("Model {}", model);

        if (!model.isActive()) {
            shutdownSession();

            if (state == State.CONNECTING_TO_DIFFUSION) {
                state = State.STOPPING;
            }
            else {
                state = State.STOPPED;
                shutdownHandler.run();
            }

            return;
        }

        if (isNotPolling(model)) {
            currentModel = model;
            shutdownSession();

            state = State.STANDBY;
        }<commit_msg>Allow a session listener to be injected into the internal REST adapter.<commit_after>/*******************************************************************************
 * Copyright (C) 2017 Push Technology Ltd.
 *
 * 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 com.pushtechnology.adapters.rest.adapter;

import static java.util.stream.Collectors.toList;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ScheduledExecutorService;

import javax.net.ssl.SSLContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.pushtechnology.adapters.rest.model.latest.DiffusionConfig;
import com.pushtechnology.adapters.rest.model.latest.Model;
import com.pushtechnology.adapters.rest.model.latest.ServiceConfig;
import com.pushtechnology.adapters.rest.polling.EndpointClientImpl;
import com.pushtechnology.adapters.rest.polling.HttpClientFactory;
import com.pushtechnology.adapters.rest.polling.ServiceSessionFactoryImpl;
import com.pushtechnology.adapters.rest.publication.PublishingClientImpl;
import com.pushtechnology.adapters.rest.session.management.DiffusionSessionFactory;
import com.pushtechnology.adapters.rest.session.management.EventedSessionListener;
import com.pushtechnology.adapters.rest.session.management.SSLContextFactory;
import com.pushtechnology.adapters.rest.session.management.SessionLossHandler;
import com.pushtechnology.adapters.rest.session.management.SessionLostListener;
import com.pushtechnology.adapters.rest.topic.management.TopicManagementClientImpl;
import com.pushtechnology.diffusion.client.session.Session;
import com.pushtechnology.diffusion.client.session.SessionFactory;

import net.jcip.annotations.GuardedBy;

/**
 * The REST Adapter.
 *
 * @author <NAME> 07/10/2017
 */
public final class InternalRESTAdapter implements RESTAdapterListener, AutoCloseable {
    private static final Logger LOG = LoggerFactory.getLogger(InternalRESTAdapter.class);
    private final ScheduledExecutorService executor;
    private final SessionLossHandler sessionLossHandler;
    private final ServiceListener serviceListener;

    private final EventedSessionListener eventedSessionListener = new EventedSessionListener();
    private final HttpClientFactory httpClientFactory;
    private final ServiceManager serviceManager = new ServiceManager();
    private final SSLContextFactory sslContextFactory = new SSLContextFactory();
    private final DiffusionSessionFactory sessionFactory;
    private final Runnable shutdownHandler;
    @GuardedBy("this")
    private Model currentModel;
    @GuardedBy("this")
    private EndpointClientImpl endpointClient;
    @GuardedBy("this")
    private SSLContext sslContext;
    @GuardedBy("this")
    private TopicManagementClientImpl topicManagementClient;
    @GuardedBy("this")
    private PublishingClientImpl publishingClient;
    @GuardedBy("this")
    private State state = State.STANDBY;
    @GuardedBy("this")
    private Session diffusionSession;

    /**
     * Constructor.
     */
    public InternalRESTAdapter(
        ScheduledExecutorService executor,
        SessionFactory sessions,
        HttpClientFactory httpClientFactory,
        ServiceListener serviceListener,
        SessionLossHandler sessionLossHandler,
        Runnable shutdownHandler) {

        this.executor = executor;
        this.sessionLossHandler = sessionLossHandler;
        this.serviceListener = serviceListener;
        this.httpClientFactory = httpClientFactory;
        sessionFactory = new DiffusionSessionFactory(sessions);
        this.shutdownHandler = shutdownHandler;
    }

    /**
     * Constructor.
     */
    public InternalRESTAdapter(
        ScheduledExecutorService executor,
        SessionFactory sessions,
        HttpClientFactory httpClientFactory,
        ServiceListener serviceListener,
        SessionLossHandler sessionLossHandler,
        Runnable shutdownHandler,
        Session.Listener listener) {

        this(executor, sessions, httpClientFactory, serviceListener, sessionLossHandler, shutdownHandler);
        eventedSessionListener.onSessionStateChange(listener);
    }

    @Override
    public synchronized void onReconfiguration(Model model) {
        LOG.warn("Model {}", model);

        if (!model.isActive()) {
            shutdownSession();

            if (state == State.CONNECTING_TO_DIFFUSION) {
                state = State.STOPPING;
            }
            else {
                state = State.STOPPED;
                shutdownHandler.run();
            }

            return;
        }

        if (isNotPolling(model)) {
            currentModel = model;
            shutdownSession();

            state = State.STANDBY;
        }
{'fraction_non_alphanumeric': 0.1057826520438684, 'fraction_numerical': 0.003589232303090728, 'mean_word_length': 3.998006975585451, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '7254054', 'n_tokens_mistral': 2669, 'n_tokens_neox': 2486, 'n_words': 599}