private ClientResponseImpl coreCall(Object... paramListIn) {
        VoltTable[] results = null;

        // use local var to avoid warnings about reassigning method argument
        Object[] paramList = paramListIn;

        try {
            if ((m_paramTypes.length > 0) && (m_paramTypes[0] == ParameterSet.class)) {
                assert(m_paramTypes.length == 1);
                paramList = new Object[] { ParameterSet.fromArrayNoCopy(paramListIn) };
            }

            if (paramList.length != m_paramTypes.length) {
                String msg = "PROCEDURE " + m_procedureName + " EXPECTS " + String.valueOf(m_paramTypes.length) +
                    " PARAMS, BUT RECEIVED " + String.valueOf(paramList.length);
                m_statusCode = ClientResponse.GRACEFUL_FAILURE;
                return ProcedureRunner.getErrorResponse(m_statusCode, m_appStatusCode, m_appStatusString, msg, null);
            }

            for (int i = 0; i < m_paramTypes.length; i++) {
                try {
                    paramList[i] = ParameterConverter.tryToMakeCompatible(m_paramTypes[i], paramList[i]);
                    // check the result type in an assert
                    assert(ParameterConverter.verifyParameterConversion(paramList[i], m_paramTypes[i]));
                } catch (Exception e) {
                    String msg = "PROCEDURE " + m_procedureName + " TYPE ERROR FOR PARAMETER " + i +
                            ": " + e.toString();
                    m_statusCode = ClientResponse.GRACEFUL_FAILURE;
                    return ProcedureRunner.getErrorResponse(m_statusCode, m_appStatusCode, m_appStatusString, msg, null);
                }
            }

            try {
                m_procedure.m_runner = this;
                Object rawResult = m_procMethod.invoke(m_procedure, paramList);

                if (rawResult instanceof CompletableFuture<?>) {
                    final CompletableFuture<?> fut = (CompletableFuture<?>) rawResult;

                    fut.thenRun(() -> {
                        //
                        // Happy path. No exceptions thrown. Procedure work is complete.
                        //
                        Object innerRawResult = null;
                        ClientResponseImpl response = null;
                        try {
                            innerRawResult = fut.get();
                        } catch (InterruptedException | ExecutionException e) {
                            assert(false);
                            // this is a bad place to be, but it's hard to know if it's crash bad...
                            innerRawResult = new ClientResponseImpl(ClientResponseImpl.UNEXPECTED_FAILURE,
                                    new VoltTable[0],
                                    "Future returned from NTProc " + m_procedureName + " failed to complete.",
                                    m_clientHandle);
                        }

                        if (innerRawResult instanceof ClientResponseImpl) {
                            response = (ClientResponseImpl) innerRawResult;
                        }
                        else {
                            try {
                                VoltTable[] r = ParameterConverter.getResultsFromRawResults(m_procedureName, innerRawResult);
                                response = responseFromTableArray(r);
                            } catch (Exception e) {
                                // this is a bad place to be, but it's hard to know if it's crash bad...
                                response = new ClientResponseImpl(ClientResponseImpl.GRACEFUL_FAILURE,
                                        new VoltTable[0],
                                        "Type " + innerRawResult.getClass().getName() +
                                            " returned from NTProc \"" + m_procedureName +
                                            "\" was not an acceptible VoltDB return type.",
                                        m_clientHandle);
                            }
                        }

                        completeCall(response);
                    })
                    .exceptionally(e -> {
                        //
                        // Exception path. Some bit of async work threw something.
                        //
                        SerializableException se = null;
                        if (e instanceof SerializableException) {
                            se = (SerializableException) e;
                        }

                        String msg = "PROCEDURE " + m_procedureName + " THREW EXCEPTION: ";
                        if (se != null) {
                            msg += se.getMessage();
                        } else {
                            msg += e.toString();
                        }
                        m_statusCode = ClientResponse.GRACEFUL_FAILURE;
                        completeCall(ProcedureRunner.getErrorResponse(m_statusCode, m_appStatusCode, m_appStatusString, msg, se));
                        return null;
                    });

                    return null;
                }
                results = ParameterConverter.getResultsFromRawResults(m_procedureName, rawResult);
            }
            catch (IllegalAccessException e) {
                // If reflection fails, invoke the same error handling that other exceptions do
                throw new InvocationTargetException(e);
            }
        }
        catch (InvocationTargetException itex) {
            //itex.printStackTrace();
            Throwable ex = itex.getCause();
            if (CoreUtils.isStoredProcThrowableFatalToServer(ex)) {
                // If the stored procedure attempted to do something other than linklibrary or instantiate
                // a missing object that results in an error, throw the error and let the server deal with
                // the condition as best as it can (usually a crashLocalVoltDB).
                throw (Error)ex;
            }
            return ProcedureRunner.getErrorResponse(m_procedureName,
                                                    true,
                                                    0,
                                                    m_appStatusCode,
                                                    m_appStatusString,
                                                    null,
                                                    ex);
        }

        return responseFromTableArray(results);
    }
