#ifndef __HWS_CLIENT_H__ #define __HWS_CLIENT_H__ #include <QObject> #include <QSettings> #include <QSharedPointer> #include <QUrl> #include <QVariant> #include "Session.h" #include "RequestError.h" namespace hws { /// Front end to making requests against the Phoenix web services API. class Client : public QObject { Q_OBJECT public: // Most of our return results are returned as this consistent format. typedef QList<QVariantMap> QVariantMapList; // URL parameters must be converted to string values. // Note that this API will handle the URI encoding. typedef QHash<QString, QString> QStringHash; // Initialize a client with a specific HWS url. Client(QObject *parent, QUrl url); /// A basic empty client that should be updated Client(QObject *parent); /// Destroy the client. Any open connections for updates will get /// automatically disconnected. ~Client(); /// The Helix Web Services URL const QUrl & url() const; /// The Helix Web Services URL void setUrl(const QUrl & url); /// When true, this should have a session instance that was known to /// work at some point. bool hasSession() const; /// The session instance is required before making any remote call. const Session & session() const; /// If you have stored a previously used session, you can just assign it /// to this client instance. void setSession(const Session & session); /// This is a leading path to almost every request in the system. It's /// configurable since some development environment setups don't have /// a nice way to handle creating DNS entries, which leads to services /// sometimes getting mounted locally under subpaths. const QString & hwsPrefixPath() const; /// This is a leading path to almost every request in the system. It's /// configurable since some development environment setups don't have /// a nice way to handle creating DNS entries, which leads to services /// sometimes getting mounted locally under subpaths. void setHWSPrefixPath(const QString & path); /// All stored sessions are saved as a JSON object under this settings /// key, which is defaulted to "HelixWebServicesSettings". /// /// This should be set on construction only. const QString & settingsKey() const; /// Returns the current settings handle for the client. If it exists, /// The settings will store the session data by URL under a particular /// key. const QSharedPointer<QSettings> settings() const; /// The current settings handle for the client. void setSettings(QSharedPointer<QSettings> settings); /// Creates a per-request configuration setting. /// /// See the documentation for details, but this will apply the correct /// prefix to the key, and leave the value untouched. /// /// @param key The configuration key, e.g., P4PORT /// @param value The 'raw' header value void addRequestConfig(QString key, QString value); /// Ignore SSL certificate errors in the connection. /// /// This is required in situations where your certificate is self-signed /// or otherwise not valid. void ignoreSslErrors(bool ignore); public slots: /// Trigger a remote call to the web services instance to validate that /// the session (and ticket) is still valid. /// /// Even if this client has no session, we'll still double check that /// we can call back to the server. void validateSession(); /// This should attempt a login as the user and password to the url /// that's been configured on this client. /// /// IMPORTANT: this will attempt to resolve the hostname of the client /// itself, which we'll use to generate a host locked ticket. void logIn(const QString & user, const QString & password); /// Execute a method of Helix Web Services. /// /// @param method An HTTP verb, e.g., "POST" /// @param path The method path to use, e.g., '/helix_versioning_engine/v78/changes' /// @param params Optional URL parameters to set /// @param body Optional request body to use void executeMethod(const QString & method, const QString & path, const QSharedPointer<QStringHash> params = QSharedPointer<QStringHash>(), const QSharedPointer<QByteArray> body = QSharedPointer<QByteArray>()); /// Execute a method of Helix Web Services. /// /// @param method An HTTP verb, e.g., "POST" /// @param path The method path to use, e.g., '/helix_versioning_engine/v78/changes' /// @param params URL parameters to set (for no parameters, set to empty pointer) /// @param body Request body set as a QVariantMap, will be serialized as JSON void executeMethod(const QString & method, const QString & path, const QSharedPointer<QStringHash> params, const QVariantMap & body); /// Execute a method of Helix Web Services. /// /// @param method An HTTP verb, e.g., "POST" /// @param path The method path to use, e.g., '/helix_versioning_engine/v78/changes' /// @param params URL parameters to set (for no parameters, set to empty pointer) /// @param body Request body set as a list of QVariantMaps, will be serialized as JSON void executeMethod(const QString & method, const QString & path, const QSharedPointer<QStringHash> params, const QVariantMapList & body); signals: /// Callback after validating a session. /// /// The error value indicates a networking or remote system problem. /// /// If the session is invalid, the error will not be set. Instead, you /// should double check the output of `client.hasSession()`. If that is /// false, you'll need to sign in again. /// /// At this point, if the session is invalid, it will be cleared from /// any QSettings cachce as well, if the client was initialized with a /// settings handle. void validateSessionDone(RequestErrorPtr error); /// When the login request has resolved this is called. /// /// Authentication errors will result in no session being created. void logInDone(RequestErrorPtr error, SessionPtr session); /// Main callback for most method calls to Helix Web Services. /// /// If the error is set, the body is definitely null. /// /// If no error occurred, you may have one or more values, depending /// on the method called. /// /// @param error If set, details on the problem. /// @param method HTTP verb of the method run /// @param path Subpath (without the prefix) of the method /// @param body If the response included a body, we convert it from JSON to a list of hashes. void executeMethodDone(RequestErrorPtr error, const QString & method, const QString & path, const QSharedPointer<QVariantMapList> body); // Implementation is hidden using PIMPL technique. // I'm hiding the direct include dependencies on Qt5Network and // Qt5WebSockets. private: class Impl; class LogInFinished; class ExecuteMethodFinished; Impl *mImpl; // Disabled methods private: Client(const Client &); Client & operator=(const Client &); }; typedef QSharedPointer<Client> ClientPtr; } #endif /* __HWS_CLIENT_H__ */
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 15741 | ptomiak | Branch HWS for my use. | ||
//guest/perforce_software/helix-web-services/main/source/helix_web_services_client_qt/hws/Client.h | |||||
#1 | 15622 | tjuricek |
Move source code to 'source/' subdirectory of branch. build/ will remain where it is. |
||
//guest/perforce_software/helix-web-services/main/helix_web_services_client_qt/hws/Client.h | |||||
#8 | 15578 | tjuricek |
Removing QSettings* usage from hws::Client. The way QSettings was being used only is relevant for one connection at a time, and, it didn't seem to work on windows nicely anyway. |
||
#7 | 15544 | tjuricek | Explain that the QSettings handle for hws::Client should only be used on connections you don't specify a P4PORT for. | ||
#6 | 15521 | tjuricek | Call client.ignoreSslErrors(true) to bypass self-signed cert problems. | ||
#5 | 15445 | tjuricek | Allow per-request overrides to be set via addRequestConfig | ||
#4 | 15423 | tjuricek |
Revised HWS Qt API. This is a major revision of the API, which removes most of the "typed" data, replacing it with a more generic "executeMethodDone" callback. The main benefit here is to allow the API to interop with different versions of p4d, and not restrict the methods it can call. We may add more helpers in the future. |
||
#3 | 14054 | tjuricek |
Allowing the Qt client to select 'all' vs 'my' projects. Right now, it should default to using "my" projects as a rule. |
||
#2 | 14049 | tjuricek |
Add methods to generate client workspaces for a user. The Qt SDK was updated based on immediate need. Also, add Ruby client SDK documentation to the docs site. Everything is early, but there's *some* reference available at least. |
||
#1 | 14025 | tjuricek |
Revise Qt SDK to a single 'helix_web_services_client' project. Most references to "Phoenix" have now been removed. Additionally, this is more similar to the other platform client SDKs in Ruby and JavaScript. Documentation via Doxygen is now available, and will be how much of the SDK reference should occur. |
||
//guest/perforce_software/helix-web-services/main/qt/p4_phoenix_services_client/phoenix/PhoenixServicesClient.h | |||||
#10 | 13532 | tjuricek |
Qt SDK: Add constructor that uses an application's QSettings for caching Sessions for each URL Added a simple validateSession remote call to ping the services instance to see if the session is indeed usable. Also, removing puma configuraiton that is automatically generated in the (shared) development instance. |
||
#9 | 13506 | tjuricek |
Change to a C++03 build. Major changes: 1. QSharedPointer::create(...) is much more restricted than in C++11, so just use the .reset() method unless you're passing in a single const reference argument to the constructor. 2. Using Qt's foreach. 3. Replace lambdas with simpler helper methods. This seems to work, but we may have subtle memory issues I'm not 100% on top of yet. |
||
#8 | 13501 | tjuricek |
Adding a space to separate out the template declaration parameters. Doesn't seem to be an issue with gcc, this must be a visual studio issue. |
||
#7 | 13497 | tjuricek | Follow QObject memory management conventions for the PhoenixServicesClient. | ||
#6 | 13483 | tjuricek | Typedef that struct. | ||
#5 | 13471 | tjuricek |
Define some JSON messages for Qt API's websocket interaction. Not tested... yet. |
||
#4 | 13470 | tjuricek |
Phoenix notification services, client API, including new phoenix_updater This is an interim commit containing a first pass implementation of the phoenix_updater. Notably missing parts: - The Qt API doesn't yet actually interact with the phoenix_updater - The phoenix_services web service doesn't filter out notifications I *may* end up creating another web application *just* to filter out notifications, since this may end up taking up a lot of background workers. |
||
#3 | 13459 | tjuricek |
Return the created project when creating a new project, since default values will often be filled out. Allow new projects to be created only with names set. We'll generate an ID at the moment, when I have better indexing, I'll double check for uniqueness. |
||
#2 | 13458 | tjuricek |
Revising P4 Web API docbook documentation to become the Perforce Web Services guide. Right now this is just focused on the Qt SDK. The remaining protocol documentation, etc, will happen eventually. |
||
#1 | 13443 | tjuricek |
Reorganized the Qt libraries into a separate part of the tree, to make it easier for CMake configuration. Added 'qt_build' and 'qt_test' tasks to at least execute tests and fail the build if they don't pass. Started the implementation of the project library interaction. Change: 1018651 Date: 3/4/15 11:43 AM Client: tjuricek_dhcp-141-n100_5959 User: tjuricek Status: pending Type: public Description: Reorganized the Qt libraries into a separate part of the tree, to make it easier for CMake configuration. Added 'qt_build' and 'qt_test' tasks to at least execute tests and fail the build if they don't pass. Started the implementation of the project library interaction. JobStatus: Jobs: Files: //web-services/p4ws-main/Rakefile //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/CMakeLists.txt //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/PhoenixIntegrationTests.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/README //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix.h //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/PhoenixProject.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/PhoenixProject.h //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/PhoenixServicesClient.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/PhoenixServicesClient.h //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/RequestError.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/RequestError.h //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/Session.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/Session.h //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/test/PhoenixServicesClientTests.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/test/PhoenixServicesClientTests.h //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/test/SessionTests.cpp //web-services/p4ws-main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/test/SessionTests.h //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/CMakeLists.txt //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services.h //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services/Branch.cpp //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services/Branch.h //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services/Project.cpp //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services/Project.h //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services/View.cpp //web-services/p4ws-main/p4_project_services/clients/qt/p4_project_services_client/p4_project_services/View.h //web-services/p4ws-main/qt/CMakeLists.txt //web-services/p4ws-main/qt/p4_phoenix_services_client/CMakeLists.txt //web-services/p4ws-main/qt/p4_phoenix_services_client/PhoenixIntegrationTests.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/README //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix.h //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/PhoenixProject.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/PhoenixProject.h //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/PhoenixServicesClient.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/PhoenixServicesClient.h //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/RequestError.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/RequestError.h //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/Session.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/phoenix/Session.h //web-services/p4ws-main/qt/p4_phoenix_services_client/test/PhoenixServicesClientTests.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/test/PhoenixServicesClientTests.h //web-services/p4ws-main/qt/p4_phoenix_services_client/test/SessionTests.cpp //web-services/p4ws-main/qt/p4_phoenix_services_client/test/SessionTests.h //web-services/p4ws-main/qt/p4_project_services_client/CMakeLists.txt //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeCache.txt //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CMakeCCompiler.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CMakeCXXCompiler.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CMakeDetermineCompilerABI_C.bin //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CMakeDetermineCompilerABI_CXX.bin //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CMakeSystem.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CompilerIdC/CMakeCCompilerId.c //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CompilerIdC/a.out //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CompilerIdCXX/CMakeCXXCompilerId.cpp //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/2.8.12/CompilerIdCXX/a.out //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/CMakeDirectoryInformation.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/CMakeOutput.log //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/Makefile.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/Makefile2 //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/TargetDirectories.txt //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/cmake.check_cache //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/DependInfo.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/build.make //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/cmake_clean.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/cmake_clean_target.cmake //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/depend.make //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/flags.make //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/link.txt //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/p4_project_services_client.dir/progress.make //web-services/p4ws-main/qt/p4_project_services_client/build/CMakeFiles/progress.marks //web-services/p4ws-main/qt/p4_project_services_client/build/Makefile //web-services/p4ws-main/qt/p4_project_services_client/build/cmake_install.cmake //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services.h //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services/Branch.cpp //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services/Branch.h //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services/Project.cpp //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services/Project.h //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services/View.cpp //web-services/p4ws-main/qt/p4_project_services_client/p4_project_services/View.h |
||
//guest/perforce_software/helix-web-services/main/p4_phoenix_services/clients/qt/p4_phoenix_services_client/phoenix/PhoenixServicesClient.h | |||||
#4 | 13439 | tjuricek |
Added a *very trivial* logIn implementation. This just makes the *current* POST request to /p4_phoenix_services/v1/sessions, which *does not* include the ability to create a host locked P4 ticket for the user. So it's not quite usable yet. But, I've made several tweaks to the API which should be stablizing. |
||
#3 | 13435 | tjuricek |
Added framework for QtTest to the p4_phoenix_services qt client (and fixing stupid compile errors). Also, ignoring .DS_Store. |
||
#2 | 13425 | tjuricek | Fixing crappy-ass whitespace | ||
#1 | 13424 | tjuricek |
First-pass at Qt Client API for Phoenix web services. The underlying project data is organized as the basic 'p4_project_services' API, which is then used by the higher-level 'phoenix' API, just to cut down on a lot of potential boiler plate. The base project model should allow for custom extensions, but it's aniticpated that the product-specific stuff doesn't really need to care too much about this. We just need to make sure that if new product extensions exist that the C++ API doesn't know about, they: a.) don't explode on read because there's something new, and b.) don't just delete the extension code. These are *just headers* to get the ball rolling on the needs of the Phoenix engine. Things like 'sessions' are interesting and may have been overlooked. |