FeatureFlagsFF4j.java
package org.europa.together.application;
import java.io.IOException;
import java.net.ConnectException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.dbcp2.BasicDataSource;
import org.europa.together.business.ConfigurationDAO;
import org.europa.together.business.CryptoTools;
import org.europa.together.business.FeatureFlags;
import org.europa.together.business.Logger;
import org.europa.together.business.PropertyReader;
import org.europa.together.domain.ConfigurationDO;
import org.europa.together.domain.HashAlgorithm;
import org.europa.together.domain.LogLevel;
import org.europa.together.exceptions.MisconfigurationException;
import org.europa.together.utils.Constraints;
import org.europa.together.utils.StringUtils;
import org.ff4j.FF4j;
import org.ff4j.audit.repository.JdbcEventRepository;
import org.ff4j.core.Feature;
import org.ff4j.property.store.JdbcPropertyStore;
import org.ff4j.store.JdbcFeatureStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
/**
* Implementation of feature toggels.
*/
@Repository
public class FeatureFlagsFF4j implements FeatureFlags {
private static final long serialVersionUID = 13L;
private static final Logger LOGGER = new LogbackLogger(FeatureFlagsFF4j.class);
@Autowired
private ConfigurationDAO configurationDAO;
@Autowired
private CryptoTools cryptoTools;
@Autowired
private PropertyReader reader;
private FF4j ff4j;
private Map<String, String> configuration;
/**
* Constructor.
*/
public FeatureFlagsFF4j() {
LOGGER.log("instance class", LogLevel.INFO);
configuration = new HashMap<>();
}
@Override
public FF4j getFeatureStore(final String propertyFile)
throws IOException, ConnectException, MisconfigurationException {
loadConfigurationFromDatabase();
if (Boolean.parseBoolean(configuration.get("ff.activation"))) {
reader.appendPropertiesFromClasspath(propertyFile);
BasicDataSource cpds = new BasicDataSource();
cpds.setDriverClassName(reader.getPropertyAsString("jdbc.driverClassName"));
cpds.setUrl(reader.getPropertyAsString("jdbc.url"));
cpds.setUsername(reader.getPropertyAsString("jdbc.user"));
cpds.setPassword(reader.getPropertyAsString("jdbc.password"));
ff4j = new FF4j();
ff4j.setFeatureStore(new JdbcFeatureStore(cpds));
ff4j.setPropertiesStore(new JdbcPropertyStore(cpds));
ff4j.setEventRepository(new JdbcEventRepository(cpds));
ff4j.audit(Boolean.parseBoolean(configuration.get("ff.audit")));
ff4j.autoCreate(Boolean.parseBoolean(configuration.get("ff.autocreate")));
} else {
String message = "Feature Flags are deactivated by database configuration";
throw new MisconfigurationException(message);
}
return ff4j.audit();
}
@Override
public boolean check(final String featureId) {
return ff4j.check(featureId);
}
@Override
public void activateFeature(final String featureId) {
ff4j.enable(featureId);
}
@Override
public void deactivateFeature(final String featureId) {
ff4j.disable(featureId);
}
@Override
public void addFeature(final Feature feature) {
ff4j.createFeature(feature);
}
@Override
public Feature getFeature(final String featureId) {
return ff4j.getFeature(featureId);
}
@Override
public void updateFeature(final Feature feature) {
if (ff4j.exist(feature.getUid())) {
ff4j.delete(feature.getUid());
}
ff4j.createFeature(feature);
}
@Override
public void removeFeature(final String featureId) {
ff4j.delete(featureId);
}
@Override
public Map<String, Feature> listAllFeatures() {
return ff4j.getFeatures();
}
private void loadConfigurationFromDatabase() throws ConnectException {
LOGGER.log("Load all configuration sets of: " + CONFIG_SET
+ " - Version: " + CONFIG_VERSION
+ " - Module: " + Constraints.MODULE_NAME, LogLevel.DEBUG);
List<ConfigurationDO> configurationEntries
= configurationDAO.getAllConfigurationSetEntries(Constraints.MODULE_NAME,
CONFIG_VERSION, CONFIG_SET);
if (!configurationEntries.isEmpty()) {
LOGGER.log("Size of config SET: " + configurationEntries.size(), LogLevel.DEBUG);
for (ConfigurationDO entry : configurationEntries) {
String value;
if (StringUtils.isEmpty(entry.getValue())) {
value = entry.getDefaultValue();
} else {
value = entry.getValue();
}
if (entry.getKey()
.equals(cryptoTools.calculateHash("ff.activation",
HashAlgorithm.SHA256))) {
this.configuration.put("ff.activation", value);
} else if (entry.getKey()
.equals(cryptoTools.calculateHash("ff.audit",
HashAlgorithm.SHA256))) {
this.configuration.put("ff.audit", value);
} else if (entry.getKey()
.equals(cryptoTools.calculateHash("ff.autocreate",
HashAlgorithm.SHA256))) {
this.configuration.put("ff.autocreate", value);
}
}
} else {
throw new ConnectException("Feature Flags can't access the configuration.");
}
}
}