Use Base64 encoding for UUID generation (auto generated doc ids, and node ids), closes #422.

This commit is contained in:
kimchy 2010-10-12 00:17:01 +02:00
parent 4f9d9c1395
commit c3cb5a3e34
5 changed files with 43 additions and 48 deletions

View File

@ -143,7 +143,7 @@ public class TransportBulkAction extends BaseAction<BulkRequest, BulkResponse> {
indexRequest.index(clusterState.metaData().concreteIndex(indexRequest.index())); indexRequest.index(clusterState.metaData().concreteIndex(indexRequest.index()));
if (allowIdGeneration) { if (allowIdGeneration) {
if (indexRequest.id() == null) { if (indexRequest.id() == null) {
indexRequest.id(UUID.randomUUID().toString()); indexRequest.id(UUID.randomBase64UUID());
// since we generate the id, change it to CREATE // since we generate the id, change it to CREATE
indexRequest.opType(IndexRequest.OpType.CREATE); indexRequest.opType(IndexRequest.OpType.CREATE);
} }

View File

@ -82,7 +82,7 @@ public class TransportIndexAction extends TransportShardReplicationOperationActi
@Override protected void doExecute(final IndexRequest indexRequest, final ActionListener<IndexResponse> listener) { @Override protected void doExecute(final IndexRequest indexRequest, final ActionListener<IndexResponse> listener) {
if (allowIdGeneration) { if (allowIdGeneration) {
if (indexRequest.id() == null) { if (indexRequest.id() == null) {
indexRequest.id(UUID.randomUUID().toString()); indexRequest.id(UUID.randomBase64UUID());
// since we generate the id, change it to CREATE // since we generate the id, change it to CREATE
indexRequest.opType(IndexRequest.OpType.CREATE); indexRequest.opType(IndexRequest.OpType.CREATE);
} }

View File

@ -1,24 +1,7 @@
/*
* Licensed to Elastic Search and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Elastic Search 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.elasticsearch.common; package org.elasticsearch.common;
import java.nio.charset.Charset;
/** /**
* <p>Encodes and decodes to and from Base64 notation.</p> * <p>Encodes and decodes to and from Base64 notation.</p>
* <p>Homepage: <a href="http://iharder.net/base64">http://iharder.net/base64</a>.</p> * <p>Homepage: <a href="http://iharder.net/base64">http://iharder.net/base64</a>.</p>
@ -246,7 +229,7 @@ public class Base64 {
/** /**
* Preferred encoding. * Preferred encoding.
*/ */
private final static String PREFERRED_ENCODING = "US-ASCII"; public final static Charset PREFERRED_ENCODING = Charset.forName("US-ASCII");
private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding
@ -537,7 +520,7 @@ public class Base64 {
byte[] ALPHABET = getAlphabet(options); byte[] ALPHABET = getAlphabet(options);
// 1 2 3 // 1 2 3
// 01234567890123456789012345678901 Bit position // 01234567890123456789012345678901 Bit position
// --------000000001111111122222222 Array position from threeBytes // --------000000001111111122222222 Array position from threeBytes
// --------| || || || | Six bit groups to index ALPHABET // --------| || || || | Six bit groups to index ALPHABET
@ -736,13 +719,7 @@ public class Base64 {
} // end finally } // end finally
// Return value according to relevant encoding. // Return value according to relevant encoding.
try { return new String(baos.toByteArray(), PREFERRED_ENCODING);
return new String(baos.toByteArray(), PREFERRED_ENCODING);
} // end try
catch (java.io.UnsupportedEncodingException uue) {
// Fall back to some Java default
return new String(baos.toByteArray());
} // end catch
} // end encode } // end encode
@ -871,12 +848,7 @@ public class Base64 {
byte[] encoded = encodeBytesToBytes(source, off, len, options); byte[] encoded = encodeBytesToBytes(source, off, len, options);
// Return value according to relevant encoding. // Return value according to relevant encoding.
try { return new String(encoded, PREFERRED_ENCODING);
return new String(encoded, PREFERRED_ENCODING);
} // end try
catch (java.io.UnsupportedEncodingException uue) {
return new String(encoded);
} // end catch
} // end encodeBytes } // end encodeBytes
@ -1235,7 +1207,7 @@ public class Base64 {
// There's a bad input character in the Base64 stream. // There's a bad input character in the Base64 stream.
throw new java.io.IOException(String.format( throw new java.io.IOException(String.format(
"Bad Base64 input character decimal %d in array position %d", ((int) source[i]) & 0xFF, i)); "Bad Base64 input character decimal %d in array position %d", ((int) source[i]) & 0xFF, i));
} // end else: } // end else:
} // each input character } // each input character
byte[] out = new byte[outBuffPosn]; byte[] out = new byte[outBuffPosn];
@ -1275,13 +1247,7 @@ public class Base64 {
throw new NullPointerException("Input string was null."); throw new NullPointerException("Input string was null.");
} // end if } // end if
byte[] bytes; byte[] bytes = s.getBytes(PREFERRED_ENCODING);
try {
bytes = s.getBytes(PREFERRED_ENCODING);
} // end try
catch (java.io.UnsupportedEncodingException uee) {
bytes = s.getBytes();
} // end catch
//</change> //</change>
// Decode // Decode
@ -1648,7 +1614,7 @@ public class Base64 {
} }
catch (Exception ex) { catch (Exception ex) {
} }
} // end finally } // end finally
} // end encodeFileToFile } // end encodeFileToFile
@ -1679,7 +1645,7 @@ public class Base64 {
} }
catch (Exception ex) { catch (Exception ex) {
} }
} // end finally } // end finally
} // end decodeFileToFile } // end decodeFileToFile
@ -1817,7 +1783,7 @@ public class Base64 {
else { else {
// Must have broken out from above. // Must have broken out from above.
throw new java.io.IOException("Improperly padded Base64 input."); throw new java.io.IOException("Improperly padded Base64 input.");
} // end } // end
} // end else: decode } // end else: decode
} // end else: get data } // end else: get data

