#589 - Add Cassandra reactive SpEL example.
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2020 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 example.springdata.cassandra.spel;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Value;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.spel.spi.EvaluationContextExtension;
|
||||
import org.springframework.data.spel.spi.ReactiveEvaluationContextExtension;
|
||||
|
||||
/**
|
||||
* Simple configuration for reactive Cassandra SpEL support.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@SpringBootApplication
|
||||
class ApplicationConfiguration {
|
||||
|
||||
@Bean
|
||||
ReactiveTenantExtension tenantExtension() {
|
||||
return ReactiveTenantExtension.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension that looks up a {@link Tenant} from the {@link reactor.util.context.Context}.
|
||||
*/
|
||||
enum ReactiveTenantExtension implements ReactiveEvaluationContextExtension {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Mono<? extends EvaluationContextExtension> getExtension() {
|
||||
return Mono.deferContextual(contextView -> Mono.just(new TenantExtension(contextView.get(Tenant.class))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtensionId() {
|
||||
return "my-reactive-tenant-extension";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actual extension providing access to the {@link Tenant} value object.
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
static class TenantExtension implements EvaluationContextExtension {
|
||||
|
||||
private final Tenant tenant;
|
||||
|
||||
@Override
|
||||
public String getExtensionId() {
|
||||
return "my-tenant-extension";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tenant getRootObject() {
|
||||
return tenant;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The root object.
|
||||
*/
|
||||
@Value
|
||||
public static class Tenant {
|
||||
|
||||
String tenantId;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2020 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 example.springdata.cassandra.spel;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
import org.springframework.data.cassandra.core.cql.PrimaryKeyType;
|
||||
import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn;
|
||||
import org.springframework.data.cassandra.core.mapping.Table;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Value
|
||||
@Table
|
||||
public class Employee {
|
||||
|
||||
@PrimaryKeyColumn(type = PrimaryKeyType.PARTITIONED) String tenantId;
|
||||
@PrimaryKeyColumn(type = PrimaryKeyType.CLUSTERED) String name;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2020 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 example.springdata.cassandra.spel;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.data.cassandra.repository.Query;
|
||||
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public interface EmployeeRepository extends ReactiveCrudRepository<Employee, String> {
|
||||
|
||||
@Query("SELECT * FROM employee WHERE tenantId = :#{getTenantId()} AND name = :name")
|
||||
Flux<Employee> findAllByName(String name);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2020 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 example.springdata.cassandra.spel;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import example.springdata.cassandra.spel.ApplicationConfiguration.Tenant;
|
||||
import example.springdata.cassandra.util.CassandraKeyspace;
|
||||
import reactor.test.StepVerifier;
|
||||
import reactor.util.context.Context;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.data.cassandra.DataCassandraTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Integration tests showing the SpEL context extension in action.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@DataCassandraTest
|
||||
public class ExpressionIntegrationTests {
|
||||
|
||||
@ClassRule public final static CassandraKeyspace CASSANDRA_KEYSPACE = CassandraKeyspace.onLocalhost();
|
||||
|
||||
@Autowired EmployeeRepository employeeRepository;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
employeeRepository.deleteAll().as(StepVerifier::create).verifyComplete();
|
||||
|
||||
employeeRepository
|
||||
.saveAll(Arrays.asList(new Employee("breaking-bad", "Walter"), new Employee("breaking-bad", "Hank"),
|
||||
new Employee("south-park", "Hank"))) //
|
||||
.as(StepVerifier::create) //
|
||||
.expectNextCount(3) //
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindByTenantIdAndName() {
|
||||
|
||||
employeeRepository.findAllByName("Walter") //
|
||||
.contextWrite(Context.of(Tenant.class, new Tenant("breaking-bad"))).as(StepVerifier::create) //
|
||||
.assertNext(actual -> {
|
||||
assertThat(actual.getTenantId()).isEqualTo("breaking-bad");
|
||||
}).verifyComplete();
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user