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()));
if (allowIdGeneration) {
if (indexRequest.id() == null) {
indexRequest.id(UUID.randomUUID().toString());
indexRequest.id(UUID.randomBase64UUID());
// since we generate the id, change it to 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) {
if (allowIdGeneration) {
if (indexRequest.id() == null) {
indexRequest.id(UUID.randomUUID().toString());
indexRequest.id(UUID.randomBase64UUID());
// since we generate the id, change it to 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;
import java.nio.charset.Charset;
/**
* <p>Encodes and decodes to and from Base64 notation.</p>
* <p>Homepage: <a href="http://iharder.net/base64">http://iharder.net/base64</a>.</p>
@ -246,7 +229,7 @@ public class Base64 {
/**
* 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
@ -537,7 +520,7 @@ public class Base64 {
byte[] ALPHABET = getAlphabet(options);
// 1 2 3
// 1 2 3
// 01234567890123456789012345678901 Bit position
// --------000000001111111122222222 Array position from threeBytes
// --------| || || || | Six bit groups to index ALPHABET
@ -736,13 +719,7 @@ public class Base64 {
} // end finally
// Return value according to relevant encoding.
try {
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
return new String(baos.toByteArray(), PREFERRED_ENCODING);
} // end encode
@ -871,12 +848,7 @@ public class Base64 {
byte[] encoded = encodeBytesToBytes(source, off, len, options);
// Return value according to relevant encoding.
try {
return new String(encoded, PREFERRED_ENCODING);
} // end try
catch (java.io.UnsupportedEncodingException uue) {
return new String(encoded);
} // end catch
return new String(encoded, PREFERRED_ENCODING);
} // end encodeBytes
@ -1235,7 +1207,7 @@ public class Base64 {
// There's a bad input character in the Base64 stream.
throw new java.io.IOException(String.format(
"Bad Base64 input character decimal %d in array position %d", ((int) source[i]) & 0xFF, i));
} // end else:
} // end else:
} // each input character
byte[] out = new byte[outBuffPosn];
@ -1275,13 +1247,7 @@ public class Base64 {
throw new NullPointerException("Input string was null.");
} // end if
byte[] bytes;
try {
bytes = s.getBytes(PREFERRED_ENCODING);
} // end try
catch (java.io.UnsupportedEncodingException uee) {
bytes = s.getBytes();
} // end catch
byte[] bytes = s.getBytes(PREFERRED_ENCODING);
//</change>
// Decode
@ -1648,7 +1614,7 @@ public class Base64 {
}
catch (Exception ex) {
}
} // end finally
} // end finally
} // end encodeFileToFile
@ -1679,7 +1645,7 @@ public class Base64 {
}
catch (Exception ex) {
}
} // end finally
} // end finally
} // end decodeFileToFile
@ -1817,7 +1783,7 @@ public class Base64 {
else {
// Must have broken out from above.
throw new java.io.IOException("Improperly padded Base64 input.");
} // end
} // end
} // end else: decode
} // end else: get data

View File

@ -19,6 +19,9 @@
package org.elasticsearch.common;
import org.elasticsearch.ElasticSearchIllegalStateException;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
@ -105,6 +108,32 @@ public class UUID implements Comparable<UUID> {
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
* the specified byte array.

View File

@ -136,7 +136,7 @@ public class ZenDiscovery extends AbstractLifecycleComponent<Discovery> implemen
@Override protected void doStart() throws ElasticSearchException {
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
String nodeId = UUID.randomUUID().toString();
String nodeId = UUID.randomBase64UUID();
localNode = new DiscoveryNode(settings.get("name"), nodeId, transportService.boundAddress().publishAddress(), nodeAttributes);
latestDiscoNodes = new DiscoveryNodes.Builder().put(localNode).localNodeId(localNode.id()).build();
nodesFD.updateNodes(latestDiscoNodes);