# TRANSFORMS (SMT)

<figure><img src="/files/hbBezLjRo6VIK9hv6pNc" alt=""><figcaption></figcaption></figure>

## 1. GDPR&#x20;

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td></td><td>GdprEmail</td><td></td><td><a href="/pages/wcxs9OkCg7LZyE7FlAKj#5.-gdpr-email">/pages/wcxs9OkCg7LZyE7FlAKj#5.-gdpr-email</a></td></tr><tr><td></td><td>GdprPesel</td><td></td><td><a href="/pages/wcxs9OkCg7LZyE7FlAKj#6.-gdpr-pesel">/pages/wcxs9OkCg7LZyE7FlAKj#6.-gdpr-pesel</a></td></tr><tr><td></td><td>GdprPhone</td><td></td><td><a href="/pages/wcxs9OkCg7LZyE7FlAKj#7.-gdpr-phone">/pages/wcxs9OkCg7LZyE7FlAKj#7.-gdpr-phone</a></td></tr><tr><td></td><td>GdprPassportId</td><td></td><td><a href="/pages/wcxs9OkCg7LZyE7FlAKj#8.-gdpr-gdprpassportid">/pages/wcxs9OkCg7LZyE7FlAKj#8.-gdpr-gdprpassportid</a></td></tr><tr><td></td><td>GdprCreditCard</td><td></td><td><a href="/pages/wcxs9OkCg7LZyE7FlAKj#9.-gdpr-creditcard">/pages/wcxs9OkCg7LZyE7FlAKj#9.-gdpr-creditcard</a></td></tr></tbody></table>

## 2. FPE&#x20;

**Example:**&#x20;

{% hint style="info" %}

```json
{
"transforms":"fpe",
"transforms.fpe.type":"FpeField$Value",
"transforms.fpe.key":"3677397A24432646294A404D63516654",
"transforms.fpe.fields":"SENDER"
}
```

{% endhint %}

## 3. INSERT FIELD&#x20;

**Example:**

{% hint style="info" %}

```json
{"transforms": "InsertField",
"transforms.InsertField.type": "org.apache.kafka.connect.transforms.InsertField$Value",
"transforms.InsertField.static.field": "TARGET_SYSTEM",
"transforms.InsertField.static.value": "GOLDENORE CDC"}
```

{% endhint %}

## 4. MASK FIELD

**Example:**

```json
{"transforms": "Name",
"transforms.Name.type": "org.apache.kafka.connect.transforms.MaskField$Value",
"transforms.Name.fields": "SENDER_NAME",
"transforms.Name.replacement": "MASK SENDER NAME"}

```

## 5. TimestampConverter

Dostepne typy danych :

string, unix, Date, Time, or Timestamp.

**Example:**

```json
{
  "transforms": "StringToNumber,TimestampConverter",
  
  "transforms.StringToNumber.type": "org.apache.kafka.connect.transforms.Cast$Value",
  "transforms.StringToNumber.spec": "epoch:int64",
  
  "transforms.TimestampConverter.type": "org.apache.kafka.connect.transforms.TimestampConverter$Value",
  "transforms.TimestampConverter.field": "epoch",
  "transforms.TimestampConverter.target.type": "string",
  "transforms.TimestampConverter.format": "yyyy-MM-dd HH:mm:ss.SSS"
}

```

Rename Field&#x20;

```json
{"transforms": "RenameField",
"transforms.RenameField.type": "org.apache.kafka.connect.transforms.ReplaceField$Value",
"transforms.RenameField.renames": "epoch:time"}
```

{% hint style="info" %}

```json
{"transforms": "TimestampConverter",
"transforms.TimestampConverter.type": "org.apache.kafka.connect.transforms.TimestampConverter$Value",
"transforms.TimestampConverter.format": "yyyy-MM-dd HH:mm:ss",
"transforms.TimestampConverter.field": "epoch",
"transforms.TimestampConverter.target.type": "string"}
```

{% endhint %}

## 6. GDPR Email

### Tabela z dostępnymi ustawieniami

