<commit_before>package net.nemerosa.ontrack.jenkins;

import hudson.Extension;
import hudson.util.ListBoxModel;
import jenkins.management.AdministrativeMonitorsConfiguration;
import jenkins.model.GlobalConfiguration;
import jenkins.model.Jenkins;
import net.nemerosa.ontrack.dsl.OntrackConnection;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.StaplerRequest;

import javax.annotation.Nullable;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Logger;

@Extension
public class OntrackConfiguration extends GlobalConfiguration {

    private static Logger LOGGER = Logger.getLogger(OntrackConfiguration.class.getName());

    public static @Nullable
    OntrackConfiguration getOntrackConfiguration() {
        Jenkins instance = Jenkins.getInstanceOrNull();
        return instance != null ? (OntrackConfiguration) instance.getDescriptor(OntrackConfiguration.class) : null;
    }

    private String ontrackConfigurationName;
    private String ontrackUrl;
    private String ontrackUser;
    private String ontrackPassword;
    private int ontrackMaxTries = 1;
    private int ontrackRetryDelaySeconds = 10000;
    private int ontrackVersionCacheExpirationSeconds = 3600;
    private OntrackSecurityMode securityMode = OntrackSecurityMode.DEFAULT;

    private final AtomicReference<VersionCache> version = new AtomicReference<>();

    public OntrackConfiguration() {
        load();
    }

    @Override
    public synchronized void load() {
        super.load();
        loadVersion();
    }

