> For the complete documentation index, see [llms.txt](https://documentation.efalia.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.efalia.com/documentations/efalia-process/vue-ensemble-api/developper-connecteur-custom.md).

# Développer un Connecteur Custom

Efalia Process permet de développer des **connecteurs Java personnalisés** pour étendre les capacités de la plateforme avec des logiques métier spécifiques ou des intégrations non couvertes par les connecteurs standards.

{% hint style="info" %}
**Avant de développer**

Avant de créer un connecteur Java, vérifiez si vos besoins ne sont pas déjà couverts par :

* Le [ScriptConnector (Groovy)](/documentations/efalia-process/vue-ensemble/connecteurs-generiques.md#scriptconnector) pour les logiques simples
* Le [Connecteur API REST](/documentations/efalia-process/vue-ensemble-api/connecteur-api-rest.md) pour appeler des services externes
* Les [Connecteurs Génériques](/documentations/efalia-process/vue-ensemble/connecteurs-generiques.md) existants
  {% endhint %}

***

## Architecture d'un Connecteur

Un connecteur Efalia Process est une **classe Java** qui implémente l'interface `IConnector`. Elle est packagée dans un fichier `.jar` déployé sur le serveur.

```
Connecteur Java
│
├── Classe implémentant IConnector
│   ├── execute() — logique principale
│   ├── Paramètres en entrée (champs Process)
│   └── Paramètres en sortie (valeurs retournées)
│
└── JAR déployé dans $CATALINA_HOME/lib/
```

***

## Prérequis de Développement

* **JDK 1.8.x** (compatibilité avec la version Java d'Efalia Process)
* Maven ou Gradle pour la gestion des dépendances
* La bibliothèque `workey-connector-api.jar` (disponible auprès d'Efalia)
* Un environnement Efalia Process de développement/recette pour les tests

***

## Structure du Projet

```
mon-connecteur/
├── pom.xml
└── src/
    └── main/
        └── java/
            └── com/
                └── example/
                    └── connectors/
                        └── MonConnecteur.java
```

### pom.xml

```xml
<dependencies>
    <dependency>
        <groupId>com.clog.workey</groupId>
        <artifactId>workey-connector-api</artifactId>
        <version>${workey.version}</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
```

***

## Implémentation

### Structure de Base

```java
package com.example.connectors;

import com.clog.workey.connector.api.IConnector;
import com.clog.workey.connector.api.ConnectorContext;
import com.clog.workey.connector.api.ConnectorResult;

public class MonConnecteur implements IConnector {

    @Override
    public ConnectorResult execute(ConnectorContext context) {
        // Récupérer les paramètres d'entrée
        String param1 = context.getInputParam(0); // 1er paramètre
        String param2 = context.getInputParam(1); // 2e paramètre

        // Accéder aux données du document Process
        String valeurChamp = context.getDocumentField("nom_interne_champ");

        // Logique métier
        String resultat = traiterDonnees(param1, param2, valeurChamp);

        // Retourner les résultats
        ConnectorResult result = new ConnectorResult();
        result.addOutput(resultat);   // 1er paramètre de sortie
        return result;
    }

    private String traiterDonnees(String p1, String p2, String champ) {
        // Votre logique ici
        return p1 + " " + p2 + " — " + champ;
    }
}
```

### Accès aux Ressources du Contexte

```java
// Paramètres en entrée
String param = context.getInputParam(0);
List<String> multiValues = context.getInputParams(0); // champ multivalué

// Champs du document
String fieldValue = context.getDocumentField("nom_champ");
context.setDocumentField("nom_champ", "nouvelle_valeur");

// Pièces jointes
byte[] fileContent = context.getAttachment("nom_champ_pj");

// API Process
WorkeyApi api = context.getApi();

// Logging
Logger logger = context.getLogger();
logger.info("Mon connecteur — traitement démarré");
logger.debug("Valeur reçue : " + param);
```

### Gestion des Erreurs

```java
@Override
public ConnectorResult execute(ConnectorContext context) {
    try {
        String result = appelServiceExterne();
        ConnectorResult connResult = new ConnectorResult();
        connResult.addOutput(result);
        return connResult;
    } catch (ServiceException e) {
        // Lance une exception — l'opération échoue avec un message utilisateur
        throw new ConnectorException(
            "Erreur lors de l'appel au service externe : " + e.getMessage(), e
        );
    }
}
```

***

## Déploiement

{% stepper %}
{% step %}

#### Builder le JAR

```bash
mvn clean package
# Génère : target/mon-connecteur-1.0.jar
```

{% endstep %}

{% step %}

#### Déployer sur le serveur

Copiez le JAR dans le répertoire des bibliothèques Tomcat :

```bash
cp target/mon-connecteur-1.0.jar $CATALINA_HOME/lib/
```

{% endstep %}

{% step %}

#### Redémarrer le serveur

```bash
$CATALINA_HOME/bin/shutdown.sh
$CATALINA_HOME/bin/startup.sh
```

{% endstep %}

{% step %}

#### Configurer dans le Designer

Dans le Designer, ajoutez une opération et sélectionnez votre connecteur par son **nom complet de classe** :

```
com.example.connectors.MonConnecteur
```

Mappez les paramètres d'entrée et de sortie avec les champs du formulaire.

📸 **CAPTURE : connecteur-custom-01-designer.png**

> Configuration du connecteur custom dans le Designer avec le nom de classe et les paramètres
> {% endstep %}
> {% endstepper %}

***

## Bonnes Pratiques

{% hint style="success" %}
**✅ Recommandations**

* Utilisez l'injection de configuration via `catalina.properties` plutôt que des valeurs en dur dans le code
* Loggez les erreurs et les informations importantes avec le Logger fourni par le contexte
* Gérez les timeouts pour les appels à des services externes
* Testez votre connecteur sur un environnement de recette avant la production
* Versionnez votre connecteur (numéro de version dans le nom du JAR)
  {% endhint %}

{% hint style="danger" %}
**❌ À éviter**

* Stocker des identifiants (mots de passe, clés API) dans le code source
* Effectuer des opérations longues sans gestion de timeout
* Ignorer les exceptions sans les logger
* Modifier le JAR directement sur le serveur de production sans recette
  {% endhint %}

***

## Lire une Configuration depuis catalina.properties

```java
// Dans votre connecteur
String apiUrl = System.getProperty("com.example.myapi.url");
String apiKey = System.getProperty("com.example.myapi.key");
```

Dans `catalina.properties` :

```properties
com.example.myapi.url=https://mon-service.example.com/api
com.example.myapi.key=ma_cle_api_secrete
```

***

Pour aller plus loin :

* [Paramétrage des Connecteurs](/documentations/efalia-process/administration/administration-technique/parametrage-connecteurs.md)
* [Connecteurs Génériques](/documentations/efalia-process/vue-ensemble/connecteurs-generiques.md)
* [ScriptConnector (Groovy)](/documentations/efalia-process/vue-ensemble/connecteurs-generiques.md#scriptconnector)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://documentation.efalia.com/documentations/efalia-process/vue-ensemble-api/developper-connecteur-custom.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