<table><thead><tr><th width="249.33333333333331">Opis</th><th>Wzór</th><th>Wartość domyślna</th></tr></thead><tbody><tr><td>Nazwa pola</td><td>"transforms.&#x3C;nazwa transformaty>.fields": "&#x3C;nazwa kolumny w której znajduje się mail>"</td><td>BRAK</td></tr><tr><td>Pole określające czy chcemy aby dane generowane przez system były zbliżone do ciągu wejściowego ( email format ) </td><td>"transforms.&#x3C;nazwa transformaty>.email.format": &#x3C;true lub false></td><td>true</td></tr><tr><td>Pole określające czy w przypadku nieprawidłowego formatu email ma być wstawiany placeholder</td><td>transforms.&#x3C;nazwa transformaty>.want.placeholder": &#x3C;true lub false></td><td>true</td></tr><tr><td>Pole określające klucz dla szyfrowania AES</td><td>"transforms.&#x3C;nazwa transformaty>.key": "&#x3C;klucz AES>"</td><td>"770A8B65BB156D24DE2A093277530142"</td></tr><tr><td>Pole określające czy nie zważając na format danych chcemy zaszyfrować dane algorytmem AES</td><td>"transforms.&#x3C;nazwa transformaty>.encryption": &#x3C;true lub false></td><td>false</td></tr><tr><td>Pole określające czy nie zważając na format danych chcemy deszyfrować dane algorytmem AES</td><td>"transforms.&#x3C;nazwa transformaty>.decryption": &#x3C;true lub false></td><td>false</td></tr></tbody></table>

#### Uwagi dodatkowe

* Pól które posiadają wartości domyślne nie musimy zawierać w definicji transformaty.
* W przypadku braku chęci wstawiania placeholdera dane szyfrowane są za pomocą algorytmu MD5
* W przypadku niemożliwości deszyfrowania (ze względu na niedozwolone znaki w kolumnie typu kropki) wykonywane jest domyślna operacja dla całej transformaty a więc szyfrowanie słownikowe

#### Przykładowe transformaty

<details>

<summary>Transformata z formatem mail(szyfrowanie słownikowe)</summary>

```json
{ 
  "transforms": "FieldMailReal",
  "transforms.FieldMailReal.type": "GdprEmail$Value",
  "transforms.FieldMailReal.fields": "email_adress",
  "transforms.FieldMailReal.email.format": true
}

lub

{
  "transforms": "FieldMail",
  "transforms.FieldMail.type": "GdprEmail$Value",
  "transforms.FieldMail.fields": "email_adress"
}
```

</details>

<details>

<summary>Transformata bez formatu mail(szyfrowanie SHA256) z placeholderem w przypadku, gdy dana w tabeli nie jest mailem</summary>

```json
{
  "transforms": "FieldMailNotReal",
  "transforms.FieldMailNotReal.type": "GdprEmail$Value",
  "transforms.FieldMailNotReal.fields": "email_adress",
  "transforms.FieldMailNotReal.email.format": false,
  "transforms.FieldMailNotReal.want.placeholder": true 
}

lub

{
  "transforms": "FieldMailNotReal",
  "transforms.FieldMailNotReal.type": "GdprEmail$Value",
  "transforms.FieldMailNotReal.fields": "email_adress",
  "transforms.FieldMailNotReal.email.format": false 
}
```

</details>

<details>

<summary>Transformata bez formatu mail(szyfrowanie SHA256) z szyfrowaniem MD5 w przypadku, gdy dana w tabeli nie jest mailem</summary>

```json
{
  "transforms": "FieldMailNotReal",
  "transforms.FieldMailNotReal.type": "GdprEmail$Value",
  "transforms.FieldMailNotReal.fields": "email_adress",
  "transforms.FieldMailNotReal.email.format": false,
  "transforms.FieldMailNotReal.want.placeholder": false 
}
```

</details>

<details>

<summary>Transformata szyfrująca AES</summary>

```json
{
  "transforms": "FieldEncryption",
  "transforms.FieldEncryption.type": "GdprEmail$Value",
  "transforms.FieldEncryption.fields": "email_adress",
  "transforms.FieldEncryption.encryption": true 
}

lub

{
  "transforms": "FieldEncryption",
  "transforms.FieldEncryption.type": "GdprEmail$Value",
  "transforms.FieldEncryption.fields": "email_adress",
  "transforms.FieldEncryption.key": "770A8B65DB156D24ED2C093277530142",
  "transforms.FieldEncryption.encryption": true 
}
```

</details>

<details>

<summary>Transformata deszyfrująca AES</summary>

