Skip to content

Commit

Permalink
Add Support to Generate GraphQL Schema for Local Service Variable Dec…
Browse files Browse the repository at this point in the history
…laration (#1704)

* [Automated] Update the native jar versions

* [Automated] Update the native jar versions

* Add support to gen schema from local service obj

* Update changelog

* Add copyright and license

* Update license header

* Apply suggestions from code reviews

* [Automated] Update the native jar versions

* [Automated] Update the native jar versions

* Use textRange to modify service declaration nodes

* Add support to generate schema for object field

* Remove unused test case resources

* Add test case with distinct service class type

* Apply suggestions from code review

* [Automated] Update the native jar versions

* [Automated] Update the native jar versions

* Add runtime tests

---------

Co-authored-by: Thisaru Guruge <thisaru@wso2.com>
  • Loading branch information
zetcco and ThisaruGuruge authored Jan 22, 2024
1 parent 49a141c commit edcb9b1
Show file tree
Hide file tree
Showing 18 changed files with 495 additions and 38 deletions.
8 changes: 4 additions & 4 deletions ballerina-tests/Dependencies.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "cache"
version = "3.7.0"
version = "3.7.1"
dependencies = [
{org = "ballerina", name = "constraint"},
{org = "ballerina", name = "jballerina.java"},
Expand Down Expand Up @@ -119,7 +119,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http"
version = "2.10.2"
version = "2.10.5"
dependencies = [
{org = "ballerina", name = "auth"},
{org = "ballerina", name = "cache"},
Expand Down Expand Up @@ -311,7 +311,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "observe"
version = "1.2.0"
version = "1.2.2"
dependencies = [
{org = "ballerina", name = "jballerina.java"}
]
Expand Down Expand Up @@ -383,7 +383,7 @@ modules = [
[[package]]
org = "ballerina"
name = "websocket"
version = "2.10.0"
version = "2.10.1"
dependencies = [
{org = "ballerina", name = "auth"},
{org = "ballerina", name = "constraint"},
Expand Down
42 changes: 42 additions & 0 deletions ballerina-tests/tests/01_listener_test.bal
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,45 @@ function testAttachServiceWithSubscriptionToHttp1BasedListener() returns error?
check validateNextMessage(wsClient2, expectedMsgPayload, id = "2");
}
}

@test:Config {
groups: ["listener", "service_object"]
}
function testServiceDeclarationUsingLocalServiceObject() returns error? {
graphql:Service localService = service object {
resource function get greeting() returns string {
return "Hello world";
}
};
check basicListener.attach(localService, "/local_service_object");

string url = "http://localhost:9091/local_service_object";
string document = string `query { greeting }`;
json actualPayload = check getJsonPayloadFromService(url, document);
json expectedPayload = {
data: {
greeting: "Hello world"
}
};
check basicListener.detach(localService);
test:assertEquals(actualPayload, expectedPayload);
}

@test:Config {
groups: ["listener", "service_object"]
}
function testServiceDeclarationUsingObjectField() returns error? {
graphql:Service localService = (new ServiceDeclarationOnObjectField()).getService();
check basicListener.attach(localService, "/object_field_service_object");

string url = "http://localhost:9091/object_field_service_object";
string document = string `query { greeting }`;
json actualPayload = check getJsonPayloadFromService(url, document);
json expectedPayload = {
data: {
greeting: "Hello world"
}
};
check basicListener.detach(localService);
test:assertEquals(actualPayload, expectedPayload);
}
16 changes: 16 additions & 0 deletions ballerina-tests/tests/test_services.bal
Original file line number Diff line number Diff line change
Expand Up @@ -2475,3 +2475,19 @@ service /defaultParam on wrappedListener {

resource function get nestedField() returns NestedField => new;
}

class ServiceDeclarationOnObjectField {

private graphql:Service objectFieldService = service object {
resource function get greeting() returns string {
return "Hello world";
}
};

public function init() {}

public function getService() returns graphql:Service {
return self.objectFieldService;
}

}
8 changes: 4 additions & 4 deletions ballerina/Dependencies.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ modules = [
[[package]]
org = "ballerina"
name = "cache"
version = "3.7.0"
version = "3.7.1"
dependencies = [
{org = "ballerina", name = "constraint"},
{org = "ballerina", name = "jballerina.java"},
Expand Down Expand Up @@ -97,7 +97,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http"
version = "2.10.2"
version = "2.10.5"
dependencies = [
{org = "ballerina", name = "auth"},
{org = "ballerina", name = "cache"},
Expand Down Expand Up @@ -301,7 +301,7 @@ modules = [
[[package]]
org = "ballerina"
name = "observe"
version = "1.2.0"
version = "1.2.2"
dependencies = [
{org = "ballerina", name = "jballerina.java"}
]
Expand Down Expand Up @@ -376,7 +376,7 @@ modules = [
[[package]]
org = "ballerina"
name = "websocket"
version = "2.10.0"
version = "2.10.1"
dependencies = [
{org = "ballerina", name = "auth"},
{org = "ballerina", name = "constraint"},
Expand Down
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

### Added
-[[#1586] Add Compile Time Schema Generation for Default Parameters](https://github.com/ballerina-platform/module-ballerina-graphql/pull/1586)
-[[#3317] Add Support to Generate GraphQL Schema for Local Service Variable Declaration](https://github.com/ballerina-platform/ballerina-library/issues/3317)

### Changed
- [[#4634] Use Aliases in GraphQL Error Path](https://github.com/ballerina-platform/ballerina-standard-library/issues/4634)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,27 @@ public void testGraphqlDataLoader() {
Assert.assertEquals(diagnosticResult.errorCount(), 0);
}

@Test
public void testGraphqlLocalServiceObjects() {
String packagePath = "25_local_service_object_declarations";
DiagnosticResult diagnosticResult = getDiagnosticResult(packagePath);
Assert.assertEquals(diagnosticResult.errorCount(), 0);
}

@Test
public void testGraphqlObjectFieldServiceObjects() {
String packagePath = "26_object_field_service_object_declarations";
DiagnosticResult diagnosticResult = getDiagnosticResult(packagePath);
Assert.assertEquals(diagnosticResult.errorCount(), 0);
}

@Test
public void testMultipleInlineServiceDeclarations() {
String packagePath = "27_inline_service_declarations";
DiagnosticResult diagnosticResult = getDiagnosticResult(packagePath);
Assert.assertEquals(diagnosticResult.errorCount(), 0);
}

private DiagnosticResult getDiagnosticResult(String path) {
Path projectDirPath = RESOURCE_DIRECTORY.resolve(path);
BuildProject project = BuildProject.load(getEnvironmentBuilder(), projectDirPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,71 @@

import ballerina/http;
import ballerina/graphql;
import ballerina/lang.runtime;

service /greeting on new http:Listener(9090) {
resource function get greeting() returns string {
return "Hello, World!";
}
}

service graphql:Service /query on new graphql:Listener(8080) {
resource function get name() returns string {
return "Jack";
}
service / on new graphql:Listener(9091) {
resource function get greeting() returns string {
return "Hello from global listener binding service";
}
}

service /greeting on new http:Listener(9092) {
resource function get greeting() returns string {
return "Hello, World!";
}
}

graphql:Service globalService = service object {
resource function get greeting() returns string {
return "Hello from global service";
}
};

service /too on new graphql:Listener(9093) {
resource function get greeting() returns string {
return "Hello from global listener binding service too";
}
}

class TestService {
private graphql:Service fieldService = service object {
resource function get greeting() returns string {
return "Hello from object field service object";
}
};

public function init() {}

public function startService() returns error? {
graphql:Listener localListener = check new(9094);
check localListener.attach(self.fieldService);
check localListener.'start();
runtime:registerListener(localListener);
}
}

public function main() returns error? {
graphql:Service localService = service object {
resource function get greeting() returns string {
return "Hello from local service 2";
}
};

TestService serviceClass = new ();
check serviceClass.startService();

graphql:Listener localListener = check new(9095);
graphql:Listener globalListener = check new(9096);
check localListener.attach(localService);
check globalListener.attach(globalService);
check localListener.'start();
check globalListener.'start();
runtime:registerListener(localListener);
runtime:registerListener(globalListener);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
org = "graphql_test"
name = "test_package"
version = "0.1.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com) All Rights Reserved.
//
// WSO2 LLC. licenses this file to you 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.

import ballerina/lang.runtime;
import ballerina/graphql;

public function main() returns error? {
graphql:Service localService1 = service object {
resource function get greeting() returns string {
return "Hello from local service 1";
}
};
graphql:Service localService2 = service object {
resource function get greeting() returns string {
return "Hello from local service 1";
}
};
graphql:Listener localListener1 = check new(9090);
graphql:Listener localListener2 = check new(9091);
check localListener1.attach(localService1);
check localListener2.attach(localService2);
check localListener1.'start();
check localListener2.'start();
runtime:registerListener(localListener1);
runtime:registerListener(localListener2);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
org = "graphql_test"
name = "test_package"
version = "0.1.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com) All Rights Reserved.
//
// WSO2 LLC. licenses this file to you 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.

import ballerina/lang.runtime;
import ballerina/graphql;

class TestService {
private graphql:Service fieldService1 = service object {
resource function get greeting() returns string {
return "Hello from object field service object 1";
}
};
private graphql:Service fieldService2 = service object {
resource function get greeting() returns string {
return "Hello from object field service object 2";
}
};

public function init() {}

public function startService() returns error? {
graphql:Listener localListener1 = check new(9090);
graphql:Listener localListener2 = check new(9091);
check localListener1.attach(self.fieldService1);
check localListener2.attach(self.fieldService2);
check localListener1.'start();
check localListener2.'start();
runtime:registerListener(localListener1);
runtime:registerListener(localListener2);
}
}

public function main() returns error? {
TestService serviceClass = new ();
check serviceClass.startService();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
org = "graphql_test"
name = "test_package"
version = "0.1.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com) All Rights Reserved.
//
// WSO2 LLC. licenses this file to you 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.

import ballerina/lang.runtime; import ballerina/graphql; import ballerina/http; service / on new http:Listener(9090) { resource function get greet() returns string { return "Hello from global http service"; } } public function main() returns error? { graphql:Service gqlService = service object { resource function get greet() returns string { return "Hello from gql service"; } }; http:Service httpService = service object { resource function get greet() returns string { return "Hello from local http service"; } }; graphql:Listener gqlListener = check new(9091); http:Listener httpListener = check new(9092); check gqlListener.attach(gqlService); check httpListener.attach(httpService); check gqlListener.'start(); check httpListener.'start(); runtime:registerListener(gqlListener); runtime:registerListener(httpListener); }
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
org = "graphql_test"
name = "test_package"
version = "0.1.0"
Loading

0 comments on commit edcb9b1

Please sign in to comment.