# Obfuscation API

## API

To extend beyond the available obfuscation implementations the below interface is provided for developers to build and deploy new types.

The key method to be implemented is `obfuscate`.&#x20;

```java
/**
 * Base obfuscationType class type
 */
public interface ObfuscationType<T> extends CustomUserType {
    T obfuscate(Object value) throws ObfuscationException;

    default void validate() throws InvalidSpecificationException{}
}
```

## Reference example

Below is a reference implementation of the `date bucketing` feature.

```java
package com.fractalworks.streams.processors.obfuscation.types;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;
import com.fractalworks.streams.core.exceptions.InvalidSpecificationException;
import com.fractalworks.streams.processors.obfuscation.ObfuscationException;
import com.fractalworks.streams.processors.obfuscation.ObfuscationType;
import com.google.common.base.Objects;
import org.joda.time.DateTime;

import java.security.SecureRandom;

@JsonRootName(value = "date bucketing")
public class DateVarianceObfuscationType implements ObfuscationType<DateTime> {

    @JsonIgnore
    private final SecureRandom randomGenerator = new SecureRandom();

    private int variance = 120;

    public CustomVarianceObfuscationType() {
        // Required default constructor
    }

    @Override
    public DateTime obfuscate(Object value) throws ObfuscationException {
        if(value instanceof DateTime dateTimeValue){
            int days;
            do {
                days = (randomGenerator.nextInt() % variance);
            } while (days == 0);
            return (randomGenerator.nextBoolean() ? dateTimeValue.plusDays(days).plusMinutes(randomGenerator.nextInt() % variance) : dateTimeValue.minusDays(days).minusMinutes(randomGenerator.nextInt() % variance));
        } else
            throw new ObfuscationException("Passed data type is not supported for this function.");
    }

    public int getVariance() {
        return variance;
    }

    @JsonProperty(value = "variance")
    public void setVariance(int variance) {
        this.variance = variance;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DateVarianceObfuscationType that = (DateVarianceObfuscationType) o;
        return variance == that.variance && Objects.equal(randomGenerator, that.randomGenerator);
    }

    @Override
    public void validate() throws InvalidSpecificationException {
        if( variance <=0){
            throw new InvalidSpecificationException("Invalid variance. Must be greater than zero");
        }
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(randomGenerator, variance);
    }
}
```


---

# 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://docs.fractalworks.io/joule/developer-guides/builder-sdk/transformation-api/obfuscation-api.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.