```json
{
  "transforms": "FieldDecryption",
  "transforms.FieldDecryption.type": "GdprEmail$Value",
  "transforms.FieldDecryption.fields": "email",
  "transforms.FieldDecryption.decryption": true 
}

lub

{
  "transforms": "FieldDecryption",
  "transforms.FieldDecryption.type": "GdprEmail$Value",
  "transforms.FieldDecryption.fields": "email",
  "transforms.FieldDecryption.key": "770A8B65DB156D24ED2C093277530142",
  "transforms.FieldDecryption.decryption": true 
}
```

</details>

## 7. GDPR Pesel

### Tabela z dostępnymi ustawieniami

<table><thead><tr><th width="249.33333333333331">Opis</th><th>Wzór</th><th>Wartość domyślna</th></tr></thead><tbody><tr><td>Nazwa pola</td><td>"transforms.&#x3C;nazwa transformaty>.fields": "&#x3C;nazwa kolumny w której znajduje się pesel>"</td><td>BRAK</td></tr></tbody></table>

#### Uwagi dodatkowe

* W przypadku, gdy w podanym polu wartość nie jest numerem pesel wstawiana zostaje wartość 0.

#### Przykładowa transformata

```json
{
  "transforms": "FieldPesel", 
  "transforms.FieldPesel.type": "GdprPesel$Value", 
  "transforms.FieldPesel.fields": "pesel" 
}
```

## 8. GDPR Phone

### Tabela z dostępnymi ustawieniami

<table><thead><tr><th width="249.33333333333331">Opis</th><th>Wzór</th><th>Wartość domyślna</th></tr></thead><tbody><tr><td>Nazwa pola</td><td>"transforms.&#x3C;nazwa transformaty>.fields": "&#x3C;nazwa kolumny w której znajduje się numer telefonu>"</td><td>BRAK</td></tr></tbody></table>

#### Uwagi dodatkowe

* W przypadku, gdy w podanym polu wartość nie jest numerem telefonu wstawiana zostaje wartość 48 z następstwem zer w zależności od długości ciągu wejściowego. W przypadku podania wartości krótszej niż 3 cyfry wstawiana jest wartość 0.
* Obsługiwane są numery międzynarodowe.
* Nie obsługiwane są numery wewnętrzne, alarmowe oraz operatora.
* Numery telefonów mogą posiadać spację między cyframi oraz numer kierunkowy kraju poprzedzony +

#### Przykładowa transformata

```json
{
  "transforms": "FieldPhoneNumber",
  "transforms.FieldPhoneNumber.type": "GdprPhoneNumber$Value",
  "transforms.FieldPhoneNumber.fields": "phone_number"
}
```

## 9. GDPR GdprPassportId

### Tabela z dostępnymi ustawieniami

<table><thead><tr><th width="249.33333333333331">Opis</th><th>Wzór</th><th>Wartość domyślna</th></tr></thead><tbody><tr><td>Nazwa pola</td><td>"transforms.&#x3C;nazwa transformaty>.fields": "&#x3C;nazwa kolumny w której znajduje się numer paszportu lub dowodu osobistego>"</td><td>BRAK</td></tr><tr><td>Pole określające czy w przypadku nieprawidłowego formatu paszportu lub dowodu osobistego ma być wstawiany placeholder</td><td>"transforms.&#x3C;nazwa transformaty>.want.placeholder": &#x3C;true lub false>"</td><td>true</td></tr><tr><td>Pole określające czy chcemy anonimizować numer paszportu czy dowodu osobistego</td><td>"transforms.&#x3C;nazwa transformaty>.type.settings": &#x3C;"passport" lub "id">"</td><td>null</td></tr></tbody></table>

#### Uwagi dodatkowe

* Pól które posiadają wartości domyślne nie musimy zawierać w definicji transformaty.
* W przypadku braku chęci wstawiania placeholdera dane szyfrowane są za pomocą algorytmu FPE za pomocą cyfr i wielkich liter.

#### Przykładowe transformaty

<details>

<summary>Transformata anonimizacji numeru paszportu z placeholderem w przypadku, gdy dana w tabeli nie jest numerem paszportu</summary>

