diff --git a/Docs/publishing-release.md b/Docs/publishing-release.md index de770fa24..eaaaa443c 100644 --- a/Docs/publishing-release.md +++ b/Docs/publishing-release.md @@ -5,7 +5,7 @@ The following tasks should be completed before publishing a release. Track the p - [ ] Review and merge any outstanding pull requests. - [ ] Review any oustanding issues assigned to this release milestone. - [ ] Branch from `develop` to `rc-[version]`, ex: `rc-2.0.0`. -- [ ] Draft release with version in the format of `v2.0.0` targeting the 'master' branch. Standard release should be named using the format `Watson Developer Cloud Unity SDK [version]`, ex: `Watson Developer Cloud Unity SDK v2.0.0`. +- [ ] Draft release with version in the format of `v2.0.0` targeting the 'master' branch. Standard release should be named using the format `IBM Watson SDK for Unity [version]`, ex: `IBM Watson SDK for Unity v2.0.0`. #### Source Changes (in `rc` branch) - [ ] Update `String.Version` in `Scripts/Utilities/Constants.cs` to the current version, ex: `watson-apis-unity-sdk/2.0.0` diff --git a/Doxyfile b/Doxyfile index 2aaba455c..bb78517d8 100644 --- a/Doxyfile +++ b/Doxyfile @@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "Watson Developer Cloud Unity SDK" +PROJECT_NAME = "IBM Watson SDK for Unity" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version diff --git a/Examples/ServiceExamples/Scripts/ExampleDiscovery.cs b/Examples/ServiceExamples/Scripts/ExampleDiscovery.cs index 14f2ecc55..0cfec981f 100644 --- a/Examples/ServiceExamples/Scripts/ExampleDiscovery.cs +++ b/Examples/ServiceExamples/Scripts/ExampleDiscovery.cs @@ -83,6 +83,12 @@ public class ExampleDiscovery : MonoBehaviour private bool _readyToContinue = false; private float _waitTime = 10f; + private bool _listCredentialsTested = false; + private bool _createCredentialsTested = false; + private bool _getCredentialTested = false; + private bool _deleteCredentialsTested = false; + private string _createdCredentialId = null; + private void Start() { LogSystem.InstallDefaultReactors(); @@ -285,6 +291,44 @@ private IEnumerator Examples() while (!_isEnvironmentReady) yield return null; + // List Credentials + Log.Debug("TestDiscovery.RunTest()", "Attempting to list credentials"); + _service.ListCredentials(OnListCredentials, OnFail, _environmentId); + while (!_listCredentialsTested) + yield return null; + + // Create Credentials + Log.Debug("TestDiscovery.RunTest()", "Attempting to create credentials"); + SourceCredentials credentialsParameter = new SourceCredentials() + { + SourceType = SourceCredentials.SourceTypeEnum.box, + CredentialDetails = new CredentialDetails() + { + CredentialType = CredentialDetails.CredentialTypeEnum.oauth2, + EnterpriseId = "myEnterpriseId", + ClientId = "myClientId", + ClientSecret = "myClientSecret", + PublicKeyId = "myPublicIdKey", + Passphrase = "myPassphrase", + PrivateKey = "myPrivateKey" + } + }; + _service.CreateCredentials(OnCreateCredentials, OnFail, _environmentId, credentialsParameter); + while (!_createCredentialsTested) + yield return null; + + // Get Credential + Log.Debug("TestDiscovery.RunTest()", "Attempting to get credential"); + _service.GetCredential(OnGetCredential, OnFail, _environmentId, _createdCredentialId); + while (!_getCredentialTested) + yield return null; + + // DeleteCredential + Log.Debug("TestDiscovery.RunTest()", "Attempting to delete credential"); + _service.DeleteCredentials(OnDeleteCredentials, OnFail, _environmentId, _createdCredentialId); + while (!_deleteCredentialsTested) + yield return null; + Log.Debug("TestDiscovery.RunTest()", "Discovery examples complete."); } @@ -327,13 +371,22 @@ private IEnumerator Delay(float waitTime) private void OnGetEnvironments(GetEnvironmentsResponse resp, Dictionary customData) { Log.Debug("ExampleDiscovery.OnGetEnvironments()", "Discovery - GetEnvironments Response: {0}", customData["json"].ToString()); + + foreach (var environment in resp.environments) + { + if (environment.read_only == false) + { + Log.Debug("ExampleDiscovery.OnGetEnvironments()", "setting environment to {0}", environment.environment_id); + _environmentId = environment.environment_id; + } + } + _getEnvironmentsTested = true; } private void OnGetEnvironment(Environment resp, Dictionary customData) { Log.Debug("ExampleDiscovery.OnGetEnvironment()", "Discovery - GetEnvironment Response: {0}", customData["json"].ToString()); - _environmentId = resp.environment_id; _getEnvironmentTested = true; } @@ -437,6 +490,30 @@ private void OnQuery(QueryResponse resp, Dictionary customData) _queryTested = true; } + private void OnListCredentials(CredentialsList response, Dictionary customData) + { + Log.Debug("ExampleDiscovery.OnListCredentials()", "Response: {0}", customData["json"].ToString()); + _listCredentialsTested = true; + } + private void OnCreateCredentials(SourceCredentials response, Dictionary customData) + { + Log.Debug("ExampleDiscovery.OnCreateCredentials()", "Response: {0}", customData["json"].ToString()); + _createdCredentialId = response.CredentialId; + _createCredentialsTested = true; + } + + private void OnGetCredential(SourceCredentials response, Dictionary customData) + { + Log.Debug("ExampleDiscovery.OnGetCredential()", "Response: {0}", customData["json"].ToString()); + _getCredentialTested = true; + } + + private void OnDeleteCredentials(DeleteCredentials response, Dictionary customData) + { + Log.Debug("ExampleDiscovery.OnDeleteCredentials()", "Response: {0}", customData["json"].ToString()); + _deleteCredentialsTested = true; + } + private void OnFail(RESTConnector.Error error, Dictionary customData) { Log.Error("ExampleDiscovery.OnFail()", "Error received: {0}", error.ToString()); diff --git a/NOTICES.txt b/NOTICES.txt new file mode 100644 index 000000000..f44688018 --- /dev/null +++ b/NOTICES.txt @@ -0,0 +1,79 @@ +This asset is governed by the Asset Store EULA; however, the following components are governed by the licenses indicated below: + +A. websocket-sharp + +The MIT License (MIT) + +Copyright (c) 2010-2018 sta.blockhead + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +B. Full Serializer + +The MIT License (MIT) + +Copyright (c) 2014 Jacob Dufault + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +C. MiniJSON + +Copyright (c) 2013 Calvin Rien + +Based on the JSON parser by Patrick van Bergen +http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html + +Simplified it so that it doesn't throw exceptions +and can be used in Unity iPhone with maximum code stripping. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 46ac7c70d..7999cae61 100755 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Ensure that you have the following prerequisites: * [Unity][get_unity]. You can use the **free** Personal edition. ## Configuring Unity -* Change the build settings in Unity (**File > Build Settings**) to any platform except for web player/Web GL. The Watson Developer Cloud Unity SDK does not support Unity Web Player. +* Change the build settings in Unity (**File > Build Settings**) to any platform except for web player/Web GL. The IBM Watson SDK for Unity does not support Unity Web Player. * If using Unity 2018.2 or later you'll need to set Scripting Runtime Version in Build Settings to .NET 4.x equivalent. We need to access security options to enable TLS 1.2. ## Getting the Watson SDK and adding it to Unity @@ -107,15 +107,16 @@ You supply either an IAM service **API key** or an **access token**: ```cs IEnumerator TokenExample() { - // Create IAM token options and supply the apikey. + // Create IAM token options and supply the apikey. IamUrl is the URL used to get the + // authorization token using the IamApiKey. It defaults to https://iam.bluemix.net/identity/token TokenOptions iamTokenOptions = new TokenOptions() { IamApiKey = "", - IamUrl = "" + IamUrl = "" }; // Create credentials using the IAM token options - _credentials = new Credentials(iamTokenOptions, ""); while (!_credentials.HasIamTokenData()) yield return null; @@ -314,6 +315,9 @@ private void OnMessage(object resp, Dictionary customData) ``` ## Authentication Tokens + +**Authenticating with the `X-Watson-Authorization-Token` header is deprecated. The token continues to work with Cloud Foundry services, but is not supported for services that use Identity and Access Management (IAM) authentication. For details see [Authenticating with IAM tokens](https://console.bluemix.net/docs/services/watson/getting-started-iam.html#iam) or the [README](#IAM) in the IBM Watson SDK you use.** + You use tokens to write applications that make authenticated requests to IBM Watson™ services without embedding service credentials in every call. You can write an authentication proxy in IBM Cloud that obtains and returns a token to your client application, which can then use the token to call the service directly. This proxy eliminates the need to channel all service requests through an intermediate server-side application, which is otherwise necessary to avoid exposing your service credentials from your client application. @@ -352,6 +356,9 @@ private void OnGetToken(AuthenticationToken authenticationToken, string customDa } ``` +## Streaming outside of US South region +Watson services have upgraded their hosts to TLS 1.2. The US South region has a TLS 1.0 endpoint that will work for streaming but if you are streaming in other regions you will need to use Unity 2018.2 and set Scripting Runtime Version in Build Settings to .NET 4.x equivalent. In lower versions of Unity you will need to create the Speech to Text instance in US South. + ## Documentation Documentation can be found [here][documentation]. You can also access the documentation by selecting API Reference the Watson menu (**Watson -> API Reference**). diff --git a/Scripts/Services/Discovery/v1/DataModels.cs b/Scripts/Services/Discovery/v1/DataModels.cs index 88de91272..d9dc1ed5d 100644 --- a/Scripts/Services/Discovery/v1/DataModels.cs +++ b/Scripts/Services/Discovery/v1/DataModels.cs @@ -16,6 +16,9 @@ */ using FullSerializer; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; using System.Text; namespace IBM.Watson.DeveloperCloud.Services.Discovery.v1 @@ -322,6 +325,11 @@ public class Configuration /// An array describing the configuration's document normalization settings. /// public NormalizationOperation[] normalizations { get; set; } + /// + /// Object containing source parameters for the configuration. + /// + [fsProperty("source")] + public Source Source { get; set; } } /// @@ -776,6 +784,11 @@ public class Collection /// Object providing information about the documents in the collection. /// public DocumentCounts document_counts { get; set; } + /// + /// Object containing source crawl status information. + /// + [fsProperty("source_crawl")] + public SourceStatus SourceCrawl { get; set; } } /// @@ -917,6 +930,12 @@ public class QueryResponse /// Query aggregations. /// public QueryAggregation aggregations { get; set; } + /// + /// The session token for this query. The session token can be used to add events associated with this query to + /// the query and event log. + /// + [fsProperty("session_token")] + public string SessionToken { get; set; } public override string ToString() { @@ -965,6 +984,24 @@ public class QueryResult public double score { get; set; } } + /// + /// Metadata of a query result. + /// + [fsObject] + public class QueryResultResultMetadata + { + /// + /// The raw score of the result. A higher score indicates a greater match to the query parameters. + /// + [fsProperty("score")] + public double? Score { get; set; } + /// + /// The confidence score of the result's analysis. A higher score indicates greater confidence. + /// + [fsProperty("confidence")] + public double? Confidence { get; set; } + } + /// /// Query aggregation. /// @@ -1005,4 +1042,508 @@ public class AggregationResult public double matching_results { get; set; } } #endregion + + #region Credentials + [fsObject] + /// + /// CredentialsList. + /// + public class CredentialsList + { + /// + /// An array of credential definitions that were created for this instance. + /// + [fsProperty("credentials")] + public List Credentials { get; set; } + } + + [fsObject] + /// + /// Object containing credential information. + /// + public class SourceCredentials + { + /// + /// The source that this credentials object connects to. + /// - `box` indicates the credentials are used to connect an instance of Enterprise Box. + /// - `salesforce` indicates the credentials are used to connect to Salesforce. + /// - `sharepoint` indicates the credentials are used to connect to Microsoft SharePoint Online. + /// + public enum SourceTypeEnum + { + + /// + /// Enum BOX for box + /// + [EnumMember(Value = "box")] + box, + + /// + /// Enum SALESFORCE for salesforce + /// + [EnumMember(Value = "salesforce")] + salesforce, + + /// + /// Enum SHAREPOINT for sharepoint + /// + [EnumMember(Value = "sharepoint")] + sharepoint + } + + /// + /// The source that this credentials object connects to. + /// - `box` indicates the credentials are used to connect an instance of Enterprise Box. + /// - `salesforce` indicates the credentials are used to connect to Salesforce. + /// - `sharepoint` indicates the credentials are used to connect to Microsoft SharePoint Online. + /// + [fsProperty("source_type")] + public SourceTypeEnum? SourceType { get; set; } + /// + /// Unique identifier for this set of credentials. + /// + [fsProperty("credential_id")] + public virtual string CredentialId { get; private set; } + /// + /// Object containing details of the stored credentials. + /// + /// Obtain credentials for your source from the administrator of the source. + /// + [fsProperty("credential_details")] + public CredentialDetails CredentialDetails { get; set; } + } + + + [fsObject] + /// + /// Object containing details of the stored credentials. + /// + /// Obtain credentials for your source from the administrator of the source. + /// + public class CredentialDetails + { + /// + /// The authentication method for this credentials definition. The **credential_type** specified must be + /// supported by the **source_type**. The following combinations are possible: + /// + /// - `\"source_type\": \"box\"` - valid `credential_type`s: `oauth2` + /// - `\"source_type\": \"salesforce\"` - valid `credential_type`s: `username_password` + /// - `\"source_type\": \"sharepoint\"` - valid `credential_type`s: `saml`. + /// + public enum CredentialTypeEnum + { + + /// + /// Enum OAUTH2 for oauth2 + /// + [EnumMember(Value = "oauth2")] + oauth2, + + /// + /// Enum SAML for saml + /// + [EnumMember(Value = "saml")] + saml, + + /// + /// Enum USERNAME_PASSWORD for username_password + /// + [EnumMember(Value = "username_password")] + username_password + } + + /// + /// The authentication method for this credentials definition. The **credential_type** specified must be + /// supported by the **source_type**. The following combinations are possible: + /// + /// - `\"source_type\": \"box\"` - valid `credential_type`s: `oauth2` + /// - `\"source_type\": \"salesforce\"` - valid `credential_type`s: `username_password` + /// - `\"source_type\": \"sharepoint\"` - valid `credential_type`s: `saml`. + /// + [fsProperty("credential_type")] + public CredentialTypeEnum? CredentialType { get; set; } + /// + /// The **client_id** of the source that these credentials connect to. Only valid, and required, with a + /// **credential_type** of `oauth2`. + /// + [fsProperty("client_id")] + public string ClientId { get; set; } + /// + /// The **enterprise_id** of the Box site that these credentials connect to. Only valid, and required, with a + /// **source_type** of `box`. + /// + [fsProperty("enterprise_id")] + public string EnterpriseId { get; set; } + /// + /// The **url** of the source that these credentials connect to. Only valid, and required, with a + /// **credential_type** of `username_password`. + /// + [fsProperty("url")] + public string Url { get; set; } + /// + /// The **username** of the source that these credentials connect to. Only valid, and required, with a + /// **credential_type** of `saml` and `username_password`. + /// + [fsProperty("username")] + public string Username { get; set; } + /// + /// The **organization_url** of the source that these credentials connect to. Only valid, and required, with a + /// **credential_type** of `saml`. + /// + [fsProperty("organization_url")] + public string OrganizationUrl { get; set; } + /// + /// The **site_collection.path** of the source that these credentials connect to. Only valid, and required, with + /// a **source_type** of `sharepoint`. + /// + [fsProperty("site_collection.path")] + public string SiteCollectionPath { get; set; } + /// + /// The **client_secret** of the source that these credentials connect to. Only valid, and required, with a + /// **credential_type** of `oauth2`. This value is never returned and is only used when creating or modifying + /// **credentials**. + /// + [fsProperty("client_secret")] + public string ClientSecret { get; set; } + /// + /// The **public_key_id** of the source that these credentials connect to. Only valid, and required, with a + /// **credential_type** of `oauth2`. This value is never returned and is only used when creating or modifying + /// **credentials**. + /// + [fsProperty("public_key_id")] + public string PublicKeyId { get; set; } + /// + /// The **private_key** of the source that these credentials connect to. Only valid, and required, with a + /// **credential_type** of `oauth2`. This value is never returned and is only used when creating or modifying + /// **credentials**. + /// + [fsProperty("private_key")] + public string PrivateKey { get; set; } + /// + /// The **passphrase** of the source that these credentials connect to. Only valid, and required, with a + /// **credential_type** of `oauth2`. This value is never returned and is only used when creating or modifying + /// **credentials**. + /// + [fsProperty("passphrase")] + public string Passphrase { get; set; } + /// + /// The **password** of the source that these credentials connect to. Only valid, and required, with + /// **credential_type**s of `saml` and `username_password`. + /// + /// **Note:** When used with a **source_type** of `salesforce`, the password consists of the Salesforce password + /// and a valid Salesforce security token concatenated. This value is never returned and is only used when + /// creating or modifying **credentials**. + /// + [fsProperty("password")] + public string Password { get; set; } + } + + [fsObject] + /// + /// Object returned after credentials are deleted. + /// + public class DeleteCredentials + { + /// + /// The status of the deletion request. + /// + public enum StatusEnum + { + + /// + /// Enum DELETED for deleted + /// + [EnumMember(Value = "deleted")] + deleted + } + + /// + /// The status of the deletion request. + /// + [fsProperty("status")] + public StatusEnum? Status { get; set; } + /// + /// The unique identifier of the credentials that have been deleted. + /// + [fsProperty("credential_id")] + public string CredentialId { get; set; } + } + + /// + /// Object containing source parameters for the configuration. + /// + [fsObject] + public class Source + { + /// + /// The type of source to connect to. + /// - `box` indicates the configuration is to connect an instance of Enterprise Box. + /// - `salesforce` indicates the configuration is to connect to Salesforce. + /// - `sharepoint` indicates the configuration is to connect to Microsoft SharePoint Online. + /// + public enum TypeEnum + { + + /// + /// Enum BOX for box + /// + [EnumMember(Value = "box")] + box, + + /// + /// Enum SALESFORCE for salesforce + /// + [EnumMember(Value = "salesforce")] + salesforce, + + /// + /// Enum SHAREPOINT for sharepoint + /// + [EnumMember(Value = "sharepoint")] + sharepoint + } + + /// + /// The type of source to connect to. + /// - `box` indicates the configuration is to connect an instance of Enterprise Box. + /// - `salesforce` indicates the configuration is to connect to Salesforce. + /// - `sharepoint` indicates the configuration is to connect to Microsoft SharePoint Online. + /// + [fsProperty("type")] + public TypeEnum? Type { get; set; } + /// + /// The **credential_id** of the credentials to use to connect to the source. Credentials are defined using the + /// **credentials** method. The **source_type** of the credentials used must match the **type** field specified + /// in this object. + /// + [fsProperty("credential_id")] + public string CredentialId { get; set; } + /// + /// Object containing the schedule information for the source. + /// + [fsProperty("schedule")] + public SourceSchedule Schedule { get; set; } + /// + /// The **options** object defines which items to crawl from the source system. + /// + [fsProperty("options")] + public SourceOptions Options { get; set; } + } + + /// + /// The **options** object defines which items to crawl from the source system. + /// + [fsObject] + public class SourceOptions + { + /// + /// Array of folders to crawl from the Box source. Only valid, and required, when the **type** field of the + /// **source** object is set to `box`. + /// + [fsProperty("folders")] + public List Folders { get; set; } + /// + /// Array of Salesforce document object types to crawl from the Salesforce source. Only valid, and required, + /// when the **type** field of the **source** object is set to `salesforce`. + /// + [fsProperty("objects")] + public List Objects { get; set; } + /// + /// Array of Microsoft SharePointoint Online site collections to crawl from the SharePoint source. Only valid + /// and required when the **type** field of the **source** object is set to `sharepoint`. + /// + [fsProperty("site_collections")] + public List SiteCollections { get; set; } + } + + /// + /// Object that defines a box folder to crawl with this configuration. + /// + [fsObject] + public class SourceOptionsFolder + { + /// + /// The Box user ID of the user who owns the folder to crawl. + /// + [fsProperty("owner_user_id")] + public string OwnerUserId { get; set; } + /// + /// The Box folder ID of the folder to crawl. + /// + [fsProperty("folder_id")] + public string FolderId { get; set; } + /// + /// The maximum number of documents to crawl for this folder. By default, all documents in the folder are + /// crawled. + /// + [fsProperty("limit")] + public long? Limit { get; set; } + } + + /// + /// Object that defines a Salesforce document object type crawl with this configuration. + /// + [fsObject] + public class SourceOptionsObject + { + /// + /// The name of the Salesforce document object to crawl. For example, `case`. + /// + [fsProperty("name")] + public string Name { get; set; } + /// + /// The maximum number of documents to crawl for this document object. By default, all documents in the document + /// object are crawled. + /// + [fsProperty("limit")] + public long? Limit { get; set; } + } + + /// + /// Object that defines a Microsoft SharePoint site collection to crawl with this configuration. + /// + [fsObject] + public class SourceOptionsSiteColl + { + /// + /// The Microsoft SharePoint Online site collection path to crawl. The path must be be relative to the + /// **organization_url** that was specified in the credentials associated with this source configuration. + /// + [fsProperty("site_collection_path")] + public string SiteCollectionPath { get; set; } + /// + /// The maximum number of documents to crawl for this site collection. By default, all documents in the site + /// collection are crawled. + /// + [fsProperty("limit")] + public long? Limit { get; set; } + } + + /// + /// Object containing the schedule information for the source. + /// + [fsObject] + public class SourceSchedule + { + /// + /// The crawl schedule in the specified **time_zone**. + /// + /// - `daily`: Runs every day between 00:00 and 06:00. + /// - `weekly`: Runs every week on Sunday between 00:00 and 06:00. + /// - `monthly`: Runs the on the first Sunday of every month between 00:00 and 06:00. + /// + public enum FrequencyEnum + { + + /// + /// Enum DAILY for daily + /// + [EnumMember(Value = "daily")] + daily, + + /// + /// Enum WEEKLY for weekly + /// + [EnumMember(Value = "weekly")] + weekly, + + /// + /// Enum MONTHLY for monthly + /// + [EnumMember(Value = "monthly")] + monthly + } + + /// + /// The crawl schedule in the specified **time_zone**. + /// + /// - `daily`: Runs every day between 00:00 and 06:00. + /// - `weekly`: Runs every week on Sunday between 00:00 and 06:00. + /// - `monthly`: Runs the on the first Sunday of every month between 00:00 and 06:00. + /// + [fsProperty("frequency")] + public FrequencyEnum? Frequency { get; set; } + /// + /// When `true`, the source is re-crawled based on the **frequency** field in this object. When `false` the + /// source is not re-crawled; When `false` and connecting to Salesforce the source is crawled annually. + /// + [fsProperty("enabled")] + public bool? Enabled { get; set; } + /// + /// The time zone to base source crawl times on. Possible values correspond to the IANA (Internet Assigned + /// Numbers Authority) time zones list. + /// + [fsProperty("time_zone")] + public string TimeZone { get; set; } + } + + /// + /// Object containing source crawl status information. + /// + [fsObject] + public class SourceStatus + { + /// + /// The current status of the source crawl for this collection. This field returns `not_configured` if the + /// default configuration for this source does not have a **source** object defined. + /// + /// - `running` indicates that a crawl to fetch more documents is in progress. + /// - `complete` indicates that the crawl has completed with no errors. + /// - `complete_with_notices` indicates that some notices were generated during the crawl. Notices can be + /// checked by using the **notices** query method. + /// - `stopped` indicates that the crawl has stopped but is not complete. + /// + public enum StatusEnum + { + + /// + /// Enum RUNNING for running + /// + [EnumMember(Value = "running")] + running, + + /// + /// Enum COMPLETE for complete + /// + [EnumMember(Value = "complete")] + complete, + + /// + /// Enum COMPLETE_WITH_NOTICES for complete_with_notices + /// + [EnumMember(Value = "complete_with_notices")] + complete_with_notices, + + /// + /// Enum STOPPED for stopped + /// + [EnumMember(Value = "stopped")] + stopped, + + /// + /// Enum NOT_CONFIGURED for not_configured + /// + [EnumMember(Value = "not_configured")] + not_configured + } + + /// + /// The current status of the source crawl for this collection. This field returns `not_configured` if the + /// default configuration for this source does not have a **source** object defined. + /// + /// - `running` indicates that a crawl to fetch more documents is in progress. + /// - `complete` indicates that the crawl has completed with no errors. + /// - `complete_with_notices` indicates that some notices were generated during the crawl. Notices can be + /// checked by using the **notices** query method. + /// - `stopped` indicates that the crawl has stopped but is not complete. + /// + [fsProperty("status")] + public StatusEnum? Status { get; set; } + /// + /// Date in UTC format indicating when the last crawl was attempted. If `null`, no crawl was completed. + /// + [fsProperty("last_updated")] + public DateTime LastUpdated { get; set; } + } + #endregion } diff --git a/Scripts/Services/Discovery/v1/Discovery.cs b/Scripts/Services/Discovery/v1/Discovery.cs index 42103fdab..844225392 100644 --- a/Scripts/Services/Discovery/v1/Discovery.cs +++ b/Scripts/Services/Discovery/v1/Discovery.cs @@ -51,6 +51,8 @@ public class Discovery : IWatsonService private const string Documents = "/v1/environments/{0}/collections/{1}/documents"; private const string Document = "/v1/environments/{0}/collections/{1}/documents/{2}"; private const string QueryCollection = "/v1/environments/{0}/collections/{1}/query"; + private const string CredentialsEndpoint = "/v1/environments/{0}/credentials"; + private const string CredentialEndpoint = "/v1/environments/{0}/credentials/{1}"; #endregion #region Public Properties @@ -155,9 +157,9 @@ public bool GetEnvironments(SuccessCallback successCall req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -277,9 +279,9 @@ public bool AddEnvironment(SuccessCallback successCallback, FailCal req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -378,9 +380,9 @@ public bool GetEnvironment(SuccessCallback successCallback, FailCal req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -475,9 +477,9 @@ public bool DeleteEnvironment(SuccessCallback success req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -574,9 +576,9 @@ private void OnDeleteEnvironmentResponse(RESTConnector.Request req, RESTConnecto req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -712,9 +714,9 @@ public bool AddConfiguration(SuccessCallback successCallback, Fai req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -815,9 +817,9 @@ public bool GetConfiguration(SuccessCallback successCallback, Fai req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -915,9 +917,9 @@ public bool DeleteConfiguration(SuccessCallback suc req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -1084,9 +1086,9 @@ private void OnDeleteConfigurationResponse(RESTConnector.Request req, RESTConnec req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -1207,9 +1209,9 @@ private void OnPreviewConfigurationResponse(RESTConnector.Request req, RESTConne req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -1341,9 +1343,9 @@ public bool AddCollection(SuccessCallback successCallback, FailCa req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -1444,9 +1446,9 @@ public bool GetCollection(SuccessCallback successCallback, FailCallb req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -1544,9 +1546,9 @@ public bool DeleteCollection(SuccessCallback successCa req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -1645,9 +1647,9 @@ public bool GetFields(SuccessCallback successCallback, FailCa req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -1918,9 +1920,9 @@ private void OnGetFieldsResponse(RESTConnector.Request req, RESTConnector.Respon req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -2033,9 +2035,9 @@ public bool DeleteDocument(SuccessCallback successCallba req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -2137,9 +2139,9 @@ public bool GetDocument(SuccessCallback successCallback, FailCal req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -2404,9 +2406,9 @@ private void OnGetDocumentResponse(RESTConnector.Request req, RESTConnector.Resp req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -2531,9 +2533,9 @@ public bool Query(SuccessCallback successCallback, FailCallback f req.SuccessCallback = successCallback; req.FailCallback = failCallback; req.CustomData = customData == null ? new Dictionary() : customData; - if(req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) { - foreach(KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) { req.Headers.Add(kvp.Key, kvp.Value); } @@ -2723,6 +2725,425 @@ private void OnDeleteUserDataResponse(RESTConnector.Request req, RESTConnector.R } #endregion + #region Credentials + #region List Credentials + /// + /// List all the source credentials that have been created for this service instance. + /// Note: All credentials are sent over an encrypted connection and encrypted at rest. + /// + /// The success callback. + /// The fail callback. + /// Optional custom data. + /// True if the call succeeds, false if the call is unsuccessful. + public bool ListCredentials(SuccessCallback successCallback, FailCallback failCallback, string environmentId, Dictionary customData = null) + { + if (successCallback == null) + throw new ArgumentNullException("successCallback"); + if (failCallback == null) + throw new ArgumentNullException("failCallback"); + if (string.IsNullOrEmpty(environmentId)) + throw new ArgumentException("environmentId"); + + ListCredentialsRequest req = new ListCredentialsRequest(); + req.SuccessCallback = successCallback; + req.FailCallback = failCallback; + req.CustomData = customData == null ? new Dictionary() : customData; + req.Headers["Content-Type"] = "application/json"; + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + { + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + { + req.Headers.Add(kvp.Key, kvp.Value); + } + } + req.Parameters["version"] = VersionDate; + req.OnResponse = OnListCredentialsResponse; + + RESTConnector connector = RESTConnector.GetConnector(Credentials, string.Format(CredentialsEndpoint, environmentId)); + if (connector == null) + return false; + + return connector.Send(req); + } + + private class ListCredentialsRequest : RESTConnector.Request + { + /// + /// The success callback. + /// + public SuccessCallback SuccessCallback { get; set; } + /// + /// The fail callback. + /// + public FailCallback FailCallback { get; set; } + /// + /// Custom data. + /// + public Dictionary CustomData { get; set; } + } + + private void OnListCredentialsResponse(RESTConnector.Request req, RESTConnector.Response resp) + { + CredentialsList result = new CredentialsList(); + fsData data = null; + Dictionary customData = ((ListCredentialsRequest)req).CustomData; + customData.Add(Constants.String.RESPONSE_HEADERS, resp.Headers); + + if (resp.Success) + { + try + { + fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data); + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + + object obj = result; + r = _serializer.TryDeserialize(data, obj.GetType(), ref obj); + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + + customData.Add("json", data); + } + catch (Exception e) + { + Log.Error("Discovery.OnListCredentialsResponse()", "Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + if (resp.Success) + { + if (((ListCredentialsRequest)req).SuccessCallback != null) + ((ListCredentialsRequest)req).SuccessCallback(result, customData); + } + else + { + if (((ListCredentialsRequest)req).FailCallback != null) + ((ListCredentialsRequest)req).FailCallback(resp.Error, customData); + } + } + #endregion + + #region CreateCredentials + /// + /// Create credentials. + /// + /// Creates a set of credentials to connect to a remote source. Created credentials are used in a configuration + /// to associate a collection with the remote source. + /// + /// **Note:** All credentials are sent over an encrypted connection and encrypted at rest. + /// + /// The function that is called when the operation is successful. + /// The function that is called when the operation fails. + /// The ID of the environment. + /// An object that defines an individual set of source credentials. + /// A Dictionary of data that will be passed to the callback. The raw json output from the REST call will be passed in this object as the value of the 'json' key. + /// Credentials + public bool CreateCredentials(SuccessCallback successCallback, FailCallback failCallback, string environmentId, SourceCredentials credentialsParameter, Dictionary customData = null) + { + if (successCallback == null) + throw new ArgumentNullException("successCallback"); + if (failCallback == null) + throw new ArgumentNullException("failCallback"); + if (string.IsNullOrEmpty(environmentId)) + throw new ArgumentNullException("environmentId"); + if (credentialsParameter == null) + throw new ArgumentNullException("credentialsParameter"); + + CreateCredentialsRequest req = new CreateCredentialsRequest(); + req.SuccessCallback = successCallback; + req.FailCallback = failCallback; + req.CustomData = customData == null ? new Dictionary() : customData; + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + { + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + { + req.Headers.Add(kvp.Key, kvp.Value); + } + } + req.Parameters["version"] = VersionDate; + req.Headers["Content-Type"] = "application/json"; + fsData data = null; + _serializer.TrySerialize(credentialsParameter, out data); + string json = data.ToString().Replace('\"', '"'); + req.Send = Encoding.UTF8.GetBytes(json); + req.OnResponse = OnCreateCredentialsResponse; + + RESTConnector connector = RESTConnector.GetConnector(Credentials, string.Format(CredentialsEndpoint, environmentId)); + if (connector == null) + return false; + + return connector.Send(req); + } + + private class CreateCredentialsRequest : RESTConnector.Request + { + /// + /// The success callback. + /// + public SuccessCallback SuccessCallback { get; set; } + /// + /// The fail callback. + /// + public FailCallback FailCallback { get; set; } + /// + /// Custom data. + /// + public Dictionary CustomData { get; set; } + } + + private void OnCreateCredentialsResponse(RESTConnector.Request req, RESTConnector.Response resp) + { + SourceCredentials result = new SourceCredentials(); + fsData data = null; + Dictionary customData = ((CreateCredentialsRequest)req).CustomData; + customData.Add(Constants.String.RESPONSE_HEADERS, resp.Headers); + + if (resp.Success) + { + try + { + fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data); + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + + object obj = result; + r = _serializer.TryDeserialize(data, obj.GetType(), ref obj); + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + } + catch (Exception e) + { + Log.Error("Assistant.OnCreateCredentialsResponse()", "Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + customData.Add("json", data); + + if (resp.Success) + { + if (((CreateCredentialsRequest)req).SuccessCallback != null) + ((CreateCredentialsRequest)req).SuccessCallback(result, customData); + } + else + { + if (((CreateCredentialsRequest)req).FailCallback != null) + ((CreateCredentialsRequest)req).FailCallback(resp.Error, customData); + } + } + #endregion + + #region Delete Credentials + /// + /// Delete credentials. + /// + /// Deletes a set of stored credentials from your Discovery instance. + /// + /// The success callback. + /// The fail callback. + /// The ID of the environment. + /// The unique identifier for a set of source credentials. + /// Custom data object to pass data including custom request headers. + /// DeleteCredentials + public bool DeleteCredentials(SuccessCallback successCallback, FailCallback failCallback, string environmentID, string credentialId, Dictionary customData = null) + { + if (successCallback == null) + throw new ArgumentNullException("successCallback"); + if (failCallback == null) + throw new ArgumentNullException("failCallback"); + if (string.IsNullOrEmpty(environmentID)) + throw new ArgumentNullException("environmentID"); + if (string.IsNullOrEmpty(credentialId)) + throw new ArgumentNullException("credentialId"); + + DeleteCredentialsRequest req = new DeleteCredentialsRequest(); + req.SuccessCallback = successCallback; + req.FailCallback = failCallback; + req.CustomData = customData == null ? new Dictionary() : customData; + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + { + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + { + req.Headers.Add(kvp.Key, kvp.Value); + } + } + req.Parameters["version"] = VersionDate; + req.OnResponse = OnDeleteCredentialsResponse; + req.Delete = true; + + RESTConnector connector = RESTConnector.GetConnector(Credentials, string.Format(CredentialEndpoint, environmentID, credentialId)); + if (connector == null) + return false; + + return connector.Send(req); + } + + private class DeleteCredentialsRequest : RESTConnector.Request + { + /// + /// The success callback. + /// + public SuccessCallback SuccessCallback { get; set; } + /// + /// The fail callback. + /// + public FailCallback FailCallback { get; set; } + /// + /// Custom data. + /// + public Dictionary CustomData { get; set; } + } + + private void OnDeleteCredentialsResponse(RESTConnector.Request req, RESTConnector.Response resp) + { + DeleteCredentials result = new DeleteCredentials(); + fsData data = null; + Dictionary customData = ((DeleteCredentialsRequest)req).CustomData; + customData.Add(Constants.String.RESPONSE_HEADERS, resp.Headers); + + if (resp.Success) + { + try + { + fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data); + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + + object obj = result; + r = _serializer.TryDeserialize(data, obj.GetType(), ref obj); + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + + customData.Add("json", data); + } + catch (Exception e) + { + Log.Error("Discovery.OnDeleteCredentialsResponse()", "OnDeleteCredentialsResponse Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + if (resp.Success) + { + if (((DeleteCredentialsRequest)req).SuccessCallback != null) + ((DeleteCredentialsRequest)req).SuccessCallback(result, customData); + } + else + { + if (((DeleteCredentialsRequest)req).FailCallback != null) + ((DeleteCredentialsRequest)req).FailCallback(resp.Error, customData); + } + } + #endregion + + #region GetCredential + /// + /// View Credentials. + /// + /// Returns details about the specified credentials. + /// + /// **Note:** Secure credential information such as a password or SSH key is never returned and must be + /// obtained from the source system. + /// + /// The success callback. + /// The fail callback. + /// The ID of the environment. + /// The unique identifier for a set of source credentials. + /// Custom data object to pass data including custom request headers. + /// Credentials + public bool GetCredential(SuccessCallback successCallback, FailCallback failCallback, string environmentID, string credentialId, Dictionary customData = null) + { + if (successCallback == null) + throw new ArgumentNullException("successCallback"); + if (failCallback == null) + throw new ArgumentNullException("failCallback"); + if (string.IsNullOrEmpty(environmentID)) + throw new ArgumentNullException("environmentID"); + if (string.IsNullOrEmpty(credentialId)) + throw new ArgumentNullException("credentialId"); + + GetCredentialRequest req = new GetCredentialRequest(); + req.SuccessCallback = successCallback; + req.FailCallback = failCallback; + req.CustomData = customData == null ? new Dictionary() : customData; + req.Headers["Content-Type"] = "application/json"; + if (req.CustomData.ContainsKey(Constants.String.CUSTOM_REQUEST_HEADERS)) + { + foreach (KeyValuePair kvp in req.CustomData[Constants.String.CUSTOM_REQUEST_HEADERS] as Dictionary) + { + req.Headers.Add(kvp.Key, kvp.Value); + } + } + req.Parameters["version"] = VersionDate; + req.OnResponse = OnGetCredentialResponse; + + RESTConnector connector = RESTConnector.GetConnector(Credentials, string.Format(CredentialEndpoint, environmentID, credentialId)); + if (connector == null) + return false; + + return connector.Send(req); + } + + private class GetCredentialRequest : RESTConnector.Request + { + /// + /// The success callback. + /// + public SuccessCallback SuccessCallback { get; set; } + /// + /// The fail callback. + /// + public FailCallback FailCallback { get; set; } + /// + /// Custom data. + /// + public Dictionary CustomData { get; set; } + } + + private void OnGetCredentialResponse(RESTConnector.Request req, RESTConnector.Response resp) + { + SourceCredentials result = new SourceCredentials(); + fsData data = null; + Dictionary customData = ((GetCredentialRequest)req).CustomData; + customData.Add(Constants.String.RESPONSE_HEADERS, resp.Headers); + + if (resp.Success) + { + try + { + fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data); + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + + object obj = result; + r = _serializer.TryDeserialize(data, obj.GetType(), ref obj); + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + + customData.Add("json", data); + } + catch (Exception e) + { + Log.Error("Discovery.OnGetCredentialResponse()", "OnGetCredentialResponse Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + if (resp.Success) + { + if (((GetCredentialRequest)req).SuccessCallback != null) + ((GetCredentialRequest)req).SuccessCallback(result, customData); + } + else + { + if (((GetCredentialRequest)req).FailCallback != null) + ((GetCredentialRequest)req).FailCallback(resp.Error, customData); + } + } + #endregion + #endregion + #region IWatsonService Interface /// public string GetServiceID() diff --git a/Scripts/Services/Discovery/v1/Model.meta b/Scripts/Services/Discovery/v1/Model.meta new file mode 100644 index 000000000..6a677c46f --- /dev/null +++ b/Scripts/Services/Discovery/v1/Model.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9b98a92f8338528479c9cc7a1361dbaa +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/UnitTests/TestDiscovery.cs b/Scripts/UnitTests/TestDiscovery.cs index 4ff5d8746..b8530572d 100644 --- a/Scripts/UnitTests/TestDiscovery.cs +++ b/Scripts/UnitTests/TestDiscovery.cs @@ -70,6 +70,12 @@ public class TestDiscovery : UnitTest private bool _deleteUserDataTested = false; private bool _readyToContinue = false; + private bool _listCredentialsTested = false; + private bool _createCredentialsTested = false; + private bool _getCredentialTested = false; + private bool _deleteCredentialsTested = false; + private string _createdCredentialId = null; + public override IEnumerator RunTest() { LogSystem.InstallDefaultReactors(); @@ -108,7 +114,7 @@ public override IEnumerator RunTest() // Create credential and instantiate service Credentials credentials = new Credentials(_username, _password, _url); - + _discovery = new Discovery(credentials); _discovery.VersionDate = _discoveryVersionDate; _filePathToIngest = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/Discovery/constitution.pdf"; @@ -215,6 +221,44 @@ public override IEnumerator RunTest() while (!_queryTested) yield return null; + // List Credentials + Log.Debug("TestDiscovery.RunTest()", "Attempting to list credentials"); + _discovery.ListCredentials(OnListCredentials, OnFail, _environmentId); + while (!_listCredentialsTested) + yield return null; + + // Create Credentials + Log.Debug("TestDiscovery.RunTest()", "Attempting to create credentials"); + SourceCredentials credentialsParameter = new SourceCredentials() + { + SourceType = SourceCredentials.SourceTypeEnum.box, + CredentialDetails = new CredentialDetails() + { + CredentialType = CredentialDetails.CredentialTypeEnum.oauth2, + EnterpriseId = "myEnterpriseId", + ClientId = "myClientId", + ClientSecret = "myClientSecret", + PublicKeyId = "myPublicIdKey", + Passphrase = "myPassphrase", + PrivateKey = "myPrivateKey" + } + }; + _discovery.CreateCredentials(OnCreateCredentials, OnFail, _environmentId, credentialsParameter); + while (!_createCredentialsTested) + yield return null; + + // Get Credential + Log.Debug("TestDiscovery.RunTest()", "Attempting to get credential"); + _discovery.GetCredential(OnGetCredential, OnFail, _environmentId, _createdCredentialId); + while (!_getCredentialTested) + yield return null; + + // DeleteCredential + Log.Debug("TestDiscovery.RunTest()", "Attempting to delete credential"); + _discovery.DeleteCredentials(OnDeleteCredentials, OnFail, _environmentId, _createdCredentialId); + while (!_deleteCredentialsTested) + yield return null; + // Delete Document Log.Debug("TestDiscovery.RunTest()", "Attempting to delete document {0}", _createdDocumentID); if (!_discovery.DeleteDocument(OnDeleteDocument, OnFail, _environmentId, _createdCollectionID, _createdDocumentID)) @@ -310,7 +354,14 @@ private IEnumerator Delay(float waitTime) private void OnGetEnvironments(GetEnvironmentsResponse resp, Dictionary customData) { Log.Debug("TestDiscovery.OnGetEnvironments()", "Discovery - GetEnvironments Response: {0}", customData["json"].ToString()); - _environmentId = resp.environments[0].environment_id; + foreach (var environment in resp.environments) + { + if (environment.read_only == false) + { + Log.Debug("TestDiscovery.OnGetEnvironments()", "setting environment to {0}", environment.environment_id); + _environmentId = environment.environment_id; + } + } Test(resp != null); _getEnvironmentsTested = true; } @@ -442,11 +493,35 @@ private void OnQuery(QueryResponse resp, Dictionary customData) private void OnDeleteUserData(object response, Dictionary customData) { - Log.Debug("ExampleAssistant.OnDeleteUserData()", "Response: {0}", customData["json"].ToString()); + Log.Debug("TestDiscovery.OnDeleteUserData()", "Response: {0}", customData["json"].ToString()); Test(response != null); _deleteUserDataTested = true; } + private void OnListCredentials(CredentialsList response, Dictionary customData) + { + Log.Debug("TestDiscovery.OnListCredentials()", "Response: {0}", customData["json"].ToString()); + _listCredentialsTested = true; + } + private void OnCreateCredentials(SourceCredentials response, Dictionary customData) + { + Log.Debug("TestDiscovery.OnCreateCredentials()", "Response: {0}", customData["json"].ToString()); + _createdCredentialId = response.CredentialId; + _createCredentialsTested = true; + } + + private void OnGetCredential(SourceCredentials response, Dictionary customData) + { + Log.Debug("TestDiscovery.OnGetCredential()", "Response: {0}", customData["json"].ToString()); + _getCredentialTested = true; + } + + private void OnDeleteCredentials(DeleteCredentials response, Dictionary customData) + { + Log.Debug("TestDiscovery.OnDeleteCredentials()", "Response: {0}", customData["json"].ToString()); + _deleteCredentialsTested = true; + } + private void OnFail(RESTConnector.Error error, Dictionary customData) { Log.Error("TestDiscovery.OnFail()", "Error received: {0}", error.ToString()); diff --git a/Scripts/UnitTests/TestLanguageTranslatorV3RCApikeyAsBasicauth.cs b/Scripts/UnitTests/TestLanguageTranslatorV3RCApikeyAsBasicauth.cs new file mode 100644 index 000000000..e23fb10dc --- /dev/null +++ b/Scripts/UnitTests/TestLanguageTranslatorV3RCApikeyAsBasicauth.cs @@ -0,0 +1,156 @@ +/** +* Copyright 2015 IBM Corp. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +using FullSerializer; +using IBM.Watson.DeveloperCloud.Connection; +using IBM.Watson.DeveloperCloud.Logging; +using IBM.Watson.DeveloperCloud.Services.LanguageTranslator.v3; +using IBM.Watson.DeveloperCloud.Utilities; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using UnityEngine; + +namespace IBM.Watson.DeveloperCloud.UnitTests +{ + public class TestLanguageTranslatorV3ApikeyAsBasicauth : UnitTest + { + private string _pharseToTranslate = "Hello, welcome to IBM Watson!"; + private fsSerializer _serializer = new fsSerializer(); + + private LanguageTranslator _languageTranslator; + + private bool _getTranslationTested = false; + private bool _getModelsTested = false; + private bool _getModelTested = false; + private bool _identifyTested = false; + private bool _getLanguagesTested = false; + private string _versionDate = "2018-05-01"; + + public override IEnumerator RunTest() + { + LogSystem.InstallDefaultReactors(); + + VcapCredentials vcapCredentials = new VcapCredentials(); + fsData data = null; + + string result = null; + string credentialsFilepath = "../sdk-credentials/credentials.json"; + + // Load credentials file if it exists. If it doesn't exist, don't run the tests. + if (File.Exists(credentialsFilepath)) + result = File.ReadAllText(credentialsFilepath); + else + yield break; + + // Add in a parent object because Unity does not like to deserialize root level collection types. + result = Utility.AddTopLevelObjectToJson(result, "VCAP_SERVICES"); + + // Convert json to fsResult + fsResult r = fsJsonParser.Parse(result, out data); + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + + // Convert fsResult to VcapCredentials + object obj = vcapCredentials; + r = _serializer.TryDeserialize(data, obj.GetType(), ref obj); + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + + // Set credentials from imported credntials + Credential credential = vcapCredentials.GetCredentialByname("language-translator-v3-sdk-rc-wdc")[0].Credentials; + _url = credential.Url.ToString(); + + Credentials credentials = new Credentials("apikey", credential.IamApikey, credential.Url); + + // Wait for tokendata + while (!credentials.HasIamTokenData()) + yield return null; + + _languageTranslator = new LanguageTranslator(_versionDate, credentials); + + if (!_languageTranslator.GetTranslation(OnGetTranslation, OnFail, _pharseToTranslate, "en", "es")) + Log.Debug("TestLanguageTranslator.GetTranslation()", "Failed to translate."); + while (!_getTranslationTested) + yield return null; + + if (!_languageTranslator.GetModels(OnGetModels, OnFail)) + Log.Debug("TestLanguageTranslator.GetModels()", "Failed to get models."); + while (!_getModelsTested) + yield return null; + + if (!_languageTranslator.GetModel(OnGetModel, OnFail, "en-es")) + Log.Debug("TestLanguageTranslator.GetModel()", "Failed to get model."); + while (!_getModelTested) + yield return null; + + if (!_languageTranslator.Identify(OnIdentify, OnFail, _pharseToTranslate)) + Log.Debug("TestLanguageTranslator.Identify()", "Failed to identify language."); + while (!_identifyTested) + yield return null; + + if (!_languageTranslator.GetLanguages(OnGetLanguages, OnFail)) + Log.Debug("TestLanguageTranslator.GetLanguages()", "Failed to get languages."); + while (!_getLanguagesTested) + yield return null; + + Log.Debug("TestLanguageTranslator.RunTest()", "Language Translator examples complete."); + + yield break; + } + + private void OnGetModels(TranslationModels models, Dictionary customData) + { + Log.Debug("TestLanguageTranslator.OnGetModels()", "Language Translator - Get models response: {0}", customData["json"].ToString()); + Test(models != null); + _getModelsTested = true; + } + + private void OnGetModel(TranslationModel model, Dictionary customData) + { + Log.Debug("TestLanguageTranslator.OnGetModel()", "Language Translator - Get model response: {0}", customData["json"].ToString()); + Test(model != null); + _getModelTested = true; + } + + private void OnGetTranslation(Translations translation, Dictionary customData) + { + Log.Debug("TestLanguageTranslator.OnGetTranslation()", "Langauge Translator - Translate Response: {0}", customData["json"].ToString()); + Test(translation != null); + _getTranslationTested = true; + } + + private void OnIdentify(IdentifiedLanguages identifiedLanguages, Dictionary customData) + { + Log.Debug("TestLanguageTranslator.OnIdentify()", "Language Translator - Identify response: {0}", customData["json"].ToString()); + Test(identifiedLanguages != null); + _identifyTested = true; + } + + private void OnGetLanguages(Languages languages, Dictionary customData) + { + Log.Debug("TestLanguageTranslator.OnGetLanguages()", "Language Translator - Get languages response: {0}", customData["json"].ToString()); + Test(languages != null); + _getLanguagesTested = true; + } + + private void OnFail(RESTConnector.Error error, Dictionary customData) + { + Log.Error("TestLanguageTranslator.OnFail()", "Error received: {0}", error.ToString()); + } + } +} diff --git a/Scripts/UnitTests/TestLanguageTranslatorV3RCApikeyAsBasicauth.cs.meta b/Scripts/UnitTests/TestLanguageTranslatorV3RCApikeyAsBasicauth.cs.meta new file mode 100644 index 000000000..143e94599 --- /dev/null +++ b/Scripts/UnitTests/TestLanguageTranslatorV3RCApikeyAsBasicauth.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5da539e1b77372f4da36311498d615ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Utilities/Constants.cs b/Scripts/Utilities/Constants.cs index 7b6556390..f45f807bb 100644 --- a/Scripts/Utilities/Constants.cs +++ b/Scripts/Utilities/Constants.cs @@ -47,7 +47,7 @@ public static class Path public static class String { /// - public const string Version = "watson-apis-unity-sdk/2.4.2"; + public const string Version = "watson-apis-unity-sdk/2.5.0"; /// public const string DebugDispalyQuality = "Quality: {0}"; /// @@ -69,7 +69,7 @@ public static class String /// /// Tracking for onboarding /// - public const string TRACKING_QUERY_PARAM = "cm_sp=WatsonPlatform-WatsonServices-_-OnPageNavLink-IBMWatson_SDKs-_-Unity"; + public const string TRACKING_QUERY_PARAM = "target=/developer/watson&cm_sp=WatsonPlatform-WatsonServices-_-OnPageNavLink-IBMWatson_SDKs-_-Unity"; } /// diff --git a/Scripts/Utilities/Credentials.cs b/Scripts/Utilities/Credentials.cs index 3e5e27d05..48d3fa065 100644 --- a/Scripts/Utilities/Credentials.cs +++ b/Scripts/Utilities/Credentials.cs @@ -35,6 +35,7 @@ public class Credentials private IamTokenData _iamTokenData; private string _iamApiKey; private string _userAcessToken; + private const string APIKEY_AS_USERNAME = "apikey"; #endregion #region Public Fields @@ -118,10 +119,7 @@ public Credentials(string url = null) /// The service endpoint. public Credentials(string username, string password, string url = null) { - Username = username; - Password = password; - if(!string.IsNullOrEmpty(url)) - Url = url; + SetCredentials(username, password, url); } /// @@ -141,7 +139,35 @@ public Credentials(string apiKey, string url = null) /// public Credentials(TokenOptions iamTokenOptions, string serviceUrl = null) { - if(!string.IsNullOrEmpty(serviceUrl)) + SetCredentials(iamTokenOptions, serviceUrl); + } + #endregion + + #region SetCredentials + private void SetCredentials(string username, string password, string url = null) + { + if (username == APIKEY_AS_USERNAME) + { + TokenOptions tokenOptions = new TokenOptions() + { + IamApiKey = password + }; + + SetCredentials(tokenOptions, url); + } + else + { + Username = username; + Password = password; + } + + if (!string.IsNullOrEmpty(url)) + Url = url; + } + + private void SetCredentials(TokenOptions iamTokenOptions, string serviceUrl = null) + { + if (!string.IsNullOrEmpty(serviceUrl)) Url = serviceUrl; _iamUrl = !string.IsNullOrEmpty(iamTokenOptions.IamUrl) ? iamTokenOptions.IamUrl : "https://iam.bluemix.net/identity/token"; _iamTokenData = new IamTokenData(); @@ -155,7 +181,7 @@ public Credentials(TokenOptions iamTokenOptions, string serviceUrl = null) GetToken(); } #endregion - + #region Get Token /// /// This function sends an access token back through a callback. The source of the token @@ -536,9 +562,9 @@ public class VcapCredentials public List GetCredentialByname(string name) { List credentialsList = new List(); - foreach(KeyValuePair> kvp in VCAP_SERVICES) + foreach (KeyValuePair> kvp in VCAP_SERVICES) { - foreach(VcapCredential credential in kvp.Value) + foreach (VcapCredential credential in kvp.Value) { if (credential.Name == name) credentialsList.Add(credential); diff --git a/Scripts/Utilities/Utility.cs b/Scripts/Utilities/Utility.cs index ffeca1c93..a14216396 100644 --- a/Scripts/Utilities/Utility.cs +++ b/Scripts/Utilities/Utility.cs @@ -1178,6 +1178,7 @@ public static string GetExtension(string mimeType) /// True if the call succeeds. public static bool GetWatsonToken(OnGetWatsonToken callback, string serviceEndpoint, string username, string password, string tokenName = "") { + Log.Warning("Utility.GetWatsonToken()", "Authenticating with the `X-Watson-Authorization-Token` header is deprecated. The token continues to work with Cloud Foundry services, but is not supported for services that use Identity and Access Management (IAM) authentication. For details see [Authenticating with IAM tokens](https://console.bluemix.net/docs/services/watson/getting-started-iam.html#iam) or the README in the IBM Watson SDK you use."); if (callback == null) throw new ArgumentNullException("callback"); if (string.IsNullOrEmpty(serviceEndpoint)) diff --git a/Travis/installSDK.sh b/Travis/installSDK.sh index e485a3041..187a42e13 100644 --- a/Travis/installSDK.sh +++ b/Travis/installSDK.sh @@ -12,7 +12,7 @@ else fi -echo "Attempting to install Watson Developer Cloud Unity SDK into the test project..." +echo "Attempting to install IBM Watson SDK for Unity into the test project..." mkdir -p Travis/UnityTestProject/Assets/Watson/ git clone https://github.com/watson-developer-cloud/unity-sdk.git Travis/UnityTestProject/Assets/Watson/ #git clone -b feature-97-integrationTesting --single-branch https://github.com/watson-developer-cloud/unity-sdk.git Travis/UnityTestProject/Assets/Watson/