View File

@ -19,6 +19,9 @@
package org.elasticsearch.common; package org.elasticsearch.common;
import org.elasticsearch.ElasticSearchIllegalStateException;
import java.io.IOException;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
@ -105,6 +108,32 @@ public class UUID implements Comparable<UUID> {
return new UUID(randomBytes); return new UUID(randomBytes);
} }
public static String randomBase64UUID() {
SecureRandom ng = numberGenerator;
if (ng == null) {
numberGenerator = ng = new SecureRandom();
}
byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= 0x80; /* set to IETF variant */
try {
byte[] encoded = Base64.encodeBytesToBytes(randomBytes, 0, randomBytes.length, Base64.URL_SAFE);
// we know the bytes are 16, and not a multi of 3, so remove the 2 padding chars that are added
assert encoded[encoded.length - 1] == '=';
assert encoded[encoded.length - 2] == '=';
// we always have padding of two at the end, encode it differently
return new String(encoded, 0, encoded.length - 2, Base64.PREFERRED_ENCODING);
} catch (IOException e) {
throw new ElasticSearchIllegalStateException("should not be thrown");
}
}
/** /**
* Static factory to retrieve a type 3 (name based) <tt>UUID</tt> based on * Static factory to retrieve a type 3 (name based) <tt>UUID</tt> based on
* the specified byte array. * the specified byte array.

View File

@ -136,7 +136,7 @@ public class ZenDiscovery extends AbstractLifecycleComponent<Discovery> implemen
@Override protected void doStart() throws ElasticSearchException { @Override protected void doStart() throws ElasticSearchException {
Map<String, String> nodeAttributes = buildCommonNodesAttributes(settings); Map<String, String> nodeAttributes = buildCommonNodesAttributes(settings);
// note, we rely on the fact that its a new id each time we start, see FD and "kill -9" handling // note, we rely on the fact that its a new id each time we start, see FD and "kill -9" handling
String nodeId = UUID.randomUUID().toString(); String nodeId = UUID.randomBase64UUID();
localNode = new DiscoveryNode(settings.get("name"), nodeId, transportService.boundAddress().publishAddress(), nodeAttributes); localNode = new DiscoveryNode(settings.get("name"), nodeId, transportService.boundAddress().publishAddress(), nodeAttributes);
latestDiscoNodes = new DiscoveryNodes.Builder().put(localNode).localNodeId(localNode.id()).build(); latestDiscoNodes = new DiscoveryNodes.Builder().put(localNode).localNodeId(localNode.id()).build();
nodesFD.updateNodes(latestDiscoNodes); nodesFD.updateNodes(latestDiscoNodes);