#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 | 15688 | Doug Scheirer |
Populate -o //guest/perforce_software/helix-web-services/... //guest/doug_scheirer/helix-web-services/.... |
||
//guest/perforce_software/helix-web-services/main/build/helix_web_services_client_qt/hws/Client.h | |||||
#5 | 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. |
||
#4 | 15521 | tjuricek | Call client.ignoreSslErrors(true) to bypass self-signed cert problems. | ||
#3 | 15448 | tjuricek |
Qt SDK revision: remove higher-level objects from the SDK. It's likely we could add higher-level objects that adapt the executeMethodDone and convert the variant maps to something, well, typed and easier to use. That's not in my current scope of work, however. |
||
#2 | 14055 | tjuricek | Updating helix_web_services_client build for new 'my' vs 'all' projects feature | ||
#1 | 14050 | tjuricek | Prep versioned release directory for inclusion into Helix Sync app. |