    @Override
    public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
        ontrackConfigurationName = json.getString("ontrackConfigurationName");
        ontrackUrl = json.getString("ontrackUrl");
        ontrackUser = json.getString("ontrackUser");
        ontrackPassword = json.getString("ontrackPassword");
        ontrackMaxTries = json.getInt("ontrackMaxTries");
        ontrackRetryDelaySeconds = json.getInt("ontrackRetryDelaySeconds");
        ontrackVersionCacheExpirationSeconds = json.getInt("ontrackVersionCacheExpirationSeconds");
        securityMode = OntrackSecurityMode.valueOf(json.getString("securityMode"));
        save();
        boolean ok = super.configure(req, json);
        // Getting the version from Ontrack
        loadVersion();
        // OK
        return ok;
    }

    private VersionCache loadVersion() {
        return version.updateAndGet(current -> {
            if (current != null) {
                long expiredTimeMs = System.currentTimeMillis() - current.getTimestamp();
                long expiredTimeSeconds = expiredTimeMs / 1000;
                if (expiredTimeSeconds >= ontrackVersionCacheExpirationSeconds) {
                    return computeVersionCache();
                } else {
                    return current;
                }
            } else {
                return computeVersionCache();
            }
        });
    }

    private VersionCache computeVersionCache() {
        Version remoteVersion = getRemoteVersion();
        if (remoteVersion != null) {
            LOGGER.info("[ontrack] Remote version = " + remoteVersion);
            return new VersionCache(remoteVersion, System.currentTimeMillis());
        } else {
            return null;
        }
    }

    private Version getRemoteVersion() {
        try {
            OntrackConnection connection = OntrackConnection.create(ontrackUrl);
            String user = ontrackUser;
            if (StringUtils.isNotBlank(user)) {
                connection = connection.authenticate(
                        user,
                        ontrackPassword
                );
            }
            String versionString = connection.build().getVersion();
            return Version.of(versionString);
        } catch (Exception ignored) {
            return null;
        }
    }

    public @Nullable
    Version getVersion() {
        VersionCache versionCache = loadVersion();
        return versionCache != null ? versionCache.getValue() : null;
    }

    String getOntrackConfigurationName() {
        return ontrackConfigurationName;
    }

    public String getOntrackUrl() {<commit_msg>#46 Version must be transient + correction of scope for Jenkins configuration name in Ontrack<commit_after>package net.nemerosa.ontrack.jenkins;

import hudson.Extension;
import hudson.util.ListBoxModel;
import jenkins.management.AdministrativeMonitorsConfiguration;
import jenkins.model.GlobalConfiguration;
import jenkins.model.Jenkins;
import net.nemerosa.ontrack.dsl.OntrackConnection;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.StaplerRequest;

import javax.annotation.Nullable;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Logger;

@Extension
public class OntrackConfiguration extends GlobalConfiguration {

    private static Logger LOGGER = Logger.getLogger(OntrackConfiguration.class.getName());

    public static @Nullable
    OntrackConfiguration getOntrackConfiguration() {
        Jenkins instance = Jenkins.getInstanceOrNull();
        return instance != null ? (OntrackConfiguration) instance.getDescriptor(OntrackConfiguration.class) : null;
    }

    private String ontrackConfigurationName;
    private String ontrackUrl;
    private String ontrackUser;
    private String ontrackPassword;
    private int ontrackMaxTries = 1;
    private int ontrackRetryDelaySeconds = 10000;
    private int ontrackVersionCacheExpirationSeconds = 3600;
    private OntrackSecurityMode securityMode = OntrackSecurityMode.DEFAULT;

    private final transient AtomicReference<VersionCache> version = new AtomicReference<>();

    public OntrackConfiguration() {
        load();
    }

    @Override
    public synchronized void load() {
        super.load();
        loadVersion();
    }

    @Override
    public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
        ontrackConfigurationName = json.getString("ontrackConfigurationName");
        ontrackUrl = json.getString("ontrackUrl");
        ontrackUser = json.getString("ontrackUser");
        ontrackPassword = json.getString("ontrackPassword");
        ontrackMaxTries = json.getInt("ontrackMaxTries");
        ontrackRetryDelaySeconds = json.getInt("ontrackRetryDelaySeconds");
        ontrackVersionCacheExpirationSeconds = json.getInt("ontrackVersionCacheExpirationSeconds");
        securityMode = OntrackSecurityMode.valueOf(json.getString("securityMode"));
        save();
        boolean ok = super.configure(req, json);
        // Getting the version from Ontrack
        loadVersion();
        // OK
        return ok;
    }

    private VersionCache loadVersion() {
        return version.updateAndGet(current -> {
            if (current != null) {
                long expiredTimeMs = System.currentTimeMillis() - current.getTimestamp();
                long expiredTimeSeconds = expiredTimeMs / 1000;
                if (expiredTimeSeconds >= ontrackVersionCacheExpirationSeconds) {
                    return computeVersionCache();
                } else {
                    return current;
                }
            } else {
                return computeVersionCache();
            }
        });
    }

    private VersionCache computeVersionCache() {
        Version remoteVersion = getRemoteVersion();
        if (remoteVersion != null) {
            LOGGER.info("[ontrack] Remote version = " + remoteVersion);
            return new VersionCache(remoteVersion, System.currentTimeMillis());
        } else {
            return null;
        }
    }

    private Version getRemoteVersion() {
        try {
            OntrackConnection connection = OntrackConnection.create(ontrackUrl);
            String user = ontrackUser;
            if (StringUtils.isNotBlank(user)) {
                connection = connection.authenticate(
                        user,
                        ontrackPassword
                );
            }
            String versionString = connection.build().getVersion();
            return Version.of(versionString);
        } catch (Exception ignored) {
            return null;
        }
    }

    public @Nullable
    Version getVersion() {
        VersionCache versionCache = loadVersion();
        return versionCache != null ? versionCache.getValue() : null;
    }

    public String getOntrackConfigurationName() {
        return ontrackConfigurationName;
    }

    public String getOntrackUrl() {
{'fraction_non_alphanumeric': 0.08268312565505997, 'fraction_numerical': 0.003493653196692675, 'mean_word_length': 2.716140199048031, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '1116606', 'n_tokens_mistral': 2129, 'n_tokens_neox': 2042, 'n_words': 467}