```json
{
  "transforms": "FieldPassport",
  "transforms.FieldPassport.type": "GdprPassportId$Value",
  "transforms.FieldPassport.fields": "passport_number",
  "transforms.FieldPassport.want.placeholder": true,
  "transforms.FieldPassport.type.settings": "passport"
}

lub 

{
  "transforms": "FieldPassport",
  "transforms.FieldPassport.type": "GdprPassportId$Value",
  "transforms.FieldPassport.fields": "passport_number",
  "transforms.FieldPassport.type.settings": "passport"
}
```

</details>

<details>

<summary>Transformata anonimizacji numeru paszportu z szyfrowaniem FPE za pomocą cyfr i wielkich liter w przypadku, gdy dana w tabeli nie jest numerem paszportu</summary>

```json
{
  "transforms": "FieldPassport",
  "transforms.FieldPassport.type": "GdprPassportId$Value",
  "transforms.FieldPassport.fields": "passport_number",
  "transforms.FieldPassport.want.placeholder": false,
  "transforms.FieldPassport.type.settings": "passport"
}
```

</details>

<details>

<summary>Transformata anonimizacji numeru dowodu osobistego z placeholderem w przypadku, gdy dana w tabeli nie jest numerem dowodu osobistego</summary>

```json
{
  "transforms": "FieldIdNumber",
  "transforms.FieldIdNumber.type": "GdprPassportId$Value",
  "transforms.FieldIdNumber.fields": "id_number",
  "transforms.FieldIdNumber.want.placeholder": true,
  "transforms.FieldIdNumber.type.settings": "id"
}

lub

{
  "transforms": "FieldIdNumber",
  "transforms.FieldIdNumber.type": "GdprPassportId$Value",
  "transforms.FieldIdNumber.fields": "id_number",
  "transforms.FieldIdNumber.type.settings": "id"
}
```

</details>

<details>

<summary>Transformata anonimizacji numeru dowodu osobistego z szyfrowaniem FPE za pomocą cyfr i wielkich liter w przypadku, gdy dana w tabeli nie jest numerem dowodu osobistego</summary>

```json
{
  "transforms": "FieldIdNumber",
  "transforms.FieldIdNumber.type": "GdprPassportId$Value",
  "transforms.FieldIdNumber.fields": "id_number",
  "transforms.FieldIdNumber.want.placeholder": false,
  "transforms.FieldIdNumber.type.settings": "id"
}
```

</details>

## 10. GDPR CreditCard

### Tabela z dostępnymi ustawieniami

<table><thead><tr><th width="249.33333333333331">Opis</th><th>Wzór</th><th>Wartość domyślna</th></tr></thead><tbody><tr><td>Nazwa pola</td><td>"transforms.&#x3C;nazwa transformaty>.fields": "&#x3C;nazwa kolumny w której znajduje się numer karty bankowej>"</td><td>BRAK</td></tr></tbody></table>

#### Uwagi dodatkowe

* W przypadku, gdy w podanym polu wartość nie jest numerem pesel wstawiane zostaje 16 zer (w przypadku przechowywania wartości w zmiennej np. bigint wstawiana jest wartość 0).

#### Przykładowa transformata

```json
{
  "transforms": "FieldCard",
  "transforms.FieldCard.type": "GdprCardNumber$Value",
  "transforms.FieldCard.fields": "credit_card"
}
```

## 11. Filter (Confluent)

### Tabela z dostępnymi ustawieniami

<table><thead><tr><th width="249.33333333333331">Opis</th><th>Wzór</th><th>Wartość domyślna</th></tr></thead><tbody><tr><td>Określa kryteria używane do filtrowania rekordów, które mają zostać uwzględnione lub wykluczone przez tę transformatę. Notacja używana do zapisu warunku filtrowania to predykat JSON Path, którego opis znajduje się w linku: https://github.com/json-path/JsonPath.</td><td>"transforms.&#x3C;nazwa transformaty>.filter.condition": "&#x3C;warunek filtrowania>"</td><td>BRAK</td></tr><tr><td>Określa akcję wykonywaną na rekordach pasujących do predykatu filter.condition. Dopuszczalne wartości to: [include, exclude]. Wartość "include", zostawia rekordy pasujące do predykatu i usuwa wszystkie rekordy, które nie spełniają predykatu. Wartość "exclude" usuwa wszystkie rekordy pasujące do predykatu.</td><td>"transforms.&#x3C;nazwa transformaty>.filter.type": "&#x3C;"include" lub "exclude">"</td><td>BRAK</td></tr><tr><td>Określa zachowanie, gdy rekord nie ma pola (pól) użytych w filter.condition. Użyj "fail", aby rzucić wyjątek i nie wykonać zadania konektora, "include", aby przepuścić rekord, lub "exclude", aby go odrzucić.</td><td>"transforms.&#x3C;nazwa transformaty>.missing.or.null.behavior": "&#x3C;"fail", "include" lub "exclude">"</td><td>fail</td></tr></tbody></table>

