Skip to content

Commit

Permalink
[ISSUE apache#339] Add a skeleton for separated openschema registry s…
Browse files Browse the repository at this point in the history
…ervice and implement most APIs that doesn't need compatibility check. (apache#525)

* [ISSUE apache#339] a skeleton of independent openschema registry service

* add license for build.gradle

add license for ```incubator-eventmesh/eventmesh-openschema/build.gradle```

* modify license

modify license of ```incubator-eventmesh/eventmesh-openschema/build.gradle```

* update license

update license of ```build.gradle``` in ```incubator-eventmesh/eventmesh-openschema/eventmesh-openschema-registry```

* Update application.yml

update license of ```application.yml``` in ```incubator-eventmesh/eventmesh-openschema/eventmesh-openschema-registry```

* [ISSUE apache#339] add FLIP-like progress

* [ISSUE apache#339] fix allowed-licenses.txt and remove unused dependencies

* [ISSUE apache#339] remove null in allowed-licenses.txt and move dependency version in root-build.gradle
  • Loading branch information
jzhou59 authored and xwm1992 committed Dec 27, 2021
1 parent b3d036c commit c0d6dcf
Show file tree
Hide file tree
Showing 34 changed files with 1,754 additions and 0 deletions.
7 changes: 7 additions & 0 deletions build.gradle
Expand Up @@ -386,6 +386,13 @@ subprojects {
dependency "org.mockito:mockito-core:2.23.0"
dependency "org.powermock:powermock-module-junit4:2.0.2"
dependency "org.powermock:powermock-api-mockito2:2.0.2"

dependency 'org.springframework.boot:spring-boot-starter-data-jdbc:2.5.4'
dependency 'org.springframework.boot:spring-boot-starter-data-jpa:2.5.4'
dependency 'org.springframework.boot:spring-boot-starter-jdbc:2.5.4'
dependency 'org.springframework:spring-beans:5.1.8.RELEASE'
dependency 'org.projectlombok:lombok:1.18.20'
dependency 'com.h2database:h2:1.4.200'
}
}
}
60 changes: 60 additions & 0 deletions docs/en/features/eventmesh-schemaregistry-design.md
Expand Up @@ -63,6 +63,66 @@ The highlevel process of messages transmission undergoes 10 steps as follows:
- step9: Schema Registry returns schema and EventMesh caches it.
- step10: EventMesh patches schema in front of messages and push it to consumer.

## Current Progress
### Status
**Current state** : Developing

**Discussion thread** : ISSUE #339

### Proposed Changes
The proposal has two aspects.

First is a separated Open Schema Registry, which includes storage and compatibility check for schema.
This proposal is under developing.

Second is the integration of Open Schema in Eventmesh, which includes validation for schema. This proposal is to be developed.

As for the first proposal, some developing statuses are as follows.

**Status Code and Exception Code**

No. | Status Code | Exception Code | Description | status
--- | :---: | :---: | :---: | :---:
1 | 401 | 40101 | Unauthorized Exception | ✔
2 | 404 | 40401 | Schema Non- Exception | ✔
3 | ^ | 40402 | Subject Non-exist Exception | ✔
4 | ^ | 40403 | Version Non-exist Exception | ✔
5 | 409 | 40901 | Compatibility Exception | ✔
6 | 422 | 42201 | Schema Format Exception | ✔
7 | ^ | 42202 | Subject Format Exception | ✔
8 | ^ | 42203 | Version Format Exception | ✔
9 | ^ | 42204 | Compatibility Format Exception | ✔
10 | 500 | 50001 | Storage Service Exception | ✔
11 | ^ | 50002 | Timeout Exception | ✔

**API developing status** :

No. | Type | URL | response | exception | code | test
--- | --- | --- | --- | --- | --- | ---
1 | GET | /schemas/ids/{string: id} | Schema.class | 40101\40401\50001 | ✔ | ❌
2 | GET | /schemas/ids/{string: id}/subjects | SubjectAndVersion.class | 40101\40401\50001 | ✔ | ❌
3 | GET | /subjects | List\<String> | 40101\50001 | ✔ | ❌
4 | GET | /subjects/{string: subject}/versions | List\<Integer> | 40101\40402\50001 | ✔ | ❌
5 | DELETE | /subjects/(string: subject) | List\<Integer> | 40101\40402\50001 | ✔ | ❌
6 | GET | /subjects/(string: subject) | Subject.class | 40101\40402\50001 | ✔ | ❌
7 | GET | /subjects/(string: subject)/versions/(version: version)/schema | SubjectWithSchema.class | 40101\40402\40403\50001 | ✔ | ❌
8 | POST | /subjects/(string: subject)/versions | SchemaIdResponse.class | 40101\40901\42201\50001\50002 | - | ❌
9 | POST | /subjects/(string: subject)/ | Subject.class | 40101\40901\42202\50001\50002 | ✔ | ❌
10 | DELETE | /subjects/(string: subject)/versions/(version: version) | int | 40101\40402\40403\40901\50001| - | ❌
11 | POST | /compatibility/subjects/(string: subject)/versions/(version: version) | CompatibilityResultResponse.class | 40101\40402\40403\42201\42203\50001| - | ❌
12 | GET | /compatibility/(string: subject) | Compatibility.class | 40101\40402\50001 | ✔ | ❌
13 | PUT | /compatibility/(string: subject) | Compatibility.class | 40101\40402\40901\42204\50001 | - | ❌

**Overall Project Structure**

```SchemaController.java```+```SchemaService.java``` : ```OpenSchema 7.1.1~7.1.2 (API 1~2)```

```SubjectController.java```+```SubjectService.java``` : ```OpenSchema 7.2.1~7.2.8 (API 3~10)```

```CompatibilityController.java```+```CompatibilityService.java``` : ```OpenSchema 7.3.1~7.3.3 (API 11~13)``` + ```Check for Compatibility```

![Project_Structure](../../images/features/eventmesh-schemaregistry-projectstructure.png)


## References
[1] [schema validator (github.com)](https://github.com/search?q=schema+validator)
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 33 additions & 0 deletions eventmesh-openschema/build.gradle
@@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.
*/

plugins {
}

group 'org.apache.eventmesh'
version '1.2.0-SNAPSHOT'

repositories {
mavenCentral()
}

dependencies {
}

test {
useJUnitPlatform()
}
44 changes: 44 additions & 0 deletions eventmesh-openschema/eventmesh-openschema-registry/build.gradle
@@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.
*/

group 'org.apache.eventmesh'
version '1.2.0-SNAPSHOT'

configurations {
compileOnly {
extendsFrom annotationProcessor
}
}

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework:spring-beans'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
}

test {
useJUnitPlatform()
}
@@ -0,0 +1,29 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.
*/
package org.apache.eventmesh.openschemaregistry;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class OpenSchemaRegistryApplication {

public static void main(String[] args) {
SpringApplication.run(OpenSchemaRegistryApplication.class, args);
}

}
@@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.
*/
package org.apache.eventmesh.openschemaregistry.controller;

import org.apache.eventmesh.openschemaregistry.domain.Compatibility;
import org.apache.eventmesh.openschemaregistry.domain.Schema;
import org.apache.eventmesh.openschemaregistry.response.CompatibilityResultResponse;
import org.apache.eventmesh.openschemaregistry.service.CompatibilityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/compatibility")
public class CompatibilityController {

@Autowired
CompatibilityService compatibilityService;

@PostMapping("/subjects/{subject}/versions/{version}")
public ResponseEntity<CompatibilityResultResponse> checkWhetherCompatible(@PathVariable("subject") String subject,
@PathVariable("version") Integer version,
@RequestBody Schema schema){
CompatibilityResultResponse resultResponse = compatibilityService.checkWhetherCompatible(subject, version, schema);
return ResponseEntity.ok(resultResponse);
}

@GetMapping("/{subject}")
public ResponseEntity<Compatibility> getCompatibilityBySubject(@PathVariable("subject") String subject){
Compatibility compatibility = compatibilityService.getCompatibilityBySubject(subject);
return ResponseEntity.ok(compatibility);
}

@PutMapping("/{subject}")
public ResponseEntity<Compatibility> updateCompatibilityBySubject(@PathVariable("subject") String subject,
@RequestBody Compatibility compatibility){
Compatibility updatedCompatibility = compatibilityService.updateCompatibilityBySubject(subject, compatibility);
return ResponseEntity.ok(updatedCompatibility);
}
}
@@ -0,0 +1,43 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.
*/
package org.apache.eventmesh.openschemaregistry.controller;

import org.apache.eventmesh.openschemaregistry.domain.Schema;
import org.apache.eventmesh.openschemaregistry.response.SubjectAndVersionResponse;
import org.apache.eventmesh.openschemaregistry.service.SchemaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/schemas")
public class SchemaController {
@Autowired
SchemaService schemaService;

@GetMapping("/ids/{id}")
public ResponseEntity<Schema> fetchSchemaById(@PathVariable("id") long id){
Schema schema = schemaService.getSchemaById(id);
return ResponseEntity.ok(schema);
}

@GetMapping("/ids/{id}/subjects")
public ResponseEntity<SubjectAndVersionResponse> fetchSubjectAndVersionById(@PathVariable("id") long id){
SubjectAndVersionResponse subjectAndVersionResponse = schemaService.getSubjectAndVersionById(id);
return ResponseEntity.ok(subjectAndVersionResponse);
}
}
@@ -0,0 +1,85 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.
*/

package org.apache.eventmesh.openschemaregistry.controller;

import org.apache.eventmesh.openschemaregistry.domain.Schema;
import org.apache.eventmesh.openschemaregistry.domain.Subject;
import org.apache.eventmesh.openschemaregistry.domain.SubjectWithSchema;
import org.apache.eventmesh.openschemaregistry.response.SchemaIdResponse;
import org.apache.eventmesh.openschemaregistry.service.SubjectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/subjects")
public class SubjectController {

@Autowired
SubjectService subjectService;

@GetMapping({"","/"})
public ResponseEntity<List<String>> getAllSubjects(){
List<String> subjects = subjectService.getAllSubjects();
return ResponseEntity.ok(subjects);
}

@GetMapping("/{subject}/versions")
public ResponseEntity<List<Integer>> getAllVersionBySubject(@PathVariable("subject") String subject){
List<Integer> versions = subjectService.getAllVersionsBySubject(subject);
return ResponseEntity.ok(versions);
}

@DeleteMapping("/subjects/{subject}")
public ResponseEntity<List<Integer>> deleteSubjectAndAllSchemaBySubject(@PathVariable("subject") String subject){
List<Integer> versions = subjectService.deleteSubjectAndAllSchemaBySubject(subject);
return ResponseEntity.ok(versions);
}

@GetMapping("/{subject}")
public ResponseEntity<Subject> getSubjectByName(@PathVariable("subject") String subject){
Subject getSubject = subjectService.getSubjectByName(subject);
return ResponseEntity.ok(getSubject);
}

@GetMapping("/{subject}/versions/{version}/schema")
public ResponseEntity<SubjectWithSchema> getSchemaBySubjectAndVersion(@PathVariable("subject")String subject, @PathVariable("version")int version){
SubjectWithSchema subjectWithSchema = subjectService.getSchemaBySubjectAndVersion(subject, version);
return ResponseEntity.ok(subjectWithSchema);
}

@PostMapping("/subjects/{subject}/versions")
public ResponseEntity<SchemaIdResponse> checkOrRegisterSchema(@PathVariable("subject") String subject, @RequestBody Schema schema){
SchemaIdResponse schemaIdResponse = subjectService.checkOrRegisterSchema(subject, schema);
return ResponseEntity.ok(schemaIdResponse);
}

@PostMapping("/subjects/{subject}")
public ResponseEntity<Subject> updateSubjectIfDifferent(@PathVariable("subject") String subjectName, @RequestBody Subject subject){
Subject updatedSubject = subjectService.updateSubjectIfDifferent(subjectName, subject);
return ResponseEntity.ok(updatedSubject);
}

@DeleteMapping("/subjects/{subject}/versions/{version}")
public ResponseEntity<Integer> deleteSchemaBySubjectAndVersion(@PathVariable("subject")String subject, @PathVariable("version") int version){
Integer deletedId = subjectService.deleteSchemaBySubjectAndVersion(subject, version);
return ResponseEntity.ok(deletedId);
}
}

0 comments on commit c0d6dcf

Please sign in to comment.