CtanConfiguration.java
/*
* Copyright © 2022-2025 The CTAN Team and individual authors
*
* This file is distributed under the 3-clause BSD license.
* See file LICENSE for details.
*/
package org.ctan.site;
import java.util.List;
import java.util.Map;
import org.ctan.site.services.util.NullCheck;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.dropwizard.core.Configuration;
import io.dropwizard.db.DataSourceFactory;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Builder.Default;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* The class <code>CtanConfiguration</code> contains the Dropwizard
* configuration specific to the CTAN site.
*
* <p>
* The configuration is externally stored in a yaml file and read at startup.
* </p>
*
* <p>
* The configuration might contain references to environment variables. This can
* be achieved with a construct like <code>${VARIABLE}</code>. This takes the
* value of VARIABLE from the environment. If the variable might not be defined
* then <code>${VARIABLE:-FALLBACK}</code> can be used to revert to FALLBACK in
* this case.
* </p>
*
* <p>
* The following example demonstrates the major configuration parameters.
* </p>
* <pre>
* appName: Comprehensive TeX Archive Network
* version: 3.0.0
*
* #---------------------------------------------------------------------------
* # Server settings.
* server:
* rootPath: '/api/*'
* applicationConnectors:
* - type: http
* port: 9000
* adminConnectors:
* - type: http
* port: 9001
*
* #---------------------------------------------------------------------------
* # CTAN settings.
* ctan:
* defaultLanguage: en
* languages:
* - en
* - de
*
* #---------------------------------------------------------------------------
* # CTAN searching settings.
* index:
* directory: /serv/www/www.ctan.org/index
*
* #---------------------------------------------------------------------------
* # CTAN content settings.
* content:
* directory: /serv/www/www.ctan.org/src/ctan-content
*
* #---------------------------------------------------------------------------
* # CTAN incoming settings.
* upload:
* addendum: /home/ftp/pub/tex/help/ctan/CTAN-upload-addendum.html
* incoming: /serv/www/www.ctan.org/incoming
* managers: ctan@ctan.org
*
* #---------------------------------------------------------------------------
* # CTAN TeX Catalogue settings.
* catalogue:
* entries: /serv/www/www.ctan.org/texcatalogue/entries
*
* #---------------------------------------------------------------------------
* # CTAN tex-archive settings.
* texArchive:
* directory: /home/ftp/pub/tex
*
* #---------------------------------------------------------------------------
* # CTAN ctan-ann settings.
* ctanAnnounce:
* directory: /serv/www/www.ctan.org/ctan-ann
*
* #---------------------------------------------------------------------------
* # MirrMon settings.
* mirrmon:
* url: https://ctan.org/mirmon
*
* #---------------------------------------------------------------------------
* # LUGs database settings.
* lugs:
* url: https://www.ntg.nl/lug/lugs/
*
* #---------------------------------------------------------------------------
* # Mail settings.
* mail:
* smtp:
* host: localhost
* port: 587
* from: no-reply@ctan.org
* list:
* mirror-registration:
* template: mirror-registration
* to: ctan@ctan.org
*
* #---------------------------------------------------------------------------
* # Database settings.
* site_db:
* driverClass: org.postgresql.Driver
* user: ${SITE_DB_USER:-www}
* password: ${SITE_DB_PASSWD}
* url: jdbc:postgresql://localhost:5432/${SITE_DB:-portal}
* properties:
* charSet: UTF-8
* hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect
* maxWaitForConnection: 1s
* validationQuery: "SELECT 1"
* minSize: 8
* maxSize: 32
* checkConnectionWhileIdle: false
*
* mirrors:
* driverClass: org.postgresql.Driver
* user: ${MIRRORS_DB_USER:-www}
* password: ${MIRRORS_DB_PASSWD}
* url: jdbc:postgresql://localhost:5432/${MIRRORS_DB:-ctan}
* properties:
* charSet: UTF-8
* hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect
* maxWaitForConnection: 1s
* validationQuery: "SELECT 1"
* minSize: 8
* maxSize: 32
* checkConnectionWhileIdle: false
* </pre>
*
* @author <a href="mailto:gene@ctan.org">Gerd Neugebauer</a>
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@SuppressFBWarnings(value = "EI_EXPOSE_REP")
public class CtanConfiguration extends Configuration {
/**
* The class <code>CatalogueConfig</code> contains the Dropwizard
* configuration for the Catalogue.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class CatalogueConfig {
/**
* The field <code>entries</code> contains the name of the entries
* subdirectory.
*/
private String entries;
}
/**
* The class <code>ContentConfig</code> contains the definition of the
* sub-configuration <code>content</code>.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class ContentConfig {
/**
* The field <code>directory</code> contains the path of the content
* directory.
*/
private String directory;
}
/**
* The class <code>CtanAnnounceConfig</code> contains the definition of the
* sub-configuration <code>ctanAnnounce</code>.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class CtanAnnounceConfig {
/**
* The field <code>directory</code> contains the directory containing
* the announcements.
*/
private String directory;
}
/**
* The class <code>CtanParams</code> contains the description of the section
* <code>ctan</code> of the configuration.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class CtanConfig {
/**
* The field <code>LOCALES</code> contains the supported locales in a
* static list. Note that this may conflict with the configuration
* option. BE CAREFUL!
*/
public static final List<String> LOCALES = List.of("en", "de");
/**
* The field <code>languages</code> contains the list of supported
* languages.
*/
private String[] languages;
}
/**
* The class <code>IndexConfig</code> contains the definition of the
* sub-configuration <code>index</code>.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class IndexConfig {
/**
* The field <code>directory</code> contains the path of the index
* master directory.
*/
private String directory;
}
/**
* The class <code>LugsConfig</code> contains the Dropwizard configuration
* for the Lugs.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class LugsConfig {
/**
* The field <code>url</code> contains the URL to retrieve the LUGs
* data.
*/
private String url;
}
/**
* The mail configuration.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class MailConfig {
/**
* The field <code>smtp</code> contains the SMTP configuration.
*/
private MailSmtpConfig smtp;
/**
* The field <code>from</code> contains the sender email address.
*/
private String from;
/**
* The field <code>list</code> contains the map of name to mail list
* data.
*/
private Map<String, MailType> list;
/**
* The method <code>getList</code> provides means to retrieve the
* configuration for one mail list.
*
* @param key the name of the mail list
* @return the mail list
*/
public MailType getList(String key) {
NullCheck.isNotNullObject(list, "mail.list");
return list.get(key);
}
}
/**
* The SMTP configuration.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class MailSmtpConfig {
/**
* The field <code>host</code> contains the SMTP host.
*/
private String host;
/**
* The field <code>port</code> contains the SMTP port as String.
*/
private String port;
/**
* The field <code>auth</code> contains the indicator whether
* authentication is required.
*/
private boolean auth;
/**
* The field <code>starttls</code> contains the SMTP starttls
* configuration.
*/
private MailSmtpStarttls starttls;
}
/**
* The SMTP starttls configuration.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class MailSmtpStarttls {
/**
* The field <code>enable</code> contains the indicator to turn on
* STARTTLS.
*/
private boolean enable;
}
/**
* The mail list type configuration.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class MailType {
/**
* The field <code>template</code> contains the name of the template to
* use.
*/
private String template;
/**
* The field <code>to</code> contains the addressee for the mails to
* this list.
*/
private String to;
}
/**
* The class <code>MirrMonConfig</code> contains the Dropwizard
* configuration for MirrMon.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class MirrMonConfig {
/**
* The field <code>url</code> contains the source of the mirmon page.
*/
private String url;
}
/**
* The class <code>TexArchiveConfig</code> contains the definition of the
* sub-configuration <code>texArchive</code>.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class TexArchiveConfig {
/**
* The field <code>directory</code> contains the <span>T<span style=
* "text-transform:uppercase;font-size:90%;vertical-align:-0.4ex;
* margin-left:-0.2em;margin-right:-0.1em;line-height: 0;" >e</span>
* X</span> archive directory.
*/
private String directory;
}
/**
* The class <code>UploadConfig</code> contains the definition of the
* sub-configuration <code>upload</code>.
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class UploadConfig {
/**
* The field <code>addendum</code> contains the name of the addendum
* file.
*/
private String addendum;
/**
* The field <code>incoming</code> contains the path of the incoming
* directory.
*/
private String incoming;
/**
* The field <code>managers</code> contains the email address for
* informing the CTAN upload managers about a new upload.
*/
private String managers;
}
/**
* The field <code>appName</code> contains the name of the application.
*/
private String appName;
/**
* The field <code>content</code> contains the base directory for the
* content tree.
*/
private ContentConfig content;
/**
* The field <code>ctan</code> contains the CTAN parameters.
*/
private CtanConfig ctan;
/**
* The field <code>ctanAnnounce</code> contains the parameters for ctan-ann.
*/
private CtanAnnounceConfig ctanAnnounce;
/**
* The field <code>lugs</code> contains the parameter for lugs.
*/
private LugsConfig lugs;
/**
* The field <code>mirrMon</code> contains the parameter for MirrMon.
*/
private MirrMonConfig mirrmon;
/**
* The field <code>index</code> contains the base directory for the search
* indices.
*/
private IndexConfig index;
/**
* The field <code>mail</code> contains configuration for mail.
*/
private MailConfig mail;
/**
* The field <code>mirrors</code> contains the mirrors database.
*/
@NotNull
@Valid
@Default
private DataSourceFactory mirrors = new DataSourceFactory();
/**
* The field <code>siteDb</code> contains the site database.
*/
@NotNull
@Valid
@Default
private DataSourceFactory siteDb = new DataSourceFactory();
/**
* The field <code>texArchive</code> contains the base directory for the TeX
* archive.
*/
private TexArchiveConfig texArchive;
/**
* The field <code>upload</code> contains the incoming directory.
*/
private UploadConfig upload;
/**
* The field <code>catalogue</code> contains the catalogue entries
* directory.
*/
private CatalogueConfig catalogue;
/**
* The field <code>version</code> contains the version of the application.
*/
private String version;
}