From d1ed700380961cf2c738d2947811c397699c0a62 Mon Sep 17 00:00:00 2001 From: Mark Fisher Date: Mon, 18 Feb 2008 14:08:15 +0000 Subject: [PATCH] Using java.util.UUID and default strategy is: UUID.randomUUUID() (INT-111). --- .../adapter/file/AbstractFileMapper.java | 2 +- .../integration/bus/MessageBus.java | 17 +- .../dispatcher/DefaultMessageDispatcher.java | 8 +- .../message/AbstractMessageMapper.java | 18 +- .../integration/message/GenericMessage.java | 24 +-- .../message/SimplePayloadMessageMapper.java | 6 +- .../{UidGenerator.java => IdGenerator.java} | 17 +- .../integration/util/RandomGuid.java | 197 ------------------ .../util/RandomGuidUidGenerator.java | 59 ------ .../integration/util/RandomUuidGenerator.java | 35 ++++ ...sts.java => RandomUuidGeneratorTests.java} | 6 +- 11 files changed, 78 insertions(+), 311 deletions(-) rename spring-integration-core/src/main/java/org/springframework/integration/util/{UidGenerator.java => IdGenerator.java} (62%) delete mode 100644 spring-integration-core/src/main/java/org/springframework/integration/util/RandomGuid.java delete mode 100644 spring-integration-core/src/main/java/org/springframework/integration/util/RandomGuidUidGenerator.java create mode 100644 spring-integration-core/src/main/java/org/springframework/integration/util/RandomUuidGenerator.java rename spring-integration-core/src/test/java/org/springframework/integration/util/{RandomGuidUidGeneratorTests.java => RandomUuidGeneratorTests.java} (85%) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/adapter/file/AbstractFileMapper.java b/spring-integration-core/src/main/java/org/springframework/integration/adapter/file/AbstractFileMapper.java index 8bb5326fee..e36d8520d9 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/adapter/file/AbstractFileMapper.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/adapter/file/AbstractFileMapper.java @@ -76,7 +76,7 @@ public abstract class AbstractFileMapper extends AbstractMessageMapper message = new GenericMessage(this.getUidGenerator().generateUid(), payload); + Message message = new GenericMessage(this.getIdGenerator().generateId(), payload); if (this.backupDirectory != null) { FileWriter writer = new FileWriter(this.backupDirectory.getAbsolutePath() + File.separator + file.getName()); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/bus/MessageBus.java b/spring-integration-core/src/main/java/org/springframework/integration/bus/MessageBus.java index a9c04fc814..8edc6b4791 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/bus/MessageBus.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/bus/MessageBus.java @@ -162,13 +162,18 @@ public class MessageBus implements ChannelRegistry, ApplicationContextAware, Lif } public void initialize() { - if (this.getErrorChannel() == null) { - this.setErrorChannel(new SimpleChannel(Integer.MAX_VALUE)); + synchronized (this.lifecycleMonitor) { + if (this.initialized) { + return; + } + if (this.getErrorChannel() == null) { + this.setErrorChannel(new SimpleChannel(Integer.MAX_VALUE)); + } + if (this.taskScheduler == null) { + this.setMessagingTaskScheduler(createDefaultScheduler()); + } + this.initialized = true; } - if (this.taskScheduler == null) { - this.setMessagingTaskScheduler(createDefaultScheduler()); - } - this.initialized = true; } private MessagingTaskScheduler createDefaultScheduler() { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/DefaultMessageDispatcher.java b/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/DefaultMessageDispatcher.java index 472de39f54..39f5bd5dd4 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/DefaultMessageDispatcher.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/DefaultMessageDispatcher.java @@ -49,7 +49,7 @@ import org.springframework.util.Assert; */ public class DefaultMessageDispatcher implements SchedulingMessageDispatcher, MessagingTaskSchedulerAware { - protected Log logger = LogFactory.getLog(this.getClass()); + protected final Log logger = LogFactory.getLog(this.getClass()); private final MessageChannel channel; @@ -59,15 +59,15 @@ public class DefaultMessageDispatcher implements SchedulingMessageDispatcher, Me private Schedule defaultSchedule = new PollingSchedule(5); - private ConcurrentMap> scheduledHandlers = new ConcurrentHashMap>(); + private final ConcurrentMap> scheduledHandlers = new ConcurrentHashMap>(); - private AtomicLong totalMessagesProcessed = new AtomicLong(); + private final AtomicLong totalMessagesProcessed = new AtomicLong(); private volatile boolean starting; private volatile boolean running; - private Object lifecycleMonitor = new Object(); + private final Object lifecycleMonitor = new Object(); public DefaultMessageDispatcher(MessageChannel channel) { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/message/AbstractMessageMapper.java b/spring-integration-core/src/main/java/org/springframework/integration/message/AbstractMessageMapper.java index db48193a91..0b6cd55eae 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/message/AbstractMessageMapper.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/message/AbstractMessageMapper.java @@ -16,28 +16,28 @@ package org.springframework.integration.message; -import org.springframework.integration.util.RandomGuidUidGenerator; -import org.springframework.integration.util.UidGenerator; +import org.springframework.integration.util.RandomUuidGenerator; +import org.springframework.integration.util.IdGenerator; import org.springframework.util.Assert; /** - * Base class that provides the default {@link UidGenerator} as well as a setter + * Base class that provides the default {@link IdGenerator} as well as a setter * for providing a custom id generator implementation. * * @author Mark Fisher */ public abstract class AbstractMessageMapper implements MessageMapper { - private UidGenerator uidGenerator = new RandomGuidUidGenerator(); + private IdGenerator idGenerator = new RandomUuidGenerator(); - public void setUidGenerator(UidGenerator uidGenerator) { - Assert.notNull(uidGenerator, "'uidGenerator' must not be null"); - this.uidGenerator = uidGenerator; + public void setIdGenerator(IdGenerator idGenerator) { + Assert.notNull(idGenerator, "'idGenerator' must not be null"); + this.idGenerator = idGenerator; } - public UidGenerator getUidGenerator() { - return this.uidGenerator; + protected IdGenerator getIdGenerator() { + return this.idGenerator; } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/message/GenericMessage.java b/spring-integration-core/src/main/java/org/springframework/integration/message/GenericMessage.java index e790fba3f8..de7a0dcdd3 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/message/GenericMessage.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/message/GenericMessage.java @@ -18,8 +18,8 @@ package org.springframework.integration.message; import java.util.Date; -import org.springframework.integration.util.RandomGuidUidGenerator; -import org.springframework.integration.util.UidGenerator; +import org.springframework.integration.util.RandomUuidGenerator; +import org.springframework.integration.util.IdGenerator; import org.springframework.util.Assert; /** @@ -29,13 +29,13 @@ import org.springframework.util.Assert; */ public class GenericMessage implements Message { - private Object id; + private final Object id; - private MessageHeader header = new MessageHeader(); + private final MessageHeader header = new MessageHeader(); - private T payload; + private final T payload; - private UidGenerator defaultUidGenerator = new RandomGuidUidGenerator(); + private final IdGenerator defaultIdGenerator = new RandomUuidGenerator(); /** @@ -53,13 +53,13 @@ public class GenericMessage implements Message { /** * Create a new message with the given payload. The id will be generated by - * the default {@link UidGenerator} strategy. + * the default {@link IdGenerator} strategy. * * @param payload the message payload */ public GenericMessage(T payload) { Assert.notNull(payload, "payload must not be null"); - this.id = this.defaultUidGenerator.generateUid(); + this.id = this.defaultIdGenerator.generateId(); this.payload = payload; } @@ -72,18 +72,10 @@ public class GenericMessage implements Message { return this.header; } - protected void setHeader(MessageHeader header) { - this.header = header; - } - public T getPayload() { return this.payload; } - protected void setPayload(T newPayload) { - this.payload = newPayload; - } - public boolean isExpired() { Date expiration = this.header.getExpiration(); return (expiration != null) ? expiration.getTime() < System.currentTimeMillis() : false; diff --git a/spring-integration-core/src/main/java/org/springframework/integration/message/SimplePayloadMessageMapper.java b/spring-integration-core/src/main/java/org/springframework/integration/message/SimplePayloadMessageMapper.java index cab790d70d..7c4455ed4d 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/message/SimplePayloadMessageMapper.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/message/SimplePayloadMessageMapper.java @@ -18,7 +18,7 @@ package org.springframework.integration.message; /** * A {@link MessageMapper} implementation that simply wraps and unwraps a - * payload object in a {@link DocumentMessage}. + * payload object in a {@link Message}. * * @author Mark Fisher */ @@ -32,10 +32,10 @@ public class SimplePayloadMessageMapper extends AbstractMessageMapper { } /** - * Return a {@link DocumentMessage} with the given object as its payload. + * Return a {@link Message} with the given object as its payload. */ public Message toMessage(T source) { - return new GenericMessage(this.getUidGenerator().generateUid(), source); + return new GenericMessage(this.getIdGenerator().generateId(), source); } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/util/UidGenerator.java b/spring-integration-core/src/main/java/org/springframework/integration/util/IdGenerator.java similarity index 62% rename from spring-integration-core/src/main/java/org/springframework/integration/util/UidGenerator.java rename to spring-integration-core/src/main/java/org/springframework/integration/util/IdGenerator.java index 858e7529d2..d7bb6f134b 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/util/UidGenerator.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/util/IdGenerator.java @@ -19,24 +19,15 @@ package org.springframework.integration.util; import java.io.Serializable; /** - * A strategy for generating ids to uniquely identify integration artifacts such - * as Messages. + * A strategy for generating unique ids. * - * @author Keith Donald + * @author Mark Fisher */ -public interface UidGenerator { +public interface IdGenerator { /** * Generate a new unique id. - * @return a serializable id, guaranteed to be unique in some context */ - public Serializable generateUid(); - - /** - * Convert the string-encoded uid into its original object form. - * @param encodedUid the string encoded uid - * @return the converted uid - */ - public Serializable parseUid(String encodedUid); + public Serializable generateId(); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/util/RandomGuid.java b/spring-integration-core/src/main/java/org/springframework/integration/util/RandomGuid.java deleted file mode 100644 index c954667d6a..0000000000 --- a/spring-integration-core/src/main/java/org/springframework/integration/util/RandomGuid.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2002-2007 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.integration.util; - -/* - * RandomGUID from http://www.javaexchange.com/aboutRandomGUID.html - * @version 1.2.1 11/05/02 @author Marc A. Mnich - * - * From www.JavaExchange.com, Open Software licensing - * - * 11/05/02 -- Performance enhancement from Mike Dubman. Moved InetAddr.getLocal to static block. Mike has measured a 10 - * fold improvement in run time. 01/29/02 -- Bug fix: Improper seeding of nonsecure Random object caused duplicate GUIDs - * to be produced. Random object is now only created once per JVM. 01/19/02 -- Modified random seeding and added new - * constructor to allow secure random feature. 01/14/02 -- Added random function seeding with JVM run time - */ - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.Random; - -/** - * Globally unique identifier generator. - *

- * In the multitude of java GUID generators, I found none that guaranteed randomness. GUIDs are guaranteed to be - * globally unique by using ethernet MACs, IP addresses, time elements, and sequential numbers. GUIDs are not expected - * to be random and most often are easy/possible to guess given a sample from a given generator. SQL Server, for example - * generates GUID that are unique but sequencial within a given instance. - *

- * GUIDs can be used as security devices to hide things such as files within a filesystem where listings are unavailable - * (e.g. files that are served up from a Web server with indexing turned off). This may be desirable in cases where - * standard authentication is not appropriate. In this scenario, the RandomGuids are used as directories. Another - * example is the use of GUIDs for primary keys in a database where you want to ensure that the keys are secret. Random - * GUIDs can then be used in a URL to prevent hackers (or users) from accessing records by guessing or simply by - * incrementing sequential numbers. - *

- * There are many other possibilities of using GUIDs in the realm of security and encryption where the element of - * randomness is important. This class was written for these purposes but can also be used as a general purpose GUID - * generator as well. - *

- * RandomGuid generates truly random GUIDs by using the system's IP address (name/IP), system time in milliseconds (as - * an integer), and a very large random number joined together in a single String that is passed through an MD5 hash. - * The IP address and system time make the MD5 seed globally unique and the random number guarantees that the generated - * GUIDs will have no discernible pattern and cannot be guessed given any number of previously generated GUIDs. It is - * generally not possible to access the seed information (IP, time, random number) from the resulting GUIDs as the MD5 - * hash algorithm provides one way encryption. - *

- * Security of RandomGuid: RandomGuid can be called one of two ways -- with the basic java Random number - * generator or a cryptographically strong random generator (SecureRandom). The choice is offered because the secure - * random generator takes about 3.5 times longer to generate its random numbers and this performance hit may not be - * worth the added security especially considering the basic generator is seeded with a cryptographically strong random - * seed. - *

- * Seeding the basic generator in this way effectively decouples the random numbers from the time component making it - * virtually impossible to predict the random number component even if one had absolute knowledge of the System time. - * Thanks to Ashutosh Narhari for the suggestion of using the static method to prime the basic random generator. - *

- * Using the secure random option, this class complies with the statistical random number generator tests specified in - * FIPS 140-2, Security Requirements for Cryptographic Modules, section 4.9.1. - *

- * I converted all the pieces of the seed to a String before handing it over to the MD5 hash so that you could print it - * out to make sure it contains the data you expect to see and to give a nice warm fuzzy. If you need better - * performance, you may want to stick to byte[] arrays. - *

- * I believe that it is important that the algorithm for generating random GUIDs be open for inspection and - * modification. This class is free for all uses. - * - * @version 1.2.1 11/05/02 - * @author Marc A. Mnich - */ -public class RandomGuid { - - private static Random random; - - private static SecureRandom secureRandom; - - private static String id; - - private String guid; - - /* - * Static block to take care of one time secureRandom seed. It takes a few seconds to initialize SecureRandom. You - * might want to consider removing this static block or replacing it with a "time since first loaded" seed to reduce - * this time. This block will run only once per JVM instance. - */ - static { - secureRandom = new SecureRandom(); - long secureInitializer = secureRandom.nextLong(); - random = new Random(secureInitializer); - try { - id = InetAddress.getLocalHost().toString(); - } catch (UnknownHostException e) { - throw new RuntimeException(e); - } - } - - /** - * Default constructor. With no specification of security option, this constructor defaults to lower security, high - * performance. - */ - public RandomGuid() { - getRandomGuid(false); - } - - /** - * Constructor with security option. Setting secure true enables each random number generated to be - * cryptographically strong. Secure false defaults to the standard Random function seeded with a single - * cryptographically strong random number. - */ - public RandomGuid(boolean secure) { - getRandomGuid(secure); - } - - /** - * Method to generate the random GUID. - */ - private void getRandomGuid(boolean secure) { - MessageDigest md5 = null; - StringBuffer sbValueBeforeMD5 = new StringBuffer(); - - try { - md5 = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } - - long time = System.currentTimeMillis(); - long rand = 0; - - if (secure) { - rand = secureRandom.nextLong(); - } else { - rand = random.nextLong(); - } - - // This StringBuffer can be as long as you need; the MD5 - // hash will always return 128 bits. You can change - // the seed to include anything you want here. - // You could even stream a file through the MD5 making - // the odds of guessing it at least as great as that - // of guessing the contents of the file! - sbValueBeforeMD5.append(id); - sbValueBeforeMD5.append(":"); - sbValueBeforeMD5.append(Long.toString(time)); - sbValueBeforeMD5.append(":"); - sbValueBeforeMD5.append(Long.toString(rand)); - - String valueBeforeMD5 = sbValueBeforeMD5.toString(); - md5.update(valueBeforeMD5.getBytes()); - - byte[] array = md5.digest(); - StringBuffer sb = new StringBuffer(); - for (int j = 0; j < array.length; ++j) { - int b = array[j] & 0xFF; - if (b < 0x10) - sb.append('0'); - sb.append(Integer.toHexString(b)); - } - guid = sb.toString(); - } - - /** - * Convert to the standard format for GUID (Useful for SQL Server UniqueIdentifiers, etc). Example: - * "C2FEEEAC-CFCD-11D1-8B05-00600806D9B6". - */ - public String toString() { - String raw = guid.toUpperCase(); - StringBuffer sb = new StringBuffer(); - sb.append(raw.substring(0, 8)); - sb.append("-"); - sb.append(raw.substring(8, 12)); - sb.append("-"); - sb.append(raw.substring(12, 16)); - sb.append("-"); - sb.append(raw.substring(16, 20)); - sb.append("-"); - sb.append(raw.substring(20)); - return sb.toString(); - } - -} diff --git a/spring-integration-core/src/main/java/org/springframework/integration/util/RandomGuidUidGenerator.java b/spring-integration-core/src/main/java/org/springframework/integration/util/RandomGuidUidGenerator.java deleted file mode 100644 index a4700c138f..0000000000 --- a/spring-integration-core/src/main/java/org/springframework/integration/util/RandomGuidUidGenerator.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2002-2007 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.integration.util; - -import java.io.Serializable; - -/** - * An id generator that uses the RandomGuid support class. The default - * implementation used by the integration system. - * - * @author Keith Donald - */ -@SuppressWarnings("serial") -public class RandomGuidUidGenerator implements UidGenerator, Serializable { - - /** - * Should the random GUID generated be secure? - */ - private boolean secure; - - /** - * Returns whether or not the generated random numbers are secure, - * meaning cryptographically strong. - */ - public boolean isSecure() { - return secure; - } - - /** - * Sets whether or not the generated random numbers should be secure. - * If set to true, generated GUIDs are cryptographically strong. - */ - public void setSecure(boolean secure) { - this.secure = secure; - } - - public Serializable generateUid() { - return new RandomGuid(secure).toString(); - } - - public Serializable parseUid(String encodedUid) { - return encodedUid; - } - -} diff --git a/spring-integration-core/src/main/java/org/springframework/integration/util/RandomUuidGenerator.java b/spring-integration-core/src/main/java/org/springframework/integration/util/RandomUuidGenerator.java new file mode 100644 index 0000000000..9a15d66c19 --- /dev/null +++ b/spring-integration-core/src/main/java/org/springframework/integration/util/RandomUuidGenerator.java @@ -0,0 +1,35 @@ +/* + * Copyright 2002-2007 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.integration.util; + +import java.io.Serializable; +import java.util.UUID; + +/** + * An id generator that generates random UUIDs. This is the default + * implementation used by the integration system. + * + * @author Mark Fisher + */ +@SuppressWarnings("serial") +public class RandomUuidGenerator implements IdGenerator { + + public Serializable generateId() { + return UUID.randomUUID(); + } + +} diff --git a/spring-integration-core/src/test/java/org/springframework/integration/util/RandomGuidUidGeneratorTests.java b/spring-integration-core/src/test/java/org/springframework/integration/util/RandomUuidGeneratorTests.java similarity index 85% rename from spring-integration-core/src/test/java/org/springframework/integration/util/RandomGuidUidGeneratorTests.java rename to spring-integration-core/src/test/java/org/springframework/integration/util/RandomUuidGeneratorTests.java index 28ecf278c8..d365aa5362 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/util/RandomGuidUidGeneratorTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/util/RandomUuidGeneratorTests.java @@ -23,12 +23,12 @@ import org.junit.Test; /** * @author Mark Fisher */ -public class RandomGuidUidGeneratorTests { +public class RandomUuidGeneratorTests { @Test public void testGeneratedIdIsNotNull() { - UidGenerator generator = new RandomGuidUidGenerator(); - Object id = generator.generateUid(); + IdGenerator generator = new RandomUuidGenerator(); + Object id = generator.generateId(); assertNotNull(id); }