All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.otto.edison.togglz.mongo.MongoTogglzRepository Maven / Gradle / Ivy

package de.otto.edison.togglz.mongo;

import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import de.otto.edison.mongo.AbstractMongoRepository;
import de.otto.edison.mongo.configuration.MongoProperties;
import de.otto.edison.togglz.FeatureClassProvider;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.togglz.core.Feature;
import org.togglz.core.repository.FeatureState;
import org.togglz.core.repository.StateRepository;
import org.togglz.core.user.UserProvider;

import java.util.Map;
import java.util.Optional;

import static org.springframework.util.ObjectUtils.isEmpty;

@ConditionalOnMissingBean(StateRepository.class)
public class MongoTogglzRepository extends AbstractMongoRepository implements StateRepository {

    private static final Logger LOG = LoggerFactory.getLogger(MongoTogglzRepository.class);

    private static final String NAME = "_id";
    private static final String ENABLED = "enabled";
    private static final String STRATEGY = "strategy";
    private static final String PARAMETERS = "parameters";

    private final MongoCollection collection;
    private final FeatureClassProvider featureClassProvider;
    private final UserProvider userProvider;

    public MongoTogglzRepository(final MongoDatabase mongoDatabase,
                                 final FeatureClassProvider featureClassProvider,
                                 final UserProvider userProvider,
                                 final MongoProperties mongoProperties) {
        super(mongoProperties);
        this.featureClassProvider = featureClassProvider;
        this.collection = mongoDatabase.getCollection("togglz");
        this.userProvider = userProvider;
    }

    /**
     * Get the persisted state of a feature from the repository. If the repository doesn't contain any information regarding
     * this feature it must return null.
     *
     * @param feature The feature to read the state for
     * @return The persisted feature state or null
     */
    @Override
    public FeatureState getFeatureState(final Feature feature) {
        final Optional featureState = findOne(feature.name());
        return featureState.orElse(null);

    }

    /**
     * Persist the supplied feature state. The repository implementation must ensure that subsequent calls to
     * {@link #getFeatureState(Feature)} return the same state as persisted using this method.
     *
     * @param featureState The feature state to persist
     * @throws UnsupportedOperationException if this state repository does not support updates
     */
    @Override
    public void setFeatureState(final FeatureState featureState) {
        createOrUpdate(featureState);
        LOG.info((!isEmpty(userProvider.getCurrentUser().getName()) ? "User '" + userProvider.getCurrentUser().getName() + "'" : "Unknown user")
                + (featureState.isEnabled() ? " enabled " : " disabled ") + "feature " + featureState.getFeature().name());
    }

    @Override
    protected MongoCollection collection() {
        return collection;
    }

    @Override
    protected String keyOf(final FeatureState value) {
        return value.getFeature().name();
    }

    @Override
    protected Document encode(final FeatureState value) {
        final Document document = new Document();

        document.append(NAME, value.getFeature().name());
        document.append(ENABLED, value.isEnabled());
        document.append(STRATEGY, value.getStrategyId());
        document.append(PARAMETERS, value.getParameterMap());

        return document;
    }

    @Override
    @SuppressWarnings("unchecked")
    protected FeatureState decode(final Document document) {
        final String name = document.getString(NAME);
        final Boolean enabled = document.getBoolean(ENABLED);
        final String strategy = document.getString(STRATEGY);
        final Map parameters = document.get(PARAMETERS, Map.class);

        final FeatureState featureState = new FeatureState(resolveEnumValue(name));
        featureState.setEnabled(enabled);
        featureState.setStrategyId(strategy);
        for (final Map.Entry parameter : parameters.entrySet()) {
            featureState.setParameter(parameter.getKey(), parameter.getValue());
        }

        return featureState;
    }

    @Override
    protected void ensureIndexes() {
        // no indices
    }

    @SuppressWarnings({"unchecked", "rawtypes"})
    private Feature resolveEnumValue(final String name) {
        final Class enumType = featureClassProvider.getFeatureClass();
        return (Feature) Enum.valueOf(enumType, name);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy