diff --git a/integrations/spring/opendal-spring-boot-starter-reactive/src/main/java/org/apache/opendal/spring/config/OpenDALReactiveAutoConfiguration.java b/integrations/spring/opendal-spring-boot-starter-reactive/src/main/java/org/apache/opendal/spring/config/OpenDALReactiveAutoConfiguration.java index 7abee7ad917..76cca8645e6 100644 --- a/integrations/spring/opendal-spring-boot-starter-reactive/src/main/java/org/apache/opendal/spring/config/OpenDALReactiveAutoConfiguration.java +++ b/integrations/spring/opendal-spring-boot-starter-reactive/src/main/java/org/apache/opendal/spring/config/OpenDALReactiveAutoConfiguration.java @@ -19,6 +19,8 @@ package org.apache.opendal.spring.config; +import org.apache.opendal.spring.core.DefaultOpenDALSerializerFactory; +import org.apache.opendal.spring.core.OpenDALSerializerFactory; import org.apache.opendal.spring.core.ReactiveOpenDALTemplate; import org.apache.opendal.spring.core.OpenDALProperties; import org.apache.opendal.spring.core.ReactiveOpenDALOperations; @@ -41,4 +43,10 @@ public OpenDALReactiveAutoConfiguration(OpenDALProperties openDALProperties) { public ReactiveOpenDALTemplate reactiveOpendalTemplate(OpenDALProperties openDALProperties) { return new ReactiveOpenDALTemplate(openDALProperties); } + + @Bean + @ConditionalOnMissingBean(name = "openDALSerializerFactory") + public OpenDALSerializerFactory openDALSerializerFactory() { + return new DefaultOpenDALSerializerFactory(); + } } diff --git a/integrations/spring/opendal-spring-boot-starter-reactive/src/test/java/org/apache/opendal/spring/config/OpenDALReactiveAutoConfigurationTest.java b/integrations/spring/opendal-spring-boot-starter-reactive/src/test/java/org/apache/opendal/spring/config/OpenDALReactiveAutoConfigurationTest.java index 9fbd22b5b65..75f14ecb4c9 100644 --- a/integrations/spring/opendal-spring-boot-starter-reactive/src/test/java/org/apache/opendal/spring/config/OpenDALReactiveAutoConfigurationTest.java +++ b/integrations/spring/opendal-spring-boot-starter-reactive/src/test/java/org/apache/opendal/spring/config/OpenDALReactiveAutoConfigurationTest.java @@ -21,6 +21,7 @@ import org.apache.opendal.spring.TestReactiveApplication; import org.apache.opendal.spring.core.OpenDALProperties; +import org.apache.opendal.spring.core.OpenDALSerializerFactory; import org.apache.opendal.spring.core.ReactiveOpenDALOperations; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -38,6 +39,9 @@ public class OpenDALReactiveAutoConfigurationTest { @Autowired private ReactiveOpenDALOperations openDALReactive; + @Autowired + private OpenDALSerializerFactory openDALSerializerFactory; + @Test public void propertiesBeanShouldBeDeclared() { Assertions.assertNotNull(openDALProperties); @@ -53,4 +57,9 @@ public void reactiveBeanShouldBeDeclared() { Assertions.assertInstanceOf(ReactiveOpenDALOperations.class, openDALReactive); } + @Test + public void serializerFactoryBeanShouldBeDeclared() { + Assertions.assertNotNull(openDALSerializerFactory); + } + } diff --git a/integrations/spring/opendal-spring-boot-starter/src/main/java/org/apache/opendal/spring/config/OpenDALAutoConfiguration.java b/integrations/spring/opendal-spring-boot-starter/src/main/java/org/apache/opendal/spring/config/OpenDALAutoConfiguration.java index dfe864acee4..e39b3f684ad 100644 --- a/integrations/spring/opendal-spring-boot-starter/src/main/java/org/apache/opendal/spring/config/OpenDALAutoConfiguration.java +++ b/integrations/spring/opendal-spring-boot-starter/src/main/java/org/apache/opendal/spring/config/OpenDALAutoConfiguration.java @@ -19,7 +19,9 @@ package org.apache.opendal.spring.config; +import org.apache.opendal.spring.core.DefaultOpenDALSerializerFactory; import org.apache.opendal.spring.core.OpenDALOperations; +import org.apache.opendal.spring.core.OpenDALSerializerFactory; import org.apache.opendal.spring.core.OpenDALTemplate; import org.apache.opendal.spring.core.OpenDALProperties; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -41,4 +43,10 @@ public OpenDALAutoConfiguration(OpenDALProperties openDALProperties) { public OpenDALTemplate opendalTemplate(OpenDALProperties openDALProperties) { return new OpenDALTemplate(openDALProperties); } + + @Bean + @ConditionalOnMissingBean(name = "openDALSerializerFactory") + public OpenDALSerializerFactory openDALSerializerFactory() { + return new DefaultOpenDALSerializerFactory(); + } } diff --git a/integrations/spring/opendal-spring-boot-starter/src/test/java/org/apache/opendal/spring/config/OpenDALAutoConfigurationTest.java b/integrations/spring/opendal-spring-boot-starter/src/test/java/org/apache/opendal/spring/config/OpenDALAutoConfigurationTest.java index 4306007c8eb..f876f4b8d18 100644 --- a/integrations/spring/opendal-spring-boot-starter/src/test/java/org/apache/opendal/spring/config/OpenDALAutoConfigurationTest.java +++ b/integrations/spring/opendal-spring-boot-starter/src/test/java/org/apache/opendal/spring/config/OpenDALAutoConfigurationTest.java @@ -22,6 +22,7 @@ import org.apache.opendal.spring.TestApplication; import org.apache.opendal.spring.core.OpenDALOperations; import org.apache.opendal.spring.core.OpenDALProperties; +import org.apache.opendal.spring.core.OpenDALSerializerFactory; import org.apache.opendal.spring.core.OpenDALTemplate; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -38,6 +39,9 @@ public class OpenDALAutoConfigurationTest { @Autowired private OpenDALOperations openDAL; + @Autowired + private OpenDALSerializerFactory openDALSerializerFactory; + @Test public void propertiesBeanShouldBeDeclared() { Assertions.assertNotNull(openDALProperties); @@ -52,4 +56,9 @@ public void beanShouldBeDeclared() { Assertions.assertNotNull(openDAL); Assertions.assertInstanceOf(OpenDALTemplate.class, openDAL); } + + @Test + public void serializerFactoryBeanShouldBeDeclared() { + Assertions.assertNotNull(openDALSerializerFactory); + } } diff --git a/integrations/spring/opendal-spring/pom.xml b/integrations/spring/opendal-spring/pom.xml index 8524a5d9391..8c638da0164 100644 --- a/integrations/spring/opendal-spring/pom.xml +++ b/integrations/spring/opendal-spring/pom.xml @@ -41,6 +41,15 @@ org.springframework.boot spring-boot + + com.fasterxml.jackson.core + jackson-databind + + + org.junit.jupiter + junit-jupiter + test + diff --git a/integrations/spring/opendal-spring/src/main/java/org/apache/opendal/spring/core/DefaultOpenDALSerializer.java b/integrations/spring/opendal-spring/src/main/java/org/apache/opendal/spring/core/DefaultOpenDALSerializer.java new file mode 100644 index 00000000000..59d9add06a5 --- /dev/null +++ b/integrations/spring/opendal-spring/src/main/java/org/apache/opendal/spring/core/DefaultOpenDALSerializer.java @@ -0,0 +1,61 @@ +/* + * 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.opendal.spring.core; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.opendal.OpenDALException; + +public class DefaultOpenDALSerializer implements OpenDALSerializer { + private static final ObjectMapper MAPPER = new ObjectMapper(); + + static { + MAPPER.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false); + MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + private final Class clazz; + + public DefaultOpenDALSerializer(Class clazz) { + this.clazz = clazz; + } + + public static DefaultOpenDALSerializer of(Class clazz) { + return new DefaultOpenDALSerializer<>(clazz); + } + + @Override + public byte[] serialize(T t) throws OpenDALException { + try { + return MAPPER.writeValueAsBytes(t); + } catch (Exception e) { + throw new OpenDALException(OpenDALException.Code.Unexpected, e.toString()); + } + } + + @Override + public T deserialize(byte[] bytes) throws OpenDALException { + try { + return MAPPER.readValue(bytes, clazz); + } catch (Exception e) { + throw new OpenDALException(OpenDALException.Code.Unexpected, e.toString()); + } + } +} diff --git a/integrations/spring/opendal-spring/src/main/java/org/apache/opendal/spring/core/DefaultOpenDALSerializerFactory.java b/integrations/spring/opendal-spring/src/main/java/org/apache/opendal/spring/core/DefaultOpenDALSerializerFactory.java new file mode 100644 index 00000000000..1250d4e641b --- /dev/null +++ b/integrations/spring/opendal-spring/src/main/java/org/apache/opendal/spring/core/DefaultOpenDALSerializerFactory.java @@ -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. + */ + +package org.apache.opendal.spring.core; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class DefaultOpenDALSerializerFactory implements OpenDALSerializerFactory { + private final Map, OpenDALSerializer> serializerMap = new ConcurrentHashMap<>(); + + @SuppressWarnings("unchecked") + @Override + public OpenDALSerializer getSerializer(Class clazz) { + return (OpenDALSerializer) serializerMap.computeIfAbsent(clazz, DefaultOpenDALSerializer::of); + } +} diff --git a/integrations/spring/opendal-spring/src/main/java/org/apache/opendal/spring/core/OpenDALSerializer.java b/integrations/spring/opendal-spring/src/main/java/org/apache/opendal/spring/core/OpenDALSerializer.java new file mode 100644 index 00000000000..1350954db53 --- /dev/null +++ b/integrations/spring/opendal-spring/src/main/java/org/apache/opendal/spring/core/OpenDALSerializer.java @@ -0,0 +1,28 @@ +/* + * 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.opendal.spring.core; + +import org.apache.opendal.OpenDALException; + +public interface OpenDALSerializer { + byte[] serialize(T t) throws OpenDALException; + + T deserialize(byte[] bytes) throws OpenDALException; +} diff --git a/integrations/spring/opendal-spring/src/main/java/org/apache/opendal/spring/core/OpenDALSerializerFactory.java b/integrations/spring/opendal-spring/src/main/java/org/apache/opendal/spring/core/OpenDALSerializerFactory.java new file mode 100644 index 00000000000..d3b6a05e533 --- /dev/null +++ b/integrations/spring/opendal-spring/src/main/java/org/apache/opendal/spring/core/OpenDALSerializerFactory.java @@ -0,0 +1,24 @@ +/* + * 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.opendal.spring.core; + +public interface OpenDALSerializerFactory { + OpenDALSerializer getSerializer(Class clazz); +} diff --git a/integrations/spring/opendal-spring/src/test/java/org/apache/opendal/spring/core/DefaultOpenDALSerializerFactoryTest.java b/integrations/spring/opendal-spring/src/test/java/org/apache/opendal/spring/core/DefaultOpenDALSerializerFactoryTest.java new file mode 100644 index 00000000000..73c80ceaaf7 --- /dev/null +++ b/integrations/spring/opendal-spring/src/test/java/org/apache/opendal/spring/core/DefaultOpenDALSerializerFactoryTest.java @@ -0,0 +1,39 @@ +/* + * 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.opendal.spring.core; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class DefaultOpenDALSerializerFactoryTest { + private OpenDALSerializerFactory factory; + + @BeforeEach + void setUp() { + factory = new DefaultOpenDALSerializerFactory(); + } + + @Test + void getSerializerSuccess() { + OpenDALSerializer serializer = factory.getSerializer(DefaultOpenDALSerializerFactoryTest.class); + Assertions.assertNotNull(serializer); + } +}