/*
* Copyright 2014 NAVER Corp.
*
* 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 com.navercorp.pinpoint.common.util;
import com.navercorp.pinpoint.common.buffer.AutomaticBuffer;
import com.navercorp.pinpoint.common.buffer.Buffer;
import com.navercorp.pinpoint.common.buffer.FixedBuffer;
import java.nio.ByteBuffer;
/**
* @author emeroad
*/
public final class TransactionIdUtils {
// value is displayed as html - should not use html syntax
public static final String TRANSACTION_ID_DELIMITER = "^";
public static final byte VERSION = 0;
private TransactionIdUtils() {
}
public static String formatString(TransactionId transactionId) {
return formatString(transactionId.getAgentId(), transactionId.getAgentStartTime(), transactionId.getTransactionSequence());
}
public static String formatString(String agentId, long agentStartTime, long transactionSequence) {
if (agentId == null) {
throw new NullPointerException("agentId must not be null");
}
StringBuilder sb = new StringBuilder(64);
sb.append(agentId);
sb.append(TRANSACTION_ID_DELIMITER);
sb.append(agentStartTime);
sb.append(TRANSACTION_ID_DELIMITER);
sb.append(transactionSequence);
return sb.toString();
}
public static byte[] formatBytes(String agentId, long agentStartTime, long transactionSequence) {
final Buffer buffer = writeTransactionId(agentId, agentStartTime, transactionSequence);
return buffer.getBuffer();
}
public static ByteBuffer formatByteBuffer(String agentId, long agentStartTime, long transactionSequence) {
final Buffer buffer = writeTransactionId(agentId, agentStartTime, transactionSequence);
return buffer.wrapByteBuffer();
}
private static Buffer writeTransactionId(String agentId, long agentStartTime, long transactionSequence) {
// agentId may be null
// version + prefixed size + string + long + long
final Buffer buffer = new AutomaticBuffer(1 + 5 + 24 + 10 + 10);
buffer.putByte(VERSION);
buffer.putPrefixedString(agentId);
buffer.putVLong(agentStartTime);
buffer.putVLong(transactionSequence);
return buffer;
}
public static TransactionId parseTransactionId(final byte[] transactionId) {
if (transactionId == null) {
throw new NullPointerException("transactionId must not be null");
}
final Buffer buffer = new FixedBuffer(transactionId);
final byte version = buffer.readByte();
if (version != VERSION) {
throw new IllegalArgumentException("invalid Version");
}
final String agentId = buffer.readPrefixedString();
final long agentStartTime = buffer.readVLong();
final long transactionSequence = buffer.readVLong();
if (agentId == null) {
return new TransactionId(agentStartTime, transactionSequence);
} else {
return new TransactionId(agentId, agentStartTime,transactionSequence);
}
}
public static TransactionId parseTransactionId(final String transactionId) {
if (transactionId == null) {
throw new NullPointerException("transactionId must not be null");
}
final int agentIdIndex = nextIndex(transactionId, 0);
if (agentIdIndex == -1) {
throw new IllegalArgumentException("agentIndex not found:" + transactionId);
}
final String agentId = transactionId.substring(0, agentIdIndex);
final int agentStartTimeIndex = nextIndex(transactionId, agentIdIndex + 1);
if (agentStartTimeIndex == -1) {
throw new IllegalArgumentException("agentStartTimeIndex not found:" + transactionId);
}
final long agentStartTime = parseLong(transactionId, agentIdIndex + 1, agentStartTimeIndex);
int transactionSequenceIndex = nextIndex(transactionId, agentStartTimeIndex + 1);
if (transactionSequenceIndex == -1) {
// next index may not exist since default value does not have a delimiter after transactionSequence.
// may need fixing when id spec changes
transactionSequenceIndex = transactionId.length();
}
final long transactionSequence = parseLong(transactionId, agentStartTimeIndex + 1, transactionSequenceIndex);
return new TransactionId(agentId, agentStartTime, transactionSequence);
}
private static int nextIndex(String transactionId, int fromIndex) {
return transactionId.indexOf(TRANSACTION_ID_DELIMITER, fromIndex);
}
private static long parseLong(String transactionId, int beginIndex, int endIndex) {
final String longString = transactionId.substring(beginIndex, endIndex);
try {
return Long.parseLong(longString);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("parseLong Error. " + longString + " transactionId:" + transactionId);
}
}
}