== Client Application Development In general, your client application is going to need to: * Know the Helix Versioning Engine topology * Obtain login tokens for Helix Versioning Engine (using <<post_auth_v1_login>>) * Call other methods on the system. Your application may use a single Helix Web Services instance to interact with multiple Helix Versioning Engines. In these cases, you will need to specify which versioning engine you are interacting with. In cases you are only using one Helix Versioning Engine, your application can then specify system wide settings. See <<system_configuration>> for more details. Working with Helix Web Services for a client generally involves making a single request at a time. Many of our core methods mimic the set of commands available to the `p4` application. But if you need to make a combined set of `p4 commands, ideally, there are extended "services" available, that handle that interaction. So, in general, your client application only needs to make one web service call at a time. [[authentication]] === Authentication Almost every Helix Web Services method requires authentication. We support http://tools.ietf.org/html/rfc2617[HTTP Basic Authentication], using the login and p4 ticket as credentials. Obtain a ticket via <<post_auth_v1_login>>. Say the user `jdoe` has obtained the ticket `B984EF267963F434BB51C063EE86E8F9`. The corresponding HTTP header to add to each request would be: .... Authorization: Basic amRvZTpCOTg0RUYyNjc5NjNGNDM0QkI1MUMwNjNFRTg2RThGOQ== .... NOTE: You can easily generate the basic header on most Unix systems using the `echo` and `base64` commands. For example, to generate the header above, would be the command `echo -n jdoe:B984EF267963F434BB51C063EE86E8F9 | base64` [[per_request_configuration]] === Per-Request Configuration Each request can specify HTTP headers to indicate override known settings the system. Each custom header takes the format: .... X-Perforce-Helix-Web-Services-[KEY] .... See <<system_configuration>> for the list of available keys. For example, to change the `P4PORT` to be used, which identifies a separate Helix Versioning Engine, you'd set this header: .... X-Perforce-Helix-Web-Services-P4PORT: helix-eu.mycompany.com:1666 .... [[error_responses]] === Error Conventions Upon success, methods of Helix Web Services return the 200 HTTP status code. If your authentication token is not valid, you will receive 403 error, which means you need to update your login token (using <<post_auth_v1_login>>). 401 errors will likely originate from the Helix Versioning Engine. In this case, we provide information to the client application via a JSON object. This object will contain three main properties: [cols="2*", options="header"] |=== | Property | Description | `MessageCode` | A numeric ID for the problem, typically defined by the Helix Versioning Engine. Should be the same value as http://www.perforce.com/perforce/r15.1/manuals/p4api/chapter.methods.html#error.getgeneric[Error::GetGeneric()]. | `MessageSeverity` | Mirrors the severity levels of http://www.perforce.com/perforce/r15.1/manuals/p4api/chapter.methods.html#error.getseverity[Error::GetSeverity()]. Generally going to be 3 or 4. | `MessageText` | Informational text that will likely not be localized appropriately for the user. |=== When 500 errors happen, a serious problem has occurred, which may mean an important subsystem is compromised. Do not expect a response body. The problem will have to be investigated on the server side. Your client should not attempt further communication with Helix Web Services. [[ruby_client_sdk_overview]] === Ruby Client SDK If your application is written in Ruby, you can use our provided Ruby client SDK. This SDK is currently available as part of the Helix Web Services source code, in the `helix_web_services_client` directory. Many Helix Web Services methods refer to this client SDK as the _Ruby API_. ==== Basic Ruby Client SDK usage There are really two primary methods: 1. link:./helix_web_services_client_ruby/HelixWebServicesClient.html#execute_method_with_body-instance_method[`execute_method_with_body`] 2. link:./helix_web_services_client_ruby/HelixWebServicesClient.html#execute_method_no_body-instance_method[`execute_method_no_body`] Along with signing in via the constructore These methods will generally parse the JSON response, and throw exceptions in case of any errors reported by the underlying server. [source,ruby] ---- require 'helix_web_services_client' client = HelixWebServicesClient.new({ :url => 'https://helix.example.com/hws', :user => 'jdoe', :password => 'joesupersecret' }) # Get starting list of depots depots = client.execute_method_no_body(:get, '/p4/v[api]/files') # Print depot names depots.each { |d| puts d['name'] } # Make a user client.execute_method_with_body(:post, '/p4/v[api]/users', nil, { 'User': 'new_user', 'FullName': 'Steve Austin', 'Email': 'saustin@example.com' }) ---- You can additionally fetch the p4 ticket via the `client.ticket` property. If you store that, you can create a new `HelixWebServicesClient` specifying that via `ticket` instead of `password`. ==== Models in the Ruby Client SDK Most HTTP methods that correspond to commands of the `p4` application, do not alter data from the Helix Versioning Engine. This can be inconvenient for application development. For example, dates are inconsistently represented, sometimes as strings, other times as timestamps. Keys that represent the same concept show up in different cases in the output data. We've developed the link:helix_web_services_client_ruby/OpenModel.html[`OpenModel`] class to help this out. Because a single version of Helix Web Services can interact with multiple instances Helix Versioning Engines at different versions, we do not want to restrict the data coming out of the server. The `OpenModel` class looks for case alternatives that might appear. It also provides a Ruby-like coding standard. [source,ruby] ---- # Get starting list of depots depots = client.depots # The depot name # # If you call the singular method using our basic API this key is sometimes # referred to by `name`, sometimes as `Depot` depots.first.depot_or_name # In some listings, this is an integer represented as a string. # # Instead of a number, returns a Ruby Time object. # # Note that you should grab the offset value from the 'serverDate' field from # the `p4 info` command. depots.first.date_as_time(offset) # Can still make a user fairly easily just using Hashes client.create_user({ 'User' => 'new_user', 'FullName' => 'Steve Austin', 'Email' => 'saustin@example.com' }) # Updating specs should use upper case syntax. depot = client.depot('to_edit') depot.Description = "Updating the description" client.update_depot(depot) ---- ==== Obtaining the Client SDK In order to use the client SDK, you'd first need to obtain a copy of the Helix Web Services source from the Perforce workshop. Visit the workshop at https://swarm.workshop.perforce.com/. On that site, you can sign up a new account. Documentation on this process is provided via that website. Once you have an account, you can then retrieve code via the Helix Versioning Engine available at `workshop.perforce.com:1666`. The source code is available at `//guest/perforce_software/helix-web-services/main/...` Use any Perforce client application, such as `p4` or P4V to connect and retrieve the source code. Official releases of Helix Web Services may publish this client SDK to rubygems. Stay tuned!
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#2 | 16114 | Doug Scheirer | Merge from main | ||
#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/source/doc/04_clientprog.asc | |||||
#2 | 15686 | tjuricek | Removed Qt SDK (will be maintained with Helix Sync), updated README | ||
#1 | 15622 | tjuricek |
Move source code to 'source/' subdirectory of branch. build/ will remain where it is. |
||
//guest/perforce_software/helix-web-services/main/doc/04_clientprog.asc | |||||
#11 | 15447 | tjuricek |
Add simple Example application to list "projects" in a HVE instance. Qt's a little weird to follow, so I may have to find a different kind of example to write. It does work, however. |
||
#10 | 15435 | tjuricek |
Add proposed HTTP methods for Helix Sync. It's a little unclear to me why you would need a local root directory to create the shared shelving changelist for a particular project (and user). So I didn't add that. |
||
#9 | 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. |
||
#8 | 15257 | tjuricek |
Added stress test, corrected per-request header config. Apparently using underscores is a "special" mechanism for HTTP headers, and requires adjusting nginx to allow such things. Might as well just recommend using hyphens, which get converted to underscores anyway. The current test just hits a listing of 20000 files against p4play. Returns a 2.5 MB response, which doesn't seem to cause problems (yay). |
||
#7 | 15240 | tjuricek |
Set api level via request path on all Helix Versioning Engine methods. This will allow migration of applications to different P4D versions. Our internal methods (like project API) should attempt to handle backward compatibility similarly. P4WEBAPI-118 |
||
#6 | 15132 | tjuricek | Provde a basic submit -e mechanism on classic perforce workspaces. | ||
#5 | 15078 | tjuricek |
clients spec method revisions Updated some other documentation. |
||
#4 | 15077 | tjuricek |
Add new 'model' technique, revised branch spec operations, test Auth::Middleware. The Ruby client now does *not* strictly type anything, but extends OpenStruct with helper methods to help deal with inconsistent data formats. See the OpenModel class documentation for more details. The Auth::Middleware class is also *finally* implemented as well. This does not take into account all possible variations of server behavior (yet), but that will happen in follow-up work. |
||
#3 | 15053 | tjuricek |
Revise the client API to use the new login method. The current specs will need to be revised since data normalization is moving out of the server and into the client. |
||
#2 | 15042 | tjuricek | Document error conventions. | ||
#1 | 15038 | tjuricek | Document 'login' auth method and client programming overview. | ||
//guest/perforce_software/helix-web-services/main/doc/03_clientprog.asc | |||||
#3 | 15032 | tjuricek |
Starting config and doc revisions. System is now broken while revisions underway. Configuration of the p4d connection is now done via a single HWSSettings middleware object injected into the Rack env. The HWSP4Cleanup middleware now cleans up any p4 injected into the Rack env. The Auth::App class now mostly just contains one method to generate a p4 ticket. /auth/v1/login. Added yard documentation for the main project. Yard docs have been reconfigured to dump into build/ directories. This should probably be done with each release. Hm... The top level rake file contains a task, 'all:doc', to update our documentation. This should probably be run for each checkin. Hm... Specs are now using Rack::Test on top of a 'live' p4d. I'd suggest you still use the p4util mechanism, which now dumps to a /tmp folder, so we can safely add P4IGNORE rules back into your local .p4config file. Old 'perforce' application now called 'helix_versioning_engine'. Removing cache data. Helix Sync may be slow. It may also get axed. We'll see. |
||
#2 | 14980 | tjuricek |
Starting to make revisions to the Asciidoc guide. These are just revisions to the preable sections. |
||
#1 | 13555 | tjuricek |
Starting Asciidoc conversion of documentation. Removed the "Shared Quality" document, that basically is online now at: https://confluence.perforce.com:8443/display/PWS/Quality+Assurance Adding some topology graphviz images used for online documentation. |