Skip to content

PluginBuild

ppodsednik edited this page Jan 8, 2026 · 4 revisions

Plugin a Worker Build

Tato stránka popisuje jak se ve vybranem projektu - v nasem pripade Kramerius - vytváří procesy, z nich pluginy a z pluginů konkrétní Worker Docker image v rámci process-platform.

Navazuje na stránky:

  • Home – základní přehled platformy
  • Architecture – runtime architektura (Manager, Worker, procesy)

Tato stránka se soustředí výhradně na build-time pohled.


Základní pojmy (stručně)

Pojem Význam
Process Čistá Java logika (např. Import, Index, Migration)
Plugin Definice, jak se proces spouští v platformě
Worker Runtime aplikace, která vykonává pluginy
Worker image Docker image s konkrétní sadou pluginů

Klíčová myšlenka:

Proces je logika. Plugin je kontrakt. Worker je runtime.


1. Procesy (processes/*)

Procesy vznikají jako běžné Gradle moduly uvnitř multimodulového projektu Kramerius.

Struktura

processes/
 ├─ import/
 ├─ index/
 └─ migration/

Každý proces:

  • je samostatný Gradle modul
  • má vlastní build.gradle
  • může záviset na sdílených modulech (např. :shared:common)
  • musí mít závislost na process-api
dependencies {
    implementation project(':shared:common')
    implementation "org.ceskaexpedice:process-api:${processapiversion}"
}

Proces:

  • může mít main metodu
  • není ještě pluginem
  • neřeší profily, plánování ani integraci s Workerem

Výstupem buildu je obyčejný JAR v build/libs.


2. Pluginy (processes/platform/*/*Plugin)

Plugin je platformní obal procesu, který definuje:

  • vstupní metodu
  • mapování parametrů
  • metadata
  • profily
  • vazbu na Worker runtime

Struktura

processes/platform/
 ├─ curator/
 │   ├─ importPlugin/
 │   ├─ indexPlugin/
 │   └─ worker/
 └─ cdk/
     ├─ migrationPlugin/
     └─ worker/

Každý *Plugin je opět samostatný Gradle modul.

Obsah pluginu

Plugin obsahuje tři zásadní části:

ProcessMethod (vstupní bod)

public class ImportPlatformStarter {

    @ProcessMethod
    public static void importMain(
            @ParameterName("inputDataDir") @IsRequired String importDirFromArgs,
            @ParameterName("startIndexer") @IsRequired Boolean startIndexerFromArgs,
            @ParameterName("license") String license,
            @ParameterName("collections")String addCollection,
            @ParameterName("pathtype") String pathtype,
            @ParameterName("indexationType") String scheduleStrategy
    ) throws IOException, SolrServerException {
        Import.importMain(inputDataDir.getAbsolutePath(), startIndexerFromArgs, license, addCollection, scheduleStrategy);
    }
}
  • označuje spustitelný proces
  • definuje parametry pomocí anotací
  • je jediným vstupním bodem, který Worker zná

Procesní logika je delegována do původního procesu:

Import.importMain(...)

SPI implementace

public class ImportSPI extends AbstractPluginSpi {


    @Override
    public String getMainClass() {
        return ImportPlatformStarter.class.getName();
    }

    @Override
    public Set<String> getScheduledProfiles() {
        return Set.of(
                "new_indexer_index_object",
                "new_indexer_index_model"
        );
    }

}

SPI:

  • umožňuje Workeru plugin objevit
  • definuje hlavní třídu
  • určuje volitelne dalsi profily, ktere muze plugin planovat (subprocess)

build.gradle pouzivajici Gradle plugin processplatform.process

plugins {
    id 'org.ceskaexpedice.processplatform.process'
}

Tento Gradle plugin:

  • vytvori profile.json s profily pluginu
  • vytvori META-INF/services soubor pro process plugin SPI
  • vytvoří process-platform plugin JAR a vlozi do nej vyse uvedene soubory

Konfigurace:

plugins {
    id 'java-library'
    id 'org.ceskaexpedice.processplatform.process' version '1.0.6'
}

