[ONOS-6683] Add gRPC northbound Application service

Change-Id: I816bba633c788e1c07790b11717897c12493b5ac
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/ApplicationEnumsProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/ApplicationEnumsProtoTranslator.java
new file mode 100644
index 0000000..d82f93e
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/ApplicationEnumsProtoTranslator.java
@@ -0,0 +1,120 @@
+/*
+ * 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.core;
+
+import org.onosproject.app.ApplicationState;
+import org.onosproject.core.ApplicationRole;
+import org.onosproject.grpc.app.models.ApplicationEnumsProto.ApplicationRoleProto;
+import org.onosproject.grpc.app.models.ApplicationEnumsProto.ApplicationStateProto;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Optional;
+
+/**
+ * gRPC ApplicationEnumsProto message to equivalent ONOS Application Enums conversion related utilities.
+ */
+public final class ApplicationEnumsProtoTranslator {
+
+    private static final Logger log = LoggerFactory.getLogger(ApplicationEnumsProtoTranslator.class);
+
+    /**
+     * Translates {@link ApplicationRole} to gRPC ApplicationRole.
+     *
+     * @param role {@link ApplicationRole}
+     * @return gRPC message
+     */
+    public static ApplicationRoleProto translate(ApplicationRole role) {
+
+        switch (role) {
+            case USER:
+                return ApplicationRoleProto.USER;
+            case ADMIN:
+                return ApplicationRoleProto.ADMIN;
+            case UNSPECIFIED:
+                return ApplicationRoleProto.UNSPECIFIED;
+
+            default:
+                log.warn("Unexpected application role: {}", role);
+                return ApplicationRoleProto.UNSPECIFIED;
+        }
+    }
+
+    /**
+     * Translates gRPC ApplicationRole to {@link ApplicationRole}.
+     *
+     * @param roleProto gRPC message
+     * @return {@link ApplicationRole}
+     */
+    public static Optional<Object> translate(ApplicationRoleProto roleProto) {
+
+        switch (roleProto) {
+            case USER:
+                return Optional.of(ApplicationRole.USER);
+            case ADMIN:
+                return Optional.of(ApplicationRole.ADMIN);
+            case UNSPECIFIED:
+                return Optional.of(ApplicationRole.UNSPECIFIED);
+
+            default:
+                log.warn("Unexpected application role proto: {}", roleProto);
+                return Optional.empty();
+        }
+    }
+
+    /**
+     * Translate {@link ApplicationState} to gRPC ApplicationState.
+     *
+     * @param state {@link ApplicationState}
+     * @return gRPC message
+     */
+    public static ApplicationStateProto translate(ApplicationState state) {
+
+        switch (state) {
+            case ACTIVE:
+                return ApplicationStateProto.ACTIVE;
+            case INSTALLED:
+                return ApplicationStateProto.INSTALLED;
+
+            default:
+                log.warn("Unexpected application state: {}", state);
+                return ApplicationStateProto.INSTALLED;
+        }
+    }
+
+    /**
+     * Translate gRPC ApplicationState to {@link ApplicationState}.
+     *
+     * @param stateProto gRPC message
+     * @return {@link ApplicationState}
+     */
+    public static Optional<Object> translate(ApplicationStateProto stateProto) {
+
+        switch (stateProto) {
+            case ACTIVE:
+                return Optional.of(ApplicationState.ACTIVE);
+            case INSTALLED:
+                return Optional.of(ApplicationState.INSTALLED);
+
+            default:
+                log.warn("Unexpected application state proto: {}", stateProto);
+                return Optional.empty();
+        }
+    }
+
+    // Utility class not intended for instantiation.
+    private ApplicationEnumsProtoTranslator() {}
+}
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/ApplicationIdProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/ApplicationIdProtoTranslator.java
new file mode 100644
index 0000000..e74ad7f
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/ApplicationIdProtoTranslator.java
@@ -0,0 +1,60 @@
+/*
+ * 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.core;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.grpc.core.models.ApplicationIdProtoOuterClass.ApplicationIdProto;
+
+import static org.onosproject.grpc.core.models.ApplicationIdProtoOuterClass.ApplicationIdProto.getDefaultInstance;
+
+/**
+ * gRPC ApplicationIdProto message to equivalent ONOS ApplicationId conversion related utilities.
+ */
+public final class ApplicationIdProtoTranslator {
+
+    /**
+     * Translates gRPC ApplicationId to {@link ApplicationId}.
+     *
+     * @param applicationId gRPC message
+     * @return {@link ApplicationId}
+     */
+    public static ApplicationId translate(ApplicationIdProto applicationId) {
+
+        return new DefaultApplicationId(applicationId.getId(), applicationId.getName());
+    }
+
+    /**
+     * Translates {@link ApplicationId} to gRPC ApplicationId message.
+     *
+     * @param applicationId {@link ApplicationId}
+     * @return gRPC ApplicationId message
+     */
+    public static ApplicationIdProto translate(ApplicationId applicationId) {
+
+        if (applicationId != null) {
+            return ApplicationIdProto.newBuilder()
+                    .setId(applicationId.id())
+                    .setName(applicationId.name())
+                    .build();
+        }
+
+        return getDefaultInstance();
+    }
+
+    // utility class not intended for instantiation.
+    private ApplicationIdProtoTranslator() {}
+}
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/ApplicationProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/ApplicationProtoTranslator.java
new file mode 100644
index 0000000..a4b2ca6
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/ApplicationProtoTranslator.java
@@ -0,0 +1,84 @@
+/*
+ * 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.core;
+
+import com.google.common.collect.Sets;
+import org.onosproject.core.Application;
+import org.onosproject.core.ApplicationRole;
+import org.onosproject.core.DefaultApplication;
+import org.onosproject.grpc.core.models.ApplicationProtoOuterClass.ApplicationProto;
+import org.onosproject.incubator.protobuf.models.security.PermissionProtoTranslator;
+import org.onosproject.security.Permission;
+
+import java.util.Optional;
+import java.util.Set;
+
+import static org.onosproject.grpc.core.models.ApplicationProtoOuterClass.ApplicationProto.getDefaultInstance;
+
+/**
+ * gRPC ApplicationProto message to equivalent ONOS Application conversion related utilities.
+ */
+public final class ApplicationProtoTranslator {
+
+    /**
+     * Translates gRPC Application to {@link Application}.
+     *
+     * @param app gRPC message
+     * @return {@link Application}
+     */
+    public static Application translate(ApplicationProto app) {
+
+        Set<Permission> permissions = Sets.newHashSet();
+
+        app.getPermissionsList().forEach(p ->
+                permissions.add(PermissionProtoTranslator.translate(p)));
+
+        return new DefaultApplication(ApplicationIdProtoTranslator.translate(app.getAppId()),
+                VersionProtoTranslator.translate(app.getVersion()), app.getTitle(),
+                app.getDescription(), app.getOrigin(), app.getCategory(), app.getUrl(),
+                app.getReadme(), app.toByteArray(),
+                (ApplicationRole) ApplicationEnumsProtoTranslator.translate(app.getRole()).get(),
+                permissions, Optional.empty(), app.getFeaturesList(), app.getRequiredAppsList());
+    }
+
+    /**
+     * Translates {@link Application} to gRPC Application message.
+     *
+     * @param application {@link Application}
+     * @return gRPC message
+     */
+    public static ApplicationProto translate(Application application) {
+
+        if (application != null) {
+            return ApplicationProto.newBuilder()
+                    .setAppId(ApplicationIdProtoTranslator.translate(application.id()))
+                    .setCategory(application.category())
+                    .setDescription(application.description())
+                    .setOrigin(application.origin())
+                    .setReadme(application.readme())
+                    .setTitle(application.title())
+                    .setUrl(application.url())
+                    .setVersion(VersionProtoTranslator.translate(application.version()))
+                    .setRole(ApplicationEnumsProtoTranslator.translate(application.role()))
+                    .build();
+        }
+
+        return getDefaultInstance();
+    }
+
+    // Utility class not intended for instantiation.
+    private ApplicationProtoTranslator() {}
+}
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/VersionProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/VersionProtoTranslator.java
new file mode 100644
index 0000000..6e0c243
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/VersionProtoTranslator.java
@@ -0,0 +1,62 @@
+/*
+ * 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.core;
+
+import org.onosproject.core.Version;
+import org.onosproject.grpc.core.models.VersionProtoOuterClass.VersionProto;
+
+import static org.onosproject.grpc.core.models.VersionProtoOuterClass.VersionProto.getDefaultInstance;
+
+/**
+ * gRPC Version message to equivalent ONOS Version conversion related utilities.
+ */
+public final class VersionProtoTranslator {
+
+    /**
+     * Translates {@link Version} to gRPC version message.
+     *
+     * @param version {@link Version}
+     * @return gRPC message
+     */
+    public static VersionProto translate(Version version) {
+
+        if (version != null) {
+            return VersionProto.newBuilder()
+                    .setMajor(version.major())
+                    .setMinor(version.minor())
+                    .setPatch(version.patch())
+                    .setBuild(version.build())
+                    .build();
+        }
+
+        return getDefaultInstance();
+    }
+
+    /**
+     * Translates gRPC version message to {@link Version}.
+     *
+     * @param version gRPC message
+     * @return {@link Version}
+     */
+    public static Version translate(VersionProto version) {
+
+        return Version.version(version.getMajor(), version.getMinor(),
+                version.getPatch(), version.getBuild());
+    }
+
+    // Utility class not intended for instantiation.
+    private VersionProtoTranslator() {}
+}
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/package-info.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/package-info.java
new file mode 100644
index 0000000..c1de17f
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/core/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 core models.
+ */
+package org.onosproject.incubator.protobuf.models.core;
\ No newline at end of file
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/security/PermissionProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/security/PermissionProtoTranslator.java
new file mode 100644
index 0000000..d3cdc7d
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/security/PermissionProtoTranslator.java
@@ -0,0 +1,61 @@
+/*
+ * 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.security;
+
+import org.onosproject.grpc.security.models.PermissionProtoOuterClass.PermissionProto;
+import org.onosproject.security.Permission;
+
+import static org.onosproject.grpc.security.models.PermissionProtoOuterClass.PermissionProto.getDefaultInstance;
+
+/**
+ * gRPC Permission message to equivalent ONOS Permission conversion related utilities.
+ */
+public final class PermissionProtoTranslator {
+
+    /**
+     * Translate {@link Permission} to gRPC permission message.
+     *
+     * @param permission {@link Permission}
+     * @return gRPC message
+     */
+    public static PermissionProto translate(Permission permission) {
+
+        if (permission != null) {
+            return PermissionProto.newBuilder()
+                    .setActions(permission.getActions())
+                    .setClassname(permission.getClassName())
+                    .setName(permission.getName())
+                    .build();
+        }
+
+        return getDefaultInstance();
+    }
+
+    /**
+     * Translate gRPC permission message to {@link Permission}.
+     *
+     * @param permission gRPC message
+     * @return {@link Permission}
+     */
+    public static Permission translate(PermissionProto permission) {
+
+        return new Permission(permission.getClassname(),
+                permission.getName(), permission.getActions());
+    }
+
+    // Utility class not intended for instantiation.
+    private PermissionProtoTranslator() {}
+}
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/security/package-info.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/security/package-info.java
new file mode 100644
index 0000000..5ee50f4
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/security/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 security models.
+ */
+package org.onosproject.incubator.protobuf.models.security;
\ No newline at end of file
diff --git a/incubator/protobuf/models/src/main/proto/core/ApplicationProto.proto b/incubator/protobuf/models/src/main/proto/core/ApplicationProto.proto
index e91ea23..2618124 100644
--- a/incubator/protobuf/models/src/main/proto/core/ApplicationProto.proto
+++ b/incubator/protobuf/models/src/main/proto/core/ApplicationProto.proto
@@ -6,11 +6,12 @@
 import "core/ApplicationIdProto.proto";
 import "app/ApplicationEnumsProto.proto";
 import "security/PermissionProto.proto";