#### Przykładowa transformata

```json
{
  "transforms": "filterPoland",
  "transforms.filterPoland.type": "io.confluent.connect.transforms.Filter$Value",
  "transforms.filterPoland.filter.condition": "$[?(@.nation== 'Poland')]",
  "transforms.filterPoland.filter.type": "include", 
  "transforms.filterPoland.missing.or.null.behavior": "fail"
}
```

### Transformata z predykatem

```json
{
  "transforms": "filterPoland",
  "transforms.filterPoland.predicate": "IsPredicate2",
  "transforms.filterPoland.type": "io.confluent.connect.transforms.Filter$Value",
  "transforms.filterPoland.filter.condition": "$[?(@.nation== 'Poland')]",
  "transforms.filterPoland.filter.type": "include", 
  "transforms.filterPoland.missing.or.null.behavior": "fail",
  "predicates": "IsPredicate2",
  "predicates.IsPredicate2.type": "org.apache.kafka.connect.transforms.predicates.TopicNameMatches",
  "predicates.IsPredicate2.pattern": ".*client"
}
```

Powyższa transformata przedstawia użycie predykatu, który pozwala nam na filtrowanie konkretnej tabeli lub tabel. Gdy replikujemy cały schemat lub wiele tabel, które mają kolumny o takiej samej nazwie filtr zadziałałby na wszystkie tabele. Użycie predykatu typu TopicNameMatches pozwala na wskazanie jednego lub wielu topicków za pomocą regex i rozwiązuje problem filtrowania wszystkich tabel znajdujących się w naszym connectorze.

## 12.  Przykład użycia wielu transformat

<pre class="language-json"><code class="lang-json">{
  "transforms": ["FirstNameField", "LastNameField", "CompanyField",  "PhoneNumberField", "NationField", "CreditCardField", "PeselField", "EmailField", "PassportField", "PolishIdField"],

 
<strong>  "transforms.FirstNameField.type": "org.apache.kafka.connect.transforms.MaskField$Value",
</strong><strong>  "transforms.FirstNameField.fields": "first_name",
</strong>  "transforms.FirstNameField.replacement": "First Name",

  "transforms.LastNameField.type": "org.apache.kafka.connect.transforms.MaskField$Value",
  "transforms.LastNameField.fields": "last_name",
  "transforms.LastNameField.replacement": "Last Name",

  "transforms.CompanyField.type":"FpeField$Value",
  "transforms.CompanyField.key":"3677397A24432646294A404D63516654",
<strong>  "transforms.CompanyField.fields":"company",
</strong>
  "transforms.PhoneNumberField.type": "GdprPhoneNumber$Value",
  "transforms.PhoneNumberField.fields": "phone_number",

  "transforms.NationField.type":"FpeField$Value",
  "transforms.NationField.key":"3677397A24432646294A404D63516654",
  "transforms.NationField.fields":"nation",

  "transforms.CreditCardField.type": "GdprCardNumber$Value",
  "transforms.CreditCardField.fields": "credit_card",

  "transforms.PeselField.type": "GdprPesel$Value", 
  "transforms.PeselField.fields": "pesel",

  "transforms.EmailField.type": "GdprEmail$Value",
  "transforms.EmailField.fields": "adress_email",

  "transforms.PassportField.type": "GdprPassportId$Value",
  "transforms.PassportField.fields": "passport_number",
  "transforms.PassportField.type.settings": "passport",

  "transforms.PolishIdField.type": "GdprPassportId$Value",
  "transforms.PolishIdField.fields": "polish_id_number",
  "transforms.PolishIdField.type.settings": "id"
}
</code></pre>


---

# Agent Instructions: 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:

```
GET https://goldenore.gitbook.io/goldenore-cdc/moduly-goldenore-cdc/transforms-smt.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
