[ONOS-6703] ComponentConfigService gRPC and unit tests

Change-Id: I508fcfc36e0619a69f6b479fdedb0fb36babad08
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/cfg/ConfigPropertyEnumsProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/cfg/ConfigPropertyEnumsProtoTranslator.java
new file mode 100644
index 0000000..d08e2fa
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/cfg/ConfigPropertyEnumsProtoTranslator.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.protobuf.models.cfg;
+
+import org.onosproject.cfg.ConfigProperty.Type;
+import org.onosproject.grpc.cfg.models.ConfigPropertyEnumsProto.ConfigPropertyTypeProto;
+
+/**
+ * gRPC ConfigProperty.Type message to equivalent ONOS enum conversion related utilities.
+ */
+public final class ConfigPropertyEnumsProtoTranslator {
+
+    /**
+     * Translates gRPC ConfigProperty type to {@link Type}.
+     *
+     * @param configPropertyTypeProto config Property proto type
+     * @return {@link Type}
+     */
+    public static Type translate(ConfigPropertyTypeProto configPropertyTypeProto) {
+
+        return Type.valueOf(configPropertyTypeProto.name());
+    }
+
+    /**
+     * Translates {@link Type} to gRPC ConfigProperty type.
+     *
+     * @param type config Property type
+     * @return gRPC ConfigProperty type
+     */
+    public static ConfigPropertyTypeProto translate(Type type) {
+
+        return ConfigPropertyTypeProto.valueOf(type.name());
+    }
+
+    // Utility class not intended for instantiation.
+    private ConfigPropertyEnumsProtoTranslator() {}
+}
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/cfg/ConfigPropertyProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/cfg/ConfigPropertyProtoTranslator.java
new file mode 100644
index 0000000..ecf9baf
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/cfg/ConfigPropertyProtoTranslator.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.protobuf.models.cfg;
+
+import org.onosproject.cfg.ConfigProperty;
+import org.onosproject.grpc.cfg.models.ConfigPropertyProtoOuterClass.ConfigPropertyProto;
+
+/**
+ * gRPC ConfigPropertyProto message to equivalent ONOS ConfigProperty conversion related utilities.
+ */
+public final class ConfigPropertyProtoTranslator {
+
+    /**
+     * Translates gRPC ConfigProperty message to {@link ConfigProperty}.
+     *
+     * @param configPropertyProto gRPC message
+     * @return {@link ConfigProperty}
+     */
+    public static ConfigProperty translate(ConfigPropertyProto configPropertyProto) {
+
+        ConfigProperty configProperty = ConfigProperty.defineProperty(configPropertyProto.getName(),
+                                                                      ConfigPropertyEnumsProtoTranslator
+                                                                              .translate(configPropertyProto
+                                                                                                 .getType()),
+                                                                      configPropertyProto.getDefaultValue(),
+                                                                      configPropertyProto.getDescriptionBytes()
+                                                                              .toString());
+        return ConfigProperty.setProperty(configProperty, configPropertyProto.getValue());
+    }
+
+    /**
+     * Translates {@link ConfigProperty} to gRPC ConfigProperty message.
+     *
+     * @param configProperty config property
+     * @return gRPC ConfigProperty message
+     */
+    public static ConfigPropertyProto translate(ConfigProperty configProperty) {
+
+        if (configProperty != null) {
+            return ConfigPropertyProto.newBuilder()
+                    .setName(configProperty.name())
+                    .setType(ConfigPropertyEnumsProtoTranslator.translate(configProperty.type()))
+                    .setDefaultValue(configProperty.defaultValue())
+                    .setDescription(configProperty.description())
+                    .setValue(configProperty.value())
+                    .build();
+        }
+
+        return ConfigPropertyProto.getDefaultInstance();
+    }
+
+    // Utility class not intended for instantiation.
+    private ConfigPropertyProtoTranslator() {}
+}
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/cfg/package-info.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/cfg/package-info.java
new file mode 100644
index 0000000..b0ea47d
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/cfg/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Utilities to handle ProtoBuf version of ONOS network models.
+ */
+package org.onosproject.incubator.protobuf.models.cfg;
\ No newline at end of file
diff --git a/incubator/protobuf/services/nb/src/main/java/org/onosproject/grpc/nb/package-info.java b/incubator/protobuf/services/nb/src/main/java/org/onosproject/grpc/nb/package-info.java
new file mode 100644
index 0000000..9701cab
--- /dev/null
+++ b/incubator/protobuf/services/nb/src/main/java/org/onosproject/grpc/nb/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * gRPC server implementations for northbound services.
+ */
+package org.onosproject.grpc.nb;
\ No newline at end of file
diff --git a/incubator/protobuf/services/nb/src/main/java/org/onosproject/incubator/protobuf/services/nb/GrpcNbComponentConfigService.java b/incubator/protobuf/services/nb/src/main/java/org/onosproject/incubator/protobuf/services/nb/GrpcNbComponentConfigService.java
new file mode 100644
index 0000000..8e0c2dd
--- /dev/null
+++ b/incubator/protobuf/services/nb/src/main/java/org/onosproject/incubator/protobuf/services/nb/GrpcNbComponentConfigService.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.protobuf.services.nb;
+
+import com.google.common.annotations.Beta;
+import io.grpc.BindableService;
+import io.grpc.stub.StreamObserver;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.incubator.protobuf.models.cfg.ConfigPropertyProtoTranslator;
+import org.onosproject.protobuf.api.GrpcServiceRegistry;
+import org.slf4j.Logger;
+
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceGrpc.ComponentConfigServiceImplBase;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.getComponentNamesRequest;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.getComponentNamesReply;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.registerPropertiesRequest;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.registerPropertiesReply;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.unregisterPropertiesRequest;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.unregisterPropertiesReply;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.getPropertiesRequest;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.getPropertiesReply;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.setPropertyRequest;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.setPropertyReply;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.preSetPropertyRequest;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.preSetPropertyReply;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.unsetPropertyRequest;
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.unsetPropertyReply;
+import static org.slf4j.LoggerFactory.getLogger;
+
+
+/**
+ * A server that provides access to the methods exposed by {@link ComponentConfigService}.
+ */
+@Beta
+@Component(immediate = true)
+public class GrpcNbComponentConfigService {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected GrpcServiceRegistry registry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentConfigService componentConfigService;
+
+    private static ComponentConfigServiceNbServerInternal instance = null;
+
+    @Activate
+    public void activate() {
+
+        registry.register(getInnerInstance());
+        log.info("Started.");
+    }
+
+    @Deactivate
+    public void deactivate() {
+
+        registry.unregister(getInnerInstance());
+        log.info("Stopped");
+    }
+
+    /**
+     * Register ComponentConfig Service, Used for unit testing purposes.
+     *
+     * @return An instance of binding ComponentConfig service
+     */
+    public InProcessServer<BindableService> registerInProcessServer() {
+        InProcessServer<BindableService> inprocessServer =
+                new InProcessServer(ComponentConfigServiceNbServerInternal.class);
+        inprocessServer.addServiceToBind(getInnerInstance());
+
+        return inprocessServer;
+    }
+
+    private final class ComponentConfigServiceNbServerInternal extends ComponentConfigServiceImplBase {
+
+        private ComponentConfigServiceNbServerInternal() {
+            super();
+        }
+
+        @Override
+        public void getComponentNames(getComponentNamesRequest request,
+                                      StreamObserver<getComponentNamesReply> responseObserver) {
+
+            getComponentNamesReply.Builder replyBuilder = getComponentNamesReply.newBuilder();
+
+            componentConfigService.getComponentNames().forEach(n -> replyBuilder.addNames(n));
+            responseObserver.onNext(replyBuilder.build());
+            responseObserver.onCompleted();
+        }
+
+        @Override
+        public void registerProperties(registerPropertiesRequest request,
+                                       StreamObserver<registerPropertiesReply> responseObserver) {
+
+            try {
+                componentConfigService.registerProperties(Class.forName(request.getComponentClass()));
+                responseObserver.onNext(registerPropertiesReply.getDefaultInstance());
+                responseObserver.onCompleted();
+            } catch (ClassNotFoundException e) {
+                responseObserver.onError(e);
+            }
+        }
+
+        @Override
+        public void unregisterProperties(unregisterPropertiesRequest request,
+                                         StreamObserver<unregisterPropertiesReply> responseObserver) {
+
+            try {
+                componentConfigService.unregisterProperties(Class.forName(request.getComponentClass()),
+                                                            request.getClear());
+                responseObserver.onNext(unregisterPropertiesReply.getDefaultInstance());
+                responseObserver.onCompleted();
+            } catch (ClassNotFoundException e) {
+                responseObserver.onError(e);
+            }
+        }
+
+        @Override
+        public void getProperties(getPropertiesRequest request, StreamObserver<getPropertiesReply> responseObserver) {
+
+            getPropertiesReply.Builder replyBuilder = getPropertiesReply.newBuilder();
+
+            componentConfigService.getProperties(request.getComponentName())
+                    .forEach(n -> replyBuilder.addConfigProperties(ConfigPropertyProtoTranslator.translate(n)));
+            responseObserver.onNext(replyBuilder.build());
+            responseObserver.onCompleted();
+        }
+
+        @Override
+        public void setProperty(setPropertyRequest request, StreamObserver<setPropertyReply> responseObserver) {
+
+            componentConfigService.setProperty(request.getComponentName(), request.getName(), request.getValue());
+            responseObserver.onNext(setPropertyReply.getDefaultInstance());
+            responseObserver.onCompleted();
+        }
+
+        @Override
+        public void preSetProperty(preSetPropertyRequest request,
+                                   StreamObserver<preSetPropertyReply> responseObserver) {
+
+            componentConfigService.preSetProperty(request.getComponentName(), request.getName(), request.getValue());
+            responseObserver.onNext(preSetPropertyReply.getDefaultInstance());
+            responseObserver.onCompleted();
+        }
+
+        @Override
+        public void unsetProperty(unsetPropertyRequest request, StreamObserver<unsetPropertyReply> responseObserver) {
+
+            componentConfigService.unsetProperty(request.getComponentName(), request.getName());
+            responseObserver.onNext(unsetPropertyReply.getDefaultInstance());
+            responseObserver.onCompleted();
+        }
+    }
+
+    private ComponentConfigServiceNbServerInternal getInnerInstance() {
+        if (instance == null) {
+            instance = new ComponentConfigServiceNbServerInternal();
+        }
+        return instance;
+    }
+}
diff --git a/incubator/protobuf/services/nb/src/test/java/org/onosproject/incubator/protobuf/services/nb/InProcessServer.java b/incubator/protobuf/services/nb/src/main/java/org/onosproject/incubator/protobuf/services/nb/InProcessServer.java
similarity index 100%
rename from incubator/protobuf/services/nb/src/test/java/org/onosproject/incubator/protobuf/services/nb/InProcessServer.java
rename to incubator/protobuf/services/nb/src/main/java/org/onosproject/incubator/protobuf/services/nb/InProcessServer.java
diff --git a/incubator/protobuf/services/nb/src/main/proto/cfg/ComponentConfigServiceNb.proto b/incubator/protobuf/services/nb/src/main/proto/cfg/ComponentConfigServiceNb.proto
new file mode 100644
index 0000000..3cc4e1c
--- /dev/null
+++ b/incubator/protobuf/services/nb/src/main/proto/cfg/ComponentConfigServiceNb.proto
@@ -0,0 +1,72 @@
+syntax="proto3";
+option java_package = "org.onosproject.grpc.nb.cfg";
+
+package nb.cfg;
+
+import "cfg/ConfigPropertyProto.proto";
+
+message getComponentNamesRequest {
+}
+
+message getComponentNamesReply {
+    repeated string names = 1;
+}
+
+message registerPropertiesRequest {
+    string component_class = 1;
+}
+
+message registerPropertiesReply {
+}
+
+message unregisterPropertiesRequest {
+    string component_class = 1;
+    bool clear = 2;
+}
+
+message unregisterPropertiesReply {
+}
+
+message getPropertiesRequest {
+    string component_name = 1;
+}
+
+message getPropertiesReply {
+    repeated .cfg.ConfigPropertyProto config_properties = 1;
+}
+
+message setPropertyRequest {
+    string component_name = 1;
+    string name = 2;
+    string value = 3;
+}
+
+message setPropertyReply {
+}
+
+message preSetPropertyRequest {
+    string component_name = 1;
+    string name = 2;
+    string value = 3;
+}
+
+message preSetPropertyReply {
+}
+
+message unsetPropertyRequest {
+    string component_name = 1;
+    string name = 2;
+}
+
+message unsetPropertyReply {
+}
+
+service ComponentConfigService {
+    rpc getComponentNames(getComponentNamesRequest) returns (getComponentNamesReply) {}
+    rpc registerProperties(registerPropertiesRequest) returns (registerPropertiesReply) {}
+    rpc unregisterProperties(unregisterPropertiesRequest) returns (unregisterPropertiesReply) {}
+    rpc getProperties(getPropertiesRequest) returns (getPropertiesReply) {}
+    rpc setProperty(setPropertyRequest) returns (setPropertyReply) {}
+    rpc preSetProperty(preSetPropertyRequest) returns (preSetPropertyReply) {}
+    rpc unsetProperty(unsetPropertyRequest) returns (unsetPropertyReply) {}
+}
\ No newline at end of file
diff --git a/incubator/protobuf/services/nb/src/test/java/org/onosproject/incubator/protobuf/services/nb/GrpcNbComponentConfigServiceTest.java b/incubator/protobuf/services/nb/src/test/java/org/onosproject/incubator/protobuf/services/nb/GrpcNbComponentConfigServiceTest.java
new file mode 100644
index 0000000..011de5a
--- /dev/null
+++ b/incubator/protobuf/services/nb/src/test/java/org/onosproject/incubator/protobuf/services/nb/GrpcNbComponentConfigServiceTest.java
@@ -0,0 +1,277 @@
+/*
+* Copyright 2017-present Open Networking Foundation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package org.onosproject.incubator.protobuf.services.nb;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import io.grpc.BindableService;
+import io.grpc.ManagedChannel;
+import io.grpc.inprocess.InProcessChannelBuilder;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.cfg.ConfigProperty;
+import org.onosproject.grpc.cfg.models.ConfigPropertyProtoOuterClass;
+import org.onosproject.grpc.nb.cfg.ComponentConfigServiceGrpc;
+import org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb;
+import org.onosproject.grpc.nb.cfg.ComponentConfigServiceGrpc.ComponentConfigServiceBlockingStub;
+import org.onosproject.incubator.protobuf.models.cfg.ConfigPropertyProtoTranslator;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.onosproject.grpc.nb.cfg.ComponentConfigServiceNb.*;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.cfg.ConfigProperty.Type.STRING;
+
+/**
+ * Unit tests of gRPC northbound component config service.
+ */
+public class GrpcNbComponentConfigServiceTest {
+
+    private static InProcessServer<BindableService> inprocessServer;
+    private static ComponentConfigServiceBlockingStub blockingStub;
+    private static ManagedChannel channel;
+
+    private static Set<String> componentNames = new HashSet<>();
+    private static final Map<String, ConfigProperty> PROPERTY_MAP = Maps.newConcurrentMap();
+    private static final Map<String, ConfigProperty> PROPERTY_MAP1 = Maps.newConcurrentMap();
+    private static final Map<String, String> STRING_MAP = Maps.newConcurrentMap();
+    private static final Map<String, String> STRING_MAP1 = Maps.newConcurrentMap();
+    private static final Map<String, String> STRING_MAP2 = Maps.newConcurrentMap();
+    private static final ComponentConfigService MOCK_COMPONENTCONFIG = new MockComponentConfigService();
+    private static final String COMPONENTCONFIGNAME = "org.onosprject.test";
+    private static final String COMPONENTCONFIGNAME1 = "org.onosprject.test1";
+    private static final String COMPONENTCONFIGNAME2 = "org.onosprject.test2";
+    private static final String PROPERTY_TEST_KEY = COMPONENTCONFIGNAME + "#" + "test";
+    private static final ConfigProperty C1 = ConfigProperty.defineProperty("foo", STRING, "dingo", "FOO");
+    private static final ConfigProperty C2 = ConfigProperty.defineProperty("bar", STRING, "bat", "BAR");
+
+    public GrpcNbComponentConfigServiceTest() {}
+
+    private static void populateComponentNames() {
+
+        componentNames.add(COMPONENTCONFIGNAME);
+        componentNames.add(COMPONENTCONFIGNAME1);
+        componentNames.add(COMPONENTCONFIGNAME2);
+        PROPERTY_MAP1.put(COMPONENTCONFIGNAME, C1);
+        STRING_MAP2.put(PROPERTY_TEST_KEY, "true");
+    }
+
+    /**
+     * Tests gRPC getComponentNames interface.
+     */
+    @Test
+    public void testGetComponentNames() throws InterruptedException {
+        getComponentNamesRequest request = ComponentConfigServiceNb.getComponentNamesRequest.getDefaultInstance();
+        getComponentNamesReply reply;
+
+        try {
+            reply = blockingStub.getComponentNames(request);
+            assertTrue(componentNames.size() == reply.getNamesCount());
+
+            Set expectedNames = Collections.emptySet();
+            expectedNames.addAll(componentNames);
+            assertTrue(reply.equals(expectedNames));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Tests gRPC registerProperties interface.
+     */
+    @Test
+    public void testRegisterProperties() throws InterruptedException {
+        registerPropertiesRequest request = ComponentConfigServiceNb.registerPropertiesRequest
+                .newBuilder().setComponentClass(COMPONENTCONFIGNAME).build();
+
+        try {
+            blockingStub.registerProperties(request);
+            assertTrue(PROPERTY_MAP.get(COMPONENTCONFIGNAME).equals(C1));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Tests gRPC unregisterProperties interface.
+     */
+    @Test
+    public void testUnregisterProperties() throws InterruptedException {
+        unregisterPropertiesRequest request = ComponentConfigServiceNb.unregisterPropertiesRequest
+                .newBuilder().setComponentClass(COMPONENTCONFIGNAME).build();
+
+        try {
+            blockingStub.unregisterProperties(request);
+            assertTrue(PROPERTY_MAP1.get(COMPONENTCONFIGNAME) == null);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Tests gRPC getProperty interface.
+     */
+    @Test
+    public void tesGetProperties() throws InterruptedException {
+        getPropertiesRequest request = ComponentConfigServiceNb.getPropertiesRequest.newBuilder()
+                .setComponentName(COMPONENTCONFIGNAME).build();
+        getPropertiesReply reply;
+
+        try {
+            reply = blockingStub.getProperties(request);
+
+            Set<ConfigProperty> configProperties = new HashSet<>();
+            for (ConfigPropertyProtoOuterClass.ConfigPropertyProto cfg : reply.getConfigPropertiesList()) {
+                configProperties.add(ConfigPropertyProtoTranslator.translate(cfg));
+            }
+
+            assertTrue(configProperties.equals(ImmutableSet.of(C1, C2)));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Tests gRPC setProperty interface.
+     */
+    @Test
+    public void testSetProperty() throws InterruptedException {
+        setPropertyRequest request = ComponentConfigServiceNb.setPropertyRequest.newBuilder()
+                .setComponentName(COMPONENTCONFIGNAME)
+                .setName("test")
+                .setValue("true")
+                .build();
+
+        try {
+            blockingStub.setProperty(request);
+            assertTrue(STRING_MAP.get(PROPERTY_TEST_KEY).equals("true"));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Tests gRPC preSetProperty interface.
+     */
+    @Test
+    public void testPreSetProperty() throws InterruptedException {
+        preSetPropertyRequest request = ComponentConfigServiceNb.preSetPropertyRequest.newBuilder()
+                .setComponentName(COMPONENTCONFIGNAME)
+                .setName("test")
+                .setValue("true")
+                .build();
+
+        try {
+            blockingStub.preSetProperty(request);
+            assertTrue(STRING_MAP1.get(PROPERTY_TEST_KEY).equals("true"));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Tests gRPC unsetProperty interface.
+     */
+    @Test
+    public void testUnsetProperty() throws InterruptedException {
+        unsetPropertyRequest request = ComponentConfigServiceNb.unsetPropertyRequest.newBuilder()
+                .setComponentName(COMPONENTCONFIGNAME)
+                .setName("test")
+                .build();
+
+        try {
+            blockingStub.unsetProperty(request);
+            assertTrue(STRING_MAP2.get(PROPERTY_TEST_KEY) == null);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Initialization before start testing gRPC northbound component config service.
+     */
+    @BeforeClass
+    public static void beforeClass() throws InstantiationException, IllegalAccessException, IOException {
+        GrpcNbComponentConfigService componentConfigService = new GrpcNbComponentConfigService();
+        componentConfigService.componentConfigService = MOCK_COMPONENTCONFIG;
+        inprocessServer = componentConfigService.registerInProcessServer();
+        inprocessServer.start();
+
+        channel = InProcessChannelBuilder.forName("test").directExecutor()
+                // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
+                // needing certificates.
+                .usePlaintext(true).build();
+        blockingStub = ComponentConfigServiceGrpc.newBlockingStub(channel);
+        populateComponentNames();
+    }
+
+    /**
+     * Finalization after test gRPC northbound component config service.
+     */
+    @AfterClass
+    public static void afterClass() {
+
+        channel.shutdownNow();
+        inprocessServer.stop();
+    }
+
+    private static class MockComponentConfigService implements ComponentConfigService {
+
+        MockComponentConfigService() {
+        }
+
+        @Override
+        public Set<String> getComponentNames() {
+            return componentNames;
+        }
+
+        @Override
+        public void registerProperties(Class<?> componentClass) {
+            PROPERTY_MAP.put(componentClass.getName(), C1);
+        }
+
+        @Override
+        public void unregisterProperties(Class<?> componentClass, boolean clear) {
+            PROPERTY_MAP1.remove(componentClass.getName());
+        }
+
+        @Override
+        public Set<ConfigProperty> getProperties(String componentName) {
+            return ImmutableSet.of(C1, C2);
+        }
+
+        @Override
+        public void setProperty(String componentName, String name, String value) {
+            STRING_MAP.put(componentName + "#" + name, value);
+        }
+
+        @Override
+        public void preSetProperty(String componentName, String name, String value) {
+            STRING_MAP1.put(componentName + "#" + name, value);
+        }
+
+        @Override
+        public void unsetProperty(String componentName, String name) {
+            STRING_MAP2.remove(componentName + "#" + name);
+        }
+    }
+}