+import "core/VersionProto.proto";
 
 // Corresponds to org.onosproject.core.Application.
 message ApplicationProto {
     core.ApplicationIdProto app_id = 1;
-    string version = 2;
+    core.VersionProto version = 2;
     string title = 3;
     string description = 4;
     string category = 5;
diff --git a/incubator/protobuf/models/src/main/proto/core/VersionProto.proto b/incubator/protobuf/models/src/main/proto/core/VersionProto.proto
new file mode 100644
index 0000000..f25699b
--- /dev/null
+++ b/incubator/protobuf/models/src/main/proto/core/VersionProto.proto
@@ -0,0 +1,12 @@
+syntax = "proto3";
+option java_package = "org.onosproject.grpc.core.models";
+
+package core;
+
+// Corresponds to org.onosproject.core.
+message VersionProto {
+    int32 major = 1;
+    int32 minor = 2;
+    string patch = 3;
+    string build = 4;
+}
diff --git a/incubator/protobuf/services/nb/src/main/java/org/onosproject/grpc/nb/app/GrpcNbApplicationService.java b/incubator/protobuf/services/nb/src/main/java/org/onosproject/grpc/nb/app/GrpcNbApplicationService.java
new file mode 100644
index 0000000..4bc5a31
--- /dev/null
+++ b/incubator/protobuf/services/nb/src/main/java/org/onosproject/grpc/nb/app/GrpcNbApplicationService.java
@@ -0,0 +1,126 @@
+/*
+ * 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.grpc.nb.app;
+
+import com.google.common.annotations.Beta;
+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.app.ApplicationService;
+import org.onosproject.app.ApplicationState;
+import org.onosproject.core.Application;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.grpc.nb.app.ApplicationServiceGrpc.ApplicationServiceImplBase;
+import org.onosproject.grpc.nb.app.ApplicationServiceNb.getApplicationReply;
+import org.onosproject.grpc.nb.app.ApplicationServiceNb.getApplicationsReply;
+import org.onosproject.grpc.nb.app.ApplicationServiceNb.getIdReply;
+import org.onosproject.grpc.nb.app.ApplicationServiceNb.getPermissionsReply;
+import org.onosproject.grpc.nb.app.ApplicationServiceNb.getStateReply;
+import org.onosproject.incubator.protobuf.models.core.ApplicationEnumsProtoTranslator;
+import org.onosproject.incubator.protobuf.models.core.ApplicationIdProtoTranslator;
+import org.onosproject.incubator.protobuf.models.core.ApplicationProtoTranslator;
+import org.onosproject.incubator.protobuf.models.security.PermissionProtoTranslator;
+
+/**
+ * A server that provides access to the methods exposed by {@link ApplicationService}.
+ */
+
+@Beta
+@Component(immediate = true)
+public class GrpcNbApplicationService {
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ApplicationService applicationService;
+
+    @Activate
+    public void activate() {
+        //TODO this should contact the registry service and register an instance
+        // of this service.
+    }
+
+    @Deactivate
+    public void deactivate() {
+    }
+
+    private class ApplicationServiceNbServerInternal extends ApplicationServiceImplBase {
+
+        public ApplicationServiceNbServerInternal() {
+            super();
+        }
+
+        @Override
+        public void getApplications(ApplicationServiceNb.getApplicationsRequest request,
+                                    StreamObserver<getApplicationsReply> responseObserver) {
+            getApplicationsReply.Builder replyBuilder = getApplicationsReply.newBuilder();
+
+            applicationService.getApplications().forEach(a ->
+                    replyBuilder.addApplication(ApplicationProtoTranslator.translate(a)));
+            responseObserver.onNext(replyBuilder.build());
+            responseObserver.onCompleted();
+        }
+
+        @Override
+        public void getId(ApplicationServiceNb.getIdRequest request,
+                          StreamObserver<getIdReply> responseObserver) {
+            ApplicationId appId = applicationService.getId(request.getName());
+
+            responseObserver.onNext(getIdReply.newBuilder()
+                    .setApplicationId(ApplicationIdProtoTranslator.translate(appId)).build());
+            responseObserver.onCompleted();
+        }
+
+        @Override
+        public void getApplication(ApplicationServiceNb.getApplicationRequest request,
+                                   StreamObserver<getApplicationReply> responseObserver) {
+
+            Application application = applicationService.getApplication(
+                    ApplicationIdProtoTranslator.translate(request.getApplicationId()));
+
+            responseObserver.onNext(getApplicationReply.newBuilder()
+                    .setApplication(ApplicationProtoTranslator
+                            .translate(application)).build());
+            responseObserver.onCompleted();
+        }
+
+        @Override
+        public void getState(ApplicationServiceNb.getStateRequest request,
+                             StreamObserver<getStateReply> responseObserver) {
+            ApplicationState state = applicationService.getState(
+                    ApplicationIdProtoTranslator.translate(request.getApplicationId()));
+
+            responseObserver.onNext(getStateReply
+                    .newBuilder().setState(ApplicationEnumsProtoTranslator
+                            .translate(state)).build());
+            responseObserver.onCompleted();
+        }
+
+        @Override
+        public void getPermissions(ApplicationServiceNb.getPermissionsRequest request,
+                                   StreamObserver<getPermissionsReply> responseObserver) {
+            getPermissionsReply.Builder replyBuilder = getPermissionsReply.newBuilder();
+
+            applicationService.getPermissions(ApplicationIdProtoTranslator
+                    .translate(request.getApplicationId()))
+                    .forEach(p -> replyBuilder.addPermission(
+                            PermissionProtoTranslator.translate(p)));
+            responseObserver.onNext(replyBuilder.build());
+            responseObserver.onCompleted();
+        }
+    }
+}
diff --git a/incubator/protobuf/services/nb/src/main/java/org/onosproject/grpc/nb/app/package-info.java b/incubator/protobuf/services/nb/src/main/java/org/onosproject/grpc/nb/app/package-info.java
new file mode 100644
index 0000000..b5cd387
--- /dev/null
+++ b/incubator/protobuf/services/nb/src/main/java/org/onosproject/grpc/nb/app/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.
+ */
+/**
+ * gRPC server implementations for northbound services.
+ */
+package org.onosproject.grpc.nb.app;
\ No newline at end of file
diff --git a/incubator/protobuf/services/nb/src/main/proto/app/ApplicationServiceNb.proto b/incubator/protobuf/services/nb/src/main/proto/app/ApplicationServiceNb.proto
new file mode 100644
index 0000000..2b4515a
--- /dev/null
+++ b/incubator/protobuf/services/nb/src/main/proto/app/ApplicationServiceNb.proto
@@ -0,0 +1,56 @@
+syntax="proto3";
+option java_package = "org.onosproject.grpc.nb.app";
+
+package nb.app;
+
+import "core/ApplicationProto.proto";
+import "core/ApplicationIdProto.proto";
+import "app/ApplicationEnumsProto.proto";
+import "security/PermissionProto.proto";
+
+message getApplicationsRequest {
+}
+
+message getApplicationsReply {
+    repeated .core.ApplicationProto application = 1;
+}
+
+message getIdRequest {
+    string name = 1;
+}
+
+message getIdReply {
+    .core.ApplicationIdProto application_id = 1;
+}
+
+message getApplicationRequest {
+    .core.ApplicationIdProto application_id = 1;
+}
+
+message getApplicationReply {
+    .core.ApplicationProto application = 1;
+}
+
+message getStateRequest {
+    .core.ApplicationIdProto application_id = 1;
+}
+
+message getStateReply {
+    .app.ApplicationStateProto state = 1;
+}
+
+message getPermissionsRequest {
+    .core.ApplicationIdProto application_id = 1;
+}
+
+message getPermissionsReply {
+    repeated .security.PermissionProto permission = 1;
+}
+
+service ApplicationService {
+    rpc getApplications(getApplicationsRequest) returns (getApplicationsReply) {}
+    rpc getId(getIdRequest) returns (getIdReply) {}
+    rpc getApplication(getApplicationRequest) returns (getApplicationReply) {}
+    rpc getState(getStateRequest) returns (getStateReply) {}
+    rpc getPermissions(getPermissionsRequest) returns (getPermissionsReply) {}
+}
\ No newline at end of file