Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ Projects that require either of the two features need to explicitly declare the

<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>zure-keyvault-webkey</artifactId>
<artifactId>azure-keyvault-webkey</artifactId>
<version>1.2.0</version>
</dependency>
```
Expand Down
45 changes: 25 additions & 20 deletions src/main/java/com/microsoft/sqlserver/jdbc/ActivityCorrelator.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
*/
final class ActivityCorrelator {

private static Map<Long, ActivityId> ActivityIdTlsMap = new ConcurrentHashMap<Long, ActivityId>();
private static Map<Long, ActivityId> activityIdTlsMap = new ConcurrentHashMap<>();

static void cleanupActivityId() {
// remove the ActivityId that belongs to this thread.
long uniqueThreadId = Thread.currentThread().getId();

if (ActivityIdTlsMap.containsKey(uniqueThreadId)) {
ActivityIdTlsMap.remove(uniqueThreadId);
if (activityIdTlsMap.containsKey(uniqueThreadId)) {
activityIdTlsMap.remove(uniqueThreadId);
}
}

Expand All @@ -32,11 +32,11 @@ static ActivityId getCurrent() {
long uniqueThreadId = Thread.currentThread().getId();

// Since the Id for each thread is unique, this assures that the below if statement is run only once per thread.
if (!ActivityIdTlsMap.containsKey(uniqueThreadId)) {
ActivityIdTlsMap.put(uniqueThreadId, new ActivityId());
if (!activityIdTlsMap.containsKey(uniqueThreadId)) {
activityIdTlsMap.put(uniqueThreadId, new ActivityId());
}

return ActivityIdTlsMap.get(uniqueThreadId);
return activityIdTlsMap.get(uniqueThreadId);
}

// Increment the Sequence number of the ActivityId in TLS
Expand All @@ -46,7 +46,7 @@ static ActivityId getNext() {
ActivityId activityId = getCurrent();

// Increment the Sequence number
activityId.Increment();
activityId.increment();

return activityId;
}
Expand All @@ -55,34 +55,39 @@ static void setCurrentActivityIdSentFlag() {
ActivityId activityId = getCurrent();
activityId.setSentFlag();
}

/*
* Prevent instantiation.
*/
private ActivityCorrelator() {}
}


class ActivityId {
private final UUID Id;
private long Sequence;
private final UUID id;
private long sequence;
private boolean isSentToServer;

ActivityId() {
Id = UUID.randomUUID();
Sequence = 0;
id = UUID.randomUUID();
sequence = 0;
isSentToServer = false;
}

UUID getId() {
return Id;
return id;
}

long getSequence() {
return Sequence;
return sequence;
}

void Increment() {
if (Sequence < 0xffffffffl) // to get to 32-bit unsigned
void increment() {
if (sequence < 0xffffffffl) // to get to 32-bit unsigned
{
++Sequence;
++sequence;
} else {
Sequence = 0;
sequence = 0;
}

isSentToServer = false;
Expand All @@ -92,16 +97,16 @@ void setSentFlag() {
isSentToServer = true;
}

boolean IsSentToServer() {
boolean isSentToServer() {
return isSentToServer;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Id.toString());
sb.append(id.toString());
sb.append("-");
sb.append(Sequence);
sb.append(sequence);
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@


final class FailoverMapSingleton {
private static int INITIALHASHMAPSIZE = 5;
private static HashMap<String, FailoverInfo> failoverMap = new HashMap<>(INITIALHASHMAPSIZE);
private static int initialHashmapSize = 5;
private static HashMap<String, FailoverInfo> failoverMap = new HashMap<>(initialHashmapSize);

private FailoverMapSingleton() {
/* hide the constructor to stop the instantiation of this class. */}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3102,7 +3102,7 @@ void writeMessageHeader() throws SQLServerException {
boolean includeTraceHeader = false;
int totalHeaderLength = TDS.MESSAGE_HEADER_LENGTH;
if (TDS.PKT_QUERY == tdsMessageType || TDS.PKT_RPC == tdsMessageType) {
if (con.isDenaliOrLater() && !ActivityCorrelator.getCurrent().IsSentToServer()
if (con.isDenaliOrLater() && !ActivityCorrelator.getCurrent().isSentToServer()
&& Util.IsActivityTraceOn()) {
includeTraceHeader = true;
totalHeaderLength += TDS.TRACE_HEADER_LENGTH;
Expand Down
69 changes: 40 additions & 29 deletions src/main/java/com/microsoft/sqlserver/jdbc/PLPInputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,18 @@
* Note PLP stands for Partially Length-prefixed Bytes. TDS 7.2 introduced this new streaming format for streaming of
* large types such as varchar(max), nvarchar(max), varbinary(max) and XML.
*
* See TDS specification, 6.3.3 Datatype Dependant Data Streams: Partially Length-prefixed Bytes for more details on the
* See TDS specification, 6.3.3 Datatype Dependent Data Streams: Partially Length-prefixed Bytes for more details on the
* PLP format.
*/

class PLPInputStream extends BaseInputStream {
static final long PLP_NULL = 0xFFFFFFFFFFFFFFFFL;
static final long UNKNOWN_PLP_LEN = 0xFFFFFFFFFFFFFFFEL;
static final int PLP_TERMINATOR = 0x00000000;
private final static byte[] EMPTY_PLP_BYTES = new byte[0];

private static final byte[] EMPTY_PLP_BYTES = new byte[0];
private static final int PLP_EOS = -1;
private int currentChunkRemain;

private int currentChunkRemain;
private int markedChunkRemain;
private int leftOverReadLimit = 0;

Expand All @@ -36,7 +35,7 @@ class PLPInputStream extends BaseInputStream {
/**
* Non-destructive method for checking whether a PLP value at the current TDSReader location is null.
*/
final static boolean isNull(TDSReader tdsReader) throws SQLServerException {
static final boolean isNull(TDSReader tdsReader) throws SQLServerException {
TDSReaderMark mark = tdsReader.mark();
// Temporary stream cannot get closes, since it closes the main stream.
try {
Expand All @@ -59,12 +58,12 @@ final static boolean isNull(TDSReader tdsReader) throws SQLServerException {
* @throws SQLServerException
* when an error occurs
*/
final static PLPInputStream makeTempStream(TDSReader tdsReader, boolean discardValue,
static final PLPInputStream makeTempStream(TDSReader tdsReader, boolean discardValue,
ServerDTVImpl dtv) throws SQLServerException {
return makeStream(tdsReader, discardValue, discardValue, dtv);
}

final static PLPInputStream makeStream(TDSReader tdsReader, InputStreamGetterArgs getterArgs,
static final PLPInputStream makeStream(TDSReader tdsReader, InputStreamGetterArgs getterArgs,
ServerDTVImpl dtv) throws SQLServerException {
PLPInputStream is = makeStream(tdsReader, getterArgs.isAdaptive, getterArgs.isStreaming, dtv);
if (null != is)
Expand All @@ -88,7 +87,7 @@ private static PLPInputStream makeStream(TDSReader tdsReader, boolean isAdaptive
* Initializes the input stream.
*/
PLPInputStream(TDSReader tdsReader, long statedPayloadLength, boolean isAdaptive, boolean isStreaming,
ServerDTVImpl dtv) throws SQLServerException {
ServerDTVImpl dtv) {
super(tdsReader, isAdaptive, isStreaming, dtv);
this.payloadLength = (UNKNOWN_PLP_LEN != statedPayloadLength) ? ((int) statedPayloadLength) : -1;
this.currentChunkRemain = this.markedChunkRemain = 0;
Expand Down Expand Up @@ -146,6 +145,7 @@ byte[] getBytes() throws SQLServerException {
* @exception IOException
* if an I/O error occurs.
*/
@Override
public long skip(long n) throws IOException {
checkClosed();
if (n < 0)
Expand All @@ -169,6 +169,7 @@ public long skip(long n) throws IOException {
* @exception IOException
* if an I/O error occurs.
*/
@Override
public int available() throws IOException {
checkClosed();
try {
Expand Down Expand Up @@ -202,6 +203,7 @@ public int available() throws IOException {
* @exception IOException
* if an I/O error occurs.
*/
@Override
public int read() throws IOException {
checkClosed();

Expand All @@ -219,6 +221,7 @@ public int read() throws IOException {
* @exception IOException
* if an I/O error occurs.
*/
@Override
public int read(byte[] b) throws IOException {
// If b is null, a NullPointerException is thrown.
if (null == b)
Expand All @@ -242,7 +245,7 @@ public int read(byte[] b) throws IOException {
* @exception IOException
* if an I/O error occurs.
*/
public int read(byte b[], int offset, int maxBytes) throws IOException {
public int read(byte[] b, int offset, int maxBytes) throws IOException {
// If b is null, a NullPointerException is thrown.
if (null == b)
throw new NullPointerException();
Expand Down Expand Up @@ -285,21 +288,23 @@ int readBytes(byte[] b, int offset, int maxBytes) throws IOException {
}
}

private int readBytesInternal(byte b[], int offset, int maxBytes) throws SQLServerException {
// If we're at EOS, say so.
// Note: For back compat, this special case needs to always be handled
// before checking user-supplied arguments below.
private int readBytesInternal(byte[] b, int offset, int maxBytes) throws SQLServerException {
/*
* If we're at EOS, say so. Note: For back compat, this special case needs to always be handled before checking
* user-supplied arguments below.
*/
if (PLP_EOS == currentChunkRemain)
return -1;

// Save off the current TDSReader position, wherever it is, and start reading
// from where we left off last time.

int bytesRead = 0;
for (;;) {
// Check that we have bytes left to read from the current chunk.
// If not then figure out the size of the next chunk or
// determine that we have reached the end of the stream.
while (true) {
/*
* Check that we have bytes left to read from the current chunk. If not then figure out the size of the next
* chunk or determine that we have reached the end of the stream.
*/
if (0 == currentChunkRemain) {
currentChunkRemain = (int) tdsReader.readUnsignedInt();
assert currentChunkRemain >= 0;
Expand All @@ -312,9 +317,10 @@ private int readBytesInternal(byte b[], int offset, int maxBytes) throws SQLServ
if (bytesRead == maxBytes)
break;

// Now we know there are bytes to be read in the current chunk.
// Further limit the max number of bytes we can read to whatever
// remains in the current chunk.
/*
* Now we know there are bytes to be read in the current chunk. Further limit the max number of bytes we can
* read to whatever remains in the current chunk.
*/
int bytesToRead = maxBytes - bytesRead;
if (bytesToRead > currentChunkRemain)
bytesToRead = currentChunkRemain;
Expand Down Expand Up @@ -350,6 +356,7 @@ private int readBytesInternal(byte b[], int offset, int maxBytes) throws SQLServ
* @param readlimit
* the number of bytes to hold (this implementation ignores this).
*/
@Override
public void mark(int readLimit) {
// Save off current position and how much of the current chunk remains
// cant throw if the tdsreader is null
Expand All @@ -367,6 +374,7 @@ public void mark(int readLimit) {
* @exception IOException
* if an I/O error occurs.
*/
@Override
public void close() throws IOException {
if (null == tdsReader)
return;
Expand All @@ -382,6 +390,7 @@ public void close() throws IOException {
* @exception IOException
* if an I/O error occurs.
*/
@Override
public void reset() throws IOException {
resetHelper();
leftOverReadLimit = readLimit;
Expand All @@ -398,10 +407,10 @@ public void reset() throws IOException {
*/
final class PLPXMLInputStream extends PLPInputStream {
// XML BOM header (the first two header bytes sent to caller).
private final static byte[] xmlBOM = {(byte) 0xFF, (byte) 0xFE};
private static final byte[] xmlBOM = {(byte) 0xFF, (byte) 0xFE};
private final ByteArrayInputStream bomStream = new ByteArrayInputStream(xmlBOM);

final static PLPXMLInputStream makeXMLStream(TDSReader tdsReader, InputStreamGetterArgs getterArgs,
static final PLPXMLInputStream makeXMLStream(TDSReader tdsReader, InputStreamGetterArgs getterArgs,
ServerDTVImpl dtv) throws SQLServerException {
// Read total length of PLP stream.
long payloadLength = tdsReader.readLong();
Expand All @@ -421,10 +430,7 @@ final static PLPXMLInputStream makeXMLStream(TDSReader tdsReader, InputStreamGet
super(tdsReader, statedPayloadLength, getterArgs.isAdaptive, getterArgs.isStreaming, dtv);
}

public void close() throws IOException {
super.close();
}

@Override
int readBytes(byte[] b, int offset, int maxBytes) throws IOException {
assert offset >= 0;
assert maxBytes >= 0;
Expand Down Expand Up @@ -461,11 +467,13 @@ int readBytes(byte[] b, int offset, int maxBytes) throws IOException {
return -1;
}

@Override
public void mark(int readLimit) {
bomStream.mark(xmlBOM.length);
super.mark(readLimit);
}

@Override
public void reset() throws IOException {
bomStream.reset();
super.reset();
Expand All @@ -475,9 +483,12 @@ public void reset() throws IOException {
* Helper function to convert the entire PLP stream into a contiguous byte array. This call is inefficient (in terms
* of memory usage and run time) for very large PLPs. Use it only if a contiguous byte array is required.
*/
@Override
byte[] getBytes() throws SQLServerException {
// Look to see if the BOM has been read
byte[] bom = new byte[2];
byte[] bytesToReturn = null;

try {
int bytesread = bomStream.read(bom);
byte[] valueWithoutBOM = super.getBytes();
Expand All @@ -487,13 +498,13 @@ byte[] getBytes() throws SQLServerException {
byte[] valueWithBOM = new byte[valueWithoutBOM.length + bytesread];
System.arraycopy(bom, 0, valueWithBOM, 0, bytesread);
System.arraycopy(valueWithoutBOM, 0, valueWithBOM, bytesread, valueWithoutBOM.length);
return valueWithBOM;
bytesToReturn = valueWithBOM;
} else
return valueWithoutBOM;
bytesToReturn = valueWithoutBOM;
} catch (IOException e) {
SQLServerException.makeFromDriverError(null, null, e.getMessage(), null, true);
}

return null;
return bytesToReturn;
}
}
Loading