com.pivotal.gemfirexd.internal.client.am.Agent Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of snappydata-store-client Show documentation
Show all versions of snappydata-store-client Show documentation
SnappyData store based off Pivotal GemFireXD
The newest version!
/*
Derby - Class com.pivotal.gemfirexd.internal.client.am.Agent
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF 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.
*/
/*
* Changes for GemFireXD distributed data platform (some marked by "GemStone changes")
*
* Portions Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
*
* 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. See accompanying
* LICENSE file.
*/
package com.pivotal.gemfirexd.internal.client.am;
import com.pivotal.gemfirexd.internal.shared.common.reference.SQLState;
public abstract class Agent {
public SqlException accumulatedReadExceptions_ = null;
private boolean enableBatchedExceptionTracking_;
private int batchedExceptionLabelIndex_;
private boolean[] batchedExceptionGenerated_;
Connection connection_; // made friendly for lobs only, refactor !!
public SectionManager sectionManager_ = null; // temporarily public, make friendly at least !!
public LogWriter logWriter_ = null;
final CrossConverters crossConverters_;
// Exceptions that occur on dnc's implementation of SqlException.getMessage() via stored proc
// cannot be thrown on the getMessage() invocation because the signature of getMessage() does not
// allow for throwing an exception.
// Therefore, we must save the exception and throw it at our very first opportunity.
SqlException deferredException_;
void checkForDeferredExceptions() throws SqlException {
if (deferredException_ != null) {
SqlException temp = deferredException_;
deferredException_ = null;
throw temp;
}
}
public void accumulateDeferredException(SqlException e) {
if (deferredException_ == null) {
deferredException_ = e;
} else {
deferredException_.setNextException(e);
}
}
protected Agent(Connection connection, LogWriter logWriter) {
connection_ = connection;
logWriter_ = logWriter;
crossConverters_ = new CrossConverters(this);
}
protected void resetAgent(LogWriter logWriter) {
// sectionManager_ is set elsewhere
accumulatedReadExceptions_ = null;
enableBatchedExceptionTracking_ = false;
batchedExceptionLabelIndex_ = 0;
batchedExceptionGenerated_ = null;
logWriter_ = logWriter;
deferredException_ = null;
}
public void resetAgent(Connection connection, LogWriter logWriter, int loginTimeout, String server, int port) throws SqlException {
resetAgent(logWriter);
resetAgent_(logWriter, loginTimeout, server, port);
}
abstract protected void resetAgent_(LogWriter logWriter, int loginTimeout, String server, int port) throws SqlException;
//-------------------- entry points ------------------------------------------
public final boolean loggingEnabled() {
return !com.pivotal.gemfirexd.internal.client.am.Configuration.traceSuspended__ && logWriter_ != null;
}
public final void setLogWriter(LogWriter logWriter) {
synchronized (connection_) {
if (logWriter_ != null) {
logWriter_.close();
}
logWriter_ = logWriter;
}
}
public final java.io.PrintWriter getLogWriter() {
return (logWriter_ == null) ? null : logWriter_.printWriter_;
}
abstract public LogWriter newLogWriter_(java.io.PrintWriter printWriter, int traceLevel);
//----------------------------------------------------------------------------
public final void accumulateReadException(SqlException e) {
if (enableBatchedExceptionTracking_) {
batchedExceptionGenerated_[batchedExceptionLabelIndex_] = true;
labelAsBatchedException(e, batchedExceptionLabelIndex_);
}
if (accumulatedReadExceptions_ == null) {
accumulatedReadExceptions_ = e;
} else {
accumulatedReadExceptions_.setNextException(e);
}
}
// Called only for disconnect event
public final void accumulateDisconnectException(DisconnectException e) {
if (enableBatchedExceptionTracking_) {
batchedExceptionGenerated_[batchedExceptionLabelIndex_] = true;
labelAsBatchedException(e, batchedExceptionLabelIndex_);
}
if (accumulatedReadExceptions_ != null) {
e.setNextException(accumulatedReadExceptions_);
}
accumulatedReadExceptions_ = null;
}
// For now, it looks like the only time we accumulate chain breaking exceptions
// is for disconnect exceptions.
public final void accumulateChainBreakingReadExceptionAndThrow(DisconnectException e) throws DisconnectException {
accumulateDisconnectException(e); // tacks disconnect exc to end of chain
markChainBreakingException_(); // sets a severity code in the NET agent
throw e; // disconnect will be caught in Reply classes, and front of original chain thrown
}
abstract protected void markChainBreakingException_();
abstract public void checkForChainBreakingException_() throws SqlException;
private final void enableBatchedExceptionTracking(int batchSize) {
enableBatchedExceptionTracking_ = true;
batchedExceptionGenerated_ = new boolean[batchSize];
batchedExceptionLabelIndex_ = 0;
}
final void disableBatchedExceptionTracking() {
enableBatchedExceptionTracking_ = false;
}
public final void setBatchedExceptionLabelIndex(int index) {
batchedExceptionLabelIndex_ = index;
}
private final SqlException labelAsBatchedException(SqlException e, int index) {
SqlException firstInChain = e;
while (e != null) {
e.setBatchPositionLabel(index);
e = (SqlException) e.getNextException();
}
return firstInChain;
}
protected final void checkForExceptions() throws SqlException {
if (accumulatedReadExceptions_ != null) {
SqlException e = accumulatedReadExceptions_;
accumulatedReadExceptions_ = null;
throw e;
}
}
// precondition: all batch execute reads have occurred
final boolean batchUpdateExceptionGenerated() {
return batchedExceptionGenerated_[batchedExceptionLabelIndex_];
}
public final void flow(Statement statement) throws SqlException {
endWriteChain();
flush_();
beginReadChain(statement);
}
public final void flowBatch(Statement statement, int batchSize) throws SqlException {
endBatchedWriteChain();
flush_();
beginBatchedReadChain(statement, batchSize);
}
public final void flowOutsideUOW() throws SqlException {
endWriteChain();
flush_();
beginReadChainOutsideUOW();
}
// flush() means to send all chained requests.
abstract public void flush_() throws DisconnectException;
// Close client resources associated with this agent, such as socket and streams for the net.
abstract public void close_() throws SqlException;
public void close() throws SqlException {
close_();
if (logWriter_ != null) {
logWriter_.close();
}
}
// GemStone changes BEGIN
public boolean disableDisconnectEvent_ = false;
public boolean forSqlException_ = false;
public abstract int getPort();
public abstract String getServer();
public abstract String getServerLocation();
public final void disconnectEvent() {
if (disableDisconnectEvent_) {
// do nothing if this flag is set
return;
}
/* (original code)
public final void disconnectEvent() {
*/
// GemStone changes END
// closes client-side resources associated with database connection
try {
close();
} catch (SqlException doNothing) {
}
connection_.completeChainBreakingDisconnect();
}
public void beginWriteChainOutsideUOW() throws SqlException {
}
public void beginWriteChain(Statement statement) throws SqlException {
connection_.writeTransactionStart(statement);
}
public final void beginBatchedWriteChain(Statement statement) throws SqlException {
beginWriteChain(statement);
}
protected void endWriteChain() {
}
protected final void endBatchedWriteChain() {
}
protected void beginReadChain(Statement statement) throws SqlException {
connection_.readTransactionStart();
}
protected final void beginBatchedReadChain(Statement statement, int batchSize) throws SqlException {
enableBatchedExceptionTracking(batchSize);
beginReadChain(statement);
}
protected void beginReadChainOutsideUOW() throws SqlException {
}
public void endReadChain() throws SqlException {
checkForExceptions();
}
public final void endBatchedReadChain(int[] updateCounts, SqlException accumulatedExceptions) throws BatchUpdateException {
disableBatchedExceptionTracking();
for (int i = 0; i < batchedExceptionGenerated_.length; i++) {
if (batchedExceptionGenerated_[i]) {
updateCounts[i] = -3;
}
}
if (accumulatedExceptions == null) {
try {
endReadChain();
} catch (SqlException e) {
accumulatedExceptions = e;
}
}
if (accumulatedExceptions != null) {
// GemStone changes BEGIN
// use the SQLState of first exception like the embedded driver (see
// EmbedStatement#executeBatch); also see #43109
java.sql.SQLException sqle = accumulatedExceptions.getSQLException(
this);
throw new BatchUpdateException(logWriter_,
sqle.getMessage(), sqle.getSQLState(), sqle.getErrorCode(),
updateCounts, accumulatedExceptions);
/* (original code)
throw new BatchUpdateException(logWriter_,
new ClientMessageId(SQLState.BATCH_NON_ATOMIC_FAILURE),
null, updateCounts, accumulatedExceptions);
*/
// GemStone changes END
}
}
}