JAMES-2541 Move serialization util to util module
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c37e9fd4 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c37e9fd4 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c37e9fd4 Branch: refs/heads/master Commit: c37e9fd4e0cd0e9f0cff7fbd8cc08c7185cc6b37 Parents: 8d83386 Author: Benoit Tellier <[email protected]> Authored: Wed Sep 5 11:34:48 2018 +0700 Committer: Benoit Tellier <[email protected]> Committed: Mon Sep 10 17:19:38 2018 +0700 ---------------------------------------------------------------------- .../apache/james/util/SerializationUtil.java | 64 +++++++++++ .../james/util/SerializationUtilTest.java | 106 ++++++++++++++++++ .../apache/james/queue/jms/JMSMailQueue.java | 9 +- .../james/queue/jms/JMSSerializationUtils.java | 64 ----------- .../queue/jms/JMSSerializationUtilsTest.java | 107 ------------------- 5 files changed, 175 insertions(+), 175 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/c37e9fd4/server/container/util/src/main/java/org/apache/james/util/SerializationUtil.java ---------------------------------------------------------------------- diff --git a/server/container/util/src/main/java/org/apache/james/util/SerializationUtil.java b/server/container/util/src/main/java/org/apache/james/util/SerializationUtil.java new file mode 100644 index 0000000..3987ad6 --- /dev/null +++ b/server/container/util/src/main/java/org/apache/james/util/SerializationUtil.java @@ -0,0 +1,64 @@ +/**************************************************************** + * 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.james.util; + +import java.io.Serializable; +import java.util.Base64; +import java.util.Optional; + +import org.apache.commons.lang3.SerializationUtils; + +/** + * This class is similar to {@link SerializationUtils}. Unlike {@link SerializationUtils} this class operates with + * {@code String}s and not byte arrays. + * <p> + * The main advantage of this utility is that it introduces an additional operation after serialization and before + * deserialization. The operation consists in encoding/decoding the serialized/deserialized data in Base64, so that data + * can be safely transmitted over the wire. + */ +public class SerializationUtil { + /** + * Serialize the input object using standard mechanisms then encodes result using base64 encoding. + * + * @param obj The object that needs to be serialized. + * + * @return The base64 representation of {@code obj}. + */ + public static String serialize(Serializable obj) { + return Optional.ofNullable(obj) + .map(SerializationUtils::serialize) + .map(Base64.getEncoder()::encodeToString) + .orElse(null); + } + + /** + * Decodes the input base64 string and deserialize it. + * + * @param <T> The resulting type after deserialization. + * @param object The base64 encoded string. + * + * @return The deserialized object. + */ + public static <T extends Serializable> T deserialize(String object) { + return Optional.ofNullable(object) + .map(Base64.getDecoder()::decode) + .<T>map(SerializationUtils::deserialize) + .orElse(null); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/c37e9fd4/server/container/util/src/test/java/org/apache/james/util/SerializationUtilTest.java ---------------------------------------------------------------------- diff --git a/server/container/util/src/test/java/org/apache/james/util/SerializationUtilTest.java b/server/container/util/src/test/java/org/apache/james/util/SerializationUtilTest.java new file mode 100644 index 0000000..c648880 --- /dev/null +++ b/server/container/util/src/test/java/org/apache/james/util/SerializationUtilTest.java @@ -0,0 +1,106 @@ +/**************************************************************** + * 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.james.util; + +import static org.apache.james.util.SerializationUtil.deserialize; +import static org.apache.james.util.SerializationUtil.serialize; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Objects; +import java.util.Optional; + +import org.apache.commons.lang3.SerializationException; +import org.junit.jupiter.api.Test; + +class SerializationUtilTest { + /** + * Serializes and deserializes the provided object. + * + * @param obj The object that needs to be serialized. + * @param <T> The type of the provided object. + * + * @return The provided object. + */ + private static <T extends Serializable> T roundtrip(T obj) { + return Optional.ofNullable(obj) + .map(SerializationUtil::serialize) + .<T>map(SerializationUtil::deserialize) + .orElseThrow(() -> new IllegalArgumentException("Cannot serialize/deserialize: " + obj)); + } + + @Test + void trySerializeShouldReturnString() { + SerializableStringHolder value = new SerializableStringHolder("value"); + + String serializedString = "rO0ABXNyAERvcmcuYXBhY2hlLmphbWVzLnV0aWwuU2VyaWFsaXphdGlvblV0aWxUZXN0JFNlcmlhbGl6Y" + + "WJsZVN0cmluZ0hvbGRlcjk393aULV9XAgABTAAFdmFsdWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHQABXZhbHVl"; + + String actual = serialize(value); + + assertThat(actual).isEqualTo(serializedString); + } + + @Test + void roundTripShouldReturnEqualObject() { + SerializableStringHolder expected = new SerializableStringHolder("value"); + + assertThat(roundtrip(expected)).isEqualTo(expected); + } + + @Test + void deserializeShouldThrowWhenNotBase64StringProvided() { + assertThatExceptionOfType(SerializationException.class) + .isThrownBy(() -> deserialize("abc")); + } + + @Test + void deserializeShouldThrowWhenNotSerializedBytesAreEncodedInBase64() { + assertThatExceptionOfType(SerializationException.class) + .isThrownBy(() -> deserialize(Base64.getEncoder().encodeToString("abc".getBytes(StandardCharsets.UTF_8)))); + } + + private static class SerializableStringHolder implements Serializable { + private final String value; + + SerializableStringHolder(String value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof SerializableStringHolder)) { + return false; + } + SerializableStringHolder that = (SerializableStringHolder) o; + return Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/c37e9fd4/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java b/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java index 4f0496a..ccb9fd1 100644 --- a/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java +++ b/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java @@ -63,6 +63,7 @@ import org.apache.james.queue.api.MailQueueItemDecoratorFactory; import org.apache.james.queue.api.ManageableMailQueue; import org.apache.james.server.core.MailImpl; import org.apache.james.server.core.MimeMessageCopyOnWriteProxy; +import org.apache.james.util.SerializationUtil; import org.apache.mailet.Mail; import org.apache.mailet.PerRecipientHeaders; import org.slf4j.Logger; @@ -323,7 +324,7 @@ public class JMSMailQueue implements ManageableMailQueue, JMSSupport, MailPriori // won't serialize the empty headers so it is mandatory // to handle nulls when reconstructing mail from message if (!mail.getPerRecipientSpecificHeaders().getHeadersByRecipient().isEmpty()) { - props.put(JAMES_MAIL_PER_RECIPIENT_HEADERS, JMSSerializationUtils.serialize(mail.getPerRecipientSpecificHeaders())); + props.put(JAMES_MAIL_PER_RECIPIENT_HEADERS, SerializationUtil.serialize(mail.getPerRecipientSpecificHeaders())); } String recipientsAsString = joiner.join(mail.getRecipients()); @@ -335,7 +336,7 @@ public class JMSMailQueue implements ManageableMailQueue, JMSSupport, MailPriori String sender = Optional.ofNullable(mail.getSender()).map(MailAddress::asString).orElse(""); org.apache.james.util.streams.Iterators.toStream(mail.getAttributeNames()) - .forEach(attrName -> props.put(attrName, JMSSerializationUtils.serialize(mail.getAttribute(attrName)))); + .forEach(attrName -> props.put(attrName, SerializationUtil.serialize(mail.getAttribute(attrName)))); props.put(JAMES_MAIL_ATTRIBUTE_NAMES, joiner.join(mail.getAttributeNames())); props.put(JAMES_MAIL_SENDER, sender); @@ -392,7 +393,7 @@ public class JMSMailQueue implements ManageableMailQueue, JMSSupport, MailPriori mail.setLastUpdated(new Date(message.getLongProperty(JAMES_MAIL_LAST_UPDATED))); mail.setName(message.getStringProperty(JAMES_MAIL_NAME)); - Optional.ofNullable(JMSSerializationUtils.<PerRecipientHeaders>deserialize(message.getStringProperty(JAMES_MAIL_PER_RECIPIENT_HEADERS))) + Optional.ofNullable(SerializationUtil.<PerRecipientHeaders>deserialize(message.getStringProperty(JAMES_MAIL_PER_RECIPIENT_HEADERS))) .ifPresent(mail::addAllSpecificHeaderForRecipient); List<MailAddress> rcpts = new ArrayList<>(); @@ -451,7 +452,7 @@ public class JMSMailQueue implements ManageableMailQueue, JMSSupport, MailPriori Object attrValue = Throwing.function(message::getObjectProperty).apply(name); if (attrValue instanceof String) { - mail.setAttribute(name, JMSSerializationUtils.deserialize((String) attrValue)); + mail.setAttribute(name, SerializationUtil.deserialize((String) attrValue)); } else { LOGGER.error("Not supported mail attribute {} of type {} for mail {}", name, attrValue, mail.getName()); } http://git-wip-us.apache.org/repos/asf/james-project/blob/c37e9fd4/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSSerializationUtils.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSSerializationUtils.java b/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSSerializationUtils.java deleted file mode 100644 index 1e14c3e..0000000 --- a/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSSerializationUtils.java +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************** - * 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.james.queue.jms; - -import java.io.Serializable; -import java.util.Base64; -import java.util.Optional; - -import org.apache.commons.lang3.SerializationUtils; - -/** - * This class is similar to {@link SerializationUtils}. Unlike {@link SerializationUtils} this class operates with - * {@code String}s and not byte arrays. - * <p> - * The main advantage of this utility is that it introduces an additional operation after serialization and before - * deserialization. The operation consists in encoding/decoding the serialized/deserialized data in Base64, so that data - * can be safely transmitted over the wire. - */ -public class JMSSerializationUtils { - /** - * Serialize the input object using standard mechanisms then encodes result using base64 encoding. - * - * @param obj The object that needs to be serialized. - * - * @return The base64 representation of {@code obj}. - */ - public static String serialize(Serializable obj) { - return Optional.ofNullable(obj) - .map(SerializationUtils::serialize) - .map(Base64.getEncoder()::encodeToString) - .orElse(null); - } - - /** - * Decodes the input base64 string and deserialize it. - * - * @param <T> The resulting type after deserialization. - * @param object The base64 encoded string. - * - * @return The deserialized object. - */ - public static <T extends Serializable> T deserialize(String object) { - return Optional.ofNullable(object) - .map(Base64.getDecoder()::decode) - .<T>map(SerializationUtils::deserialize) - .orElse(null); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/c37e9fd4/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSSerializationUtilsTest.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSSerializationUtilsTest.java b/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSSerializationUtilsTest.java deleted file mode 100644 index 6ab010f..0000000 --- a/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSSerializationUtilsTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************** - * 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.james.queue.jms; - -import static org.apache.james.queue.jms.JMSSerializationUtils.deserialize; -import static org.apache.james.queue.jms.JMSSerializationUtils.serialize; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -import java.io.Serializable; -import java.nio.charset.StandardCharsets; -import java.util.Objects; -import java.util.Optional; - -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.lang3.SerializationException; -import org.junit.jupiter.api.Test; - -class JMSSerializationUtilsTest { - /** - * Serializes and deserializes the provided object. - * - * @param obj The object that needs to be serialized. - * @param <T> The type of the provided object. - * - * @return The provided object. - */ - private static <T extends Serializable> T roundtrip(T obj) { - return Optional.ofNullable(obj) - .map(JMSSerializationUtils::serialize) - .<T>map(JMSSerializationUtils::deserialize) - .orElseThrow(() -> new IllegalArgumentException("Cannot serialize/deserialize: " + obj)); - } - - @Test - void trySerializeShouldReturnString() { - SerializableStringHolder value = new SerializableStringHolder("value"); - - String serializedIntegerString = "rO0ABXNyAE1vcmcuYXBhY2hlLmphbWVzLnF1ZXVlLmptcy5KTVNTZXJpYWxp" + - "emF0aW9uVXRpbHNUZXN0JFNlcmlhbGl6YWJsZVN0cmluZ0hvbGRlcsy4/DEA" + - "8nRZAgABTAAFdmFsdWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHQABXZhbHVl"; - - String actual = serialize(value); - - assertThat(actual).isEqualTo(serializedIntegerString); - } - - @Test - void roundTripShouldReturnEqualObject() { - SerializableStringHolder expected = new SerializableStringHolder("value"); - - assertThat(roundtrip(expected)).isEqualTo(expected); - } - - @Test - void deserializeShouldThrowWhenNotBase64StringProvided() { - assertThatExceptionOfType(SerializationException.class) - .isThrownBy(() -> deserialize("abc")); - } - - @Test - void deserializeShouldThrowWhenNotSerializedBytesAreEncodedInBase64() { - assertThatExceptionOfType(SerializationException.class) - .isThrownBy(() -> deserialize(Base64.encodeBase64String("abc".getBytes(StandardCharsets.UTF_8)))); - } - - private static class SerializableStringHolder implements Serializable { - private final String value; - - SerializableStringHolder(String value) { - this.value = value; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof SerializableStringHolder)) { - return false; - } - SerializableStringHolder that = (SerializableStringHolder) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - return Objects.hash(value); - } - } -} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
