Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Protostream #18

Merged
merged 1 commit into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Refer to the comprehensive [documentation](https://docs.quarkiverse.io/quarkus-i

## Samples

Check out the [samples](https://github.com/quarkiverse/quarkus-infinispan-embedded/tree/main/sample).
Check out the [sample](https://github.com/quarkiverse/quarkus-infinispan-embedded/tree/main/sample).

## Getting Started

Expand All @@ -34,8 +34,6 @@ Feel free to contribute to this project by submitting issues or pull requests.
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.




## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
Expand All @@ -46,6 +44,8 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wburns"><img src="https://avatars.githubusercontent.com/u/648175?v=4?s=100" width="100px;" alt="Will Burns"/><br /><sub><b>Will Burns</b></sub></a><br /><a href="https://github.com/quarkiverse/quarkus-infinispan-embedded/commits?author=wburns" title="Code">💻</a> <a href="#maintenance-wburns" title="Maintenance">🚧</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ryanemerson"><img src="https://avatars.githubusercontent.com/u/765332?v=4?s=100" width="100px;" alt="Ryan Emerson"/><br /><sub><b>Ryan Emerson</b></sub></a><br /><a href="https://github.com/quarkiverse/quarkus-infinispan-embedded/commits?author=ryanemerson" title="Code">💻</a> <a href="#maintenance-ryanemerson" title="Maintenance">🚧</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/karesti"><img src="https://avatars.githubusercontent.com/u/233499?v=4?s=100" width="100px;" alt="Katia Aresti"/><br /><sub><b>Katia Aresti</b></sub></a><br /><a href="https://github.com/quarkiverse/quarkus-infinispan-embedded/commits?author=karesti" title="Code">💻</a> <a href="#maintenance-karesti" title="Maintenance">🚧</a></td>
</tr>
</tbody>
Expand Down
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/includes/attributes.adoc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
:project-version: 1.0.0
:infinispan-version: 15.0.8.Final
:infinispan-version: 15.0.11.Final
:examples-dir: ./../examples/
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,19 @@
import org.infinispan.configuration.parsing.ConfigurationParser;
import org.infinispan.configuration.serializing.ConfigurationSerializer;
import org.infinispan.factories.impl.ModuleMetadataBuilder;
import org.infinispan.health.CacheHealth;
import org.infinispan.health.ClusterHealth;
import org.infinispan.interceptors.AsyncInterceptor;
import org.infinispan.notifications.Listener;
import org.infinispan.persistence.spi.CacheWriter;
import org.infinispan.persistence.spi.NonBlockingStore;
import org.infinispan.protostream.BaseMarshaller;
import org.infinispan.protostream.EnumMarshaller;
import org.infinispan.protostream.FileDescriptorSource;
import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.MessageMarshaller;
import org.infinispan.protostream.SerializationContextInitializer;
import org.infinispan.protostream.schema.Schema;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.ClassInfo;
Expand All @@ -34,6 +43,7 @@
import io.quarkiverse.infinispan.embedded.runtime.InfinispanEmbeddedRuntimeConfig;
import io.quarkiverse.infinispan.embedded.runtime.InfinispanRecorder;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
Expand All @@ -58,6 +68,7 @@ FeatureBuildItem feature() {
@BuildStep
void addInfinispanDependencies(BuildProducer<IndexDependencyBuildItem> indexDependency) {
indexDependency.produce(new IndexDependencyBuildItem("org.jgroups", "jgroups"));
indexDependency.produce(new IndexDependencyBuildItem("org.jgroups", "jgroups-raft"));
indexDependency.produce(new IndexDependencyBuildItem("org.infinispan", "infinispan-commons"));
indexDependency.produce(new IndexDependencyBuildItem("org.infinispan", "infinispan-core"));
indexDependency.produce(new IndexDependencyBuildItem("org.infinispan", "infinispan-cachestore-jdbc-common"));
Expand Down Expand Up @@ -85,6 +96,25 @@ void setup(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
}
}

// Protostream
Index index = applicationIndexBuildItem.getIndex();
Collection<ClassInfo> initializerClasses = index.getAllKnownImplementors(DotName.createSimple(
SerializationContextInitializer.class.getName()));
initializerClasses
.addAll(index.getAllKnownImplementors(DotName.createSimple(GeneratedSchema.class.getName())));
Set<String> initializers = new HashSet<>(initializerClasses.size());
for (ClassInfo ci : initializerClasses) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to load the class here? I'm not sure this will always work depending on the classpath (I could be wrong).

Can we not use public ServiceProviderBuildItem(String serviceInterfaceClassName, List<String> providers) which does not require a Class object?

Copy link
Contributor Author

@karesti karesti Dec 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ryanemerson This is the way it is done in the infinispan client to make it work. I don't know if what you mentions works, I will try

Class<?> initializerClass = null;
try {
initializerClass = Thread.currentThread().getContextClassLoader().loadClass(ci.toString());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
initializers.add(initializerClass.getName());
}
serviceProvider
.produce(new ServiceProviderBuildItem(SerializationContextInitializer.class.getName(), initializers));

Set<DotName> excludedClasses = new HashSet<>();
excludedReflectionClasses.forEach(excludedBuildItem -> {
excludedClasses.add(excludedBuildItem.getExcludedClass());
Expand Down Expand Up @@ -124,6 +154,8 @@ void setup(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
// Due to the index not containing AbstractExternalizer it doesn't know that it implements AdvancedExternalizer
// thus we also have to include classes that extend AbstractExternalizer
addReflectionForClass(AbstractExternalizer.class, appOnlyIndex, reflectiveClass, Collections.emptySet());
addReflectionForClass(CacheHealth.class, appOnlyIndex, reflectiveClass, Collections.emptySet());
addReflectionForClass(ClusterHealth.class, appOnlyIndex, reflectiveClass, Collections.emptySet());

// Add optional SQL classes. These will only be included if the optional jars are present on the classpath and indexed by Jandex.
addReflectionForName("org.infinispan.persistence.jdbc.common.configuration.ConnectionFactoryConfiguration", true,
Expand Down Expand Up @@ -180,6 +212,12 @@ private void addReflectionForName(String className, boolean isInterface, IndexVi
}
}

@BuildStep
UnremovableBeanBuildItem ensureBeanLookupAvailable() {
return UnremovableBeanBuildItem.beanTypes(BaseMarshaller.class, EnumMarshaller.class, MessageMarshaller.class,
FileDescriptorSource.class, Schema.class, SerializationContextInitializer.class);
}

@Record(ExecutionTime.RUNTIME_INIT)
@BuildStep
void configureRuntimeProperties(InfinispanRecorder recorder, InfinispanEmbeddedRuntimeConfig runtimeConfig) {
Expand Down
8 changes: 7 additions & 1 deletion extension/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core-graalvm</artifactId>
<exclusions>
<exclusion>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jgroups</groupId>
Expand Down Expand Up @@ -80,7 +86,7 @@
</dependency>
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
<artifactId>nativeimage</artifactId>
</dependency>
<!-- We need to make these dependencies non-optional in order to have the native compilation working -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.quarkiverse.infinispan.embedded.runtime;

public class InfinispanEmbeddedException extends RuntimeException {
private static final long serialVersionUID = 1L;

public InfinispanEmbeddedException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ EmbeddedCacheManager manager() {
return new DefaultCacheManager(configHolder, true);
} catch (IOException e) {
Log.error(e);
throw new RuntimeException(e);
throw new InfinispanEmbeddedException(
String.format("Unable to create the EmbeddedCacheManager with the xmlConfig %s", configurationFile), e);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.infinispan.quarkus.embedded;

import org.infinispan.protostream.GeneratedSchema;
import org.infinispan.protostream.annotations.Proto;
import org.infinispan.protostream.annotations.ProtoSchema;

@Proto
public record Book(String name, String author) {

@ProtoSchema(includeClasses = Book.class, schemaPackageName = "it.quarkus")
public interface BookSchema extends GeneratedSchema {

}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.infinispan.quarkus.embedded;

import static org.infinispan.commons.dataconversion.MediaType.APPLICATION_PROTOSTREAM;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
Expand All @@ -10,13 +12,15 @@
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;

import org.infinispan.Cache;
import org.infinispan.commons.api.CacheContainerAdmin;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
Expand Down Expand Up @@ -117,4 +121,29 @@ public String simpleCluster() throws IOException {
}
return "Success";
}

@Path("PROTO/GET/books/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Book get(@PathParam("id") String id) {
Cache<String, Book> books = emc.administration()
.withFlags(CacheContainerAdmin.AdminFlag.VOLATILE)
.getOrCreateCache("books", new ConfigurationBuilder()
.encoding().mediaType(APPLICATION_PROTOSTREAM)
.build());
return books.get(id);
}

@Path("PROTO/POST/books/{id}")
@POST
@Produces(MediaType.TEXT_PLAIN)
public String create(@PathParam("id") String id, Book book) {
Cache<String, Book> books = emc.administration()
.withFlags(CacheContainerAdmin.AdminFlag.VOLATILE)
.getOrCreateCache("books", new ConfigurationBuilder()
.encoding().mediaType(APPLICATION_PROTOSTREAM)
.build());
books.put(id, book);
return id;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
quarkus.infinispan-embedded.xml-config=embedded.xml
quarkus.log.console.level=INFO
quarkus.log.category."org.infinispan".level=TRACE
quarkus.log.category."org.infinispan".level=DEBUG
quarkus.native.resources.includes=stacks/udp.xml,stacks.tcp.xml,stacks/tcp_mping/tcp1.xml,stacks/tcp_mping/tcp2.xml,embedded.xml,dist.xml
quarkus.datasource.db-kind=postgresql
quarkus.datasource.devservices.init-script-path=import.sql
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.infinispan.quarkus.embedded;

import static io.restassured.RestAssured.given;
import static io.restassured.RestAssured.when;
import static org.hamcrest.Matchers.is;

Expand All @@ -9,12 +10,14 @@
import java.nio.file.Paths;
import java.util.stream.Stream;

import org.hamcrest.CoreMatchers;
import org.infinispan.commons.util.Util;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;

import io.quarkus.logging.Log;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;

/**
* @author William Burns
Expand Down Expand Up @@ -101,4 +104,25 @@ public void testSimpleCluster() {
Log.info("Running cluster test");
when().get("/test/CLUSTER").then().body(is("Success"));
}

@Test
public void testProtostreamCache() {
Log.info("Protostream marshalling class");
given()
.contentType(ContentType.JSON)
.body("{\"name\":\"Infinispan Book\",\"author\":\"Jack Nicholson\"}")
.when()
.post("/test/PROTO/POST/books/123")
.then()
.statusCode(200)
.body(CoreMatchers.is("123"));

given()
.when().get("/test/PROTO/GET/books/123")
.then()
.statusCode(200)
.body(CoreMatchers.is(
"{\"name\":\"Infinispan Book\",\"author\":\"Jack Nicholson\"}"));

}
}
82 changes: 80 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@
<module>docs</module>
</modules>
</profile>

<profile>
<id>it</id>
<activation>
Expand All @@ -120,6 +119,85 @@
<module>sample</module>
</modules>
</profile>

<profile>
<id>format</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>!no-format</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>net.revelc.code.formatter</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>format</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>impsort-maven-plugin</artifactId>
<configuration>
<removeUnused>true</removeUnused>
</configuration>
<executions>
<execution>
<id>sort-imports</id>
<goals>
<goal>sort</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>validate</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>no-format</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>net.revelc.code.formatter</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>validate</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>impsort-maven-plugin</artifactId>
<configuration>
<removeUnused>true</removeUnused>
</configuration>
<executions>
<execution>
<id>check-imports</id>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
14 changes: 14 additions & 0 deletions sample/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<!-- Minimal test dependencies to *-deployment artifacts for consistent build order -->
<dependency>
<groupId>io.quarkiverse.infinispan</groupId>
<artifactId>quarkus-infinispan-embedded-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Loading
Loading