description "Import FOXML format"

processPlugin {
	spiImplementation='org.kramerius.plugin.ImportSPI'
	profiles = [
			[profileId: "import",description: "Import FOXML and NDKMETS format - legacy name of process",jvmArgs: ["-Xms1g","-Xmx32g"]]
	]
	excludeDependencies = [
        'com.sun.jersey',
        'javax.ws.rs'
    ]
}

dependencies{
    implementation project(':processes:import')
    implementation "org.ceskaexpedice:process-api:${processapiversion}"
}

➡️ Tady oficiálně vzniká plugin.


3. Worker jako build modul

worker modul neobsahuje žádný Java kód.

Jeho účel:

  • vybrat konkrétní pluginy
  • sestavit Worker runtime
  • vytvořit Docker image

Příklad: curator/worker

plugins {
	id 'com.google.cloud.tools.jib'
    id 'org.ceskaexpedice.processplatform.worker' version '1.0.5'
}

dependencies {
    implementation project(":processes:platform:curator:importPlugin")
    implementation project(":processes:platform:curator:indexPlugin")
}

processWorker {
	workerName = "curatorworker"
	warArtifact = "org.ceskaexpedice:process-worker:${processapiversion}"

	autoShareLibraries = true

	plugins = [
        project(":processes:platform:curator:importPlugin"),
        project(":processes:platform:curator:indexPlugin"),
    ]
}


jib {
    from {
        image = 'tomcat:9.0.87-jdk21-temurin-jammy' 
    }
    to {
        image = "ceskaexpedice/curator-worker:${version}"
    }
    extraDirectories {
        paths {
            path {
				from = project.file('build/worker/webapps').path
                into = '/usr/local/tomcat/webapps' 
            }            
		}   
        paths {
            path {
                from = project.file('build/worker/lib/plugins')
                into = '/usr/local/tomcat/lib/plugins' 
            }
        }
    }
	container {
		entrypoint = ['/usr/local/tomcat/bin/catalina.sh', 'run']
        user = '0'
    }
}

Výběr pluginů pro Worker

Závislosti

dependencies {
    implementation project(':processes:platform:curator:importPlugin')
}

Zajišťují, že pluginy jsou k dispozici pro build.

Skutečný výběr pluginů

processWorker {
    workerName = 'curatorworker'
    plugins = [
        project(':processes:platform:curator:importPlugin'),
        project(':processes:platform:curator:indexPlugin')
    ]
}

➡️ Zde se explicitně říká, které pluginy patří do Workeru.


Výsledek buildu Workeru

Gradle plugin processplatform.worker vytvoří runtime layout:

build/worker/
 ├─ webapps/
 │   └─ processWorker.war
 └─ lib/
     └─ plugins/
          └─ import/
               ├─ importPlugin.jar
          └─ index/
               ├─ indexPlugin.jar

Dalsi knihovny jar potrebne pro dany plugin se ulozi take do plugins/import - napr. import.jar z kramerius/processes nebo, pokud jsou sdilene s ostatnimi pluginy, primo do processWorker.war (WEB-INF/lib) Toto je hotový Worker, ještě bez Dockeru.


Docker image pomocí Jib

Jib:

  • vezme runtime layout
  • vloží ho do Tomcat image
jib {
    from { image = 'tomcat:9-jdk21' }
    to { image = 'ceskaexpedice/curator-worker:${version}' }
}

Výsledkem je deterministický Worker image s pevnou sadou pluginů.


Celkový build řetězec

graph TD
    A[Process<br/>Import] --> B[Plugin<br/>importPlugin]
    B --> C[Worker build<br/>curator/worker]
    C --> D[Docker image<br/>curator-worker]
Loading

Shrnutí

  • Proces je čistá Java logika
  • Plugin definuje proces pro platformu
  • Worker vybírá pluginy při buildu
  • Docker image je pouze runtime obálka

Tento přístup umožňuje:

  • pevně definované workery
  • jednoduchý a reprodukovatelný build
  • jasné oddělení odpovědností

Odkazy: Home, Running the Platform