diff --git a/.gitignore b/.gitignore index 64d448025de3..1e8c80ebe761 100644 --- a/.gitignore +++ b/.gitignore @@ -158,6 +158,17 @@ flex/interactive/sdk/python/gs_interactive/rest.py !flex/interactive/sdk/python/gs_interactive/models/long_text.py +interactive_engine/groot-http/.openapi-generator/ +interactive_engine/groot-http/src/test/ +interactive_engine/groot-http/src/main/resources/ +interactive_engine/groot-http/src/main/java/org/ +interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/api/ +interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/models/ +interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/*.java +!interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/models/GSDataType.java +!interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/models/StringTypeString.java +!interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/models/TemporalTypeTemporal.java + **/.cache/ **/*.ci-friendly-pom.xml diff --git a/flex/interactive/sdk/generate_sdk.sh b/flex/interactive/sdk/generate_sdk.sh index e38c33bc9920..776bc21b476f 100755 --- a/flex/interactive/sdk/generate_sdk.sh +++ b/flex/interactive/sdk/generate_sdk.sh @@ -81,6 +81,21 @@ function do_gen_python() { eval $cmd } + +function do_gen_spring() { + echo "Generating Spring API" + OUTPUT_PATH="${CUR_DIR}/../../../interactive_engine/groot-http" + GROOT_PACKAGE_NAME="com.alibaba.graphscope.groot" + GROOT_ARTIFACT_ID="groot-http" + additional_properties="apiPackage=${GROOT_PACKAGE_NAME}.service.api,modelPackage=${GROOT_PACKAGE_NAME}.service.models,artifactId=${GROOT_ARTIFACT_ID},groupId=${GROUP_ID},invokerPackage=${GROOT_PACKAGE_NAME}" + export JAVA_OPTS="-Dlog.level=${LOG_LEVEL}" + cmd="openapi-generator-cli generate -i ${OPENAPI_SPEC_PATH} -g spring -o ${OUTPUT_PATH}" + cmd=" ${cmd} --additional-properties=${additional_properties}" + echo "Running command: ${cmd}" + + eval $cmd +} + function do_gen() { # expect only one argument if [ $# -ne 1 ]; then @@ -97,6 +112,9 @@ function do_gen() { python) do_gen_python ;; + spring) + do_gen_spring + ;; *) err "Unsupported language: $lang" usage diff --git a/flex/openapi/openapi_interactive.yaml b/flex/openapi/openapi_interactive.yaml index bdbf4474907b..bad56d032afa 100644 --- a/flex/openapi/openapi_interactive.yaml +++ b/flex/openapi/openapi_interactive.yaml @@ -1387,6 +1387,7 @@ components: properties: timestamp: type: string + nullable: true DateType: x-body-name: date_type type: object @@ -1395,6 +1396,7 @@ components: properties: date32: type: string + nullable: true TemporalType: x-body-name: temporal_type type: object @@ -2111,4 +2113,3 @@ components: type: array items: $ref: '#/components/schemas/EdgeRequest' - diff --git a/interactive_engine/groot-http/.openapi-generator-ignore b/interactive_engine/groot-http/.openapi-generator-ignore new file mode 100644 index 000000000000..8d61b64621cd --- /dev/null +++ b/interactive_engine/groot-http/.openapi-generator-ignore @@ -0,0 +1,31 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md + +src/main/java/com/alibaba/graphscope/groot/service/models/GSDataType.java +src/main/java/com/alibaba/graphscope/groot/service/models/StringTypeString.java +src/main/java/com/alibaba/graphscope/groot/service/models/TemporalTypeTemporal.java + +README.md + +pom.xml \ No newline at end of file diff --git a/interactive_engine/groot-http/README.md b/interactive_engine/groot-http/README.md new file mode 100644 index 000000000000..5cd22b6081a2 --- /dev/null +++ b/interactive_engine/groot-http/README.md @@ -0,0 +1,21 @@ +# OpenAPI generated server + +Spring Boot Server + +## Overview +This server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. +By using the [OpenAPI-Spec](https://openapis.org), you can easily generate a server stub. +This is an example of building a OpenAPI-enabled server in Java using the SpringBoot framework. + + +The underlying library integrating OpenAPI to Spring Boot is [springdoc](https://springdoc.org). +Springdoc will generate an OpenAPI v3 specification based on the generated Controller and Model classes. +The specification is available to download using the following url: +http://localhost:8080/v3/api-docs/ + +Start your server as a simple java application + +You can view the api documentation in swagger-ui by pointing to +http://localhost:8080/swagger-ui.html + +Change default port value in application.properties \ No newline at end of file diff --git a/interactive_engine/groot-http/pom.xml b/interactive_engine/groot-http/pom.xml new file mode 100644 index 000000000000..b6040424cea3 --- /dev/null +++ b/interactive_engine/groot-http/pom.xml @@ -0,0 +1,82 @@ + + 4.0.0 + com.alibaba.graphscope + groot-http + jar + groot-http + 1.0.0 + + 1.8 + ${java.version} + ${java.version} + UTF-8 + 1.6.14 + 5.3.1 + + + org.springframework.boot + spring-boot-starter-parent + 2.7.15 + + + + src/main/java + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.data + spring-data-commons + + + + org.springdoc + springdoc-openapi-ui + ${springdoc.version} + + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + org.openapitools + jackson-databind-nullable + 0.2.6 + + + + org.springframework.boot + spring-boot-starter-validation + + + com.fasterxml.jackson.core + jackson-databind + + + org.springframework.boot + spring-boot-starter-test + test + + + diff --git a/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/deserializer/GSDataTypeDeserializer.java b/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/deserializer/GSDataTypeDeserializer.java new file mode 100644 index 000000000000..2d6f5af9c952 --- /dev/null +++ b/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/deserializer/GSDataTypeDeserializer.java @@ -0,0 +1,62 @@ +/* + * Copyright 2022 Alibaba Group Holding Limited. + * + * 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 com.alibaba.graphscope.groot.service.deserializer; + +import com.alibaba.graphscope.groot.service.models.GSDataType; +import com.alibaba.graphscope.groot.service.models.PrimitiveType; +import com.alibaba.graphscope.groot.service.models.StringType; +import com.alibaba.graphscope.groot.service.models.StringTypeString; +import com.alibaba.graphscope.groot.service.models.TemporalType; +import com.alibaba.graphscope.groot.service.models.TemporalTypeTemporal; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; + +public class GSDataTypeDeserializer extends JsonDeserializer { + public GSDataTypeDeserializer() {} + + @Override + public GSDataType deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + JsonNode node = jp.getCodec().readTree(jp); + ObjectMapper mapper = (ObjectMapper) jp.getCodec(); + System.out.println("GSDataTypeDeserializer"); + System.out.println(node); + + if (node.has("string")) { + StringType stringType = new StringType(); + stringType.setString(mapper.treeToValue(node.get("string"), StringTypeString.class)); + return stringType; + } else if (node.has("temporal")) { + // ObjectMapper objectMapper = new ObjectMapper(); + TemporalType temporalType = new TemporalType(); + temporalType.setTemporal( + mapper.treeToValue(node.get("temporal"), TemporalTypeTemporal.class)); + return temporalType; + } else if (node.has("primitive_type")) { + return new PrimitiveType( + PrimitiveType.PrimitiveTypeEnum.fromValue( + jp.getCodec().treeToValue(node.get("primitive_type"), String.class))); + } else { + throw new IOException("Unknown variant for GSDataType"); + } + } +} diff --git a/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/deserializer/StringTypeStringDeserializer.java b/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/deserializer/StringTypeStringDeserializer.java new file mode 100644 index 000000000000..523ab82cdf12 --- /dev/null +++ b/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/deserializer/StringTypeStringDeserializer.java @@ -0,0 +1,63 @@ +/* + * Copyright 2022 Alibaba Group Holding Limited. + * + * 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 com.alibaba.graphscope.groot.service.deserializer; + +import com.alibaba.graphscope.groot.service.models.FixedChar; +import com.alibaba.graphscope.groot.service.models.FixedCharChar; +import com.alibaba.graphscope.groot.service.models.LongText; +import com.alibaba.graphscope.groot.service.models.StringTypeString; +import com.alibaba.graphscope.groot.service.models.VarChar; +import com.alibaba.graphscope.groot.service.models.VarCharVarChar; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; + +import java.io.IOException; + +public class StringTypeStringDeserializer extends JsonDeserializer { + public StringTypeStringDeserializer() {} + + @Override + public StringTypeString deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + JsonNode node = jp.getCodec().readTree(jp); + System.out.println("StringTypeStringDeserializer"); + System.out.println(node); + + if (node.has("var_char")) { + System.out.println("var_char"); + VarCharVarChar varChar = new VarCharVarChar(); + if (node.get("var_char").has("max_length")) { + // return new VarChar(new + // VarCharVarChar(jp.getCodec().treeToValue(node.get("var_char").get("max_length"), + // String.class))); + varChar.setMaxLength(node.get("var_char").get("max_length").asInt()); + } else { + throw new IOException("max_length not found in var_char"); + } + return new VarChar(varChar); + } else if (node.has("long_text")) { + return new LongText(jp.getCodec().treeToValue(node.get("long_text"), String.class)); + } else if (node.has("fixed_char")) { + return new FixedChar( + jp.getCodec().treeToValue(node.get("fixed_char"), FixedCharChar.class)); + } else { + throw new IOException("Unknown variant for GSDataType"); + } + } +} diff --git a/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/deserializer/TemporalTypeTemporalDeserializer.java b/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/deserializer/TemporalTypeTemporalDeserializer.java new file mode 100644 index 000000000000..728f2390ad04 --- /dev/null +++ b/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/deserializer/TemporalTypeTemporalDeserializer.java @@ -0,0 +1,45 @@ +/* + * Copyright 2022 Alibaba Group Holding Limited. + * + * 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 com.alibaba.graphscope.groot.service.deserializer; + +import com.alibaba.graphscope.groot.service.models.DateType; +import com.alibaba.graphscope.groot.service.models.TemporalTypeTemporal; +import com.alibaba.graphscope.groot.service.models.TimeStampType; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; + +import java.io.IOException; + +public class TemporalTypeTemporalDeserializer extends JsonDeserializer { + public TemporalTypeTemporalDeserializer() {} + + @Override + public TemporalTypeTemporal deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + JsonNode node = jp.getCodec().readTree(jp); + + if (node.has("date32")) { + return new DateType(); + } else if (node.has("timestamp")) { + return new TimeStampType(); + } else { + throw new IOException("Unknown variant for GSDataType"); + } + } +} diff --git a/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/models/GSDataType.java b/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/models/GSDataType.java new file mode 100644 index 000000000000..a17cd2596630 --- /dev/null +++ b/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/models/GSDataType.java @@ -0,0 +1,33 @@ +/* + * Copyright 2022 Alibaba Group Holding Limited. + * + * 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 com.alibaba.graphscope.groot.service.models; + +import com.alibaba.graphscope.groot.service.deserializer.GSDataTypeDeserializer; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import java.util.*; + +import javax.annotation.Generated; +import javax.validation.constraints.*; + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(using = GSDataTypeDeserializer.class) +@Generated( + value = "org.openapitools.codegen.languages.SpringCodegen", + date = "2025-01-13T19:18:58.368636+08:00[Asia/Shanghai]", + comments = "Generator version: 7.10.0") +public interface GSDataType {} diff --git a/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/models/StringTypeString.java b/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/models/StringTypeString.java new file mode 100644 index 000000000000..4acadfa0a372 --- /dev/null +++ b/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/models/StringTypeString.java @@ -0,0 +1,33 @@ +/* + * Copyright 2022 Alibaba Group Holding Limited. + * + * 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 com.alibaba.graphscope.groot.service.models; + +import com.alibaba.graphscope.groot.service.deserializer.StringTypeStringDeserializer; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import java.util.*; + +import javax.annotation.Generated; +import javax.validation.constraints.*; + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(using = StringTypeStringDeserializer.class) +@Generated( + value = "org.openapitools.codegen.languages.SpringCodegen", + date = "2025-01-13T19:18:58.368636+08:00[Asia/Shanghai]", + comments = "Generator version: 7.10.0") +public interface StringTypeString {} diff --git a/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/models/TemporalTypeTemporal.java b/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/models/TemporalTypeTemporal.java new file mode 100644 index 000000000000..10177290ee5f --- /dev/null +++ b/interactive_engine/groot-http/src/main/java/com/alibaba/graphscope/groot/service/models/TemporalTypeTemporal.java @@ -0,0 +1,33 @@ +/* + * Copyright 2022 Alibaba Group Holding Limited. + * + * 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 com.alibaba.graphscope.groot.service.models; + +import com.alibaba.graphscope.groot.service.deserializer.TemporalTypeTemporalDeserializer; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import java.util.*; + +import javax.annotation.Generated; +import javax.validation.constraints.*; + +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) +@JsonDeserialize(using = TemporalTypeTemporalDeserializer.class) +@Generated( + value = "org.openapitools.codegen.languages.SpringCodegen", + date = "2025-01-13T19:18:58.368636+08:00[Asia/Shanghai]", + comments = "Generator version: 7.10.0") +public interface TemporalTypeTemporal {}