/* * Copyright 2016-2017 the original author or authors. * * 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.springframework.cloud.stream.schema.server; import java.util.List; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.cloud.stream.schema.server.config.SchemaServerProperties; import org.springframework.cloud.stream.schema.server.model.Schema; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.context.WebApplicationContext; import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD; /** * @author Vinicius Carvalho * @author Ilayaperumal Gopinathan */ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD) public class SchemaRegistryServerAvroTests { final String USER_SCHEMA_V1 = "{\"namespace\": \"example.avro\",\n" + " \"type\": \"record\",\n" + " \"name\": \"User\",\n" + " \"fields\": [\n" + " {\"name\": \"name\", \"type\": \"string\"},\n" + " {\"name\": \"favorite_number\", \"type\": [\"int\", \"null\"]}\n" + " ]\n" + "}"; final String USER_SCHEMA_V2 = "{\"namespace\": \"example.avro\",\n" + " \"type\": \"record\",\n" + " \"name\": \"User\",\n" + " \"fields\": [\n" + " {\"name\": \"name\", \"type\": \"string\"},\n" + " {\"name\": \"favorite_number\", \"type\": [\"int\", \"null\"]},\n" + " {\"name\": \"favorite_color\", \"type\": [\"string\", \"null\"]}\n" + " ]\n" + "}"; @Autowired private TestRestTemplate client; @Autowired private SchemaServerProperties schemaServerProperties; @Autowired private WebApplicationContext wac; @Test public void testUnsupportedFormat() throws Exception { Schema schema = new Schema(); schema.setFormat("spring"); schema.setSubject("boot"); ResponseEntity<Schema> response = client.postForEntity("http://localhost:8990/", schema, Schema.class); Assert.assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); } @Test public void testInvalidSchema() throws Exception { Schema schema = new Schema(); schema.setFormat("avro"); schema.setSubject("boot"); schema.setDefinition("{}"); ResponseEntity<Schema> response = client.postForEntity("http://localhost:8990/", schema, Schema.class); Assert.assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); } @Test public void testUserSchemaV1() throws Exception { Schema schema = new Schema(); schema.setFormat("avro"); schema.setSubject("org.springframework.cloud.stream.schema.User"); schema.setDefinition(USER_SCHEMA_V1); ResponseEntity<Schema> response = client.postForEntity("http://localhost:8990/", schema, Schema.class); Assert.assertTrue(response.getStatusCode().is2xxSuccessful()); Assert.assertEquals(new Integer(1), response.getBody().getVersion()); List<String> location = response.getHeaders().get(HttpHeaders.LOCATION); Assert.assertNotNull(location); ResponseEntity<Schema> persistedSchema = client.getForEntity(location.get(0), Schema.class); Assert.assertEquals(response.getBody().getId(), persistedSchema.getBody().getId()); } @Test public void testUserSchemaV2() throws Exception { Schema schema = new Schema(); schema.setFormat("avro"); schema.setSubject("org.springframework.cloud.stream.schema.User"); schema.setDefinition(USER_SCHEMA_V1); Schema schema2 = new Schema(); schema2.setFormat("avro"); schema2.setSubject("org.springframework.cloud.stream.schema.User"); schema2.setDefinition(USER_SCHEMA_V2); ResponseEntity<Schema> response = client.postForEntity("http://localhost:8990/", schema, Schema.class); Assert.assertTrue(response.getStatusCode().is2xxSuccessful()); Assert.assertEquals(new Integer(1), response.getBody().getVersion()); List<String> location = response.getHeaders().get(HttpHeaders.LOCATION); Assert.assertNotNull(location); ResponseEntity<Schema> response2 = client.postForEntity("http://localhost:8990/", schema2, Schema.class); Assert.assertTrue(response.getStatusCode().is2xxSuccessful()); Assert.assertEquals(new Integer(2), response2.getBody().getVersion()); List<String> location2 = response2.getHeaders().get(HttpHeaders.LOCATION); Assert.assertNotNull(location2); } @Test public void testIdempotentRegistration() throws Exception { Schema schema = new Schema(); schema.setFormat("avro"); schema.setSubject("org.springframework.cloud.stream.schema.User"); schema.setDefinition(USER_SCHEMA_V1); ResponseEntity<Schema> response = client.postForEntity("http://localhost:8990/", schema, Schema.class); Assert.assertTrue(response.getStatusCode().is2xxSuccessful()); Assert.assertEquals(new Integer(1), response.getBody().getVersion()); List<String> location = response.getHeaders().get(HttpHeaders.LOCATION); Assert.assertNotNull(location); ResponseEntity<Schema> response2 = client.postForEntity("http://localhost:8990/", schema, Schema.class); Assert.assertEquals(response.getBody().getId(), response2.getBody().getId()); } @Test public void testSchemaNotfound() throws Exception { ResponseEntity<Schema> response = client .getForEntity("http://localhost:8990/foo/avro/v42", Schema.class); Assert.assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()); } @Test public void testSchemaDeletionBySubjectFormatVersion() throws Exception { Schema schema = new Schema(); schema.setFormat("avro"); schema.setSubject("test"); schema.setDefinition(USER_SCHEMA_V1); ResponseEntity<Schema> response1 = client.postForEntity("http://localhost:8990/", schema, Schema.class); Assert.assertTrue(response1.getStatusCode().is2xxSuccessful()); schemaServerProperties.setAllowSchemaDeletion(true); client.delete("http://localhost:8990/test/avro/v1"); ResponseEntity<Schema> response2 = client .getForEntity("http://localhost:8990/test/avro/v1", Schema.class); Assert.assertEquals(HttpStatus.NOT_FOUND, response2.getStatusCode()); } @Test public void testSchemaDeletionById() throws Exception { Schema schema = new Schema(); schema.setFormat("avro"); schema.setSubject("test"); schema.setDefinition(USER_SCHEMA_V1); ResponseEntity<Schema> response1 = client.postForEntity("http://localhost:8990/", schema, Schema.class); Assert.assertTrue(response1.getStatusCode().is2xxSuccessful()); ResponseEntity<Schema> response2 = client .getForEntity("http://localhost:8990/test/avro/v1", Schema.class); Assert.assertEquals(HttpStatus.OK, response2.getStatusCode()); schemaServerProperties.setAllowSchemaDeletion(true); client.delete("http://localhost:8990/schemas/1"); ResponseEntity<Schema> response3 = client .getForEntity("http://localhost:8990/test/avro/1", Schema.class); Assert.assertEquals(HttpStatus.NOT_FOUND, response3.getStatusCode()); } @Test public void testSchemaDeletionBySubject() throws Exception { Schema schema1 = new Schema(); schema1.setFormat("avro"); schema1.setSubject("test"); schema1.setDefinition(USER_SCHEMA_V1); ResponseEntity<Schema> response1 = client.postForEntity("http://localhost:8990/", schema1, Schema.class); Assert.assertTrue(response1.getStatusCode().is2xxSuccessful()); Assert.assertEquals(HttpStatus.OK, client.getForEntity("http://localhost:8990/test/avro/v1", Schema.class).getStatusCode()); client.getForEntity("http://localhost:8990/test/avro/1", Schema.class); Schema schema2 = new Schema(); schema2.setFormat("avro"); schema2.setSubject("test"); schema2.setDefinition(USER_SCHEMA_V2); ResponseEntity<Schema> response2 = client.postForEntity("http://localhost:8990/", schema2, Schema.class); Assert.assertTrue(response2.getStatusCode().is2xxSuccessful()); Assert.assertEquals(HttpStatus.OK, client.getForEntity("http://localhost:8990/test/avro/v2", Schema.class).getStatusCode()); schemaServerProperties.setAllowSchemaDeletion(true); client.delete("http://localhost:8990/test"); ResponseEntity<Schema> response4 = client .getForEntity("http://localhost:8990/test/avro/v1", Schema.class); Assert.assertEquals(HttpStatus.NOT_FOUND, response4.getStatusCode()); ResponseEntity<Schema> response5 = client .getForEntity("http://localhost:8990/test/avro/v2", Schema.class); Assert.assertEquals(HttpStatus.NOT_FOUND, response5.getStatusCode()); } @Test public void testSchemaDeletionNotAllowed() throws Exception { Schema schema = new Schema(); schema.setFormat("avro"); schema.setSubject("test"); schema.setDefinition(USER_SCHEMA_V1); ResponseEntity<Schema> response1 = client.postForEntity("http://localhost:8990/", schema, Schema.class); Assert.assertTrue(response1.getStatusCode().is2xxSuccessful()); ResponseEntity<Object> deleteBySubjectFormatVersion = client.exchange("http://localhost:8990/test/avro/v1", HttpMethod.DELETE, null, Object.class); assertThat(deleteBySubjectFormatVersion.getStatusCode()).isEqualTo(HttpStatus.METHOD_NOT_ALLOWED); ResponseEntity<Object> deleteBySubject = client.exchange("http://localhost:8990/test", HttpMethod.DELETE, null, Object.class); assertThat(deleteBySubject.getStatusCode()).isEqualTo(HttpStatus.METHOD_NOT_ALLOWED); ResponseEntity<Object> deleteById = client.exchange("http://localhost:8990/schemas/1", HttpMethod.DELETE, null, Object.class); assertThat(deleteById.getStatusCode()).isEqualTo(HttpStatus.METHOD_NOT_ALLOWED); } @Test public void testFindSchemasBySubjectAndVersion() throws Exception { Schema v1 = new Schema(); v1.setFormat("avro"); v1.setSubject("test"); v1.setDefinition(USER_SCHEMA_V1); ResponseEntity<Schema> response1 = client.postForEntity("http://localhost:8990/", v1, Schema.class); Assert.assertTrue(response1.getStatusCode().is2xxSuccessful()); Schema v2 = new Schema(); v2.setFormat("avro"); v2.setSubject("test"); v2.setDefinition(USER_SCHEMA_V2); ResponseEntity<Schema> response2 = client.postForEntity("http://localhost:8990/", v2, Schema.class); Assert.assertTrue(response2.getStatusCode().is2xxSuccessful()); ResponseEntity<List<Schema>> schemaResponse = client.exchange("http://localhost:8990/test/avro", HttpMethod.GET, null, new ParameterizedTypeReference<List<Schema>>() { }); Assert.assertTrue(schemaResponse.getStatusCode().is2xxSuccessful()); Assert.assertEquals(2, schemaResponse.getBody().size()); } }