Split out AAAEncryptionServiceConfigurator 51/104251/3
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 5 Feb 2023 14:16:19 +0000 (15:16 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 6 Feb 2023 09:20:18 +0000 (10:20 +0100)
The configuration update bits are quite independent from the actual
configuration. This splits out the configuration update handler from
the actual service.

JIRA: AAA-250
Change-Id: Id971a57cac68293a57fc0c21e863742b38980d77
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
aaa-encrypt-service/impl/src/main/java/org/opendaylight/aaa/encrypt/impl/AAAEncryptionServiceConfigurator.java [new file with mode: 0644]
aaa-encrypt-service/impl/src/main/java/org/opendaylight/aaa/encrypt/impl/AAAEncryptionServiceImpl.java
aaa-encrypt-service/impl/src/main/java/org/opendaylight/aaa/encrypt/impl/MdsalUtils.java [deleted file]
aaa-encrypt-service/impl/src/main/resources/OSGI-INF/blueprint/encryptservice.xml
aaa-encrypt-service/impl/src/test/java/org/opendaylight/aaa/encrypt/impl/AAAEncryptServiceImplTest.java

diff --git a/aaa-encrypt-service/impl/src/main/java/org/opendaylight/aaa/encrypt/impl/AAAEncryptionServiceConfigurator.java b/aaa-encrypt-service/impl/src/main/java/org/opendaylight/aaa/encrypt/impl/AAAEncryptionServiceConfigurator.java
new file mode 100644 (file)
index 0000000..cc74718
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.aaa.encrypt.impl;
+
+import com.google.common.base.Strings;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.io.File;
+import java.io.IOException;
+import java.security.SecureRandom;
+import java.util.Base64;
+import java.util.concurrent.ExecutionException;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.CommitInfo;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.config.aaa.authn.encrypt.service.config.rev160915.AaaEncryptServiceConfig;
+import org.opendaylight.yang.gen.v1.config.aaa.authn.encrypt.service.config.rev160915.AaaEncryptServiceConfigBuilder;
+import org.opendaylight.yang.gen.v1.config.aaa.authn.encrypt.service.config.rev160915.EncryptServiceConfig;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+/**
+ * Intermediate component dealing with establishing initial configuration for {@link AAAEncryptionServiceImpl}. In
+ * particular it deals with generating and persisting of encryption salt and encryption password.
+ */
+public final class AAAEncryptionServiceConfigurator implements EncryptServiceConfig {
+    private static final Logger LOG = LoggerFactory.getLogger(AAAEncryptionServiceConfigurator.class);
+
+    // Note: this is a strong binding to Blueprint, which is loading etc/opendaylight/datastore/initial/config
+    private static final String DEFAULT_CONFIG_FILE_PATH = "etc" + File.separator + "opendaylight" + File.separator
+        + "datastore" + File.separator + "initial" + File.separator + "config" + File.separator
+        + "aaa-encrypt-service-config.xml";
+    private static final SecureRandom RANDOM = new SecureRandom();
+
+    private final EncryptServiceConfig delegate;
+
+    public AAAEncryptionServiceConfigurator(final DataBroker dataBroker,
+            final AaaEncryptServiceConfig blueprintConfig) {
+        if (Strings.isNullOrEmpty(blueprintConfig.getEncryptSalt())
+            || Strings.isNullOrEmpty(blueprintConfig.getEncryptKey())) {
+            final var generatedConfig = generateConfig(blueprintConfig);
+
+            // Update initial configuration and config datastore
+            updateEncrySrvConfig(generatedConfig.requireEncryptKey(), generatedConfig.requireEncryptSalt());
+            updateDatastore(dataBroker, generatedConfig);
+
+            delegate = generatedConfig;
+        } else {
+            delegate = blueprintConfig;
+        }
+    }
+
+    private static @NonNull AaaEncryptServiceConfig generateConfig(final EncryptServiceConfig blueprintConfig) {
+        LOG.debug("Set the Encryption service password and encrypt salt");
+        final var salt = new byte[16];
+        RANDOM.nextBytes(salt);
+
+        return new AaaEncryptServiceConfigBuilder(blueprintConfig)
+            .setEncryptKey(RandomStringUtils.random(blueprintConfig.requirePasswordLength(), true, true))
+            .setEncryptSalt(Base64.getEncoder().encodeToString(salt))
+            .build();
+    }
+
+    // FIXME: Update configuration datastore, but only if not present?! this looks weird lifecycle-wise
+    private static void updateDatastore(final DataBroker dataBroker, final @NonNull AaaEncryptServiceConfig config) {
+        final var iid = InstanceIdentifier.create(AaaEncryptServiceConfig.class);
+
+        final var tx = dataBroker.newReadWriteTransaction();
+        final var existsFuture = tx.exists(LogicalDatastoreType.CONFIGURATION, iid);
+
+        final boolean exists;
+        try {
+            exists = existsFuture.get();
+        } catch (InterruptedException | ExecutionException e) {
+            tx.cancel();
+            LOG.error("Failed to read configuration", e);
+            return;
+        }
+        if (exists) {
+            tx.cancel();
+            LOG.info("Configuration already present, skipping update");
+            return;
+        }
+
+        LOG.debug("Populating configuration: {}, {}", iid, config);
+        tx.put(LogicalDatastoreType.CONFIGURATION, iid, config);
+        // Perform the transaction.submit asynchronously
+        Futures.addCallback(tx.commit(), new FutureCallback<CommitInfo>() {
+            @Override
+            public void onFailure(final Throwable throwable) {
+                LOG.error("initDatastore: configuration data populated: {}", iid);
+            }
+
+            @Override
+            public void onSuccess(final CommitInfo result) {
+                LOG.info("initDatastore: transaction succeeded");
+            }
+        }, MoreExecutors.directExecutor());
+    }
+
+    private static void updateEncrySrvConfig(final String newPwd, final String newSalt) {
+        LOG.debug("Update encryption service config file");
+        try {
+            final File configFile = new File(DEFAULT_CONFIG_FILE_PATH);
+            if (configFile.exists()) {
+                final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(configFile);
+                final Node keyNode = doc.getElementsByTagName("encrypt-key").item(0);
+                keyNode.setTextContent(newPwd);
+                final Node salt = doc.getElementsByTagName("encrypt-salt").item(0);
+                salt.setTextContent(newSalt);
+                TransformerFactory.newInstance().newTransformer().transform(new DOMSource(doc),
+                    new StreamResult(new File(DEFAULT_CONFIG_FILE_PATH)));
+            } else {
+                LOG.warn("The encryption service config file does not exist {}", DEFAULT_CONFIG_FILE_PATH);
+            }
+        } catch (ParserConfigurationException | TransformerException | SAXException | IOException e) {
+            LOG.error("Error while updating the encryption service config file", e);
+        }
+    }
+
+    @Override
+    public Class<? extends EncryptServiceConfig> implementedInterface() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getEncryptKey() {
+        return delegate.getEncryptKey();
+    }
+
+    @Override
+    public Integer getPasswordLength() {
+        return delegate.getPasswordLength();
+    }
+
+    @Override
+    public String getEncryptSalt() {
+        return delegate.getEncryptSalt();
+    }
+
+    @Override
+    public String getEncryptMethod() {
+        return delegate.getEncryptMethod();
+    }
+
+    @Override
+    public String getEncryptType() {
+        return delegate.getEncryptType();
+    }
+
+    @Override
+    public Integer getEncryptIterationCount() {
+        return delegate.getEncryptIterationCount();
+    }
+
+    @Override
+    public Integer getEncryptKeyLength() {
+        return delegate.getEncryptKeyLength();
+    }
+
+    @Override
+    public String getCipherTransforms() {
+        return delegate.getCipherTransforms();
+    }
+}
index b6f4c11affc986ede2d18a9028b314a1c7243d48..8ffba0059bfbb70bfe1296b18abdb24bfe854a3d 100644 (file)
@@ -7,13 +7,10 @@
  */
 package org.opendaylight.aaa.encrypt.impl;
 
-import java.io.File;
-import java.io.IOException;
 import java.nio.charset.Charset;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.KeySpec;
 import java.util.Base64;
@@ -26,23 +23,10 @@ import javax.crypto.SecretKeyFactory;
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.PBEKeySpec;
 import javax.crypto.spec.SecretKeySpec;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import org.apache.commons.lang3.RandomStringUtils;
 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
-import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.yang.gen.v1.config.aaa.authn.encrypt.service.config.rev160915.AaaEncryptServiceConfig;
-import org.opendaylight.yang.gen.v1.config.aaa.authn.encrypt.service.config.rev160915.AaaEncryptServiceConfigBuilder;
+import org.opendaylight.yang.gen.v1.config.aaa.authn.encrypt.service.config.rev160915.EncryptServiceConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
 
 /**
  * Provides a basic encryption service implementation with configuration knobs.
@@ -52,38 +36,18 @@ import org.xml.sax.SAXException;
 @Deprecated
 public class AAAEncryptionServiceImpl implements AAAEncryptionService {
     private static final Logger LOG = LoggerFactory.getLogger(AAAEncryptionServiceImpl.class);
-    private static final String DEFAULT_CONFIG_FILE_PATH = "etc" + File.separator + "opendaylight" + File.separator
-            + "datastore" + File.separator + "initial" + File.separator + "config" + File.separator
-            + "aaa-encrypt-service-config.xml";
-    private static final SecureRandom RANDOM = new SecureRandom();
 
     private final SecretKey key;
     private final Cipher encryptCipher;
     private final Cipher decryptCipher;
 
-    public AAAEncryptionServiceImpl(AaaEncryptServiceConfig encrySrvConfig, final DataBroker dataBroker) {
-        if (encrySrvConfig.getEncryptSalt() == null) {
-            throw new IllegalArgumentException(
-                    "null encryptSalt in AaaEncryptServiceConfig: " + encrySrvConfig.toString());
-        }
-        if (encrySrvConfig.getEncryptKey() != null && encrySrvConfig.getEncryptKey().isEmpty()) {
-            LOG.debug("Set the Encryption service password and encrypt salt");
-            String newPwd = RandomStringUtils.random(encrySrvConfig.getPasswordLength(), true, true);
-            byte[] salt = new byte[16];
-            RANDOM.nextBytes(salt);
-            String encodedSalt = Base64.getEncoder().encodeToString(salt);
-            encrySrvConfig = new AaaEncryptServiceConfigBuilder(encrySrvConfig).setEncryptKey(newPwd)
-                    .setEncryptSalt(encodedSalt).build();
-            updateEncrySrvConfig(newPwd, encodedSalt);
-            initializeConfigDataTree(encrySrvConfig, dataBroker);
-        }
-
-        final byte[] encryptionKeySalt = Base64.getDecoder().decode(encrySrvConfig.getEncryptSalt());
+    public AAAEncryptionServiceImpl(final EncryptServiceConfig encrySrvConfig) {
+        final byte[] encryptionKeySalt = Base64.getDecoder().decode(encrySrvConfig.requireEncryptSalt());
         IvParameterSpec tempIvSpec = null;
         SecretKey tempKey = null;
         try {
             final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(encrySrvConfig.getEncryptMethod());
-            final KeySpec spec = new PBEKeySpec(encrySrvConfig.getEncryptKey().toCharArray(), encryptionKeySalt,
+            final KeySpec spec = new PBEKeySpec(encrySrvConfig.requireEncryptKey().toCharArray(), encryptionKeySalt,
                     encrySrvConfig.getEncryptIterationCount(), encrySrvConfig.getEncryptKeyLength());
             tempKey = new SecretKeySpec(keyFactory.generateSecret(spec).getEncoded(), encrySrvConfig.getEncryptType());
             tempIvSpec = new IvParameterSpec(encryptionKeySalt);
@@ -182,33 +146,4 @@ public class AAAEncryptionServiceImpl implements AAAEncryptionService {
         }
         return encryptedData;
     }
-
-    private static void updateEncrySrvConfig(final String newPwd, final String newSalt) {
-        LOG.debug("Update encryption service config file");
-        try {
-            final File configFile = new File(DEFAULT_CONFIG_FILE_PATH);
-            if (configFile.exists()) {
-                final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(configFile);
-                final Node keyNode = doc.getElementsByTagName("encrypt-key").item(0);
-                keyNode.setTextContent(newPwd);
-                final Node salt = doc.getElementsByTagName("encrypt-salt").item(0);
-                salt.setTextContent(newSalt);
-                TransformerFactory.newInstance().newTransformer().transform(new DOMSource(doc),
-                    new StreamResult(new File(DEFAULT_CONFIG_FILE_PATH)));
-            } else {
-                LOG.warn("The encryption service config file does not exist {}", DEFAULT_CONFIG_FILE_PATH);
-            }
-        } catch (ParserConfigurationException | TransformerException | SAXException | IOException e) {
-            LOG.error("Error while updating the encryption service config file", e);
-        }
-    }
-
-    private static void initializeConfigDataTree(final AaaEncryptServiceConfig encrySrvConfig,
-            final DataBroker dataBroker) {
-        if (MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
-                MdsalUtils.getEncryptionSrvConfigIid()) == null) {
-            MdsalUtils.initalizeDatastore(LogicalDatastoreType.CONFIGURATION, dataBroker,
-                    MdsalUtils.getEncryptionSrvConfigIid(), encrySrvConfig);
-        }
-    }
 }
diff --git a/aaa-encrypt-service/impl/src/main/java/org/opendaylight/aaa/encrypt/impl/MdsalUtils.java b/aaa-encrypt-service/impl/src/main/java/org/opendaylight/aaa/encrypt/impl/MdsalUtils.java
deleted file mode 100644 (file)
index ef1ee8f..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2017 Inocybe Technologies. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.aaa.encrypt.impl;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.util.Optional;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.mdsal.binding.api.ReadTransaction;
-import org.opendaylight.mdsal.binding.api.WriteTransaction;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.yang.gen.v1.config.aaa.authn.encrypt.service.config.rev160915.AaaEncryptServiceConfig;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * MdsalUtils manages all the mdsal data operation.
- *
- * @author mserngawy
- */
-public final class MdsalUtils {
-    private static final Logger LOG = LoggerFactory.getLogger(MdsalUtils.class);
-
-    private MdsalUtils() {
-
-    }
-
-    public static InstanceIdentifier<AaaEncryptServiceConfig> getEncryptionSrvConfigIid() {
-        return InstanceIdentifier.builder(AaaEncryptServiceConfig.class).build();
-    }
-
-    /**
-     * initialize the data tree for the given InstanceIdentifier type.
-     *
-     * @param type data store type
-     * @param dataBroker Mdsal data Broker
-     * @param iid InstanceIdentifier type
-     * @param object data object
-     */
-    public static <T extends DataObject> void initalizeDatastore(final LogicalDatastoreType type,
-            final DataBroker dataBroker, final InstanceIdentifier<T> iid, final T object) {
-        // Put data to MD-SAL data store
-        final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
-        transaction.put(type, iid, object);
-
-        // Perform the transaction.submit asynchronously
-        Futures.addCallback(transaction.commit(), new FutureCallback<CommitInfo>() {
-            @Override
-            public void onFailure(final Throwable throwable) {
-                LOG.error("initDatastore: transaction failed");
-            }
-
-            @Override
-            public void onSuccess(final CommitInfo result) {
-                LOG.debug("initDatastore: transaction succeeded");
-            }
-        }, MoreExecutors.directExecutor());
-        LOG.info("initDatastore: data populated: {}, {}, {}", type, iid, object);
-    }
-
-    /**
-     * Executes read as a blocking transaction.
-     *
-     * @param store {@link LogicalDatastoreType} to read
-     * @param path {@link InstanceIdentifier} for path to read
-     * @param <D> the data object type
-     * @return the result as the data object requested
-     */
-    public static <D extends org.opendaylight.yangtools.yang.binding.DataObject> D read(
-            final DataBroker dataBroker, final LogicalDatastoreType store, final InstanceIdentifier<D> path)  {
-        try (ReadTransaction transaction = dataBroker.newReadOnlyTransaction()) {
-            Optional<D> optionalDataObject = transaction.read(store, path).get();
-            if (optionalDataObject.isPresent()) {
-                return optionalDataObject.get();
-            }
-        } catch (InterruptedException | ExecutionException e) {
-            LOG.warn("Failed to read {} ", path, e);
-        }
-
-        return null;
-    }
-}
index 36c2471040c3d13aab4bf339394e51d77fff89a0..800ef51a2936092e658bbda8f08fba1a433f0a0f 100644 (file)
@@ -1,18 +1,20 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
-                 xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0">
-
+           xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0">
   <reference id="dataBroker" interface="org.opendaylight.mdsal.binding.api.DataBroker"/>
 
   <odl:clustered-app-config id="encryptConfig" default-config-file-name="aaa-encrypt-service-config.xml"
         binding-class="org.opendaylight.yang.gen.v1.config.aaa.authn.encrypt.service.config.rev160915.AaaEncryptServiceConfig">
   </odl:clustered-app-config>
 
-  <bean id="encryptService" class="org.opendaylight.aaa.encrypt.impl.AAAEncryptionServiceImpl">
-    <argument ref="encryptConfig"/>
+  <bean id="encryptServiceConfigurator" class="org.opendaylight.aaa.encrypt.impl.AAAEncryptionServiceConfigurator">
     <argument ref="dataBroker"/>
+    <argument ref="encryptConfig"/>
   </bean>
 
+  <bean id="encryptService" class="org.opendaylight.aaa.encrypt.impl.AAAEncryptionServiceImpl">
+    <argument ref="encryptServiceConfigurator"/>
+  </bean>
   <service ref="encryptService" interface="org.opendaylight.aaa.encrypt.AAAEncryptionService"/>
 
 </blueprint>
index fd558b8413719973018a5c4c936851bfebce8914..f04fb96cc61b2a3354c3f1d19ca2fd7e121521d7 100644 (file)
@@ -7,19 +7,17 @@
  */
 package org.opendaylight.aaa.encrypt.impl;
 
-import static org.mockito.ArgumentMatchers.any;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 
-import java.util.Optional;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.mdsal.binding.api.ReadTransaction;
+import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.yang.gen.v1.config.aaa.authn.encrypt.service.config.rev160915.AaaEncryptServiceConfig;
 import org.opendaylight.yang.gen.v1.config.aaa.authn.encrypt.service.config.rev160915.AaaEncryptServiceConfigBuilder;
@@ -32,41 +30,42 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 @Deprecated
 @RunWith(MockitoJUnitRunner.StrictStubs.class)
 public class AAAEncryptServiceImplTest {
-
-    private AAAEncryptionServiceImpl impl;
     @Mock
     private DataBroker dataBroker;
+    @Mock
+    private ReadWriteTransaction tx;
+
+    private AAAEncryptionServiceImpl impl;
 
     @Before
     public void setup() {
-        AaaEncryptServiceConfig module = new AaaEncryptServiceConfigBuilder()
+        final var module = new AaaEncryptServiceConfigBuilder()
                 .setCipherTransforms("AES/CBC/PKCS5Padding").setEncryptIterationCount(32768).setEncryptKey("")
                 .setEncryptKeyLength(128).setEncryptMethod("PBKDF2WithHmacSHA1").setEncryptSalt("")
                 .setEncryptType("AES").setPasswordLength(12).build();
 
-        final ReadTransaction rtx = mock(ReadTransaction.class);
-        doReturn(rtx).when(dataBroker).newReadOnlyTransaction();
-        doReturn(FluentFutures.immediateFluentFuture(Optional.of(module))).when(rtx).read(
-            any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+        doReturn(tx).when(dataBroker).newReadWriteTransaction();
+        doReturn(FluentFutures.immediateTrueFluentFuture()).when(tx)
+            .exists(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(AaaEncryptServiceConfig.class));
 
-        impl = new AAAEncryptionServiceImpl(module, dataBroker);
+        impl = new AAAEncryptionServiceImpl(new AAAEncryptionServiceConfigurator(dataBroker, module));
     }
 
     @Test
     public void testShortString() {
         String before = "shortone";
         String encrypt = impl.encrypt(before);
-        Assert.assertNotEquals(before, encrypt);
+        assertNotEquals(before, encrypt);
         String after = impl.decrypt(encrypt);
-        Assert.assertEquals(before, after);
+        assertEquals(before, after);
     }
 
     @Test
     public void testLongString() {
         String before = "This is a very long string to encrypt for testing 1...2...3";
         String encrypt = impl.encrypt(before);
-        Assert.assertNotEquals(before, encrypt);
+        assertNotEquals(before, encrypt);
         String after = impl.decrypt(encrypt);
-        Assert.assertEquals(before, after);
+        assertEquals(before, after);
     }
 }