mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-03 12:10:57 -06:00
#4416 First implementation of gRPC-based Python interface
First implementation with Asynchronous gRPC server, a few services and some client python code.
This commit is contained in:
parent
7df5ce9a92
commit
922386c673
@ -27,4 +27,8 @@
|
||||
#define PRODUCTVER "@PRODUCTVER@"
|
||||
#define STRPRODUCTVER "@STRPRODUCTVER@"
|
||||
|
||||
#define RESINSIGHT_MAJOR_VERSION @RESINSIGHT_MAJOR_VERSION@
|
||||
#define RESINSIGHT_MINOR_VERSION @RESINSIGHT_MINOR_VERSION@
|
||||
#define RESINSIGHT_PATCH_VERSION @RESINSIGHT_PATCH_VERSION@
|
||||
|
||||
#define RESINSIGHT_OCTAVE_VERSION "@OCTAVE_VERSION_STRING@"
|
||||
|
21
ApplicationCode/Adm/RiaVersionInfo.py.cmake
Normal file
21
ApplicationCode/Adm/RiaVersionInfo.py.cmake
Normal file
@ -0,0 +1,21 @@
|
||||
#
|
||||
# Copyright (C) 2019- Equinor ASA
|
||||
#
|
||||
# ResInsight is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
# See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
# for more details.
|
||||
#
|
||||
# Python version of RiaVersionInfo.h
|
||||
# Just sets version constants
|
||||
|
||||
RESINSIGHT_MAJOR_VERSION = "@RESINSIGHT_MAJOR_VERSION@"
|
||||
RESINSIGHT_MINOR_VERSION = "@RESINSIGHT_MINOR_VERSION@"
|
||||
RESINSIGHT_PATCH_VERSION = "@RESINSIGHT_PATCH_VERSION@"
|
@ -1292,6 +1292,36 @@ cvf::Font* RiaApplication::defaultWellLabelFont()
|
||||
return m_defaultWellLabelFont.p();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaApplication::initializeGrpcServer(const cvf::ProgramOptions& progOpt)
|
||||
{
|
||||
#ifdef ENABLE_GRPC
|
||||
if (!m_preferences->enableGrpcServer()) return false;
|
||||
|
||||
int defaultPortNumber = m_preferences->defaultGrpcPortNumber();
|
||||
bool fixedPort = false;
|
||||
if (cvf::Option o = progOpt.option("grpcserver"))
|
||||
{
|
||||
if (o.valueCount() == 1)
|
||||
{
|
||||
defaultPortNumber = o.value(0).toInt(defaultPortNumber);
|
||||
fixedPort = true;
|
||||
}
|
||||
}
|
||||
int portNumber = defaultPortNumber;
|
||||
if (!fixedPort)
|
||||
{
|
||||
portNumber = RiaGrpcServer::findAvailablePortNumber(defaultPortNumber);
|
||||
}
|
||||
m_grpcServer.reset(new RiaGrpcServer(portNumber));
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -20,6 +20,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#ifdef ENABLE_GRPC
|
||||
#include "RiaGrpcServer.h"
|
||||
#endif
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
@ -93,7 +96,7 @@ public:
|
||||
EXIT_COMPLETED,
|
||||
EXIT_WITH_ERROR
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
static RiaApplication* instance();
|
||||
RiaApplication();
|
||||
@ -171,6 +174,8 @@ public:
|
||||
cvf::Font* defaultAnnotationFont();
|
||||
cvf::Font* defaultWellLabelFont();
|
||||
|
||||
bool initializeGrpcServer(const cvf::ProgramOptions& progOpt);
|
||||
|
||||
// Public implementation specific overrides
|
||||
virtual void initialize();
|
||||
virtual ApplicationStatus handleArguments(cvf::ProgramOptions* progOpt) = 0;
|
||||
@ -178,8 +183,7 @@ public:
|
||||
virtual void addToRecentFiles(const QString& fileName) {}
|
||||
virtual void showInformationMessage(const QString& infoText) = 0;
|
||||
virtual void showErrorMessage(const QString& errMsg) = 0;
|
||||
virtual void cleanupBeforeProgramExit() {}
|
||||
|
||||
virtual void launchGrpcServer() = 0;
|
||||
protected:
|
||||
// Protected implementation specific overrides
|
||||
virtual void invokeProcessEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents) = 0;
|
||||
@ -203,11 +207,14 @@ protected:
|
||||
RiaSocketServer* m_socketServer;
|
||||
caf::UiProcess* m_workerProcess;
|
||||
|
||||
#ifdef ENABLE_GRPC
|
||||
std::unique_ptr<RiaGrpcServer> m_grpcServer;
|
||||
#endif
|
||||
|
||||
// Execute for all settings
|
||||
std::list<int> m_currentCaseIds;
|
||||
QString m_currentProgram;
|
||||
QStringList m_currentArguments;
|
||||
|
||||
RiaPreferences* m_preferences;
|
||||
|
||||
std::map<QString, QString> m_fileDialogDefaultDirectories;
|
||||
|
@ -339,6 +339,16 @@ void RiaConsoleApplication::showErrorMessage(const QString& errMsg)
|
||||
RiaLogging::error(errMsg);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaConsoleApplication::launchGrpcServer()
|
||||
{
|
||||
#ifdef ENABLE_GRPC
|
||||
m_grpcServer->run();
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -41,7 +41,7 @@ public:
|
||||
ApplicationStatus handleArguments(cvf::ProgramOptions* progOpt) override;
|
||||
void showInformationMessage(const QString& text) override;
|
||||
void showErrorMessage(const QString& errMsg) override;
|
||||
|
||||
void launchGrpcServer() override;
|
||||
protected:
|
||||
// Protected implementation specific overrides
|
||||
void invokeProcessEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents) override;
|
||||
|
@ -170,6 +170,15 @@ namespace RiaDefines
|
||||
ImportFileType obtainFileTypeFromFileName(const QString& fileName);
|
||||
QString defaultDirectoryLabel(ImportFileType fileTypes);
|
||||
|
||||
enum CaseType
|
||||
{
|
||||
ECLIPSE_RESULT_CASE = 1,
|
||||
ECLIPSE_INPUT_CASE = 2,
|
||||
ECLIPSE_STAT_CASE = 3,
|
||||
ECLIPSE_SOURCE_CASE = 4,
|
||||
GEOMECH_ODB_CASE = 5
|
||||
};
|
||||
|
||||
enum FontSettingType
|
||||
{
|
||||
SCENE_FONT,
|
||||
|
@ -178,13 +178,11 @@ RiaGuiApplication::RiaGuiApplication(int& argc, char** argv)
|
||||
, m_mainWindow(nullptr)
|
||||
, m_mainPlotWindow(nullptr)
|
||||
{
|
||||
// For idle processing
|
||||
// m_idleTimerStarted = false;
|
||||
installEventFilter(this);
|
||||
|
||||
setWindowIcon(QIcon(":/AppLogo48x48.png"));
|
||||
|
||||
m_recentFileActionProvider = std::unique_ptr<RiuRecentFileActionProvider>(new RiuRecentFileActionProvider);
|
||||
|
||||
connect(this, SIGNAL(aboutToQuit()), this, SLOT(onProgramExit()));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -571,8 +569,8 @@ void RiaGuiApplication::initialize()
|
||||
|
||||
RiaLogging::setLoggerInstance(new RiuMessagePanelLogger(m_mainWindow->messagePanel()));
|
||||
RiaLogging::loggerInstance()->setLevel(RI_LL_DEBUG);
|
||||
|
||||
m_socketServer = new RiaSocketServer(this);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1231,6 +1229,19 @@ void RiaGuiApplication::showErrorMessage(const QString& errMsg)
|
||||
errDialog.showMessage(errMsg);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGuiApplication::launchGrpcServer()
|
||||
{
|
||||
#ifdef ENABLE_GRPC
|
||||
m_grpcServer->runInThread();
|
||||
m_idleTimer = new QTimer(this);
|
||||
connect(m_idleTimer, SIGNAL(timeout()), this, SLOT(runIdleProcessing()));
|
||||
m_idleTimer->start(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1367,10 +1378,14 @@ void RiaGuiApplication::onProjectClosed()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGuiApplication::cleanupBeforeProgramExit()
|
||||
void RiaGuiApplication::onProgramExit()
|
||||
{
|
||||
closeAllWindows();
|
||||
invokeProcessEvents();
|
||||
#ifdef ENABLE_GRPC
|
||||
if (m_grpcServer)
|
||||
{
|
||||
m_grpcServer->quit();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1575,6 +1590,27 @@ void RiaGuiApplication::applyGuiPreferences(const RiaPreferences* oldPreferences
|
||||
caf::PdmUiItem::enableExtraDebugText(m_preferences->appendFieldKeywordToToolTipText());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGuiApplication::updateGrpcServer()
|
||||
{
|
||||
#ifdef ENABLE_GRPC
|
||||
bool isGrpcRunning = m_grpcServer != nullptr && m_grpcServer->isRunning();
|
||||
bool shouldItBeRunning = m_preferences->enableGrpcServer();
|
||||
if (isGrpcRunning && !shouldItBeRunning)
|
||||
{
|
||||
m_grpcServer->quit();
|
||||
}
|
||||
else if (!isGrpcRunning && shouldItBeRunning)
|
||||
{
|
||||
int portNumber = RiaGrpcServer::findAvailablePortNumber(m_preferences->defaultGrpcPortNumber());
|
||||
m_grpcServer.reset(new RiaGrpcServer(portNumber));
|
||||
m_grpcServer->runInThread();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1637,6 +1673,19 @@ void RiaGuiApplication::slotWorkerProcessFinished(int exitCode, QProcess::ExitSt
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGuiApplication::runIdleProcessing()
|
||||
{
|
||||
#ifdef ENABLE_GRPC
|
||||
if (!caf::ProgressInfoStatic::isRunning())
|
||||
{
|
||||
m_grpcServer->processOneRequest();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -28,8 +28,10 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMutex>
|
||||
#include <QPointer>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
@ -121,6 +123,7 @@ public:
|
||||
|
||||
static void clearAllSelections();
|
||||
void applyGuiPreferences(const RiaPreferences* oldPreferences = nullptr);
|
||||
void updateGrpcServer();
|
||||
|
||||
// Public RiaApplication overrides
|
||||
void initialize() override;
|
||||
@ -129,7 +132,7 @@ public:
|
||||
void addToRecentFiles(const QString& fileName) override;
|
||||
void showInformationMessage(const QString& text) override;
|
||||
void showErrorMessage(const QString& errMsg) override;
|
||||
void cleanupBeforeProgramExit() override;
|
||||
void launchGrpcServer() override;
|
||||
protected:
|
||||
// Protected RiaApplication overrides
|
||||
void invokeProcessEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents) override;
|
||||
@ -142,7 +145,7 @@ protected:
|
||||
void startMonitoringWorkProgress(caf::UiProcess* uiProcess) override;
|
||||
void stopMonitoringWorkProgress() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
void setWindowCaptionFromAppState();
|
||||
|
||||
void createMainWindow();
|
||||
@ -159,11 +162,16 @@ private:
|
||||
|
||||
private slots:
|
||||
void slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void runIdleProcessing();
|
||||
void onProgramExit();
|
||||
|
||||
private:
|
||||
RiuMainWindow* m_mainWindow;
|
||||
RiuPlotMainWindow* m_mainPlotWindow;
|
||||
|
||||
#ifdef ENABLE_GRPC
|
||||
QPointer<QTimer> m_idleTimer;
|
||||
#endif
|
||||
|
||||
std::unique_ptr<RiuRecentFileActionProvider> m_recentFileActionProvider;
|
||||
|
||||
std::unique_ptr<RiuMdiMaximizeWindowGuard> m_maximizeWindowGuard;
|
||||
|
@ -41,11 +41,11 @@ int main(int argc, char *argv[])
|
||||
RiaLogging::loggerInstance()->setLevel(RI_LL_DEBUG);
|
||||
|
||||
std::unique_ptr<RiaApplication> app (createApplication(argc, argv));
|
||||
app->initialize();
|
||||
|
||||
cvf::ProgramOptions progOpt;
|
||||
bool result = RiaArgumentParser::parseArguments(&progOpt);
|
||||
|
||||
bool result = RiaArgumentParser::parseArguments(&progOpt);
|
||||
app->initialize();
|
||||
|
||||
if (!result)
|
||||
{
|
||||
@ -60,7 +60,6 @@ int main(int argc, char *argv[])
|
||||
app->showErrorMessage(RiaApplication::commandLineParameterHelp() +
|
||||
cvfqt::Utils::toQString(usageText) +
|
||||
unknownOptionsText.join("\n"));
|
||||
app->cleanupBeforeProgramExit();
|
||||
if (dynamic_cast<RiaGuiApplication*>(app.get()) == nullptr)
|
||||
{
|
||||
return 1;
|
||||
@ -84,6 +83,10 @@ int main(int argc, char *argv[])
|
||||
int exitCode = 0;
|
||||
try
|
||||
{
|
||||
if (app->initializeGrpcServer(progOpt))
|
||||
{
|
||||
app->launchGrpcServer();
|
||||
}
|
||||
exitCode = QCoreApplication::instance()->exec();
|
||||
}
|
||||
catch (std::exception& exep )
|
||||
|
@ -51,6 +51,9 @@ RiaPreferences::RiaPreferences(void)
|
||||
{
|
||||
CAF_PDM_InitField(&navigationPolicy, "navigationPolicy", caf::AppEnum<RiaGuiApplication::RINavigationPolicy>(RiaGuiApplication::NAVIGATION_POLICY_RMS), "Navigation Mode", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&enableGrpcServer, "enableGrpcServer", true, "Enable gRPC script server", "", "Remote Procedure Call Scripting Engine", "");
|
||||
CAF_PDM_InitField(&defaultGrpcPortNumber, "defaultGrpcPort", 50051, "Default gRPC port", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&scriptDirectories, "scriptDirectory", "Shared Script Folder(s)", "", "", "");
|
||||
scriptDirectories.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
|
||||
|
||||
@ -129,7 +132,7 @@ RiaPreferences::RiaPreferences(void)
|
||||
|
||||
m_tabNames << "General";
|
||||
m_tabNames << "Eclipse";
|
||||
m_tabNames << "Octave";
|
||||
m_tabNames << "Scripting";
|
||||
if (RiaApplication::enableDevelopmentFeatures())
|
||||
{
|
||||
m_tabNames << "System";
|
||||
@ -245,6 +248,12 @@ void RiaPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering&
|
||||
}
|
||||
else if (uiConfigName == m_tabNames[2])
|
||||
{
|
||||
#ifdef ENABLE_GRPC
|
||||
caf::PdmUiGroup* grpcGroup = uiOrdering.addNewGroup("gRPC Server");
|
||||
grpcGroup->add(&enableGrpcServer);
|
||||
grpcGroup->add(&defaultGrpcPortNumber);
|
||||
#endif
|
||||
|
||||
caf::PdmUiGroup* octaveGroup = uiOrdering.addNewGroup("Octave");
|
||||
octaveGroup->add(&octaveExecutable);
|
||||
octaveGroup->add(&octaveShowHeaderInfoWhenExecutingScripts);
|
||||
|
@ -68,6 +68,9 @@ public:
|
||||
public: // Pdm Fields
|
||||
caf::PdmField<caf::AppEnum< RiaGuiApplication::RINavigationPolicy > > navigationPolicy;
|
||||
|
||||
caf::PdmField<bool> enableGrpcServer;
|
||||
caf::PdmField<int> defaultGrpcPortNumber;
|
||||
|
||||
caf::PdmField<QString> scriptDirectories;
|
||||
caf::PdmField<QString> scriptEditorExecutable;
|
||||
|
||||
|
@ -56,6 +56,7 @@
|
||||
bool RiaArgumentParser::parseArguments(cvf::ProgramOptions* progOpt)
|
||||
{
|
||||
CVF_ASSERT(progOpt);
|
||||
progOpt->registerOption("grpcserver", "[<portnumber>]", "Run as a GRPC server. Default port is 50051", cvf::ProgramOptions::SINGLE_VALUE);
|
||||
progOpt->registerOption("console", "", "Run as a console application without Graphics");
|
||||
progOpt->registerOption("last", "", "Open last used project.");
|
||||
progOpt->registerOption("project", "<filename>", "Open project file <filename>.", cvf::ProgramOptions::SINGLE_VALUE);
|
||||
|
@ -23,6 +23,9 @@ endif(Qt5Core_FOUND)
|
||||
CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/ApplicationCode/Adm/RiaVersionInfo.h.cmake
|
||||
${CMAKE_BINARY_DIR}/Generated/RiaVersionInfo.h
|
||||
)
|
||||
CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/ApplicationCode/Adm/RiaVersionInfo.py.cmake
|
||||
${CMAKE_BINARY_DIR}/Python/generated/RiaVersionInfo.py
|
||||
)
|
||||
|
||||
if (MSVC AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 19.11))
|
||||
# VS 2017 : Disable warnings from from gtest code, using deprecated code related to TR1
|
||||
@ -44,6 +47,7 @@ include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Commands
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Commands/EclipseCommands
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/FileInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GrpcInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SocketInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Measurement
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization
|
||||
@ -97,6 +101,12 @@ list( APPEND CPP_SOURCES
|
||||
${UNIT_TEST_FILES}
|
||||
)
|
||||
|
||||
if (RESINSIGHT_ENABLE_GRPC)
|
||||
list( APPEND REFERENCED_CMAKE_FILES
|
||||
GrpcInterface/CMakeLists.cmake
|
||||
)
|
||||
endif(RESINSIGHT_ENABLE_GRPC)
|
||||
|
||||
list( APPEND REFERENCED_CMAKE_FILES
|
||||
Application/CMakeLists_files.cmake
|
||||
Application/Tools/CMakeLists_files.cmake
|
||||
@ -152,7 +162,7 @@ list( APPEND REFERENCED_CMAKE_FILES
|
||||
CommandFileInterface/Core/CMakeLists_files.cmake
|
||||
Commands/FractureCommands/CMakeLists_files.cmake
|
||||
)
|
||||
|
||||
|
||||
option (RESINSIGHT_INCLUDE_APPLICATION_UNIT_TESTS "Include ApplicationCode Unit Tests" OFF)
|
||||
if (RESINSIGHT_INCLUDE_APPLICATION_UNIT_TESTS)
|
||||
add_definitions(-DUSE_UNIT_TESTS)
|
||||
@ -230,7 +240,6 @@ if (RESINSIGHT_ENABLE_PROTOTYPE_FEATURE_SOURING)
|
||||
add_definitions(-DENABLE_SOURING)
|
||||
endif()
|
||||
|
||||
|
||||
#############################################################################
|
||||
# Qt specifics: Moc, ui, resources
|
||||
#############################################################################
|
||||
@ -306,11 +315,16 @@ source_group( "UnitTests" FILES ${UNIT_TEST_FILES} )
|
||||
|
||||
if (MSVC)
|
||||
set( EXE_FILES WIN32)
|
||||
if (RESINSIGHT_ENABLE_GRPC)
|
||||
# GRPC generates a lot of harmless warnings on MSVC
|
||||
set_source_files_properties(${GRPC_CPP_SOURCES} PROPERTIES COMPILE_FLAGS "/wd4251 /wd4702 /wd4005 /wd4244 /wd4125")
|
||||
endif(RESINSIGHT_ENABLE_GRPC)
|
||||
elseif (APPLE)
|
||||
set( EXE_FILES MACOSX_BUNDLE)
|
||||
endif()
|
||||
set( EXE_FILES
|
||||
${EXE_FILES}
|
||||
${GRPC_HEADER_FILES}
|
||||
${CPP_SOURCES}
|
||||
${MOC_SOURCE_FILES}
|
||||
${FORM_FILES_CPP}
|
||||
@ -321,9 +335,23 @@ set( EXE_FILES
|
||||
../ResInsightVersion.cmake
|
||||
.clang-format
|
||||
.clang-tidy
|
||||
Adm/RiaVersionInfo.h.cmake
|
||||
)
|
||||
|
||||
add_executable( ResInsight ${EXE_FILES} )
|
||||
if (RESINSIGHT_ENABLE_GRPC)
|
||||
list(APPEND EXE_FILES
|
||||
${GRPC_CPP_SOURCES}
|
||||
${GRPC_HEADER_FILES}
|
||||
${GRPC_PYTHON_SOURCES_FULL_PATH}
|
||||
Adm/RiaVersionInfo.py.cmake
|
||||
)
|
||||
if (DEFINED GRPC_LIBRARY_DIRS)
|
||||
message(STATUS "Using GRPC Library Dir: ${GRPC_LIBRARY_DIRS}")
|
||||
link_directories("${GRPC_LIBRARY_DIRS}")
|
||||
endif(DEFINED GRPC_LIBRARY_DIRS)
|
||||
endif(RESINSIGHT_ENABLE_GRPC)
|
||||
|
||||
add_executable( ResInsight ${EXE_FILES})
|
||||
|
||||
if (MSVC)
|
||||
# The following warnings are supposed to be used in ResInsight, but temporarily disabled to avoid too much noise
|
||||
@ -376,6 +404,10 @@ set( LINK_LIBRARIES
|
||||
${QT_LIBRARIES}
|
||||
)
|
||||
|
||||
if (RESINSIGHT_ENABLE_GRPC)
|
||||
list(APPEND LINK_LIBRARIES ${GRPC_LIBRARIES})
|
||||
endif()
|
||||
|
||||
# According to ivarun this is needed on OpenSuse, and Fedora. See: https://github.com/OPM/ResInsight/pull/7
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
list(APPEND EXTERNAL_LINK_LIBRARIES
|
||||
@ -502,6 +534,31 @@ foreach (FILE_TO_COPY ${RI_DLL_FILENAMES})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Copy all grpc libraries and python files
|
||||
if (RESINSIGHT_ENABLE_GRPC)
|
||||
if(UNIX)
|
||||
foreach (GRPC_LIBRARY ${GRPC_LIBRARIES})
|
||||
add_custom_command(TARGET ResInsight POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${GRPC_INSTALL_PREFIX}/lib/lib${GRPC_LIBRARY}.so"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>"
|
||||
)
|
||||
endforeach(GRPC_LIBRARY ${GRPC_LIBRARIES})
|
||||
endif(UNIX)
|
||||
|
||||
if (PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
|
||||
add_custom_target(GeneratedPythonSources DEPENDS ${GRPC_GENERATED_PYTHON_SOURCES})
|
||||
add_dependencies(ResInsight GeneratedPythonSources)
|
||||
|
||||
foreach (PYTHON_SCRIPT ${GRPC_PYTHON_SOURCES})
|
||||
if (EXISTS "${GRPC_PYTHON_SOURCE_PATH}/${PYTHON_SCRIPT}")
|
||||
configure_file("${GRPC_PYTHON_SOURCE_PATH}/${PYTHON_SCRIPT}"
|
||||
"${GRPC_PYTHON_DEST_PATH}/${PYTHON_SCRIPT}"
|
||||
COPYONLY)
|
||||
endif(EXISTS "${GRPC_PYTHON_SOURCE_PATH}/${PYTHON_SCRIPT}")
|
||||
endforeach(PYTHON_SCRIPT ${GRPC_PYTHON_SOURCES})
|
||||
endif(PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
|
||||
endif(RESINSIGHT_ENABLE_GRPC)
|
||||
|
||||
#############################################################################
|
||||
# Install
|
||||
|
@ -38,6 +38,22 @@ RicfSetTimeStep::RicfSetTimeStep()
|
||||
RICF_InitField(&m_timeStepIndex, "timeStep", -1, "Time Step Index", "", "", "");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicfSetTimeStep::setCaseId(int caseId)
|
||||
{
|
||||
m_caseId = caseId;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicfSetTimeStep::setTimeStepIndex(int timeStepIndex)
|
||||
{
|
||||
m_timeStepIndex = timeStepIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -66,5 +82,6 @@ void RicfSetTimeStep::execute()
|
||||
for (Rim3dView* view : eclipseCase->views())
|
||||
{
|
||||
view->setCurrentTimeStepAndUpdate(m_timeStepIndex);
|
||||
view->createDisplayModelAndRedraw();
|
||||
}
|
||||
}
|
||||
|
@ -34,9 +34,13 @@ class RicfSetTimeStep : public RicfCommandObject
|
||||
public:
|
||||
RicfSetTimeStep();
|
||||
|
||||
void setCaseId(int caseId);
|
||||
void setTimeStepIndex(int timeStepIndex);
|
||||
|
||||
void execute() override;
|
||||
|
||||
private:
|
||||
|
||||
caf::PdmField<int> m_caseId;
|
||||
caf::PdmField<int> m_timeStepIndex;
|
||||
};
|
||||
|
@ -58,6 +58,7 @@ void RicEditPreferencesFeature::onActionTriggered(bool isChecked)
|
||||
caf::PdmSettings::writeFieldsToApplicationStore(app->preferences());
|
||||
app->applyPreferences(oldPreferences.get());
|
||||
app->applyGuiPreferences(oldPreferences.get());
|
||||
app->updateGrpcServer();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
158
ApplicationCode/GrpcInterface/CMakeLists.cmake
Normal file
158
ApplicationCode/GrpcInterface/CMakeLists.cmake
Normal file
@ -0,0 +1,158 @@
|
||||
set ( SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcServer.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCallbacks.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCallbacks.inl
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcServiceInterface.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcGridInfoService.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcProjectInfoService.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCommandService.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcResInfoService.h
|
||||
)
|
||||
|
||||
set ( SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcServer.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcServiceInterface.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcGridInfoService.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcProjectInfoService.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCommandService.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcResInfoService.cpp
|
||||
)
|
||||
|
||||
add_definitions(-DENABLE_GRPC)
|
||||
|
||||
if (MSVC)
|
||||
add_definitions(-D_WIN32_WINNT=0x600)
|
||||
|
||||
# Find Protobuf installation
|
||||
# Looks for protobuf-config.cmake file installed by Protobuf's cmake installation.
|
||||
set(protobuf_MODULE_COMPATIBLE ON CACHE BOOL "")
|
||||
find_package(Protobuf CONFIG 3.0 REQUIRED)
|
||||
message(STATUS "Using protobuf ${protobuf_VERSION}")
|
||||
|
||||
# Find gRPC installation
|
||||
# Looks for gRPCConfig.cmake file installed by gRPC's cmake installation.
|
||||
find_package(gRPC CONFIG REQUIRED NO_MODULE)
|
||||
message(STATUS "Using gRPC ${gRPC_VERSION}")
|
||||
|
||||
set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
|
||||
set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
|
||||
|
||||
set(_GRPC_GRPCPP_UNSECURE gRPC::grpc++_unsecure gRPC::grpc_unsecure gRPC::gpr)
|
||||
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>)
|
||||
set(GRPC_LIBRARIES ${_GRPC_GRPCPP_UNSECURE} ${_PROTOBUF_LIBPROTOBUF})
|
||||
|
||||
if (MSVC)
|
||||
set_target_properties(${GRPC_LIBRARIES} PROPERTIES
|
||||
MAP_IMPORTED_CONFIG_MINSIZEREL RELEASE
|
||||
MAP_IMPORTED_CONFIG_RELWITHDEBINFO RELEASE
|
||||
)
|
||||
endif(MSVC)
|
||||
else()
|
||||
if (NOT DEFINED GRPC_INSTALL_PREFIX OR NOT EXISTS ${GRPC_INSTALL_PREFIX})
|
||||
message(FATAL_ERROR "You need a valid GRPC_INSTALL_PREFIX set to build with GRPC")
|
||||
endif()
|
||||
set(ENV{PKG_CONFIG_PATH} "${GRPC_INSTALL_PREFIX}/lib/pkgconfig")
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(GRPC REQUIRED grpc++_unsecure>=1.20 grpc_unsecure gpr protobuf)
|
||||
set(_PROTOBUF_PROTOC "${GRPC_INSTALL_PREFIX}/bin/protoc")
|
||||
set(_GRPC_CPP_PLUGIN_EXECUTABLE "${GRPC_INSTALL_PREFIX}/bin/grpc_cpp_plugin")
|
||||
include_directories(AFTER ${GRPC_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# Cannot use the nice new FindPackage modules for python since that is CMake 3.12+
|
||||
if(PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
|
||||
message(STATUS "Using Python ${PYTHON_EXECUTABLE}")
|
||||
endif(PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
|
||||
|
||||
# Proto files
|
||||
set(PROTO_FILES
|
||||
"Empty"
|
||||
"CaseInfo"
|
||||
"GridInfo"
|
||||
"ProjectInfo"
|
||||
"Commands"
|
||||
"ResInfo"
|
||||
)
|
||||
|
||||
set(GRPC_PYTHON_SOURCE_PATH "${CMAKE_SOURCE_DIR}/Python")
|
||||
set(GRPC_PYTHON_DEST_PATH "${CMAKE_BINARY_DIR}/Python")
|
||||
|
||||
foreach(proto_file ${PROTO_FILES})
|
||||
get_filename_component(rips_proto "${CMAKE_CURRENT_LIST_DIR}/GrpcProtos/${proto_file}.proto" ABSOLUTE)
|
||||
get_filename_component(rips_proto_path "${rips_proto}" PATH)
|
||||
|
||||
set(rips_proto_srcs "${CMAKE_BINARY_DIR}/Generated/${proto_file}.pb.cc")
|
||||
set(rips_proto_hdrs "${CMAKE_BINARY_DIR}/Generated/${proto_file}.pb.h")
|
||||
set(rips_grpc_srcs "${CMAKE_BINARY_DIR}/Generated/${proto_file}.grpc.pb.cc")
|
||||
set(rips_grpc_hdrs "${CMAKE_BINARY_DIR}/Generated/${proto_file}.grpc.pb.h")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${rips_proto_srcs}" "${rips_proto_hdrs}" "${rips_grpc_srcs}" "${rips_grpc_hdrs}"
|
||||
COMMAND ${_PROTOBUF_PROTOC}
|
||||
ARGS --grpc_out "${CMAKE_BINARY_DIR}/Generated"
|
||||
--cpp_out "${CMAKE_BINARY_DIR}/Generated"
|
||||
-I "${rips_proto_path}"
|
||||
--plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
|
||||
"${rips_proto}"
|
||||
DEPENDS "${rips_proto}"
|
||||
)
|
||||
|
||||
if (PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
|
||||
set(rips_proto_python "generated/${proto_file}_pb2.py")
|
||||
set(rips_grpc_python "generated/${proto_file}_pb2_grpc.py")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${GRPC_PYTHON_SOURCE_PATH}/${rips_proto_python}" "${GRPC_PYTHON_SOURCE_PATH}/${rips_grpc_python}"
|
||||
COMMAND ${PYTHON_EXECUTABLE}
|
||||
ARGS -m grpc_tools.protoc
|
||||
-I "${rips_proto_path}"
|
||||
--python_out "${GRPC_PYTHON_SOURCE_PATH}/generated"
|
||||
--grpc_python_out "${GRPC_PYTHON_SOURCE_PATH}/generated"
|
||||
"${rips_proto}"
|
||||
DEPENDS "${rips_proto}"
|
||||
COMMENT "Generating ${rips_proto_python} and ${rips_grpc_python}"
|
||||
VERBATIM
|
||||
)
|
||||
list (APPEND GRPC_PYTHON_GENERATED_SOURCES
|
||||
${rips_proto_python}
|
||||
${rips_grpc_python}
|
||||
)
|
||||
|
||||
endif(PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
|
||||
|
||||
list( APPEND GRPC_HEADER_FILES
|
||||
${rips_proto_hdrs}
|
||||
${rips_grpc_hdrs}
|
||||
)
|
||||
|
||||
list( APPEND GRPC_CPP_SOURCES
|
||||
${rips_proto_srcs}
|
||||
${rips_grpc_srcs}
|
||||
)
|
||||
|
||||
endforeach(proto_file)
|
||||
|
||||
if (PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
|
||||
list(APPEND GRPC_PYTHON_SOURCES
|
||||
${GRPC_PYTHON_GENERATED_SOURCES}
|
||||
"api/__init__.py"
|
||||
"api/ResInsight.py"
|
||||
"examples/CommandExample.py"
|
||||
"examples/GridInfoStreamingExample.py"
|
||||
"examples/ResultValues.py"
|
||||
"examples/SelectedCases.py"
|
||||
"examples/AllCases.py"
|
||||
"tests/test_sample.py"
|
||||
)
|
||||
|
||||
foreach(PYTHON_SCRIPT ${GRPC_PYTHON_SOURCES})
|
||||
list(APPEND GRPC_PYTHON_SOURCES_FULL_PATH "${GRPC_PYTHON_SOURCE_PATH}/${PYTHON_SCRIPT}")
|
||||
endforeach()
|
||||
source_group(TREE ${GRPC_PYTHON_SOURCE_PATH} FILES ${GRPC_PYTHON_SOURCES_FULL_PATH} PREFIX "Python")
|
||||
|
||||
endif(PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
|
||||
|
||||
list ( APPEND GRPC_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
|
||||
list ( APPEND GRPC_CPP_SOURCES ${SOURCE_GROUP_SOURCE_FILES})
|
||||
|
||||
source_group( "GrpcInterface" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.cmake )
|
31
ApplicationCode/GrpcInterface/GrpcProtos/CaseInfo.proto
Normal file
31
ApplicationCode/GrpcInterface/GrpcProtos/CaseInfo.proto
Normal file
@ -0,0 +1,31 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package rips;
|
||||
|
||||
message Case {
|
||||
int32 id = 1;
|
||||
}
|
||||
|
||||
message CaseInfo
|
||||
{
|
||||
int32 id = 1;
|
||||
int32 group_id = 2;
|
||||
string name = 3;
|
||||
string type = 4;
|
||||
}
|
||||
|
||||
message CaseInfos
|
||||
{
|
||||
repeated CaseInfo case_info = 1;
|
||||
}
|
||||
|
||||
message CaseGroup
|
||||
{
|
||||
int32 id = 1;
|
||||
string name = 2;
|
||||
}
|
||||
|
||||
message CaseGroups
|
||||
{
|
||||
repeated CaseGroup case_group = 1;
|
||||
}
|
60
ApplicationCode/GrpcInterface/GrpcProtos/Commands.proto
Normal file
60
ApplicationCode/GrpcInterface/GrpcProtos/Commands.proto
Normal file
@ -0,0 +1,60 @@
|
||||
syntax = "proto3";
|
||||
|
||||
import "Empty.proto";
|
||||
|
||||
package rips;
|
||||
|
||||
service Commands
|
||||
{
|
||||
rpc Execute(CommandParams) returns(Empty) {}
|
||||
}
|
||||
|
||||
message SetTimeStepParams
|
||||
{
|
||||
int32 caseId = 1;
|
||||
int32 timeStep = 2;
|
||||
}
|
||||
|
||||
message SetMainWindowSizeParams
|
||||
{
|
||||
int32 height = 1;
|
||||
int32 width = 2;
|
||||
}
|
||||
|
||||
message FilePathRequest
|
||||
{
|
||||
string path = 1;
|
||||
}
|
||||
|
||||
message ReplaceCaseRequest
|
||||
{
|
||||
string newGridFile = 1;
|
||||
int32 caseId = 2;
|
||||
}
|
||||
|
||||
message ReplaceSourceCasesRequest
|
||||
{
|
||||
string gridListFile = 1;
|
||||
}
|
||||
|
||||
message ExportMultiCaseRequest
|
||||
{
|
||||
string gridListFile = 1;
|
||||
}
|
||||
|
||||
message CommandParams
|
||||
{
|
||||
oneof params
|
||||
{
|
||||
SetTimeStepParams setTimeStep = 1;
|
||||
SetMainWindowSizeParams setMainWindowSize = 2;
|
||||
FilePathRequest openProject = 3;
|
||||
Empty closeProject = 4;
|
||||
FilePathRequest setStartDir = 5;
|
||||
FilePathRequest loadCase = 6;
|
||||
ReplaceCaseRequest replaceCase = 7;
|
||||
ReplaceSourceCasesRequest replaceSourceCases = 8;
|
||||
ExportMultiCaseRequest exportMultiCaseSnapshots = 9;
|
||||
}
|
||||
}
|
||||
|
7
ApplicationCode/GrpcInterface/GrpcProtos/Empty.proto
Normal file
7
ApplicationCode/GrpcInterface/GrpcProtos/Empty.proto
Normal file
@ -0,0 +1,7 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package rips;
|
||||
|
||||
message Empty
|
||||
{
|
||||
}
|
89
ApplicationCode/GrpcInterface/GrpcProtos/GridInfo.proto
Normal file
89
ApplicationCode/GrpcInterface/GrpcProtos/GridInfo.proto
Normal file
@ -0,0 +1,89 @@
|
||||
syntax = "proto3";
|
||||
|
||||
import "CaseInfo.proto";
|
||||
|
||||
package rips;
|
||||
|
||||
service GridInfo
|
||||
{
|
||||
// This function returns a two dimensional matrix: One row for each grid, starting with the main grid.
|
||||
rpc GetGridCount(Case) returns(GridCount) {}
|
||||
rpc GetGridDimensions(Case) returns (GridDimensions) {}
|
||||
rpc StreamActiveCellInfo(ActiveCellInfoRequest) returns (stream ActiveCellInfoArray) {}
|
||||
rpc GetAllCoarseningInfoArray(Case) returns (CoarseningInfoArray) {}
|
||||
rpc GetTimeSteps(Case) returns (TimeStepDates) {}
|
||||
rpc GetTimeStepDaysSinceStart(Case) returns (DoubleDates) {}
|
||||
}
|
||||
|
||||
message GridCount
|
||||
{
|
||||
int32 count = 1;
|
||||
}
|
||||
|
||||
message GridDimensions
|
||||
{
|
||||
repeated Vec3i dimensions = 1;
|
||||
}
|
||||
|
||||
message Vec3i {
|
||||
int32 i = 1;
|
||||
int32 j = 2;
|
||||
int32 k = 3;
|
||||
}
|
||||
|
||||
enum PorosityModelType
|
||||
{
|
||||
MATRIX_MODEL = 0;
|
||||
FRACTURE_MODEL = 1;
|
||||
}
|
||||
|
||||
message ActiveCellInfoRequest
|
||||
{
|
||||
int32 case_id = 1;
|
||||
PorosityModelType porosity_model = 2;
|
||||
}
|
||||
|
||||
message ActiveCellInfoArray
|
||||
{
|
||||
repeated ActiveCellInfo data = 1;
|
||||
}
|
||||
|
||||
message ActiveCellInfo
|
||||
{
|
||||
int32 grid_index = 1;
|
||||
int32 parent_grid_index = 2;
|
||||
int32 coarsening_box_index = 3;
|
||||
Vec3i local_ijk = 4;
|
||||
Vec3i parent_ijk = 5;
|
||||
}
|
||||
|
||||
message CoarseningInfoArray
|
||||
{
|
||||
repeated CoarseningInfo data = 1;
|
||||
}
|
||||
|
||||
message CoarseningInfo
|
||||
{
|
||||
Vec3i min = 1;
|
||||
Vec3i max = 2;
|
||||
}
|
||||
|
||||
message TimeStepDates
|
||||
{
|
||||
repeated TimeStepDate date = 1;
|
||||
}
|
||||
|
||||
message TimeStepDate
|
||||
{
|
||||
int32 year = 1;
|
||||
int32 month = 2;
|
||||
int32 day = 3;
|
||||
int32 hour = 4;
|
||||
int32 minute = 5;
|
||||
int32 second = 6;
|
||||
}
|
||||
|
||||
message DoubleDates
|
||||
{
|
||||
repeated double date_decimal = 1;
|
||||
}
|
16
ApplicationCode/GrpcInterface/GrpcProtos/ProjectInfo.proto
Normal file
16
ApplicationCode/GrpcInterface/GrpcProtos/ProjectInfo.proto
Normal file
@ -0,0 +1,16 @@
|
||||
syntax = "proto3";
|
||||
|
||||
import "CaseInfo.proto";
|
||||
import "Empty.proto";
|
||||
|
||||
package rips;
|
||||
|
||||
service ProjectInfo {
|
||||
rpc CurrentCase(Empty) returns (Case) {}
|
||||
rpc CurrentCaseInfo(Empty) returns (CaseInfo) {}
|
||||
rpc CaseInfoFromCase(Case) returns (CaseInfo) {}
|
||||
rpc SelectedCases(Empty) returns (CaseInfos) {}
|
||||
rpc AllCaseGroups(Empty) returns (CaseGroups) {}
|
||||
rpc AllCases(Empty) returns (CaseInfos) {}
|
||||
rpc CasesInGroup(CaseGroup) returns (CaseInfos) {}
|
||||
}
|
15
ApplicationCode/GrpcInterface/GrpcProtos/ResInfo.proto
Normal file
15
ApplicationCode/GrpcInterface/GrpcProtos/ResInfo.proto
Normal file
@ -0,0 +1,15 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package rips;
|
||||
|
||||
import "Empty.proto";
|
||||
|
||||
service ResInfo {
|
||||
rpc GetVersion(Empty) returns (Version) {}
|
||||
}
|
||||
|
||||
message Version {
|
||||
int32 major_version = 1;
|
||||
int32 minor_version = 2;
|
||||
int32 patch_version = 3;
|
||||
}
|
173
ApplicationCode/GrpcInterface/RiaGrpcCallbacks.h
Normal file
173
ApplicationCode/GrpcInterface/RiaGrpcCallbacks.h
Normal file
@ -0,0 +1,173 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include <QString>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpcpp/grpcpp.h>
|
||||
|
||||
using grpc::CompletionQueue;
|
||||
using grpc::ServerAsyncResponseWriter;
|
||||
using grpc::ServerAsyncWriter;
|
||||
using grpc::ServerCompletionQueue;
|
||||
using grpc::ServerContext;
|
||||
using grpc::ServerWriter;
|
||||
using grpc::Status;
|
||||
|
||||
class RiaGrpcServiceInterface;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Base class for all gRPC-callbacks
|
||||
//
|
||||
//==================================================================================================
|
||||
class RiaAbstractGrpcCallback
|
||||
{
|
||||
public:
|
||||
enum CallState
|
||||
{
|
||||
CREATE_HANDLER,
|
||||
INIT_REQUEST,
|
||||
PROCESS_REQUEST,
|
||||
FINISH_REQUEST
|
||||
};
|
||||
|
||||
public:
|
||||
inline RiaAbstractGrpcCallback();
|
||||
|
||||
virtual ~RiaAbstractGrpcCallback() {}
|
||||
virtual QString name() const = 0;
|
||||
virtual RiaAbstractGrpcCallback* createNewFromThis() const = 0;
|
||||
virtual void createRequestHandler(ServerCompletionQueue* completionQueue) = 0;
|
||||
virtual void initRequest() = 0;
|
||||
virtual void processRequest() = 0;
|
||||
virtual void finishRequest() {}
|
||||
|
||||
inline CallState callState() const;
|
||||
inline const Status& status() const;
|
||||
|
||||
protected:
|
||||
inline void setCallState(CallState state);
|
||||
|
||||
protected:
|
||||
CallState m_state;
|
||||
Status m_status;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Templated gRPC-callback base class
|
||||
//
|
||||
//==================================================================================================
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT>
|
||||
class RiaGrpcRequestCallback : public RiaAbstractGrpcCallback
|
||||
{
|
||||
public:
|
||||
RiaGrpcRequestCallback(ServiceT* service);
|
||||
|
||||
QString name() const override;
|
||||
const RequestT& request() const;
|
||||
ReplyT& reply();
|
||||
|
||||
protected:
|
||||
virtual QString methodType() const = 0;
|
||||
|
||||
protected:
|
||||
ServiceT* m_service;
|
||||
RequestT m_request;
|
||||
ReplyT m_reply;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Templated gRPC-callback for non-streaming services
|
||||
//
|
||||
//==================================================================================================
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT>
|
||||
class RiaGrpcCallback : public RiaGrpcRequestCallback<ServiceT, RequestT, ReplyT>
|
||||
{
|
||||
public:
|
||||
typedef ServerAsyncResponseWriter<ReplyT> ResponseWriterT;
|
||||
typedef std::function<Status(ServiceT&, ServerContext*, const RequestT*, ReplyT*)> MethodImplT;
|
||||
typedef std::function<
|
||||
void(ServiceT&, ServerContext*, RequestT*, ResponseWriterT*, CompletionQueue*, ServerCompletionQueue*, void*)>
|
||||
MethodRequestT;
|
||||
|
||||
RiaGrpcCallback(ServiceT* service, MethodImplT methodImpl, MethodRequestT methodRequest);
|
||||
|
||||
RiaAbstractGrpcCallback* createNewFromThis() const override;
|
||||
void createRequestHandler(ServerCompletionQueue* completionQueue) override;
|
||||
void initRequest() override;
|
||||
void processRequest() override;
|
||||
|
||||
protected:
|
||||
virtual QString methodType() const;
|
||||
|
||||
private:
|
||||
ServerContext m_context;
|
||||
ResponseWriterT m_responder;
|
||||
MethodImplT m_methodImpl;
|
||||
MethodRequestT m_methodRequest;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Templated *streaming* gRPC-callback calling service implementation callbacks
|
||||
//
|
||||
// The streaming callback needs a state handler for setting up and maintaining order.
|
||||
//
|
||||
// A fully functional stream handler needs to implement the following methods:
|
||||
// 1. Default Constructor
|
||||
// 2. grpc::Status init(const grpc::Message* request)
|
||||
// 3. grpc::status assignReply(grpc::Message* reply)
|
||||
//
|
||||
//==================================================================================================
|
||||
|
||||
//==================================================================================================
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT, typename StateHandlerT>
|
||||
class RiaGrpcStreamCallback : public RiaGrpcRequestCallback<ServiceT, RequestT, ReplyT>
|
||||
{
|
||||
public:
|
||||
typedef ServerAsyncWriter<ReplyT> ResponseWriterT;
|
||||
typedef std::function<Status(ServiceT&, ServerContext*, const RequestT*, ReplyT*, StateHandlerT*)> MethodImplT;
|
||||
typedef std::function<
|
||||
void(ServiceT&, ServerContext*, RequestT*, ResponseWriterT*, CompletionQueue*, ServerCompletionQueue*, void*)>
|
||||
MethodRequestT;
|
||||
|
||||
RiaGrpcStreamCallback(ServiceT* service, MethodImplT methodImpl, MethodRequestT methodRequest, StateHandlerT* stateHandler);
|
||||
|
||||
RiaAbstractGrpcCallback* createNewFromThis() const override;
|
||||
void createRequestHandler(ServerCompletionQueue* completionQueue) override;
|
||||
void initRequest() override;
|
||||
void processRequest() override;
|
||||
|
||||
protected:
|
||||
virtual QString methodType() const;
|
||||
|
||||
private:
|
||||
ServerContext m_context;
|
||||
ResponseWriterT m_responder;
|
||||
MethodImplT m_methodImpl;
|
||||
MethodRequestT m_methodRequest;
|
||||
size_t m_dataCount; // This is used to keep track of progress. Only one item is sent for each invocation.
|
||||
std::unique_ptr<StateHandlerT> m_stateHandler;
|
||||
};
|
||||
|
||||
#include "RiaGrpcCallbacks.inl"
|
239
ApplicationCode/GrpcInterface/RiaGrpcCallbacks.inl
Normal file
239
ApplicationCode/GrpcInterface/RiaGrpcCallbacks.inl
Normal file
@ -0,0 +1,239 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline RiaAbstractGrpcCallback::RiaAbstractGrpcCallback()
|
||||
: m_state(CREATE_HANDLER)
|
||||
, m_status(Status::OK)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaAbstractGrpcCallback::CallState RiaAbstractGrpcCallback::callState() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const Status& RiaAbstractGrpcCallback::status() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline void RiaAbstractGrpcCallback::setCallState(CallState state)
|
||||
{
|
||||
m_state = state;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT>
|
||||
RiaGrpcRequestCallback<ServiceT, RequestT, ReplyT>::RiaGrpcRequestCallback(ServiceT* service)
|
||||
: m_service(service)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT>
|
||||
QString RiaGrpcRequestCallback<ServiceT, RequestT, ReplyT>::name() const
|
||||
{
|
||||
QString fullName = QString("%1:%2(%3, %4)")
|
||||
.arg(typeid(ServiceT).name())
|
||||
.arg(methodType())
|
||||
.arg(typeid(RequestT).name())
|
||||
.arg(typeid(ReplyT).name());
|
||||
return fullName;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT>
|
||||
const RequestT& RiaGrpcRequestCallback<ServiceT, RequestT, ReplyT>::request() const
|
||||
{
|
||||
return m_request;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT>
|
||||
ReplyT& RiaGrpcRequestCallback<ServiceT, RequestT, ReplyT>::reply()
|
||||
{
|
||||
return m_reply;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT>
|
||||
RiaGrpcCallback<ServiceT, RequestT, ReplyT>::RiaGrpcCallback(ServiceT* service,
|
||||
MethodImplT methodImpl,
|
||||
MethodRequestT methodRequest)
|
||||
: RiaGrpcRequestCallback<ServiceT, RequestT, ReplyT>(service)
|
||||
, m_responder(&m_context)
|
||||
, m_methodImpl(methodImpl)
|
||||
, m_methodRequest(methodRequest)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT>
|
||||
RiaAbstractGrpcCallback* RiaGrpcCallback<ServiceT, RequestT, ReplyT>::createNewFromThis() const
|
||||
{
|
||||
return new RiaGrpcCallback<ServiceT, RequestT, ReplyT>(this->m_service, this->m_methodImpl, this->m_methodRequest);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT>
|
||||
void RiaGrpcCallback<ServiceT, RequestT, ReplyT>::createRequestHandler(ServerCompletionQueue* completionQueue)
|
||||
{
|
||||
m_methodRequest(*this->m_service, &m_context, &this->m_request, &m_responder, completionQueue, completionQueue, this);
|
||||
this->setCallState(RiaAbstractGrpcCallback::INIT_REQUEST);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT>
|
||||
void RiaGrpcCallback<ServiceT, RequestT, ReplyT>::initRequest()
|
||||
{
|
||||
this->setCallState(RiaAbstractGrpcCallback::PROCESS_REQUEST);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT>
|
||||
void RiaGrpcCallback<ServiceT, RequestT, ReplyT>::processRequest()
|
||||
{
|
||||
this->m_status = m_methodImpl(*this->m_service, &m_context, &this->m_request, &this->m_reply);
|
||||
m_responder.Finish(this->m_reply, this->m_status, this);
|
||||
this->setCallState(RiaAbstractGrpcCallback::FINISH_REQUEST);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT>
|
||||
QString RiaGrpcCallback<ServiceT, RequestT, ReplyT>::methodType() const
|
||||
{
|
||||
return "RegularMethod";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT, typename StateHandlerT>
|
||||
RiaGrpcStreamCallback<ServiceT, RequestT, ReplyT, StateHandlerT>::RiaGrpcStreamCallback(ServiceT* service,
|
||||
MethodImplT methodImpl,
|
||||
MethodRequestT methodRequest,
|
||||
StateHandlerT* stateHandler)
|
||||
: RiaGrpcRequestCallback<ServiceT, RequestT, ReplyT>(service)
|
||||
, m_responder(&m_context)
|
||||
, m_methodImpl(methodImpl)
|
||||
, m_methodRequest(methodRequest)
|
||||
, m_dataCount(0u)
|
||||
, m_stateHandler(stateHandler)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT, typename StateHandlerT>
|
||||
RiaAbstractGrpcCallback* RiaGrpcStreamCallback<ServiceT, RequestT, ReplyT, StateHandlerT>::createNewFromThis() const
|
||||
{
|
||||
return new RiaGrpcStreamCallback<ServiceT, RequestT, ReplyT, StateHandlerT>(
|
||||
this->m_service, m_methodImpl, m_methodRequest, new StateHandlerT);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT, typename StateHandlerT>
|
||||
void RiaGrpcStreamCallback<ServiceT, RequestT, ReplyT, StateHandlerT>::createRequestHandler(
|
||||
ServerCompletionQueue* completionQueue)
|
||||
{
|
||||
m_methodRequest(*this->m_service, &m_context, &this->m_request, &m_responder, completionQueue, completionQueue, this);
|
||||
this->setCallState(RiaAbstractGrpcCallback::INIT_REQUEST);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Perform initialisation tasks at the time of receiving a request
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT, typename StateHandlerT>
|
||||
void RiaGrpcStreamCallback<ServiceT, RequestT, ReplyT, StateHandlerT>::initRequest()
|
||||
{
|
||||
this->m_status = m_stateHandler->init(&this->m_request);
|
||||
this->setCallState(RiaAbstractGrpcCallback::PROCESS_REQUEST);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT, typename StateHandlerT>
|
||||
void RiaGrpcStreamCallback<ServiceT, RequestT, ReplyT, StateHandlerT>::processRequest()
|
||||
{
|
||||
this->m_reply = ReplyT(); // Make sure it is reset
|
||||
|
||||
if (!this->m_status.ok())
|
||||
{
|
||||
m_responder.Finish(this->m_status, this);
|
||||
this->setCallState(RiaAbstractGrpcCallback::FINISH_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_status = m_methodImpl(*this->m_service, &m_context, &this->m_request, &this->m_reply, m_stateHandler.get());
|
||||
if (this->m_status.ok())
|
||||
{
|
||||
m_responder.Write(this->m_reply, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->setCallState(RiaAbstractGrpcCallback::FINISH_REQUEST);
|
||||
// Out of range means we're finished but it isn't an error
|
||||
if (this->m_status.error_code() == grpc::OUT_OF_RANGE)
|
||||
{
|
||||
this->m_status = Status::OK;
|
||||
}
|
||||
m_responder.Finish(this->m_status, this);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename ServiceT, typename RequestT, typename ReplyT, typename StateHandlerT>
|
||||
QString RiaGrpcStreamCallback<ServiceT, RequestT, ReplyT, StateHandlerT>::methodType() const
|
||||
{
|
||||
return "StreamingMethod";
|
||||
}
|
155
ApplicationCode/GrpcInterface/RiaGrpcCommandService.cpp
Normal file
155
ApplicationCode/GrpcInterface/RiaGrpcCommandService.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RiaGrpcCommandService.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RiaGrpcCallbacks.h"
|
||||
|
||||
#include "RicfSetTimeStep.h"
|
||||
|
||||
#include "cafAssert.h"
|
||||
#include "cafPdmDefaultObjectFactory.h"
|
||||
#include "cafPdmValueField.h"
|
||||
|
||||
using namespace rips;
|
||||
using namespace google::protobuf;
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef GetMessage
|
||||
#undef GetMessage
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaGrpcCommandService::Execute(grpc::ServerContext* context, const CommandParams* request, Empty* reply)
|
||||
{
|
||||
auto requestDescriptor = request->GetDescriptor();
|
||||
RiaLogging::info(QString::fromStdString(requestDescriptor->name()));
|
||||
|
||||
CommandParams::ParamsCase paramsCase = request->params_case();
|
||||
if (paramsCase != CommandParams::PARAMS_NOT_SET)
|
||||
{
|
||||
auto grpcOneOfMessage = requestDescriptor->FindFieldByNumber((int)paramsCase);
|
||||
CAF_ASSERT(grpcOneOfMessage->type() == FieldDescriptor::TYPE_MESSAGE);
|
||||
|
||||
const Message& params = request->GetReflection()->GetMessage(*request, grpcOneOfMessage);
|
||||
QString grpcOneOfMessageName = QString::fromStdString(grpcOneOfMessage->name());
|
||||
RiaLogging::info(QString("Found Command: %1").arg(grpcOneOfMessageName));
|
||||
auto pdmObjectHandle = caf::PdmDefaultObjectFactory::instance()->create(grpcOneOfMessageName);
|
||||
auto commandHandle = dynamic_cast<RicfCommandObject*>(pdmObjectHandle);
|
||||
if (commandHandle)
|
||||
{
|
||||
auto subMessageDescriptor = grpcOneOfMessage->message_type();
|
||||
int numParameters = subMessageDescriptor->field_count();
|
||||
for (int i = 0; i < numParameters; ++i)
|
||||
{
|
||||
auto parameter = subMessageDescriptor->field(i);
|
||||
if (parameter)
|
||||
{
|
||||
QString parameterName = QString::fromStdString(parameter->name());
|
||||
auto pdmValueFieldHandle = dynamic_cast<caf::PdmValueField*>(pdmObjectHandle->findField(parameterName));
|
||||
if (pdmValueFieldHandle)
|
||||
{
|
||||
RiaLogging::info(QString("Found Matching Parameter: %1").arg(parameterName));
|
||||
assignFieldValue(pdmValueFieldHandle, params, parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
commandHandle->execute();
|
||||
|
||||
return Status::OK;
|
||||
}
|
||||
}
|
||||
return grpc::Status(grpc::NOT_FOUND, "Command not found");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RiaAbstractGrpcCallback*> RiaGrpcCommandService::createCallbacks()
|
||||
{
|
||||
typedef RiaGrpcCommandService Self;
|
||||
|
||||
return {new RiaGrpcCallback<Self, CommandParams, Empty>(this, &Self::Execute, &Self::RequestExecute)};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGrpcCommandService::assignFieldValue(caf::PdmValueField* pdmValueField,
|
||||
const Message& params,
|
||||
const FieldDescriptor* paramDescriptor)
|
||||
{
|
||||
FieldDescriptor::Type fieldDataType = paramDescriptor->type();
|
||||
QVariant qValue;
|
||||
switch (fieldDataType)
|
||||
{
|
||||
case FieldDescriptor::TYPE_BOOL: {
|
||||
auto value = params.GetReflection()->GetBool(params, paramDescriptor);
|
||||
qValue = QVariant(value);
|
||||
break;
|
||||
}
|
||||
case FieldDescriptor::TYPE_INT32: {
|
||||
int value = params.GetReflection()->GetInt32(params, paramDescriptor);
|
||||
qValue = QVariant(value);
|
||||
break;
|
||||
}
|
||||
case FieldDescriptor::TYPE_UINT32: {
|
||||
uint value = params.GetReflection()->GetUInt32(params, paramDescriptor);
|
||||
qValue = QVariant(value);
|
||||
break;
|
||||
}
|
||||
case FieldDescriptor::TYPE_INT64: {
|
||||
int64_t value = params.GetReflection()->GetInt64(params, paramDescriptor);
|
||||
qValue = QVariant((qlonglong) value);
|
||||
break;
|
||||
}
|
||||
case FieldDescriptor::TYPE_UINT64: {
|
||||
uint64_t value = params.GetReflection()->GetUInt64(params, paramDescriptor);
|
||||
qValue = QVariant((qulonglong) value);
|
||||
break;
|
||||
}
|
||||
case FieldDescriptor::TYPE_STRING: {
|
||||
auto value = params.GetReflection()->GetString(params, paramDescriptor);
|
||||
qValue = QVariant(QString::fromStdString(value));
|
||||
break;
|
||||
}
|
||||
case FieldDescriptor::TYPE_FLOAT: {
|
||||
auto value = params.GetReflection()->GetFloat(params, paramDescriptor);
|
||||
qValue = QVariant(value);
|
||||
break;
|
||||
}
|
||||
case FieldDescriptor::TYPE_DOUBLE: {
|
||||
auto value = params.GetReflection()->GetDouble(params, paramDescriptor);
|
||||
qValue = QVariant(value);
|
||||
break;
|
||||
}
|
||||
case FieldDescriptor::TYPE_ENUM: {
|
||||
auto value = params.GetReflection()->GetEnumValue(params, paramDescriptor);
|
||||
qValue = QVariant(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pdmValueField->setFromQVariant(qValue);
|
||||
}
|
||||
|
||||
static bool RiaGrpcCommandService_init =
|
||||
RiaGrpcServiceFactory::instance()->registerCreator<RiaGrpcCommandService>(typeid(RiaGrpcCommandService).hash_code());
|
58
ApplicationCode/GrpcInterface/RiaGrpcCommandService.h
Normal file
58
ApplicationCode/GrpcInterface/RiaGrpcCommandService.h
Normal file
@ -0,0 +1,58 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RiaGrpcServiceInterface.h"
|
||||
|
||||
#include "Commands.grpc.pb.h"
|
||||
|
||||
#include <grpcpp/grpcpp.h>
|
||||
#include <vector>
|
||||
|
||||
namespace rips
|
||||
{
|
||||
class Empty;
|
||||
}
|
||||
|
||||
namespace caf
|
||||
{
|
||||
class PdmValueField;
|
||||
}
|
||||
|
||||
namespace google
|
||||
{
|
||||
namespace protobuf
|
||||
{
|
||||
class FieldDescriptor;
|
||||
class Message;
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
class RiaAbstractGrpcCallback;
|
||||
|
||||
class RiaGrpcCommandService : public rips::Commands::AsyncService, public RiaGrpcServiceInterface
|
||||
{
|
||||
public:
|
||||
grpc::Status Execute(grpc::ServerContext* context, const rips::CommandParams* request, rips::Empty* reply) override;
|
||||
std::vector<RiaAbstractGrpcCallback*> createCallbacks() override;
|
||||
|
||||
private:
|
||||
void assignFieldValue(caf::PdmValueField* pdmValueField,
|
||||
const google::protobuf::Message& params,
|
||||
const google::protobuf::FieldDescriptor* paramDescriptor);
|
||||
};
|
283
ApplicationCode/GrpcInterface/RiaGrpcGridInfoService.cpp
Normal file
283
ApplicationCode/GrpcInterface/RiaGrpcGridInfoService.cpp
Normal file
@ -0,0 +1,283 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RiaGrpcGridInfoService.h"
|
||||
#include "RiaGrpcCallbacks.h"
|
||||
|
||||
#include "RigActiveCellInfo.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimGeoMechCase.h"
|
||||
|
||||
#include <string.h> // memcpy
|
||||
|
||||
using namespace rips;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaActiveCellInfoStateHandler::RiaActiveCellInfoStateHandler()
|
||||
: m_request(nullptr)
|
||||
, m_eclipseCase(nullptr)
|
||||
, m_activeCellInfo(nullptr)
|
||||
, m_currentCellIdx(0u)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaActiveCellInfoStateHandler::init(const rips::ActiveCellInfoRequest* request)
|
||||
{
|
||||
CAF_ASSERT(request);
|
||||
m_request = request;
|
||||
|
||||
m_porosityModel = RiaDefines::PorosityModelType(m_request->porosity_model());
|
||||
RimCase* rimCase = RiaGrpcServiceInterface::findCase(m_request->case_id());
|
||||
m_eclipseCase = dynamic_cast<RimEclipseCase*>(rimCase);
|
||||
|
||||
if (!m_eclipseCase)
|
||||
{
|
||||
return grpc::Status(grpc::NOT_FOUND, "Eclipse Case not found");
|
||||
}
|
||||
|
||||
if (!m_eclipseCase->eclipseCaseData() || !m_eclipseCase->eclipseCaseData()->mainGrid())
|
||||
{
|
||||
return grpc::Status(grpc::NOT_FOUND, "Eclipse Case Data not found");
|
||||
}
|
||||
|
||||
m_activeCellInfo = m_eclipseCase->eclipseCaseData()->activeCellInfo(m_porosityModel);
|
||||
|
||||
if (!m_activeCellInfo)
|
||||
{
|
||||
return grpc::Status(grpc::NOT_FOUND, "Active Cell Info not found");
|
||||
}
|
||||
|
||||
size_t globalCoarseningBoxCount = 0;
|
||||
|
||||
for (size_t gridIdx = 0; gridIdx < m_eclipseCase->eclipseCaseData()->gridCount(); gridIdx++)
|
||||
{
|
||||
m_globalCoarseningBoxIndexStart.push_back(globalCoarseningBoxCount);
|
||||
|
||||
RigGridBase* grid = m_eclipseCase->eclipseCaseData()->grid(gridIdx);
|
||||
|
||||
size_t localCoarseningBoxCount = grid->coarseningBoxCount();
|
||||
globalCoarseningBoxCount += localCoarseningBoxCount;
|
||||
}
|
||||
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaActiveCellInfoStateHandler::assignNextActiveCellInfoData(rips::ActiveCellInfo* cellInfo)
|
||||
{
|
||||
const std::vector<RigCell>& reservoirCells = m_eclipseCase->eclipseCaseData()->mainGrid()->globalCellArray();
|
||||
|
||||
while (m_currentCellIdx < reservoirCells.size())
|
||||
{
|
||||
size_t cellIdxToTry = m_currentCellIdx++;
|
||||
if (m_activeCellInfo->isActive(cellIdxToTry))
|
||||
{
|
||||
assignActiveCellInfoData(cellInfo, reservoirCells, cellIdxToTry);
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
}
|
||||
return Status(grpc::OUT_OF_RANGE, "We've reached the end. This is not an error but means transmission is finished");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaActiveCellInfoStateHandler::assignActiveCellInfoData(rips::ActiveCellInfo* cellInfo,
|
||||
const std::vector<RigCell>& reservoirCells,
|
||||
size_t cellIdx)
|
||||
{
|
||||
RigGridBase* grid = reservoirCells[cellIdx].hostGrid();
|
||||
CVF_ASSERT(grid != nullptr);
|
||||
size_t cellIndex = reservoirCells[cellIdx].gridLocalCellIndex();
|
||||
|
||||
size_t i, j, k;
|
||||
grid->ijkFromCellIndex(cellIndex, &i, &j, &k);
|
||||
|
||||
size_t pi, pj, pk;
|
||||
RigGridBase* parentGrid = nullptr;
|
||||
|
||||
if (grid->isMainGrid())
|
||||
{
|
||||
pi = i;
|
||||
pj = j;
|
||||
pk = k;
|
||||
parentGrid = grid;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t parentCellIdx = reservoirCells[cellIdx].parentCellIndex();
|
||||
parentGrid = (static_cast<RigLocalGrid*>(grid))->parentGrid();
|
||||
CVF_ASSERT(parentGrid != nullptr);
|
||||
parentGrid->ijkFromCellIndex(parentCellIdx, &pi, &pj, &pk);
|
||||
}
|
||||
|
||||
cellInfo->set_grid_index((int)grid->gridIndex());
|
||||
cellInfo->set_parent_grid_index((int)parentGrid->gridIndex());
|
||||
|
||||
size_t coarseningIdx = reservoirCells[cellIdx].coarseningBoxIndex();
|
||||
if (coarseningIdx != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
size_t globalCoarseningIdx = m_globalCoarseningBoxIndexStart[grid->gridIndex()] + coarseningIdx;
|
||||
cellInfo->set_coarsening_box_index((int)globalCoarseningIdx);
|
||||
}
|
||||
else
|
||||
{
|
||||
cellInfo->set_coarsening_box_index(-1);
|
||||
}
|
||||
{
|
||||
rips::Vec3i* local_ijk = new rips::Vec3i;
|
||||
local_ijk->set_i((int)i);
|
||||
local_ijk->set_j((int)j);
|
||||
local_ijk->set_k((int)k);
|
||||
cellInfo->set_allocated_local_ijk(local_ijk);
|
||||
}
|
||||
{
|
||||
rips::Vec3i* parent_ijk = new rips::Vec3i;
|
||||
parent_ijk->set_i((int)pi);
|
||||
parent_ijk->set_j((int)pj);
|
||||
parent_ijk->set_k((int)pk);
|
||||
cellInfo->set_allocated_parent_ijk(parent_ijk);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigActiveCellInfo* RiaActiveCellInfoStateHandler::activeCellInfo() const
|
||||
{
|
||||
return m_activeCellInfo;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<RigCell>& RiaActiveCellInfoStateHandler::reservoirCells() const
|
||||
{
|
||||
const std::vector<RigCell>& reservoirCells = m_eclipseCase->eclipseCaseData()->mainGrid()->globalCellArray();
|
||||
return reservoirCells;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaActiveCellInfoStateHandler::assignReply(rips::ActiveCellInfoArray* reply)
|
||||
{
|
||||
const size_t packageSize = RiaGrpcServiceInterface::numberOfMessagesForByteCount(sizeof(rips::ActiveCellInfoArray));
|
||||
size_t packageIndex = 0u;
|
||||
reply->mutable_data()->Reserve((int)packageSize);
|
||||
for (; packageIndex < packageSize && m_currentCellIdx < m_activeCellInfo->reservoirCellCount(); ++packageIndex)
|
||||
{
|
||||
rips::ActiveCellInfo singleCellInfo;
|
||||
grpc::Status singleCellInfoStatus = assignNextActiveCellInfoData(&singleCellInfo);
|
||||
if (singleCellInfoStatus.ok())
|
||||
{
|
||||
rips::ActiveCellInfo* allocCellInfo = reply->add_data();
|
||||
*allocCellInfo = singleCellInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (packageIndex > 0u)
|
||||
{
|
||||
return Status::OK;
|
||||
}
|
||||
return Status(grpc::OUT_OF_RANGE, "We've reached the end. This is not an error but means transmission is finished");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaGrpcGridInfoService::GetGridCount(grpc::ServerContext* context, const rips::Case* request, rips::GridCount* reply)
|
||||
{
|
||||
RimCase* rimCase = findCase(request->id());
|
||||
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(rimCase);
|
||||
size_t gridCount = 0u;
|
||||
if (eclipseCase)
|
||||
{
|
||||
gridCount = eclipseCase->mainGrid()->gridCount();
|
||||
reply->set_count((int)gridCount);
|
||||
return Status::OK;
|
||||
}
|
||||
return grpc::Status(grpc::NOT_FOUND, "Eclipse Case not found");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaGrpcGridInfoService::GetGridDimensions(grpc::ServerContext* context,
|
||||
const rips::Case* request,
|
||||
rips::GridDimensions* reply)
|
||||
{
|
||||
RimCase* rimCase = findCase(request->id());
|
||||
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(rimCase);
|
||||
if (eclipseCase)
|
||||
{
|
||||
size_t gridCount = eclipseCase->mainGrid()->gridCount();
|
||||
for (size_t i = 0; i < gridCount; ++i)
|
||||
{
|
||||
const RigGridBase* grid = eclipseCase->mainGrid()->gridByIndex(i);
|
||||
rips::Vec3i* dimensions = reply->add_dimensions();
|
||||
dimensions->set_i((int)grid->cellCountI());
|
||||
dimensions->set_j((int)grid->cellCountJ());
|
||||
dimensions->set_k((int)grid->cellCountK());
|
||||
}
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
return grpc::Status(grpc::NOT_FOUND, "Eclipse Case not found");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaGrpcGridInfoService::StreamActiveCellInfo(grpc::ServerContext* context,
|
||||
const rips::ActiveCellInfoRequest* request,
|
||||
rips::ActiveCellInfoArray* reply,
|
||||
RiaActiveCellInfoStateHandler* stateHandler)
|
||||
{
|
||||
return stateHandler->assignReply(reply);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RiaAbstractGrpcCallback*> RiaGrpcGridInfoService::createCallbacks()
|
||||
{
|
||||
typedef RiaGrpcGridInfoService Self;
|
||||
|
||||
return {new RiaGrpcCallback<Self, Case, GridCount>(this, &Self::GetGridCount, &Self::RequestGetGridCount),
|
||||
new RiaGrpcCallback<Self, Case, GridDimensions>(this, &Self::GetGridDimensions, &Self::RequestGetGridDimensions),
|
||||
new RiaGrpcStreamCallback<Self, ActiveCellInfoRequest, ActiveCellInfoArray, RiaActiveCellInfoStateHandler>(
|
||||
this, &Self::StreamActiveCellInfo, &Self::RequestStreamActiveCellInfo, new RiaActiveCellInfoStateHandler)};
|
||||
}
|
||||
|
||||
static bool RiaGrpcGridInfoService_init =
|
||||
RiaGrpcServiceFactory::instance()->registerCreator<RiaGrpcGridInfoService>(typeid(RiaGrpcGridInfoService).hash_code());
|
80
ApplicationCode/GrpcInterface/RiaGrpcGridInfoService.h
Normal file
80
ApplicationCode/GrpcInterface/RiaGrpcGridInfoService.h
Normal file
@ -0,0 +1,80 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "GridInfo.grpc.pb.h"
|
||||
|
||||
#include "RiaGrpcServiceInterface.h"
|
||||
#include "RiaPorosityModel.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace rips
|
||||
{
|
||||
class Case;
|
||||
}
|
||||
|
||||
class RiaAbstractGrpcCallback;
|
||||
class RigCell;
|
||||
class RigActiveCellInfo;
|
||||
class RimEclipseCase;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// State handler for streaming of active cell info
|
||||
//
|
||||
//==================================================================================================
|
||||
class RiaActiveCellInfoStateHandler
|
||||
{
|
||||
public:
|
||||
typedef grpc::Status Status;
|
||||
|
||||
RiaActiveCellInfoStateHandler();
|
||||
|
||||
Status init(const rips::ActiveCellInfoRequest* request);
|
||||
Status assignNextActiveCellInfoData(rips::ActiveCellInfo* cellInfo);
|
||||
void assignActiveCellInfoData(rips::ActiveCellInfo* cellInfo, const std::vector<RigCell>& reservoirCells, size_t cellIdx);
|
||||
Status assignReply(rips::ActiveCellInfoArray* reply);
|
||||
RigActiveCellInfo* activeCellInfo() const;
|
||||
const std::vector<RigCell>& reservoirCells() const;
|
||||
|
||||
protected:
|
||||
const rips::ActiveCellInfoRequest* m_request;
|
||||
RimEclipseCase* m_eclipseCase;
|
||||
RiaDefines::PorosityModelType m_porosityModel;
|
||||
RigActiveCellInfo* m_activeCellInfo;
|
||||
std::vector<size_t> m_globalCoarseningBoxIndexStart;
|
||||
size_t m_currentCellIdx;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// gRPC-service answering requests about grid information for a given case
|
||||
//
|
||||
//==================================================================================================
|
||||
class RiaGrpcGridInfoService final : public rips::GridInfo::AsyncService, public RiaGrpcServiceInterface
|
||||
{
|
||||
public:
|
||||
grpc::Status GetGridCount(grpc::ServerContext* context, const rips::Case* request, rips::GridCount* reply) override;
|
||||
grpc::Status GetGridDimensions(grpc::ServerContext* context, const rips::Case* request, rips::GridDimensions* reply) override;
|
||||
grpc::Status StreamActiveCellInfo(grpc::ServerContext* context,
|
||||
const rips::ActiveCellInfoRequest* request,
|
||||
rips::ActiveCellInfoArray* reply,
|
||||
RiaActiveCellInfoStateHandler* stateHandler);
|
||||
std::vector<RiaAbstractGrpcCallback*> createCallbacks() override;
|
||||
};
|
249
ApplicationCode/GrpcInterface/RiaGrpcProjectInfoService.cpp
Normal file
249
ApplicationCode/GrpcInterface/RiaGrpcProjectInfoService.cpp
Normal file
@ -0,0 +1,249 @@
|
||||
#include "RiaGrpcProjectInfoService.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaGrpcCallbacks.h"
|
||||
#include "RiaSocketTools.h"
|
||||
|
||||
#include "RimCase.h"
|
||||
#include "RimCaseCollection.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseCaseCollection.h"
|
||||
#include "RimGeoMechCase.h"
|
||||
#include "RimGridView.h"
|
||||
#include "RimIdenticalGridCaseGroup.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include "CaseInfo.grpc.pb.h"
|
||||
|
||||
using grpc::ServerCompletionQueue;
|
||||
using grpc::ServerContext;
|
||||
using grpc::Status;
|
||||
|
||||
using namespace rips;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Status RiaGrpcProjectInfoService::CurrentCase(ServerContext* context, const rips::Empty* request, rips::Case* reply)
|
||||
{
|
||||
RimGridView* view = RiaApplication::instance()->activeGridView();
|
||||
if (view)
|
||||
{
|
||||
RimCase* currentCase = view->ownerCase();
|
||||
if (currentCase)
|
||||
{
|
||||
reply->set_id(currentCase->caseId());
|
||||
return Status::OK;
|
||||
}
|
||||
}
|
||||
return Status(grpc::NOT_FOUND, "No current case found");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Status RiaGrpcProjectInfoService::CurrentCaseInfo(ServerContext* context, const rips::Empty* request, rips::CaseInfo* reply)
|
||||
{
|
||||
RimGridView* view = RiaApplication::instance()->activeGridView();
|
||||
if (view)
|
||||
{
|
||||
RimCase* currentCase = view->ownerCase();
|
||||
if (currentCase)
|
||||
{
|
||||
qint64 caseId = currentCase->caseId();
|
||||
qint64 caseGroupId = -1;
|
||||
QString caseName, caseType;
|
||||
RiaSocketTools::getCaseInfoFromCase(currentCase, caseId, caseName, caseType, caseGroupId);
|
||||
|
||||
reply->set_id(caseId);
|
||||
reply->set_group_id(caseGroupId);
|
||||
reply->set_name(caseName.toStdString());
|
||||
reply->set_type(caseType.toStdString());
|
||||
return Status::OK;
|
||||
}
|
||||
}
|
||||
return Status(grpc::NOT_FOUND, "No current case found");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status
|
||||
RiaGrpcProjectInfoService::CaseInfoFromCase(grpc::ServerContext* context, const rips::Case* request, rips::CaseInfo* reply)
|
||||
{
|
||||
RimCase* rimCase = findCase(request->id());
|
||||
if (rimCase)
|
||||
{
|
||||
qint64 caseId = rimCase->caseId();
|
||||
qint64 caseGroupId = -1;
|
||||
QString caseName, caseType;
|
||||
RiaSocketTools::getCaseInfoFromCase(rimCase, caseId, caseName, caseType, caseGroupId);
|
||||
|
||||
reply->set_id(caseId);
|
||||
reply->set_group_id(caseGroupId);
|
||||
reply->set_name(caseName.toStdString());
|
||||
reply->set_type(caseType.toStdString());
|
||||
return Status::OK;
|
||||
}
|
||||
return Status(grpc::NOT_FOUND, "No cases found");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Status RiaGrpcProjectInfoService::SelectedCases(ServerContext* context, const rips::Empty* request, rips::CaseInfos* reply)
|
||||
{
|
||||
std::vector<RimCase*> cases;
|
||||
caf::SelectionManager::instance()->objectsByType(&cases);
|
||||
|
||||
if (cases.empty())
|
||||
{
|
||||
return Status(grpc::NOT_FOUND, "No cases selected");
|
||||
}
|
||||
|
||||
for (RimCase* rimCase : cases)
|
||||
{
|
||||
qint64 caseId = rimCase->caseId();
|
||||
qint64 caseGroupId = -1;
|
||||
QString caseName, caseType;
|
||||
RiaSocketTools::getCaseInfoFromCase(rimCase, caseId, caseName, caseType, caseGroupId);
|
||||
|
||||
rips::CaseInfo* caseInfo = reply->add_case_info();
|
||||
caseInfo->set_id(caseId);
|
||||
caseInfo->set_group_id(caseGroupId);
|
||||
caseInfo->set_name(caseName.toStdString());
|
||||
caseInfo->set_type(caseType.toStdString());
|
||||
}
|
||||
return Status::OK;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status
|
||||
RiaGrpcProjectInfoService::AllCaseGroups(grpc::ServerContext* context, const rips::Empty* request, rips::CaseGroups* reply)
|
||||
{
|
||||
RimProject* proj = RiaApplication::instance()->project();
|
||||
RimEclipseCaseCollection* analysisModels =
|
||||
(proj && proj->activeOilField()) ? proj->activeOilField()->analysisModels() : nullptr;
|
||||
if (analysisModels)
|
||||
{
|
||||
for (RimIdenticalGridCaseGroup* cg : analysisModels->caseGroups())
|
||||
{
|
||||
rips::CaseGroup* caseGroup = reply->add_case_group();
|
||||
caseGroup->set_id(cg->groupId());
|
||||
caseGroup->set_name(cg->name().toStdString());
|
||||
}
|
||||
return Status::OK;
|
||||
}
|
||||
return Status(grpc::NOT_FOUND, "No case groups found");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaGrpcProjectInfoService::AllCases(grpc::ServerContext* context, const rips::Empty* request, rips::CaseInfos* reply)
|
||||
{
|
||||
std::vector<RimCase*> cases;
|
||||
RiaApplication::instance()->project()->allCases(cases);
|
||||
|
||||
if (cases.empty())
|
||||
{
|
||||
return Status(grpc::NOT_FOUND, "No cases found");
|
||||
}
|
||||
|
||||
for (RimCase* rimCase : cases)
|
||||
{
|
||||
qint64 caseId = rimCase->caseId();
|
||||
qint64 caseGroupId = -1;
|
||||
QString caseName, caseType;
|
||||
RiaSocketTools::getCaseInfoFromCase(rimCase, caseId, caseName, caseType, caseGroupId);
|
||||
|
||||
rips::CaseInfo* caseInfo = reply->add_case_info();
|
||||
caseInfo->set_id(caseId);
|
||||
caseInfo->set_group_id(caseGroupId);
|
||||
caseInfo->set_name(caseName.toStdString());
|
||||
caseInfo->set_type(caseType.toStdString());
|
||||
}
|
||||
return Status::OK;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status
|
||||
RiaGrpcProjectInfoService::CasesInGroup(grpc::ServerContext* context, const rips::CaseGroup* request, rips::CaseInfos* reply)
|
||||
{
|
||||
RimProject* proj = RiaApplication::instance()->project();
|
||||
RimEclipseCaseCollection* analysisModels =
|
||||
(proj && proj->activeOilField()) ? proj->activeOilField()->analysisModels() : nullptr;
|
||||
if (analysisModels)
|
||||
{
|
||||
int groupId = request->id();
|
||||
RimIdenticalGridCaseGroup* caseGroup = nullptr;
|
||||
|
||||
for (size_t i = 0; i < analysisModels->caseGroups().size(); i++)
|
||||
{
|
||||
RimIdenticalGridCaseGroup* cg = analysisModels->caseGroups()[i];
|
||||
|
||||
if (groupId == cg->groupId())
|
||||
{
|
||||
caseGroup = cg;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<RimCase*> cases;
|
||||
if (caseGroup)
|
||||
{
|
||||
for (size_t i = 0; i < caseGroup->statisticsCaseCollection()->reservoirs.size(); i++)
|
||||
{
|
||||
cases.push_back(caseGroup->statisticsCaseCollection()->reservoirs[i]);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < caseGroup->caseCollection()->reservoirs.size(); i++)
|
||||
{
|
||||
cases.push_back(caseGroup->caseCollection()->reservoirs[i]);
|
||||
}
|
||||
}
|
||||
if (!cases.empty())
|
||||
{
|
||||
for (RimCase* rimCase : cases)
|
||||
{
|
||||
qint64 caseId = rimCase->caseId();
|
||||
qint64 caseGroupId = -1;
|
||||
QString caseName, caseType;
|
||||
RiaSocketTools::getCaseInfoFromCase(rimCase, caseId, caseName, caseType, caseGroupId);
|
||||
|
||||
rips::CaseInfo* caseInfo = reply->add_case_info();
|
||||
caseInfo->set_id(caseId);
|
||||
caseInfo->set_group_id(caseGroupId);
|
||||
caseInfo->set_name(caseName.toStdString());
|
||||
caseInfo->set_type(caseType.toStdString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return Status(grpc::NOT_FOUND, "No cases found");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RiaAbstractGrpcCallback*> RiaGrpcProjectInfoService::createCallbacks()
|
||||
{
|
||||
typedef RiaGrpcProjectInfoService Self;
|
||||
|
||||
return {
|
||||
new RiaGrpcCallback<Self, Empty, Case>(this, &Self::CurrentCase, &Self::RequestCurrentCase),
|
||||
new RiaGrpcCallback<Self, Empty, CaseInfo>(this, &Self::CurrentCaseInfo, &Self::RequestCurrentCaseInfo),
|
||||
new RiaGrpcCallback<Self, Case, CaseInfo>(this, &Self::CaseInfoFromCase, &Self::RequestCaseInfoFromCase),
|
||||
new RiaGrpcCallback<Self, Empty, CaseInfos>(this, &Self::SelectedCases, &Self::RequestSelectedCases),
|
||||
new RiaGrpcCallback<Self, Empty, CaseGroups>(this, &Self::AllCaseGroups, &Self::RequestAllCaseGroups),
|
||||
new RiaGrpcCallback<Self, Empty, CaseInfos>(this, &Self::AllCases, &Self::RequestAllCases),
|
||||
new RiaGrpcCallback<Self, CaseGroup, CaseInfos>(this, &Self::CasesInGroup, &Self::RequestCasesInGroup)};
|
||||
}
|
||||
|
||||
static bool RiaGrpcProjectInfoService_init =
|
||||
RiaGrpcServiceFactory::instance()->registerCreator<RiaGrpcProjectInfoService>(typeid(RiaGrpcProjectInfoService).hash_code());
|
51
ApplicationCode/GrpcInterface/RiaGrpcProjectInfoService.h
Normal file
51
ApplicationCode/GrpcInterface/RiaGrpcProjectInfoService.h
Normal file
@ -0,0 +1,51 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "ProjectInfo.grpc.pb.h"
|
||||
#include "RiaGrpcServiceInterface.h"
|
||||
|
||||
#include <grpcpp/grpcpp.h>
|
||||
|
||||
namespace rips
|
||||
{
|
||||
class Empty;
|
||||
class CaseInfo;
|
||||
} // namespace rips
|
||||
|
||||
class RiaAbstractGrpcCallback;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// gRPC-service answering requests about project information
|
||||
//
|
||||
//==================================================================================================
|
||||
class RiaGrpcProjectInfoService final : public rips::ProjectInfo::AsyncService, public RiaGrpcServiceInterface
|
||||
{
|
||||
public:
|
||||
grpc::Status CurrentCase(grpc::ServerContext* context, const rips::Empty* request, rips::Case* reply) override;
|
||||
grpc::Status CurrentCaseInfo(grpc::ServerContext* context, const rips::Empty* request, rips::CaseInfo* reply) override;
|
||||
grpc::Status CaseInfoFromCase(grpc::ServerContext* context, const rips::Case* request, rips::CaseInfo* reply) override;
|
||||
grpc::Status SelectedCases(grpc::ServerContext* context, const rips::Empty* request, rips::CaseInfos* reply) override;
|
||||
grpc::Status AllCaseGroups(grpc::ServerContext* context, const rips::Empty* request, rips::CaseGroups* reply) override;
|
||||
grpc::Status AllCases(grpc::ServerContext* context, const rips::Empty* request, rips::CaseInfos* reply) override;
|
||||
grpc::Status CasesInGroup(grpc::ServerContext* context, const rips::CaseGroup* request, rips::CaseInfos* reply) override;
|
||||
|
||||
public:
|
||||
std::vector<RiaAbstractGrpcCallback*> createCallbacks() override;
|
||||
};
|
44
ApplicationCode/GrpcInterface/RiaGrpcResInfoService.cpp
Normal file
44
ApplicationCode/GrpcInterface/RiaGrpcResInfoService.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RiaGrpcResInfoService.h"
|
||||
|
||||
#include "RiaVersionInfo.h"
|
||||
#include "RiaGrpcCallbacks.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
grpc::Status RiaGrpcResInfoService::GetVersion(grpc::ServerContext* context, const rips::Empty* request, rips::Version* reply)
|
||||
{
|
||||
reply->set_major_version(RESINSIGHT_MAJOR_VERSION);
|
||||
reply->set_minor_version(RESINSIGHT_MINOR_VERSION);
|
||||
reply->set_patch_version(RESINSIGHT_PATCH_VERSION);
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RiaAbstractGrpcCallback*> RiaGrpcResInfoService::createCallbacks()
|
||||
{
|
||||
typedef RiaGrpcResInfoService Self;
|
||||
return { new RiaGrpcCallback<Self, rips::Empty, rips::Version>(this, &Self::GetVersion, &Self::RequestGetVersion) };
|
||||
}
|
||||
|
||||
static bool RiaGrpcResInfoService_init =
|
||||
RiaGrpcServiceFactory::instance()->registerCreator<RiaGrpcResInfoService>(typeid(RiaGrpcResInfoService).hash_code());
|
50
ApplicationCode/GrpcInterface/RiaGrpcResInfoService.h
Normal file
50
ApplicationCode/GrpcInterface/RiaGrpcResInfoService.h
Normal file
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RiaGrpcServiceInterface.h"
|
||||
|
||||
#include "ResInfo.grpc.pb.h"
|
||||
|
||||
#include <grpcpp/grpcpp.h>
|
||||
#include <vector>
|
||||
|
||||
namespace rips
|
||||
{
|
||||
class Empty;
|
||||
class Version;
|
||||
}
|
||||
|
||||
namespace caf
|
||||
{
|
||||
class PdmValueField;
|
||||
}
|
||||
|
||||
class RiaAbstractGrpcCallback;
|
||||
|
||||
class RiaGrpcResInfoService : public rips::ResInfo::AsyncService, public RiaGrpcServiceInterface
|
||||
{
|
||||
public:
|
||||
grpc::Status GetVersion(grpc::ServerContext* context, const rips::Empty* request, rips::Version* reply) override;
|
||||
std::vector<RiaAbstractGrpcCallback*> createCallbacks() override;
|
||||
|
||||
};
|
||||
|
||||
|
366
ApplicationCode/GrpcInterface/RiaGrpcServer.cpp
Normal file
366
ApplicationCode/GrpcInterface/RiaGrpcServer.cpp
Normal file
@ -0,0 +1,366 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RiaGrpcServer.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaDefines.h"
|
||||
|
||||
#include "RiaGrpcCallbacks.h"
|
||||
#include "RiaGrpcServiceInterface.h"
|
||||
#include "RiaGrpcGridInfoService.h"
|
||||
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimProject.h"
|
||||
|
||||
#include "cafAssert.h"
|
||||
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpcpp/grpcpp.h>
|
||||
|
||||
#include <QTcpServer>
|
||||
|
||||
using grpc::CompletionQueue;
|
||||
using grpc::Server;
|
||||
using grpc::ServerAsyncResponseWriter;
|
||||
using grpc::ServerBuilder;
|
||||
using grpc::ServerCompletionQueue;
|
||||
using grpc::ServerContext;
|
||||
using grpc::Status;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// The GRPC server implementation
|
||||
//
|
||||
//==================================================================================================
|
||||
class RiaGrpcServerImpl
|
||||
{
|
||||
public:
|
||||
RiaGrpcServerImpl(int portNumber);
|
||||
~RiaGrpcServerImpl();
|
||||
int portNumber() const;
|
||||
bool isRunning() const;
|
||||
void run();
|
||||
void runInThread();
|
||||
void initialize();
|
||||
void processOneRequest();
|
||||
void quit();
|
||||
int currentPortNumber;
|
||||
|
||||
private:
|
||||
void waitForNextRequest();
|
||||
void process(RiaAbstractGrpcCallback* method);
|
||||
|
||||
private:
|
||||
int m_portNumber;
|
||||
std::unique_ptr<grpc::ServerCompletionQueue> m_completionQueue;
|
||||
std::unique_ptr<grpc::Server> m_server;
|
||||
std::list<std::shared_ptr<RiaGrpcServiceInterface>> m_services;
|
||||
std::list<RiaAbstractGrpcCallback*> m_unprocessedRequests;
|
||||
std::mutex m_requestMutex;
|
||||
std::thread m_thread;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaGrpcServerImpl::RiaGrpcServerImpl(int portNumber)
|
||||
: m_portNumber(portNumber)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaGrpcServerImpl::~RiaGrpcServerImpl()
|
||||
{
|
||||
quit();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RiaGrpcServerImpl::portNumber() const
|
||||
{
|
||||
return m_portNumber;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaGrpcServerImpl::isRunning() const
|
||||
{
|
||||
return m_server != nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGrpcServerImpl::run()
|
||||
{
|
||||
initialize();
|
||||
while (true)
|
||||
{
|
||||
waitForNextRequest();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGrpcServerImpl::runInThread()
|
||||
{
|
||||
initialize();
|
||||
m_thread = std::thread(&RiaGrpcServerImpl::waitForNextRequest, this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGrpcServerImpl::initialize()
|
||||
{
|
||||
CAF_ASSERT(m_portNumber > 0 && m_portNumber <= (int) std::numeric_limits<quint16>::max());
|
||||
|
||||
QString serverAddress = QString("localhost:%1").arg(m_portNumber);
|
||||
|
||||
ServerBuilder builder;
|
||||
builder.AddListeningPort(serverAddress.toStdString(), grpc::InsecureServerCredentials());
|
||||
|
||||
for (auto key : RiaGrpcServiceFactory::instance()->allKeys())
|
||||
{
|
||||
std::shared_ptr<RiaGrpcServiceInterface> service(RiaGrpcServiceFactory::instance()->create(key));
|
||||
builder.RegisterService(dynamic_cast<grpc::Service*>(service.get()));
|
||||
m_services.push_back(service);
|
||||
}
|
||||
|
||||
m_completionQueue = builder.AddCompletionQueue();
|
||||
m_server = builder.BuildAndStart();
|
||||
|
||||
CVF_ASSERT(m_server);
|
||||
RiaLogging::info(QString("Server listening on %1").arg(serverAddress));
|
||||
|
||||
// Spawn new CallData instances to serve new clients.
|
||||
for (auto service : m_services)
|
||||
{
|
||||
for (auto callback : service->createCallbacks())
|
||||
{
|
||||
process(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGrpcServerImpl::processOneRequest()
|
||||
{
|
||||
std::lock_guard<std::mutex> requestLock(m_requestMutex);
|
||||
if (!m_unprocessedRequests.empty())
|
||||
{
|
||||
RiaAbstractGrpcCallback* method = m_unprocessedRequests.front();
|
||||
m_unprocessedRequests.pop_front();
|
||||
process(method);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Gracefully shut down the GRPC server. The internal order is important.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGrpcServerImpl::quit()
|
||||
{
|
||||
if (m_server)
|
||||
{
|
||||
RiaLogging::info("Shutting down gRPC server");
|
||||
// Clear unhandled requests
|
||||
while (!m_unprocessedRequests.empty())
|
||||
{
|
||||
RiaAbstractGrpcCallback* method = m_unprocessedRequests.front();
|
||||
m_unprocessedRequests.pop_front();
|
||||
delete method;
|
||||
}
|
||||
|
||||
// Shutdown server and queue
|
||||
m_server->Shutdown();
|
||||
m_completionQueue->Shutdown();
|
||||
|
||||
// Wait for thread to join after handling the shutdown call
|
||||
m_thread.join();
|
||||
|
||||
// Must destroy server before services
|
||||
m_server.reset();
|
||||
m_completionQueue.reset();
|
||||
|
||||
// Finally clear services
|
||||
m_services.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGrpcServerImpl::waitForNextRequest()
|
||||
{
|
||||
void* tag;
|
||||
bool ok = false;
|
||||
|
||||
while (m_completionQueue->Next(&tag, &ok))
|
||||
{
|
||||
RiaAbstractGrpcCallback* method = static_cast<RiaAbstractGrpcCallback*>(tag);
|
||||
if (ok)
|
||||
{
|
||||
std::lock_guard<std::mutex> requestLock(m_requestMutex);
|
||||
m_unprocessedRequests.push_back(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGrpcServerImpl::process(RiaAbstractGrpcCallback* method)
|
||||
{
|
||||
if (method->callState() == RiaAbstractGrpcCallback::CREATE_HANDLER)
|
||||
{
|
||||
RiaLogging::debug(QString("Initialising request handler for: %1").arg(method->name()));
|
||||
method->createRequestHandler(m_completionQueue.get());
|
||||
}
|
||||
else if (method->callState() == RiaAbstractGrpcCallback::INIT_REQUEST)
|
||||
{
|
||||
// Perform initialization and immediately process the first request
|
||||
// The initialization is necessary for streaming services.
|
||||
RiaLogging::info(QString("Starting handling: %1").arg(method->name()));
|
||||
method->initRequest();
|
||||
method->processRequest();
|
||||
}
|
||||
else if (method->callState() == RiaAbstractGrpcCallback::PROCESS_REQUEST)
|
||||
{
|
||||
method->processRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::info(QString("Finished handling: %1").arg(method->name()));
|
||||
method->finishRequest();
|
||||
process(method->createNewFromThis());
|
||||
delete method;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaGrpcServer::RiaGrpcServer(int portNumber)
|
||||
{
|
||||
m_serverImpl = new RiaGrpcServerImpl(portNumber);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaGrpcServer::~RiaGrpcServer()
|
||||
{
|
||||
delete m_serverImpl;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RiaGrpcServer::portNumber() const
|
||||
{
|
||||
if (m_serverImpl) return m_serverImpl->portNumber();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaGrpcServer::isRunning() const
|
||||
{
|
||||
if (m_serverImpl) return m_serverImpl->isRunning();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGrpcServer::run()
|
||||
{
|
||||
m_serverImpl->run();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGrpcServer::runInThread()
|
||||
{
|
||||
m_serverImpl->runInThread();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGrpcServer::initialize()
|
||||
{
|
||||
m_serverImpl->initialize();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGrpcServer::processOneRequest()
|
||||
{
|
||||
m_serverImpl->processOneRequest();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaGrpcServer::quit()
|
||||
{
|
||||
if (m_serverImpl)
|
||||
m_serverImpl->quit();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RiaGrpcServer::findAvailablePortNumber(int defaultPortNumber)
|
||||
{
|
||||
int startPort = 50051;
|
||||
|
||||
if (defaultPortNumber > 0 && defaultPortNumber < (int)std::numeric_limits<quint16>::max())
|
||||
{
|
||||
startPort = defaultPortNumber;
|
||||
}
|
||||
|
||||
int endPort = std::min(startPort + 100, (int)std::numeric_limits<quint16>::max());
|
||||
|
||||
QTcpServer serverTest;
|
||||
quint16 port = static_cast<quint16>(startPort);
|
||||
for (; port <= static_cast<quint16>(endPort); ++port)
|
||||
{
|
||||
if (serverTest.listen(QHostAddress::LocalHost, port))
|
||||
{
|
||||
return static_cast<int>(port);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
53
ApplicationCode/GrpcInterface/RiaGrpcServer.h
Normal file
53
ApplicationCode/GrpcInterface/RiaGrpcServer.h
Normal file
@ -0,0 +1,53 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
class RiaGrpcServerImpl;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// The GRPC server.
|
||||
//
|
||||
//==================================================================================================
|
||||
class RiaGrpcServer
|
||||
{
|
||||
public:
|
||||
RiaGrpcServer(int portNumber);
|
||||
~RiaGrpcServer();
|
||||
|
||||
int portNumber() const;
|
||||
bool isRunning() const;
|
||||
void run();
|
||||
void runInThread();
|
||||
void processOneRequest();
|
||||
void quit();
|
||||
static int findAvailablePortNumber(int defaultPortNumber);
|
||||
|
||||
private:
|
||||
void initialize();
|
||||
|
||||
private:
|
||||
RiaGrpcServerImpl* m_serverImpl;
|
||||
};
|
54
ApplicationCode/GrpcInterface/RiaGrpcServiceInterface.cpp
Normal file
54
ApplicationCode/GrpcInterface/RiaGrpcServiceInterface.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RiaGrpcServiceInterface.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimCase.h"
|
||||
|
||||
#include <grpcpp/grpcpp.h>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCase* RiaGrpcServiceInterface::findCase(int caseId)
|
||||
{
|
||||
std::vector<RimCase*> cases;
|
||||
RiaApplication::instance()->project()->allCases(cases);
|
||||
|
||||
for (RimCase* rimCase : cases)
|
||||
{
|
||||
if (caseId == rimCase->caseId())
|
||||
{
|
||||
return rimCase;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Find the number of messages that will fit in the given bytes.
|
||||
/// The default argument is meant to be a sensible size for GRPC.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RiaGrpcServiceInterface::numberOfMessagesForByteCount(size_t messageSize,
|
||||
size_t numBytesWantedInPackage /*= 64 * 1024u*/)
|
||||
{
|
||||
size_t messageCount = numBytesWantedInPackage / messageSize;
|
||||
return messageCount;
|
||||
}
|
||||
|
43
ApplicationCode/GrpcInterface/RiaGrpcServiceInterface.h
Normal file
43
ApplicationCode/GrpcInterface/RiaGrpcServiceInterface.h
Normal file
@ -0,0 +1,43 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include <grpcpp/grpcpp.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RiaAbstractGrpcCallback;
|
||||
class RimCase;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// gRPC-service interface which all gRPC-services has to implement
|
||||
//
|
||||
//==================================================================================================
|
||||
class RiaGrpcServiceInterface
|
||||
{
|
||||
public:
|
||||
virtual std::vector<RiaAbstractGrpcCallback*> createCallbacks() = 0;
|
||||
virtual ~RiaGrpcServiceInterface() = default;
|
||||
static RimCase* findCase(int caseId);
|
||||
static size_t numberOfMessagesForByteCount(size_t messageSize, size_t byteCount = 64 * 1024u);
|
||||
};
|
||||
|
||||
#include "cafFactory.h"
|
||||
typedef caf::Factory<RiaGrpcServiceInterface, size_t> RiaGrpcServiceFactory;
|
||||
|
@ -703,7 +703,7 @@ double RigFlowDiagResults::maxAbsPairFlux(int timeStepIndex)
|
||||
calculateNativeResultsIfNotPreviouslyAttempted(timeStepIndex, RigFlowDiagResultAddress::PHASE_ALL);
|
||||
double maxFlux = 0.0;
|
||||
|
||||
if (timeStepIndex < m_injProdPairFluxCommunicationTimesteps.size())
|
||||
if ((size_t) timeStepIndex < m_injProdPairFluxCommunicationTimesteps.size())
|
||||
{
|
||||
for (const auto& commPair : m_injProdPairFluxCommunicationTimesteps[timeStepIndex][RigFlowDiagResultAddress::PHASE_ALL])
|
||||
{
|
||||
|
@ -456,6 +456,7 @@ namespace caf {
|
||||
//==================================================================================================
|
||||
|
||||
bool ProgressInfoStatic::s_disabled = false;
|
||||
bool ProgressInfoStatic::s_running = false;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
@ -488,7 +489,7 @@ namespace caf {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s_running = true;
|
||||
maxProgressStack_v.push_back(maxProgressValue);
|
||||
progressStack_v.push_back(0);
|
||||
progressSpanStack_v.push_back(1);
|
||||
@ -610,6 +611,14 @@ namespace caf {
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool ProgressInfoStatic::isRunning()
|
||||
{
|
||||
return s_running;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -652,6 +661,7 @@ namespace caf {
|
||||
{
|
||||
dialog->reset();
|
||||
dialog->close();
|
||||
s_running = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -85,14 +85,14 @@ public:
|
||||
static void setProgress(size_t progressValue);
|
||||
static void incrementProgress();
|
||||
static void setNextProgressIncrement(size_t nextStepSize);
|
||||
|
||||
static bool isRunning();
|
||||
static void finished();
|
||||
|
||||
private:
|
||||
static bool isUpdatePossible();
|
||||
private:
|
||||
friend class ProgressInfoBlocker;
|
||||
|
||||
static bool s_running;
|
||||
static bool s_disabled;
|
||||
};
|
||||
|
||||
|
33
GRPC_install_instructions.txt
Normal file
33
GRPC_install_instructions.txt
Normal file
@ -0,0 +1,33 @@
|
||||
########## Windows using vcpkg ###################
|
||||
1. Clone VCPKG
|
||||
git clone https://github.com/microsoft/vcpkg.git
|
||||
|
||||
4. Install VCPKG from within vcpkg folder:
|
||||
.\boostrap-vcpkg.sh
|
||||
5. Perform integrated install (as admin) within vcpkg folder. Not sure if it is necessary.
|
||||
.\vcpkg integrate install
|
||||
5. Install GRPC
|
||||
.\vcpkg install grpc --triplet x64-windows
|
||||
6. Run cmake with -DCMAKE_TOOLCHAIN_FILE=LOCATION_OF_VCPKG/buildsystems/vcpkg.cmake
|
||||
This can be set on the configure dialog that comes up when you press configure with a fresh build folder.
|
||||
7. Enable GRPC by setting RESINSIGHT_ENABLE_GRPC = true
|
||||
8. Make sure the python executable is found by setting PYTHON_EXECUTABLE=LOCATION_OF_PYTHON.EXE
|
||||
|
||||
############ Linux as STANDALONE GPRC (using GRPC_INSTALL_PREFIX=/opt/grpc as an example) ###############
|
||||
1. Clone grpc
|
||||
https://github.com/grpc/grpc.git
|
||||
2. From within grpc folder, check out stable version of grpc and initialise repo:
|
||||
git checkout v1.20.1
|
||||
git submodule init
|
||||
git submodule update
|
||||
3. Make sure you're building with devtools-3, since you'll be using that for ResInsight too
|
||||
scl enable devtoolset-3 bash
|
||||
make prefix=/opt/grpc
|
||||
sudo make prefix=/opt/grpc install
|
||||
3. Install protobuf (still within grpc folder)
|
||||
cd third_party/protobuf
|
||||
sudo make prefix=/opt/grpc install
|
||||
4. Install grpcio-tools for Python (this may have to be done as root user):
|
||||
pip install grpcio-tools
|
||||
5. Run cmake making sure GRPC_INSTALL_PREFIX is set to /opt/grpc, PYTHON_EXECUTABLE set to a good python 3 and RESINSIGHT_ENABLE_GRPC = true
|
||||
|
3
Python/.gitignore
vendored
Normal file
3
Python/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
__pycache__
|
||||
.pytest_cache
|
||||
generated
|
159
Python/api/ResInsight.py
Normal file
159
Python/api/ResInsight.py
Normal file
@ -0,0 +1,159 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import grpc
|
||||
import os
|
||||
import sys
|
||||
import socket
|
||||
|
||||
sys.path.insert(1, os.path.join(sys.path[0], '../generated'))
|
||||
|
||||
import Empty_pb2
|
||||
import CaseInfo_pb2
|
||||
import CaseInfo_pb2_grpc
|
||||
import Commands_pb2
|
||||
import Commands_pb2_grpc
|
||||
import GridInfo_pb2
|
||||
import GridInfo_pb2_grpc
|
||||
import ProjectInfo_pb2
|
||||
import ProjectInfo_pb2_grpc
|
||||
import ResInfo_pb2
|
||||
import ResInfo_pb2_grpc
|
||||
import RiaVersionInfo
|
||||
|
||||
MAX_MESSAGE_LENGTH = 128 * 1024 * 1024
|
||||
|
||||
class ResInfo:
|
||||
def __init__(self, channel):
|
||||
self.resInfo = ResInfo_pb2_grpc.ResInfoStub(channel)
|
||||
def versionMessage(self):
|
||||
return self.resInfo.GetVersion(Empty_pb2.Empty())
|
||||
def majorVersion(self):
|
||||
return self.versionMessage().major_version
|
||||
def minorVersion(self):
|
||||
return self.versionMessage().minor_version
|
||||
def patchVersion(self):
|
||||
return self.versionMessage().patch_version
|
||||
def versionString(self):
|
||||
return str(self.majorVersion()) + "." + str(self.minorVersion()) + "." + str(self.patchVersion())
|
||||
|
||||
class CommandExecutor:
|
||||
def __init__(self, channel):
|
||||
self.commands = Commands_pb2_grpc.CommandsStub(channel)
|
||||
|
||||
def execute(self, commandParams):
|
||||
try:
|
||||
self.commands.Execute(commandParams)
|
||||
except grpc.RpcError as e:
|
||||
if e.code() == grpc.StatusCode.NOT_FOUND:
|
||||
print("Command not found")
|
||||
else:
|
||||
print("Other error")
|
||||
|
||||
def setTimeStep(self, caseId, timeStep):
|
||||
return self.execute(Commands_pb2.CommandParams(setTimeStep=Commands_pb2.SetTimeStepParams(caseId=caseId, timeStep=timeStep)))
|
||||
|
||||
def setMainWindowSize(self, width, height):
|
||||
return self.execute(Commands_pb2.CommandParams(setMainWindowSize=Commands_pb2.SetMainWindowSizeParams(width=width, height=height)))
|
||||
|
||||
def openProject(self, path):
|
||||
return self.execute(Commands_pb2.CommandParams(openProject=Commands_pb2.FilePathRequest(path=path)))
|
||||
|
||||
def loadCase(self, path):
|
||||
return self.execute(Commands_pb2.CommandParams(loadCase=Commands_pb2.FilePathRequest(path=path)))
|
||||
|
||||
def closeProject(self):
|
||||
return self.execute(Commands_pb2.CommandParams(closeProject=Empty_pb2.Empty()))
|
||||
|
||||
class GridInfo:
|
||||
def __init__(self, channel):
|
||||
self.gridInfo = GridInfo_pb2_grpc.GridInfoStub(channel)
|
||||
|
||||
def getGridCount(self, caseId=0):
|
||||
return self.gridInfo.GetGridCount(CaseInfo_pb2.Case(id=caseId)).count
|
||||
|
||||
def getGridDimensions(self, caseId=0):
|
||||
return self.gridInfo.GetGridDimensions(CaseInfo_pb2.Case(id=caseId)).dimensions
|
||||
|
||||
def streamActiveCellInfo(self, caseId=0):
|
||||
return self.gridInfo.StreamActiveCellInfo(CaseInfo_pb2.Case(id=caseId))
|
||||
|
||||
class ProjectInfo:
|
||||
def __init__(self, channel):
|
||||
self.projectInfo = ProjectInfo_pb2_grpc.ProjectInfoStub(channel)
|
||||
def selectedCases(self):
|
||||
selected = self.projectInfo.SelectedCases(Empty_pb2.Empty())
|
||||
if selected is not None:
|
||||
return selected.case_info
|
||||
else:
|
||||
return None
|
||||
def allCases(self):
|
||||
cases = self.projectInfo.AllCases(Empty_pb2.Empty())
|
||||
if cases is not None:
|
||||
return allCases.case_info
|
||||
else:
|
||||
return None
|
||||
|
||||
class Instance:
|
||||
@staticmethod
|
||||
def is_port_in_use(port):
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||
s.settimeout(0.2)
|
||||
return s.connect_ex(('localhost', port)) == 0
|
||||
|
||||
@staticmethod
|
||||
def launch():
|
||||
port = 50051
|
||||
portEnv = os.environ.get('RESINSIGHT_GRPC_PORT')
|
||||
if portEnv:
|
||||
port = int(portEnv)
|
||||
|
||||
resInsightExecutable = os.environ.get('RESINSIGHT_EXECUTABLE')
|
||||
if resInsightExecutable is None:
|
||||
print('Error: Could not launch any ResInsight instances because RESINSIGHT_EXECUTABLE is not set')
|
||||
return None
|
||||
|
||||
while Instance.is_port_in_use(port):
|
||||
port += 1
|
||||
|
||||
print('Port ' + str(port))
|
||||
print('Trying to launch', resInsightExecutable)
|
||||
pid = os.spawnl(os.P_NOWAIT, resInsightExecutable, " --grpcserver " + str(port))
|
||||
print(pid)
|
||||
return Instance(port)
|
||||
|
||||
@staticmethod
|
||||
def find(startPort = 50051, endPort = 50071):
|
||||
portEnv = os.environ.get('RESINSIGHT_GRPC_PORT')
|
||||
if portEnv:
|
||||
startPort = int(portEnv)
|
||||
endPort = startPort + 20
|
||||
|
||||
for tryPort in range(startPort, endPort):
|
||||
if Instance.is_port_in_use(tryPort):
|
||||
return Instance(tryPort)
|
||||
|
||||
print('Error: Could not find any ResInsight instances responding between ports ' + str(startPort) + ' and ' + str(endPort))
|
||||
return None
|
||||
|
||||
def __init__(self, port = 50051):
|
||||
location = "localhost:" + str(port)
|
||||
self.channel = grpc.insecure_channel(location, options=[('grpc.max_receive_message_length', MAX_MESSAGE_LENGTH)])
|
||||
|
||||
# Main version check package
|
||||
self.resInfo = ResInfo(self.channel)
|
||||
try:
|
||||
majorVersionOk = self.resInfo.majorVersion() == int(RiaVersionInfo.RESINSIGHT_MAJOR_VERSION)
|
||||
minorVersionOk = self.resInfo.minorVersion() == int(RiaVersionInfo.RESINSIGHT_MINOR_VERSION)
|
||||
if not (majorVersionOk and minorVersionOk):
|
||||
raise Exception('Version of ResInsight does not match version of Python API')
|
||||
except grpc.RpcError as e:
|
||||
if e.code() == grpc.StatusCode.UNAVAILABLE:
|
||||
print('Info: Could not find any instances at port ' + str(port))
|
||||
except Exception as e:
|
||||
print('Error:', e)
|
||||
|
||||
# Service packages
|
||||
self.commands = CommandExecutor(self.channel)
|
||||
self.gridInfo = GridInfo(self.channel)
|
||||
self.projectInfo = ProjectInfo(self.channel)
|
||||
|
0
Python/api/__init__.py
Normal file
0
Python/api/__init__.py
Normal file
13
Python/examples/AllCases.py
Normal file
13
Python/examples/AllCases.py
Normal file
@ -0,0 +1,13 @@
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(1, os.path.join(sys.path[0], '../api'))
|
||||
|
||||
import ResInsight
|
||||
|
||||
resInsight = ResInsight.Instance.find()
|
||||
if resInsight is not None:
|
||||
caseInfos = resInsight.projectInfo.allCases()
|
||||
|
||||
print ("Got " + str(len(caseInfos)) + " cases: ")
|
||||
for caseInfo in caseInfos:
|
||||
print(caseInfo.name)
|
11
Python/examples/CommandExample.py
Normal file
11
Python/examples/CommandExample.py
Normal file
@ -0,0 +1,11 @@
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(1, os.path.join(sys.path[0], '../api'))
|
||||
import ResInsight
|
||||
|
||||
# Load instance
|
||||
resInsight = ResInsight.Instance.find()
|
||||
|
||||
# Run a couple of commands
|
||||
resInsight.commands.setTimeStep(caseId=0, timeStep=3)
|
||||
resInsight.commands.setMainWindowSize(width=800, height=500)
|
21
Python/examples/GridInfoStreamingExample.py
Normal file
21
Python/examples/GridInfoStreamingExample.py
Normal file
@ -0,0 +1,21 @@
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(1, os.path.join(sys.path[0], '../api'))
|
||||
import ResInsight
|
||||
|
||||
resInsight = ResInsight.Instance.find()
|
||||
#gridCount = resInsight.gridInfo.getGridCount(caseId=0)
|
||||
#gridDimensions = resInsight.gridInfo.getAllGridDimensions(caseId=0)
|
||||
|
||||
activeCellInfoChunks = resInsight.gridInfo.streamActiveCellInfo(caseId=0)
|
||||
|
||||
#print("Number of grids: " + str(gridCount))
|
||||
#print(gridDimensions)
|
||||
|
||||
receivedActiveCells = []
|
||||
for activeCellChunk in activeCellInfoChunks:
|
||||
for activeCell in activeCellChunk.data:
|
||||
receivedActiveCells.append(activeCell)
|
||||
print("Number of active cells: " + str(len(receivedActiveCells)))
|
||||
print("First active cell: ")
|
||||
print(receivedActiveCells[0])
|
45
Python/examples/ResultValues.py
Normal file
45
Python/examples/ResultValues.py
Normal file
@ -0,0 +1,45 @@
|
||||
from ResInsight import ResInsight
|
||||
import grpc
|
||||
import logging
|
||||
import sys
|
||||
|
||||
def run():
|
||||
# NOTE(gRPC Python Team): .close() is possible on a channel and should be
|
||||
# used in circumstances in which the with statement does not fit the needs
|
||||
# of the code.
|
||||
logging.basicConfig()
|
||||
|
||||
try:
|
||||
port = 50051
|
||||
if len(sys.argv) > 1:
|
||||
port = sys.argv[1]
|
||||
resInsight = ResInsight("localhost:" + port)
|
||||
timeStepsInfo = resInsight.grid.numberOfTimeSteps(ResInsight.Case(id=0))
|
||||
print ("Number of time steps: " + str(timeStepsInfo.value))
|
||||
resultsAllTimeSteps = []
|
||||
for timeStep in range(0, timeStepsInfo.value - 1):
|
||||
results = resInsight.grid.results(ResInsight.ResultRequest(ResInsight.Case(id=0), ResInsight.ResultAddress(0, "SOIL"), timeStep))
|
||||
print ("Got " + str(len(results.value)) + " values")
|
||||
resultsAllTimeSteps.append(results.value)
|
||||
|
||||
print("Have stored results array containing " + str(len(resultsAllTimeSteps)) + " time steps")
|
||||
|
||||
print("Looking for first cell with a decent SOIL value")
|
||||
indexFirstProperCell = 0
|
||||
for i in range(0, len(resultsAllTimeSteps[0])):
|
||||
result = resultsAllTimeSteps[0][i]
|
||||
if indexFirstProperCell == 0 and result > 0.01:
|
||||
indexFirstProperCell = i
|
||||
|
||||
for resultsForTimeStep in resultsAllTimeSteps:
|
||||
print ("Result for cell " + str(indexFirstProperCell) + ": " + str(resultsForTimeStep[indexFirstProperCell]))
|
||||
|
||||
except grpc.RpcError as e:
|
||||
if e.code() == grpc.StatusCode.NOT_FOUND:
|
||||
print("Case id not found")
|
||||
else:
|
||||
logging.error('Other error: %s', e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
14
Python/examples/SelectedCases.py
Normal file
14
Python/examples/SelectedCases.py
Normal file
@ -0,0 +1,14 @@
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(1, os.path.join(sys.path[0], '../api'))
|
||||
|
||||
import ResInsight
|
||||
|
||||
resInsight = ResInsight.Instance.find()
|
||||
if resInsight is not None:
|
||||
caseInfos = resInsight.projectInfo.selectedCases()
|
||||
|
||||
print ("Got " + str(len(caseInfos)) + " cases: ")
|
||||
for caseInfo in caseInfos:
|
||||
print(caseInfo.name)
|
||||
|
51
Python/tests/test_sample.py
Normal file
51
Python/tests/test_sample.py
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
import os, sys
|
||||
|
||||
# Add the 'api' path to system path to be able to import modules from the 'api' folder
|
||||
# python current working directory must be 'tests'
|
||||
sys.path.insert(1, os.path.join(sys.path[0], '..\\api'))
|
||||
|
||||
import ResInsight
|
||||
|
||||
resInsight = ResInsight.Instance()
|
||||
|
||||
|
||||
# content of test_sample.py
|
||||
def getActiveCellCount(caseId):
|
||||
activeCellInfoChunks = resInsight.gridInfo.streamActiveCellInfo(caseId)
|
||||
|
||||
receivedActiveCells = []
|
||||
for activeCellChunk in activeCellInfoChunks:
|
||||
for activeCell in activeCellChunk.data:
|
||||
receivedActiveCells.append(activeCell)
|
||||
return len(receivedActiveCells)
|
||||
|
||||
def myOpenProject(filepath):
|
||||
resInsight = ResInsight.Instance()
|
||||
#resInsight.commands.setMainWindowSize(width=800, height=500)
|
||||
resInsight.commands.openProject(filepath)
|
||||
|
||||
def test_openProjectAndCountCells():
|
||||
testRepositoryRoot = "d:\\gitroot-ceesol\\ResInsight-regression-test"
|
||||
|
||||
#casePath = testRepositoryRoot + "\\ModelData\\TEST10K_FLT_LGR_NNC\\TEST10K_FLT_LGR_NNC.EGRID"
|
||||
#openEclipseCase(casePath)
|
||||
|
||||
# projectPath = testRepositoryRoot + "\\ProjectFiles\\ProjectFilesSmallTests\\TestCase_10K_Complete\\RegressionTest.rsp"
|
||||
# projectPath = testRepositoryRoot + "\\ProjectFiles\\ProjectFilesSmallTests\\TestCase_Norne\\RegressionTest.rsp"
|
||||
projectPath = testRepositoryRoot + "\\ProjectFiles\\ProjectFilesSmallTests\\TestCase_10K_Watertight\\RegressionTest.rsp"
|
||||
myOpenProject(projectPath)
|
||||
|
||||
assert getActiveCellCount(0) == 11125
|
||||
|
||||
|
||||
|
||||
def test_openCaseAndCountCells():
|
||||
testRepositoryRoot = "d:\\gitroot-ceesol\\ResInsight-regression-test"
|
||||
|
||||
casePath = testRepositoryRoot + "\\ModelData\\TEST10K_FLT_LGR_NNC\\TEST10K_FLT_LGR_NNC.EGRID"
|
||||
resInsight.commands.loadCase(casePath)
|
||||
|
||||
assert getActiveCellCount(0) == 11125
|
||||
|
||||
resInsight.commands.closeProject()
|
Loading…
Reference in New Issue
Block a user