private ClientResponseImpl coreCall ( Object ... paramListIn ) { VoltTable [ ] results = null ; Object [ ] paramList = paramListIn ; try { if ( ( m_paramTypes . length > 0 ) && ( m_paramTypes [ 0 ] == ParameterSet . class ) ) { assert ( m_paramTypes . length == 1 ) ; paramList = new Object [ ] { ParameterSet . fromArrayNoCopy ( paramListIn ) } ; } if ( paramList . length != m_paramTypes . length ) { String msg = "PROCEDURE " + m_procedureName + " EXPECTS " + String . valueOf ( m_paramTypes . length ) + " PARAMS, BUT RECEIVED " + String . valueOf ( paramList . length ) ; m_statusCode = ClientResponse . GRACEFUL_FAILURE ; return ProcedureRunner . getErrorResponse ( m_statusCode , m_appStatusCode , m_appStatusString , msg , null ) ; } for ( int i = 0 ; i < m_paramTypes . length ; i ++ ) { try { paramList [ i ] = ParameterConverter . tryToMakeCompatible ( m_paramTypes [ i ] , paramList [ i ] ) ; assert ( ParameterConverter . verifyParameterConversion ( paramList [ i ] , m_paramTypes [ i ] ) ) ; } catch ( Exception e ) { String msg = "PROCEDURE " + m_procedureName + " TYPE ERROR FOR PARAMETER " + i + ": " + e . toString ( ) ; m_statusCode = ClientResponse . GRACEFUL_FAILURE ; return ProcedureRunner . getErrorResponse ( m_statusCode , m_appStatusCode , m_appStatusString , msg , null ) ; } } try { m_procedure . m_runner = this ; Object rawResult = m_procMethod . invoke ( m_procedure , paramList ) ; if ( rawResult instanceof CompletableFuture < ? > ) { final CompletableFuture < ? > fut = ( CompletableFuture < ? > ) rawResult ; fut . thenRun ( ( ) -> { Object innerRawResult = null ; ClientResponseImpl response = null ; try { innerRawResult = fut . get ( ) ; } catch ( InterruptedException | ExecutionException e ) { assert ( false ) ; innerRawResult = new ClientResponseImpl ( ClientResponseImpl . UNEXPECTED_FAILURE , new VoltTable [ 0 ] , "Future returned from NTProc " + m_procedureName + " failed to complete." , m_clientHandle ) ; } if ( innerRawResult instanceof ClientResponseImpl ) { response = ( ClientResponseImpl ) innerRawResult ; } else { try { VoltTable [ ] r = ParameterConverter . getResultsFromRawResults ( m_procedureName , innerRawResult ) ; response = responseFromTableArray ( r ) ; } catch ( Exception e ) { response = new ClientResponseImpl ( ClientResponseImpl . GRACEFUL_FAILURE , new VoltTable [ 0 ] , "Type " + innerRawResult . getClass ( ) . getName ( ) + " returned from NTProc \"" + m_procedureName + "\" was not an acceptible VoltDB return type." , m_clientHandle ) ; } } completeCall ( response ) ; } ) . exceptionally ( e -> { SerializableException se = null ; if ( e instanceof SerializableException ) { se = ( SerializableException ) e ; } String msg = "PROCEDURE " + m_procedureName + " THREW EXCEPTION: " ; if ( se != null ) { msg += se . getMessage ( ) ; } else { msg += e . toString ( ) ; } m_statusCode = ClientResponse . GRACEFUL_FAILURE ; completeCall ( ProcedureRunner . getErrorResponse ( m_statusCode , m_appStatusCode , m_appStatusString , msg , se ) ) ; return null ; } ) ; return null ; } results = ParameterConverter . getResultsFromRawResults ( m_procedureName , rawResult ) ; } catch ( IllegalAccessException e ) { throw new InvocationTargetException ( e ) ; } } catch ( InvocationTargetException itex ) { Throwable ex = itex . getCause ( ) ; if ( CoreUtils . isStoredProcThrowableFatalToServer ( ex ) ) { throw ( Error ) ex ; } return ProcedureRunner . getErrorResponse ( m_procedureName , true , 0 , m_appStatusCode , m_appStatusString , null , ex ) ; } return responseFromTableArray ( results ) ; }
Core Synchronous call to NT procedure run(..) method.
@return ClientResponseImpl non-null if done and null if there is an
async task still running.