diff --git a/.travis.yml b/.travis.yml index 27743b400..9f8f23be3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,5 +17,5 @@ before_script: script: - ./Travis/createProject.sh - ./Travis/installSDK.sh -- ./Travis/runTests.sh -- ./Travis/build.sh +# - ./Travis/runTests.sh +# - ./Travis/build.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 216ef2658..faead64c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ Change Log ========== +## Version 2.3.0 +_2018-05-31_ +* New: IAM support in Visual Recognition. +* Fixed: Use non-region specific url for IamUrl. +* Fixed: Authenticating with apikey sets the service url to `gateway-a`. +* New: Abstract `DeleteUserData()` for Speech to Text and Text to Speech. + ## Version 2.2.3 _2018-05-21_ * New: Abstract `DeleteUserData()` for Assistant, Conversation and Discovery ([#387](https://github.com/watson-developer-cloud/unity-sdk/pull/387)). diff --git a/Doxyfile b/Doxyfile index 0282a9592..5a6a0bd0d 100644 --- a/Doxyfile +++ b/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "Watson Developer Cloud Unity SDK" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 2.2.3 +PROJECT_NUMBER = 2.3.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/Examples/ServiceExamples/Scripts/ExampleVisualRecognition.cs b/Examples/ServiceExamples/Scripts/ExampleVisualRecognition.cs index 880cfc818..724c15f3a 100644 --- a/Examples/ServiceExamples/Scripts/ExampleVisualRecognition.cs +++ b/Examples/ServiceExamples/Scripts/ExampleVisualRecognition.cs @@ -15,9 +15,9 @@ * */ // Uncomment to train a new classifier -//#define TRAIN_CLASSIFIER +#define TRAIN_CLASSIFIER // Uncommnent to delete the trained classifier -//#define DELETE_TRAINED_CLASSIFIER +#define DELETE_TRAINED_CLASSIFIER using UnityEngine; using System.Collections; @@ -33,8 +33,12 @@ public class ExampleVisualRecognition : MonoBehaviour [SerializeField] private string _apikey; [SerializeField] + private string _iamApikey; + [SerializeField] private string _url; [SerializeField] + private string _iamUrl; + [SerializeField] private string _versionDate; #endregion @@ -42,7 +46,9 @@ public class ExampleVisualRecognition : MonoBehaviour private string _classifierID = ""; private string _imageURL = "https://upload.wikimedia.org/wikipedia/commons/e/e9/Official_portrait_of_Barack_Obama.jpg"; +#if TRAIN_CLASSIFIER private string _coreMLDownloadPath = ""; +#endif #if DELETE_TRAINED_CLASSIFIER private string _classifierToDelete; @@ -61,14 +67,41 @@ public class ExampleVisualRecognition : MonoBehaviour private bool _detectFacesGetTested = false; private bool _detectFacesPostTested = false; private bool _getCoreMLModelTested = false; + private bool _isClassifierReady = false; void Start() { LogSystem.InstallDefaultReactors(); - // Create credential and instantiate service - Credentials credentials = new Credentials(_apikey, _url); + Runnable.Run(CreateService()); + } + + private IEnumerator CreateService() + { + Credentials credentials = null; + if (!string.IsNullOrEmpty(_apikey)) + { + // Authenticate using apikey + credentials = new Credentials(_apikey, _url); + } + else if (!string.IsNullOrEmpty(_iamApikey)) + { + // Authenticate using iamApikey + TokenOptions tokenOptions = new TokenOptions() + { + IamApiKey = _iamApikey, + IamUrl = _iamUrl + }; + + credentials = new Credentials(tokenOptions, _url); + + // Wait for tokendata + while (!credentials.HasIamTokenData()) + yield return null; + } + + // Create credential and instantiate service _visualRecognition = new VisualRecognition(credentials); _visualRecognition.VersionDate = _versionDate; @@ -86,25 +119,25 @@ private IEnumerator Examples() yield return null; #if TRAIN_CLASSIFIER - // Train classifier - Log.Debug("ExampleVisualRecognition.Examples()", "Attempting to train classifier"); - string positiveExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/giraffe_positive_examples.zip"; - string negativeExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/negative_examples.zip"; - Dictionary positiveExamples = new Dictionary(); - positiveExamples.Add("giraffe", positiveExamplesPath); - if (!_visualRecognition.TrainClassifier(OnTrainClassifier, OnFail, "unity-test-classifier-example", positiveExamples, negativeExamplesPath)) - Log.Debug("ExampleVisualRecognition.TrainClassifier()", "Failed to train classifier!"); - - while (!_trainClassifierTested) - yield return null; - - // Find classifier by ID - Log.Debug("ExampleVisualRecognition.Examples()", "Attempting to find classifier by ID"); - if (!_visualRecognition.GetClassifier(OnGetClassifier, OnFail, _classifierID)) - Log.Debug("ExampleVisualRecognition.GetClassifier()", "Failed to get classifier!"); - - while (!_getClassifierTested) - yield return null; + // Train classifier + Log.Debug("ExampleVisualRecognition.Examples()", "Attempting to train classifier"); + string positiveExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/giraffe_positive_examples.zip"; + string negativeExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/negative_examples.zip"; + Dictionary positiveExamples = new Dictionary(); + positiveExamples.Add("giraffe", positiveExamplesPath); + if (!_visualRecognition.TrainClassifier(OnTrainClassifier, OnFail, "unity-test-classifier-example", positiveExamples, negativeExamplesPath)) + Log.Debug("ExampleVisualRecognition.TrainClassifier()", "Failed to train classifier!"); + + while (!_trainClassifierTested) + yield return null; + + // Find classifier by ID + Log.Debug("ExampleVisualRecognition.Examples()", "Attempting to find classifier by ID"); + if (!_visualRecognition.GetClassifier(OnGetClassifier, OnFail, _classifierID)) + Log.Debug("ExampleVisualRecognition.GetClassifier()", "Failed to get classifier!"); + + while (!_getClassifierTested) + yield return null; #endif // Classify get @@ -144,34 +177,35 @@ private IEnumerator Examples() yield return null; #if DELETE_TRAINED_CLASSIFIER - #region Delay - Runnable.Run(Delay(_delayTime)); - while (_isWaitingForDelay) - yield return null; - #endregion - - // Delete classifier by ID - Log.Debug("ExampleVisualRecognition.Examples()", "Attempting to delete classifier"); - if (!_visualRecognition.DeleteClassifier(OnDeleteClassifier, OnFail, _classifierToDelete)) - Log.Debug("ExampleVisualRecognition.DeleteClassifier()", "Failed to delete classifier!"); - - while (!_deleteClassifierTested) - yield return null; -#endif + Runnable.Run(IsClassifierReady(_classifierToDelete)); + while (!_isClassifierReady) + yield return null; - _visualRecognition.DownloadCoreMLModel(_classifierID, _coreMLDownloadPath); + // Download Core ML Model + Log.Debug("ExampleVisualRecognition.RunTest()", "Attempting to get Core ML Model"); + if (!_visualRecognition.GetCoreMLModel(OnGetCoreMLModel, OnFail, _classifierID)) + Log.Debug("TestVisualRecognition.GetCoreMLModel()", "Failed to get core ml model!"); while (!_getCoreMLModelTested) yield return null; + // Delete classifier by ID + Log.Debug("ExampleVisualRecognition.Examples()", "Attempting to delete classifier"); + if (!_visualRecognition.DeleteClassifier(OnDeleteClassifier, OnFail, _classifierToDelete)) + Log.Debug("ExampleVisualRecognition.DeleteClassifier()", "Failed to delete classifier!"); + + while (!_deleteClassifierTested) + yield return null; +#endif + Log.Debug("ExampleVisualRecognition.Examples()", "Visual Recogition tests complete"); } -private void OnGetClassifiers(ClassifiersBrief classifiers, Dictionary customData) -{ - Log.Debug("ExampleVisualRecognition.OnGetClassifiers()", "VisualRecognition - GetClassifiers Response: {0}", customData["json"].ToString()); + private void OnGetClassifiers(ClassifiersBrief classifiers, Dictionary customData) + { + Log.Debug("ExampleVisualRecognition.OnGetClassifiers()", "VisualRecognition - GetClassifiers Response: {0}", customData["json"].ToString()); - _getClassifiersTested = true; -} + _getClassifiersTested = true; + } #if DELETE_TRAINED_CLASSIFIER private void OnGetClassifier(ClassifierVerbose classifier, Dictionary customData) @@ -202,51 +236,79 @@ private void OnTrainClassifier(ClassifierVerbose classifier, Dictionary customData) -{ - Log.Debug("ExampleVisualRecognition.OnClassifyGet()", "{0}", customData["json"].ToString()); - _classifyGetTested = true; + private void OnClassifyGet(ClassifiedImages classify, Dictionary customData) + { + Log.Debug("ExampleVisualRecognition.OnClassifyGet()", "{0}", customData["json"].ToString()); + _classifyGetTested = true; -} + } -private void OnClassifyPost(ClassifiedImages classify, Dictionary customData) -{ - Log.Debug("ExampleVisualRecognition.OnClassifyPost()", "{0}", customData["json"].ToString()); - _classifyPostTested = true; -} + private void OnClassifyPost(ClassifiedImages classify, Dictionary customData) + { + Log.Debug("ExampleVisualRecognition.OnClassifyPost()", "{0}", customData["json"].ToString()); + _classifyPostTested = true; + } -private void OnDetectFacesGet(DetectedFaces multipleImages, Dictionary customData) -{ - Log.Debug("ExampleVisualRecognition.OnDetectFacesGet()", "{0}", customData["json"].ToString()); - _detectFacesGetTested = true; -} + private void OnDetectFacesGet(DetectedFaces multipleImages, Dictionary customData) + { + Log.Debug("ExampleVisualRecognition.OnDetectFacesGet()", "{0}", customData["json"].ToString()); + _detectFacesGetTested = true; + } -private void OnDetectFacesPost(DetectedFaces multipleImages, Dictionary customData) -{ - Log.Debug("ExampleVisualRecognition.OnDetectFacesPost()", "{0}", customData["json"].ToString()); - _detectFacesPostTested = true; -} + private void OnDetectFacesPost(DetectedFaces multipleImages, Dictionary customData) + { + Log.Debug("ExampleVisualRecognition.OnDetectFacesPost()", "{0}", customData["json"].ToString()); + _detectFacesPostTested = true; + } + +#if DELETE_TRAINED_CLASSIFIER + private void OnGetCoreMLModel(byte[] resp, Dictionary customData) + { + Log.Debug("ExampleVisualRecognition.OnGetCoreMLModel()", "SUCCESS!"); + _getCoreMLModelTested = true; + } +#endif -#region Delay -// Introducing a delay because of a known issue with Visual Recognition where newly created classifiers -// will disappear without being deleted if a delete is attempted less than ~10 seconds after creation. #if DELETE_TRAINED_CLASSIFIER - private float _delayTime = 15f; - private bool _isWaitingForDelay = false; + #region Is Classifier Ready + // Checking if classifier is ready before deletion due to a known bug in the Visual Recognition service where + // if a classifier is deleted before it is `ready` or `failed` the classifier will still exist in object storage + // but will be inaccessable to the user. + private IEnumerator IsClassifierReady(string classifierId) + { + Log.Debug("TestVisualRecognition.IsClassifierReady()", "Checking if classifier is ready in 15 seconds..."); + + yield return new WaitForSeconds(15f); + + Dictionary customData = new Dictionary(); + customData.Add("classifierId", classifierId); + if (!_visualRecognition.GetClassifier(OnCheckIfClassifierIsReady, OnFailCheckingIfClassifierIsReady, classifierId)) + IsClassifierReady(classifierId); + } + + private void OnCheckIfClassifierIsReady(ClassifierVerbose response, Dictionary customData) + { + Log.Debug("TestVisualRecognition.IsClassifierReady()", "Classifier status is {0}", response.status); + if (response.status == "ready" || response.status == "failed") + { + _isClassifierReady = true; + } + else + { - private IEnumerator Delay(float delayTime) + Runnable.Run(IsClassifierReady(response.classifier_id)); + } + } + private void OnFailCheckingIfClassifierIsReady(RESTConnector.Error error, Dictionary customData) { - _isWaitingForDelay = true; - Log.Debug("ExampleVisualRecognition.Delay()", "Delaying for {0} seconds....", delayTime); - yield return new WaitForSeconds(delayTime); - _isWaitingForDelay = false; + IsClassifierReady(_classifierToDelete); } + #endregion #endif -#endregion -private void OnFail(RESTConnector.Error error, Dictionary customData) -{ - Log.Error("ExampleRetrieveAndRank.OnFail()", "Error received: {0}", error.ToString()); -} + private void OnFail(RESTConnector.Error error, Dictionary customData) + { + Log.Error("ExampleRetrieveAndRank.OnFail()", "Error received: {0}", error.ToString()); + } } diff --git a/README.md b/README.md index 37103db9c..1dca32f37 100755 --- a/README.md +++ b/README.md @@ -109,7 +109,9 @@ void IEnumerator TokenExample() // Alternatively you can supply an access token. TokenOptions iamTokenOptions = new TokenOptions() { - IamApiKey = "" + IamApiKey = "", + IamAccessToken = "", + IamUrl = "" }; // Create credentials using the IAM token options diff --git a/Scripts/Services/SpeechToText/v1/SpeechToText.cs b/Scripts/Services/SpeechToText/v1/SpeechToText.cs index 94cf49a77..caa9b04bc 100644 --- a/Scripts/Services/SpeechToText/v1/SpeechToText.cs +++ b/Scripts/Services/SpeechToText/v1/SpeechToText.cs @@ -3614,6 +3614,107 @@ private void OnAddAcousticResourceResp(RESTConnector.Request req, RESTConnector. } #endregion + #region Delete User Data + /// + /// Deletes all data associated with a specified customer ID. The method has no effect if no data is associated with the customer ID. + /// You associate a customer ID with data by passing the X-Watson-Metadata header with a request that passes data. + /// For more information about personal data and customer IDs, see [**Information security**](https://console.bluemix.net/docs/services/discovery/information-security.html). + /// + /// The function that is called when the operation is successful. + /// The function that is called when the operation fails. + /// The customer ID for which all data is to be deleted. + /// object + /// 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. + public bool DeleteUserData(SuccessCallback successCallback, FailCallback failCallback, string customerId, Dictionary customData = null) + { + if (successCallback == null) + throw new ArgumentNullException("successCallback"); + if (failCallback == null) + throw new ArgumentNullException("failCallback"); + if (string.IsNullOrEmpty(customerId)) + throw new ArgumentNullException("customerId"); + + DeleteUserDataRequestObj req = new DeleteUserDataRequestObj(); + 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["customer_id"] = customerId; + req.Delete = true; + + req.OnResponse = OnDeleteUserDataResponse; + + RESTConnector connector = RESTConnector.GetConnector(Credentials, "/v1/user_data"); + if (connector == null) + return false; + + return connector.Send(req); + } + + private class DeleteUserDataRequestObj : 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 OnDeleteUserDataResponse(RESTConnector.Request req, RESTConnector.Response resp) + { + object result = new object(); + fsData data = null; + Dictionary customData = ((DeleteUserDataRequestObj)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("SpeechToText.OnDeleteUserDataResponse()", "Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + if (resp.Success) + { + if (((DeleteUserDataRequestObj)req).SuccessCallback != null) + ((DeleteUserDataRequestObj)req).SuccessCallback(result, customData); + } + else + { + if (((DeleteUserDataRequestObj)req).FailCallback != null) + ((DeleteUserDataRequestObj)req).FailCallback(resp.Error, customData); + } + } + #endregion + #region IWatsonService interface /// public string GetServiceID() diff --git a/Scripts/Services/TextToSpeech/v1/TextToSpeech.cs b/Scripts/Services/TextToSpeech/v1/TextToSpeech.cs index 6b00a2937..4713ae9b7 100755 --- a/Scripts/Services/TextToSpeech/v1/TextToSpeech.cs +++ b/Scripts/Services/TextToSpeech/v1/TextToSpeech.cs @@ -1540,6 +1540,107 @@ private void OnAddCustomizationWordResp(RESTConnector.Request req, RESTConnector } #endregion + #region Delete User Data + /// + /// Deletes all data associated with a specified customer ID. The method has no effect if no data is associated with the customer ID. + /// You associate a customer ID with data by passing the X-Watson-Metadata header with a request that passes data. + /// For more information about personal data and customer IDs, see [**Information security**](https://console.bluemix.net/docs/services/discovery/information-security.html). + /// + /// The function that is called when the operation is successful. + /// The function that is called when the operation fails. + /// The customer ID for which all data is to be deleted. + /// object + /// 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. + public bool DeleteUserData(SuccessCallback successCallback, FailCallback failCallback, string customerId, Dictionary customData = null) + { + if (successCallback == null) + throw new ArgumentNullException("successCallback"); + if (failCallback == null) + throw new ArgumentNullException("failCallback"); + if (string.IsNullOrEmpty(customerId)) + throw new ArgumentNullException("customerId"); + + DeleteUserDataRequestObj req = new DeleteUserDataRequestObj(); + 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["customer_id"] = customerId; + req.Delete = true; + + req.OnResponse = OnDeleteUserDataResponse; + + RESTConnector connector = RESTConnector.GetConnector(Credentials, "/v1/user_data"); + if (connector == null) + return false; + + return connector.Send(req); + } + + private class DeleteUserDataRequestObj : 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 OnDeleteUserDataResponse(RESTConnector.Request req, RESTConnector.Response resp) + { + object result = new object(); + fsData data = null; + Dictionary customData = ((DeleteUserDataRequestObj)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("TextToSpeech.OnDeleteUserDataResponse()", "Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + if (resp.Success) + { + if (((DeleteUserDataRequestObj)req).SuccessCallback != null) + ((DeleteUserDataRequestObj)req).SuccessCallback(result, customData); + } + else + { + if (((DeleteUserDataRequestObj)req).FailCallback != null) + ((DeleteUserDataRequestObj)req).FailCallback(resp.Error, customData); + } + } + #endregion + #region IWatsonService interface /// public string GetServiceID() diff --git a/Scripts/Services/VisualRecognition/v3/VisualRecognition.cs b/Scripts/Services/VisualRecognition/v3/VisualRecognition.cs index e605b904d..9f3eae601 100644 --- a/Scripts/Services/VisualRecognition/v3/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/v3/VisualRecognition.cs @@ -51,10 +51,9 @@ public class VisualRecognition : IWatsonService private const string DetectFacesEndpoint = "/v3/detect_faces"; private const string ClassifiersEndpoint = "/v3/classifiers"; private const string CoreMLEndpoint = "/v3/classifiers/{0}/core_ml_model"; - private string _apikey = null; private fsSerializer _serializer = new fsSerializer(); private Credentials _credentials = null; - private string _url = "https://gateway.watsonplatform.net/tone-analyzer/api"; + private string _url = "https://gateway.watsonplatform.net/visual-recognition/api"; private string _versionDate; #endregion @@ -103,14 +102,17 @@ public Credentials Credentials #region Constructor public VisualRecognition(Credentials credentials) { - if (credentials.HasApiKey()) + if (!credentials.HasApiKey() && !credentials.HasIamApikey() && !credentials.HasIamAuthorizationToken()) { - Credentials = credentials; + throw new WatsonException("Please provide either an apikey, iamApikey or iamAuthorizationToken to authenticate the service."); } - else + + if (string.IsNullOrEmpty(credentials.Url)) { - throw new WatsonException("Please provide an apikey to use the Visual Recognition service. For more information, see https://github.com/watson-developer-cloud/unity-sdk/#configuring-your-service-credentials"); + credentials.Url = Url; } + + Credentials = credentials; } #endregion @@ -148,10 +150,6 @@ public VisualRecognition(Credentials credentials) throw new ArgumentNullException("successCallback"); if (failCallback == null) throw new ArgumentNullException("failCallback"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); if (string.IsNullOrEmpty(url)) throw new ArgumentNullException("url"); @@ -163,16 +161,17 @@ public VisualRecognition(Credentials credentials) 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); } } req.OnResponse = OnClassifyResp; req.Headers["Accepted-Language"] = acceptLanguage; - req.Parameters["api_key"] = _apikey; + if (Credentials.HasApiKey()) + req.Parameters["api_key"] = Credentials.ApiKey; req.Parameters["url"] = url; req.Parameters["version"] = VersionDate; if (owners != default(string[])) @@ -202,10 +201,6 @@ public VisualRecognition(Credentials credentials) throw new ArgumentNullException("successCallback"); if (failCallback == null) throw new ArgumentNullException("failCallback"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); if (string.IsNullOrEmpty(imagePath)) throw new ArgumentNullException("Define an image path to classify!"); @@ -249,10 +244,6 @@ public VisualRecognition(Credentials credentials) throw new ArgumentNullException("successCallback"); if (failCallback == null) throw new ArgumentNullException("failCallback"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); if (imageData == null) throw new ArgumentNullException("Image data is required to classify!"); @@ -263,15 +254,16 @@ public VisualRecognition(Credentials credentials) 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); } } req.OnResponse = OnClassifyResp; - req.Parameters["api_key"] = _apikey; + if (Credentials.HasApiKey()) + req.Parameters["api_key"] = Credentials.ApiKey; req.Parameters["version"] = VersionDate; req.Headers["Content-Type"] = "multipart/form-data"; req.Headers["Accept"] = "application/json"; @@ -371,10 +363,6 @@ public bool DetectFaces(string url, SuccessCallback successCallba throw new ArgumentNullException("failCallback"); if (string.IsNullOrEmpty(url)) throw new ArgumentNullException("url"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); RESTConnector connector = RESTConnector.GetConnector(Credentials, DetectFacesEndpoint); if (connector == null) @@ -384,15 +372,16 @@ public bool DetectFaces(string url, 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); } } req.OnResponse = OnDetectFacesResp; - req.Parameters["api_key"] = _apikey; + if (Credentials.HasApiKey()) + req.Parameters["api_key"] = Credentials.ApiKey; req.Parameters["url"] = url; req.Parameters["version"] = VersionDate; @@ -415,10 +404,6 @@ public bool DetectFaces(SuccessCallback successCallback, FailCall throw new ArgumentNullException("failCallback"); if (string.IsNullOrEmpty(imagePath)) throw new ArgumentNullException("Define an image path to classify!"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); byte[] imageData = null; if (imagePath != default(string)) @@ -455,10 +440,6 @@ public bool DetectFaces(SuccessCallback successCallback, FailCall throw new ArgumentNullException("successCallback"); if (failCallback == null) throw new ArgumentNullException("failCallback"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); if (imageData == null) throw new ArgumentNullException("Image data is required to DetectFaces!"); @@ -469,15 +450,16 @@ public bool DetectFaces(SuccessCallback successCallback, FailCall 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); } } req.OnResponse = OnDetectFacesResp; - req.Parameters["api_key"] = _apikey; + if (Credentials.HasApiKey()) + req.Parameters["api_key"] = Credentials.ApiKey; req.Parameters["version"] = VersionDate; req.Forms = new Dictionary(); req.Forms["images_file"] = new RESTConnector.Form(imageData); @@ -561,10 +543,6 @@ public bool GetClassifiersBrief(SuccessCallback successCallbac throw new ArgumentNullException("successCallback"); if (failCallback == null) throw new ArgumentNullException("failCallback"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); RESTConnector connector = RESTConnector.GetConnector(Credentials, ClassifiersEndpoint); if (connector == null) @@ -574,14 +552,15 @@ public bool GetClassifiersBrief(SuccessCallback successCallbac 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); } } - req.Parameters["api_key"] = _apikey; + if (Credentials.HasApiKey()) + req.Parameters["api_key"] = Credentials.ApiKey; req.Parameters["version"] = VersionDate; req.Timeout = 20.0f * 60.0f; req.OnResponse = OnGetClassifiersBriefResp; @@ -663,10 +642,6 @@ public bool GetClassifiersVerbose(SuccessCallback successCal throw new ArgumentNullException("successCallback"); if (failCallback == null) throw new ArgumentNullException("failCallback"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); RESTConnector connector = RESTConnector.GetConnector(Credentials, ClassifiersEndpoint); if (connector == null) @@ -676,14 +651,15 @@ public bool GetClassifiersVerbose(SuccessCallback successCal 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); } } - req.Parameters["api_key"] = _apikey; + if (Credentials.HasApiKey()) + req.Parameters["api_key"] = Credentials.ApiKey; req.Parameters["version"] = VersionDate; req.Timeout = 20.0f * 60.0f; req.OnResponse = OnGetClassifiersBriefResp; @@ -767,10 +743,6 @@ public bool GetClassifier(SuccessCallback successCallback, Fa throw new ArgumentNullException("failCallback"); if (string.IsNullOrEmpty(classifierId)) throw new ArgumentNullException("classifierId"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); RESTConnector connector = RESTConnector.GetConnector(Credentials, ClassifiersEndpoint + "/" + classifierId); if (connector == null) @@ -780,14 +752,15 @@ public bool GetClassifier(SuccessCallback successCallback, Fa 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); } } - req.Parameters["api_key"] = _apikey; + if (Credentials.HasApiKey()) + req.Parameters["api_key"] = Credentials.ApiKey; req.Parameters["version"] = VersionDate; req.Parameters["verbose"] = true; req.OnResponse = OnGetClassifierResp; @@ -872,10 +845,6 @@ private void OnGetClassifierResp(RESTConnector.Request req, RESTConnector.Respon throw new ArgumentNullException("successCallback"); if (failCallback == null) throw new ArgumentNullException("failCallback"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); if (string.IsNullOrEmpty(classifierName)) throw new ArgumentNullException("ClassifierName"); if (positiveExamples == null) @@ -923,10 +892,6 @@ public bool TrainClassifier(SuccessCallback successCallback, throw new ArgumentNullException("successCallback"); if (failCallback == null) throw new ArgumentNullException("failCallback"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); if (string.IsNullOrEmpty(classifierName)) throw new ArgumentNullException("ClassifierName"); if (positiveExamplesData.Count < 2 && negativeExamplesData == null) @@ -940,15 +905,16 @@ public bool TrainClassifier(SuccessCallback successCallback, 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); } } req.OnResponse = OnTrainClassifierResp; - req.Parameters["api_key"] = _apikey; + if (Credentials.HasApiKey()) + req.Parameters["api_key"] = Credentials.ApiKey; req.Parameters["version"] = VersionDate; req.Forms = new Dictionary(); req.Forms["name"] = new RESTConnector.Form(classifierName); @@ -1008,7 +974,7 @@ private void OnTrainClassifierResp(RESTConnector.Request req, RESTConnector.Resp resp.Success = false; } } - + if (resp.Success) { if (((TrainClassifierReq)req).SuccessCallback != null) @@ -1040,10 +1006,6 @@ private void OnTrainClassifierResp(RESTConnector.Request req, RESTConnector.Resp throw new ArgumentNullException("successCallback"); if (failCallback == null) throw new ArgumentNullException("failCallback"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); if (string.IsNullOrEmpty(classifierName)) throw new ArgumentNullException("ClassifierName"); if (positiveExamples.Count == 0 && string.IsNullOrEmpty(negativeExamplesPath)) @@ -1094,10 +1056,6 @@ public bool UpdateClassifier(SuccessCallback successCallback, throw new ArgumentNullException("successCallback"); if (failCallback == null) throw new ArgumentNullException("failCallback"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); if (string.IsNullOrEmpty(classifierName)) throw new ArgumentNullException("ClassifierName"); if (positiveExamplesData.Count == 0 && negativeExamplesData == null) @@ -1111,15 +1069,16 @@ public bool UpdateClassifier(SuccessCallback successCallback, 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); } } req.OnResponse = OnTrainClassifierResp; - req.Parameters["api_key"] = _apikey; + if (Credentials.HasApiKey()) + req.Parameters["api_key"] = Credentials.ApiKey; req.Parameters["version"] = VersionDate; req.Forms = new Dictionary(); req.Forms["name"] = new RESTConnector.Form(classifierName); @@ -1149,10 +1108,6 @@ public bool DeleteClassifier(SuccessCallback successCallback, FailCallback throw new ArgumentNullException("failCallback"); if (string.IsNullOrEmpty(classifierId)) throw new ArgumentNullException("classifierId"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); RESTConnector connector = RESTConnector.GetConnector(Credentials, ClassifiersEndpoint + "/" + classifierId); if (connector == null) @@ -1162,14 +1117,15 @@ public bool DeleteClassifier(SuccessCallback successCallback, FailCallback 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); } } - req.Parameters["api_key"] = _apikey; + if (Credentials.HasApiKey()) + req.Parameters["api_key"] = Credentials.ApiKey; req.Parameters["version"] = VersionDate; req.OnResponse = OnDeleteClassifierResp; req.Delete = true; @@ -1220,10 +1176,6 @@ public bool GetCoreMLModel(SuccessCallback successCallback, FailCallback throw new ArgumentNullException("successCallback"); if (failCallback == null) throw new ArgumentNullException("failCallback"); - if (string.IsNullOrEmpty(_apikey)) - _apikey = Credentials.ApiKey; - if (string.IsNullOrEmpty(_apikey)) - throw new WatsonException("No API Key was found!"); if (string.IsNullOrEmpty(classifierID)) throw new ArgumentNullException("A classifierID is required for GetCoreMLModel!"); @@ -1231,14 +1183,15 @@ public bool GetCoreMLModel(SuccessCallback successCallback, FailCallback 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); } } - req.Parameters["api_key"] = _apikey; + if (Credentials.HasApiKey()) + req.Parameters["api_key"] = Credentials.ApiKey; req.Parameters["version"] = VersionDate; req.OnResponse = GetCoreMLModelResponse; @@ -1307,6 +1260,109 @@ private void OnDownloadCoreMLModelFail(RESTConnector.Error error, Dictionary + /// Deletes all data associated with a specified customer ID. The method has no effect if no data is associated with the customer ID. + /// You associate a customer ID with data by passing the X-Watson-Metadata header with a request that passes data. + /// For more information about personal data and customer IDs, see [**Information security**](https://console.bluemix.net/docs/services/discovery/information-security.html). + /// + /// The function that is called when the operation is successful. + /// The function that is called when the operation fails. + /// The customer ID for which all data is to be deleted. + /// object + /// 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. + public bool DeleteUserData(SuccessCallback successCallback, FailCallback failCallback, string customerId, Dictionary customData = null) + { + if (successCallback == null) + throw new ArgumentNullException("successCallback"); + if (failCallback == null) + throw new ArgumentNullException("failCallback"); + if (string.IsNullOrEmpty(customerId)) + throw new ArgumentNullException("customerId"); + + DeleteUserDataRequestObj req = new DeleteUserDataRequestObj(); + 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["customer_id"] = customerId; + if (Credentials.HasApiKey()) + req.Parameters["api_key"] = Credentials.ApiKey; + req.Delete = true; + + req.OnResponse = OnDeleteUserDataResponse; + + RESTConnector connector = RESTConnector.GetConnector(Credentials, "/v3/user_data"); + if (connector == null) + return false; + + return connector.Send(req); + } + + private class DeleteUserDataRequestObj : 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 OnDeleteUserDataResponse(RESTConnector.Request req, RESTConnector.Response resp) + { + object result = new object(); + fsData data = null; + Dictionary customData = ((DeleteUserDataRequestObj)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("VisualRecognition.OnDeleteUserDataResponse()", "Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + if (resp.Success) + { + if (((DeleteUserDataRequestObj)req).SuccessCallback != null) + ((DeleteUserDataRequestObj)req).SuccessCallback(result, customData); + } + else + { + if (((DeleteUserDataRequestObj)req).FailCallback != null) + ((DeleteUserDataRequestObj)req).FailCallback(resp.Error, customData); + } + } + #endregion + #region private methods private string GetMimeType(string imagePath) { diff --git a/Scripts/UnitTests/TestAssistant.cs b/Scripts/UnitTests/TestAssistantCF.cs similarity index 99% rename from Scripts/UnitTests/TestAssistant.cs rename to Scripts/UnitTests/TestAssistantCF.cs index 25944048e..778d2594c 100644 --- a/Scripts/UnitTests/TestAssistant.cs +++ b/Scripts/UnitTests/TestAssistantCF.cs @@ -27,7 +27,7 @@ namespace Assets.Watson.Scripts.UnitTests { - class TestAssistant : UnitTest + class TestAssistantCF : UnitTest { private string _username = null; private string _password = null; @@ -35,7 +35,7 @@ class TestAssistant : UnitTest private string _createdWorkspaceId; private Assistant _service; - private string _assistantVersionDate = "2017-05-26"; + private string _assistantVersionDate = "2018-02-16"; private fsSerializer _serializer = new fsSerializer(); @@ -53,7 +53,7 @@ class TestAssistant : UnitTest private static string _createdValue = "untiyuntiyalue"; private static string _createdIntent = "untiyIntent"; private static string _createdIntentDescription = "Intent created by the Unity SDK Assistant example script."; - private static string _createdCounterExampleText = "untiyExample text"; + private static string _createdCounterExampleText = "untiyExampleText"; private static string _createdSynonym = "untiySynonym"; private static string _createdExample = "untiyExample"; private static string _dialogNodeName = "untiyDialognode"; diff --git a/Scripts/UnitTests/TestAssistant.cs.meta b/Scripts/UnitTests/TestAssistantCF.cs.meta similarity index 71% rename from Scripts/UnitTests/TestAssistant.cs.meta rename to Scripts/UnitTests/TestAssistantCF.cs.meta index 25bc128a9..b88a992a8 100644 --- a/Scripts/UnitTests/TestAssistant.cs.meta +++ b/Scripts/UnitTests/TestAssistantCF.cs.meta @@ -1,7 +1,5 @@ fileFormatVersion: 2 -guid: 5958342710cb51e458cf7b06206fe2b6 -timeCreated: 1520383360 -licenseType: Free +guid: ae655d7583b54c34791896dc78358f2d MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Scripts/UnitTests/TestAssistantRC.cs b/Scripts/UnitTests/TestAssistantRC.cs new file mode 100644 index 000000000..acf2fe13b --- /dev/null +++ b/Scripts/UnitTests/TestAssistantRC.cs @@ -0,0 +1,798 @@ +/** +* 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. +* +*/ +// Uncomment to test RC +//#define TEST_RC + +using System.Collections; +using System.Collections.Generic; +using IBM.Watson.DeveloperCloud.UnitTests; +using IBM.Watson.DeveloperCloud.Services.Assistant.v1; +using IBM.Watson.DeveloperCloud.Utilities; +using IBM.Watson.DeveloperCloud.Logging; +using FullSerializer; +using IBM.Watson.DeveloperCloud.Connection; +using System.IO; + +namespace Assets.Watson.Scripts.UnitTests +{ +#if TEST_RC + class TestAssistantRC : UnitTest + { + private string _username = null; + private string _password = null; + private string _workspaceId = null; + private string _createdWorkspaceId; + + private Assistant _service; + private string _assistantVersionDate = "2018-02-16"; + + private fsSerializer _serializer = new fsSerializer(); + + private string _inputString = "Hello"; + private string _conversationString0 = "unlock the door"; + private string _conversationString1 = "turn on the ac"; + private string _conversationString2 = "turn down the radio"; + private static string _lastIntent = null; + + private static string _createdWorkspaceName = "unity-sdk-example-workspace-delete"; + private static string _createdWorkspaceDescription = "A Workspace created by the Unity SDK Assistant example script. Please delete this."; + private static string _createdWorkspaceLanguage = "en"; + private static string _createdEntity = "untiyEntity"; + private static string _createdEntityDescription = "Entity created by the Unity SDK Assistant example script."; + private static string _createdValue = "untiyuntiyalue"; + private static string _createdIntent = "untiyIntent"; + private static string _createdIntentDescription = "Intent created by the Unity SDK Assistant example script."; + private static string _createdCounterExampleText = "untiyExample text"; + private static string _createdSynonym = "untiySynonym"; + private static string _createdExample = "untiyExample"; + private static string _dialogNodeName = "untiyDialognode"; + private static string _dialogNodeDesc = "Unity SDK Integration test dialog node"; + private static Dictionary _context = null; + + private bool _listWorkspacesTested = false; + private bool _createWorkspaceTested = false; + private bool _getWorkspaceTested = false; + private bool _updateWorkspaceTested = false; + private bool _messageTested = false; + private bool _listIntentsTested = false; + private bool _createIntentTested = false; + private bool _getIntentTested = false; + private bool _updateIntentTested = false; + private bool _listExamplesTested = false; + private bool _createExampleTested = false; + private bool _getExampleTested = false; + private bool _updateExampleTested = false; + private bool _listEntitiesTested = false; + private bool _createEntityTested = false; + private bool _getEntityTested = false; + private bool _updateEntityTested = false; + private bool _listValuesTested = false; + private bool _createValueTested = false; + private bool _getValueTested = false; + private bool _updateValueTested = false; + private bool _listSynonymsTested = false; + private bool _createSynonymTested = false; + private bool _getSynonymTested = false; + private bool _updateSynonymTested = false; + private bool _listDialogNodesTested = false; + private bool _createDialogNodeTested = false; + private bool _getDialogNodeTested = false; + private bool _updateDialogNodeTested = false; + private bool _listLogsInWorkspaceTested = false; + private bool _listAllLogsTested = false; + private bool _listCounterexamplesTested = false; + private bool _createCounterexampleTested = false; + private bool _getCounterexampleTested = false; + private bool _updateCounterexampleTested = false; + private bool _deleteCounterexampleTested = false; + private bool _deleteDialogNodeTested = false; + private bool _deleteSynonymTested = false; + private bool _deleteValueTested = false; + private bool _deleteEntityTested = false; + private bool _deleteExampleTested = false; + private bool _deleteIntentTested = false; + private bool _deleteWorkspaceTested = false; + private bool _deleteUserDataTested = false; + + private string _unitySdkTestCustomerID = "unity-sdk-test-customer-id"; + + 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("assistant-sdk-iam")[0].Credentials; + // Create credential and instantiate service + TokenOptions tokenOptions = new TokenOptions() + { + IamApiKey = credential.IamApikey, + IamUrl = "https://iam.stage1.bluemix.net/identity/token" + }; + + Credentials credentials = new Credentials(tokenOptions, credential.Url); + _workspaceId = credential.WorkspaceId.ToString(); + + // Wait for tokendata + while (!credentials.HasIamTokenData()) + yield return null; + + _service = new Assistant(credentials); + _service.VersionDate = _assistantVersionDate; + + // List Workspaces + _service.ListWorkspaces(OnListWorkspaces, OnFail); + while (!_listWorkspacesTested) + yield return null; + // Create Workspace + CreateWorkspace workspace = new CreateWorkspace() + { + Name = _createdWorkspaceName, + Description = _createdWorkspaceDescription, + Language = _createdWorkspaceLanguage, + LearningOptOut = true + }; + _service.CreateWorkspace(OnCreateWorkspace, OnFail, workspace); + while (!_createWorkspaceTested) + yield return null; + // Get Workspace + _service.GetWorkspace(OnGetWorkspace, OnFail, _createdWorkspaceId); + while (!_getWorkspaceTested) + yield return null; + // Update Workspace + UpdateWorkspace updateWorkspace = new UpdateWorkspace() + { + Name = _createdWorkspaceName + "-updated", + Description = _createdWorkspaceDescription + "-updated", + Language = _createdWorkspaceLanguage + }; + _service.UpdateWorkspace(OnUpdateWorkspace, OnFail, _createdWorkspaceId, updateWorkspace); + while (!_updateWorkspaceTested) + yield return null; + + // Message with customerID + // Create customData object + Dictionary customData = new Dictionary(); + // Create a dictionary of custom headers + Dictionary customHeaders = new Dictionary(); + // Add to the header dictionary + customHeaders.Add("X-Watson-Metadata", "customer_id=" + _unitySdkTestCustomerID); + // Add the header dictionary to the custom data object + customData.Add(Constants.String.CUSTOM_REQUEST_HEADERS, customHeaders); + Dictionary input = new Dictionary(); + input.Add("text", _inputString); + MessageRequest messageRequest = new MessageRequest() + { + Input = input + }; + _service.Message(OnMessage, OnFail, _workspaceId, messageRequest, null, customData); + while (!_messageTested) + yield return null; + _messageTested = false; + + input["text"] = _conversationString0; + MessageRequest messageRequest0 = new MessageRequest() + { + Input = input, + Context = _context + }; + _service.Message(OnMessage, OnFail, _workspaceId, messageRequest0); + while (!_messageTested) + yield return null; + _messageTested = false; + + input["text"] = _conversationString1; + MessageRequest messageRequest1 = new MessageRequest() + { + Input = input, + Context = _context + }; + _service.Message(OnMessage, OnFail, _workspaceId, messageRequest1); + while (!_messageTested) + yield return null; + _messageTested = false; + + input["text"] = _conversationString2; + MessageRequest messageRequest2 = new MessageRequest() + { + Input = input, + Context = _context + }; + _service.Message(OnMessage, OnFail, _workspaceId, messageRequest2); + while (!_messageTested) + yield return null; + + // List Intents + _service.ListIntents(OnListIntents, OnFail, _createdWorkspaceId); + while (!_listIntentsTested) + yield return null; + // Create Intent + CreateIntent createIntent = new CreateIntent() + { + Intent = _createdIntent, + Description = _createdIntentDescription + }; + _service.CreateIntent(OnCreateIntent, OnFail, _createdWorkspaceId, createIntent); + while (!_createIntentTested) + yield return null; + // Get Intent + _service.GetIntent(OnGetIntent, OnFail, _createdWorkspaceId, _createdIntent); + while (!_getIntentTested) + yield return null; + // Update Intents + string updatedIntent = _createdIntent + "-updated"; + string updatedIntentDescription = _createdIntentDescription + "-updated"; + UpdateIntent updateIntent = new UpdateIntent() + { + Intent = updatedIntent, + Description = updatedIntentDescription + }; + _service.UpdateIntent(OnUpdateIntent, OnFail, _createdWorkspaceId, _createdIntent, updateIntent); + while (!_updateIntentTested) + yield return null; + + // List Examples + _service.ListExamples(OnListExamples, OnFail, _createdWorkspaceId, updatedIntent); + while (!_listExamplesTested) + yield return null; + // Create Examples + CreateExample createExample = new CreateExample() + { + Text = _createdExample + }; + _service.CreateExample(OnCreateExample, OnFail, _createdWorkspaceId, updatedIntent, createExample); + while (!_createExampleTested) + yield return null; + // Get Example + _service.GetExample(OnGetExample, OnFail, _createdWorkspaceId, updatedIntent, _createdExample); + while (!_getExampleTested) + yield return null; + // Update Examples + string updatedExample = _createdExample + "-updated"; + UpdateExample updateExample = new UpdateExample() + { + Text = updatedExample + }; + _service.UpdateExample(OnUpdateExample, OnFail, _createdWorkspaceId, updatedIntent, _createdExample, updateExample); + while (!_updateExampleTested) + yield return null; + + // List Entities + _service.ListEntities(OnListEntities, OnFail, _createdWorkspaceId); + while (!_listEntitiesTested) + yield return null; + // Create Entities + CreateEntity entity = new CreateEntity() + { + Entity = _createdEntity, + Description = _createdEntityDescription + }; + _service.CreateEntity(OnCreateEntity, OnFail, _createdWorkspaceId, entity); + while (!_createEntityTested) + yield return null; + // Get Entity + _service.GetEntity(OnGetEntity, OnFail, _createdWorkspaceId, _createdEntity); + while (!_getEntityTested) + yield return null; + // Update Entities + string updatedEntity = _createdEntity + "-updated"; + string updatedEntityDescription = _createdEntityDescription + "-updated"; + UpdateEntity updateEntity = new UpdateEntity() + { + Entity = updatedEntity, + Description = updatedEntityDescription + }; + _service.UpdateEntity(OnUpdateEntity, OnFail, _createdWorkspaceId, _createdEntity, updateEntity); + while (!_updateEntityTested) + yield return null; + + // List Values + _service.ListValues(OnListValues, OnFail, _createdWorkspaceId, updatedEntity); + while (!_listValuesTested) + yield return null; + // Create Values + CreateValue value = new CreateValue() + { + Value = _createdValue + }; + _service.CreateValue(OnCreateValue, OnFail, _createdWorkspaceId, updatedEntity, value); + while (!_createValueTested) + yield return null; + // Get Value + _service.GetValue(OnGetValue, OnFail, _createdWorkspaceId, updatedEntity, _createdValue); + while (!_getValueTested) + yield return null; + // Update Values + string updatedValue = _createdValue + "-updated"; + UpdateValue updateValue = new UpdateValue() + { + Value = updatedValue + }; + _service.UpdateValue(OnUpdateValue, OnFail, _createdWorkspaceId, updatedEntity, _createdValue, updateValue); + while (!_updateValueTested) + yield return null; + + // List Synonyms + _service.ListSynonyms(OnListSynonyms, OnFail, _createdWorkspaceId, updatedEntity, updatedValue); + while (!_listSynonymsTested) + yield return null; + // Create Synonyms + CreateSynonym synonym = new CreateSynonym() + { + Synonym = _createdSynonym + }; + _service.CreateSynonym(OnCreateSynonym, OnFail, _createdWorkspaceId, updatedEntity, updatedValue, synonym); + while (!_createSynonymTested) + yield return null; + // Get Synonym + _service.GetSynonym(OnGetSynonym, OnFail, _createdWorkspaceId, updatedEntity, updatedValue, _createdSynonym); + while (!_getSynonymTested) + yield return null; + // Update Synonyms + string updatedSynonym = _createdSynonym + "-updated"; + UpdateSynonym updateSynonym = new UpdateSynonym() + { + Synonym = updatedSynonym + }; + _service.UpdateSynonym(OnUpdateSynonym, OnFail, _createdWorkspaceId, updatedEntity, updatedValue, _createdSynonym, updateSynonym); + while (!_updateSynonymTested) + yield return null; + + // List Dialog Nodes + _service.ListDialogNodes(OnListDialogNodes, OnFail, _createdWorkspaceId); + while (!_listDialogNodesTested) + yield return null; + // Create Dialog Nodes + CreateDialogNode createDialogNode = new CreateDialogNode() + { + DialogNode = _dialogNodeName, + Description = _dialogNodeDesc + }; + _service.CreateDialogNode(OnCreateDialogNode, OnFail, _createdWorkspaceId, createDialogNode); + while (!_createDialogNodeTested) + yield return null; + // Get Dialog Node + _service.GetDialogNode(OnGetDialogNode, OnFail, _createdWorkspaceId, _dialogNodeName); + while (!_getDialogNodeTested) + yield return null; + // Update Dialog Nodes + string updatedDialogNodeName = _dialogNodeName + "_updated"; + string updatedDialogNodeDescription = _dialogNodeDesc + "_updated"; + UpdateDialogNode updateDialogNode = new UpdateDialogNode() + { + DialogNode = updatedDialogNodeName, + Description = updatedDialogNodeDescription + }; + _service.UpdateDialogNode(OnUpdateDialogNode, OnFail, _createdWorkspaceId, _dialogNodeName, updateDialogNode); + while (!_updateDialogNodeTested) + yield return null; + + // List Logs In Workspace + _service.ListLogs(OnListLogs, OnFail, _createdWorkspaceId); + while (!_listLogsInWorkspaceTested) + yield return null; + // List All Logs + var filter = "(language::en,request.context.metadata.deployment::deployment_1)"; + _service.ListAllLogs(OnListAllLogs, OnFail, filter); + while (!_listAllLogsTested) + yield return null; + + // List Counterexamples + _service.ListCounterexamples(OnListCounterexamples, OnFail, _createdWorkspaceId); + while (!_listCounterexamplesTested) + yield return null; + // Create Counterexamples + CreateCounterexample example = new CreateCounterexample() + { + Text = _createdCounterExampleText + }; + _service.CreateCounterexample(OnCreateCounterexample, OnFail, _createdWorkspaceId, example); + while (!_createCounterexampleTested) + yield return null; + // Get Counterexample + _service.GetCounterexample(OnGetCounterexample, OnFail, _createdWorkspaceId, _createdCounterExampleText); + while (!_getCounterexampleTested) + yield return null; + // Update Counterexamples + string updatedCounterExampleText = _createdCounterExampleText + "-updated"; + UpdateCounterexample updateCounterExample = new UpdateCounterexample() + { + Text = updatedCounterExampleText + }; + _service.UpdateCounterexample(OnUpdateCounterexample, OnFail, _createdWorkspaceId, _createdCounterExampleText, updateCounterExample); + while (!_updateCounterexampleTested) + yield return null; + + // Delete Counterexample + _service.DeleteCounterexample(OnDeleteCounterexample, OnFail, _createdWorkspaceId, updatedCounterExampleText); + while (!_deleteCounterexampleTested) + yield return null; + // Delete Dialog Node + _service.DeleteDialogNode(OnDeleteDialogNode, OnFail, _createdWorkspaceId, updatedDialogNodeName); + while (!_deleteDialogNodeTested) + yield return null; + // Delete Synonym + _service.DeleteSynonym(OnDeleteSynonym, OnFail, _createdWorkspaceId, updatedEntity, updatedValue, updatedSynonym); + while (!_deleteSynonymTested) + yield return null; + // Delete Value + _service.DeleteValue(OnDeleteValue, OnFail, _createdWorkspaceId, updatedEntity, updatedValue); + while (!_deleteValueTested) + yield return null; + // Delete Entity + _service.DeleteEntity(OnDeleteEntity, OnFail, _createdWorkspaceId, updatedEntity); + while (!_deleteEntityTested) + yield return null; + // Delete Example + _service.DeleteExample(OnDeleteExample, OnFail, _createdWorkspaceId, updatedIntent, updatedExample); + while (!_deleteExampleTested) + yield return null; + // Delete Intent + _service.DeleteIntent(OnDeleteIntent, OnFail, _createdWorkspaceId, updatedIntent); + while (!_deleteIntentTested) + yield return null; + // Delete Workspace + _service.DeleteWorkspace(OnDeleteWorkspace, OnFail, _createdWorkspaceId); + while (!_deleteWorkspaceTested) + yield return null; + // Delete User Data + _service.DeleteUserData(OnDeleteUserData, OnFail, _unitySdkTestCustomerID); + while (!_deleteUserDataTested) + yield return null; + + Log.Debug("TestAssistant.RunTest()", "Assistant examples complete."); + + yield break; + } + + private void OnDeleteWorkspace(object response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnDeleteWorkspace()", "Response: {0}", customData["json"].ToString()); + _deleteWorkspaceTested = true; + } + + private void OnDeleteIntent(object response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnDeleteIntent()", "Response: {0}", customData["json"].ToString()); + _deleteIntentTested = true; + } + + private void OnDeleteExample(object response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnDeleteExample()", "Response: {0}", customData["json"].ToString()); + _deleteExampleTested = true; + } + + private void OnDeleteEntity(object response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnDeleteEntity()", "Response: {0}", customData["json"].ToString()); + _deleteEntityTested = true; + } + + private void OnDeleteValue(object response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnDeleteValue()", "Response: {0}", customData["json"].ToString()); + _deleteValueTested = true; + } + + private void OnDeleteSynonym(object response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnDeleteSynonym()", "Response: {0}", customData["json"].ToString()); + _deleteSynonymTested = true; + } + + private void OnDeleteDialogNode(object response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnDeleteDialogNode()", "Response: {0}", customData["json"].ToString()); + _deleteDialogNodeTested = true; + } + + private void OnDeleteCounterexample(object response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnDeleteCounterexample()", "Response: {0}", customData["json"].ToString()); + _deleteCounterexampleTested = true; + } + + private void OnDeleteUserData(object response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnDeleteUserData()", "Response: {0}", customData["json"].ToString()); + _deleteUserDataTested = true; + } + + private void OnUpdateCounterexample(Counterexample response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnUpdateCounterexample()", "Response: {0}", customData["json"].ToString()); + _updateCounterexampleTested = true; + } + + private void OnGetCounterexample(Counterexample response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnGetCounterexample()", "Response: {0}", customData["json"].ToString()); + _getCounterexampleTested = true; + } + + private void OnCreateCounterexample(Counterexample response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnCreateCounterexample()", "Response: {0}", customData["json"].ToString()); + _createCounterexampleTested = true; + } + + private void OnListCounterexamples(CounterexampleCollection response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnListCounterexamples()", "Response: {0}", customData["json"].ToString()); + _listCounterexamplesTested = true; + } + + private void OnListAllLogs(LogCollection response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnListAllLogs()", "Response: {0}", customData["json"].ToString()); + _listAllLogsTested = true; + } + + private void OnListLogs(LogCollection response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnListLogs()", "Response: {0}", customData["json"].ToString()); + _listLogsInWorkspaceTested = true; + } + + private void OnUpdateDialogNode(DialogNode response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnUpdateDialogNode()", "Response: {0}", customData["json"].ToString()); + _updateDialogNodeTested = true; + } + + private void OnGetDialogNode(DialogNode response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnGetDialogNode()", "Response: {0}", customData["json"].ToString()); + _getDialogNodeTested = true; + } + + private void OnCreateDialogNode(DialogNode response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnCreateDialogNode()", "Response: {0}", customData["json"].ToString()); + _createDialogNodeTested = true; + } + + private void OnListDialogNodes(DialogNodeCollection response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnListDialogNodes()", "Response: {0}", customData["json"].ToString()); + _listDialogNodesTested = true; + } + + private void OnUpdateSynonym(Synonym response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnUpdateSynonym()", "Response: {0}", customData["json"].ToString()); + _updateSynonymTested = true; + } + + private void OnGetSynonym(Synonym response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnGetSynonym()", "Response: {0}", customData["json"].ToString()); + _getSynonymTested = true; + } + + private void OnCreateSynonym(Synonym response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnCreateSynonym()", "Response: {0}", customData["json"].ToString()); + _createSynonymTested = true; + } + + private void OnListSynonyms(SynonymCollection response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnListSynonyms()", "Response: {0}", customData["json"].ToString()); + _listSynonymsTested = true; + } + + private void OnUpdateValue(Value response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnUpdateValue()", "Response: {0}", customData["json"].ToString()); + _updateValueTested = true; + } + + private void OnGetValue(ValueExport response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnGetValue()", "Response: {0}", customData["json"].ToString()); + _getValueTested = true; + } + + private void OnCreateValue(Value response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnCreateValue()", "Response: {0}", customData["json"].ToString()); + _createValueTested = true; + } + + private void OnListValues(ValueCollection response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnListValues()", "Response: {0}", customData["json"].ToString()); + _listValuesTested = true; + } + + private void OnUpdateEntity(Entity response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnUpdateEntity()", "Response: {0}", customData["json"].ToString()); + _updateEntityTested = true; + } + + private void OnGetEntity(EntityExport response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnGetEntity()", "Response: {0}", customData["json"].ToString()); + _getEntityTested = true; + } + + private void OnCreateEntity(Entity response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnCreateEntity()", "Response: {0}", customData["json"].ToString()); + _createEntityTested = true; + } + + private void OnListEntities(EntityCollection response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnListEntities()", "Response: {0}", customData["json"].ToString()); + _listEntitiesTested = true; + } + + private void OnUpdateExample(Example response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnUpdateExample()", "Response: {0}", customData["json"].ToString()); + _updateExampleTested = true; + } + + private void OnGetExample(Example response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnGetExample()", "Response: {0}", customData["json"].ToString()); + _getExampleTested = true; + } + + private void OnCreateExample(Example response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnCreateExample()", "Response: {0}", customData["json"].ToString()); + _createExampleTested = true; + } + + private void OnListExamples(ExampleCollection response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnListExamples()", "Response: {0}", customData["json"].ToString()); + _listExamplesTested = true; + } + + private void OnUpdateIntent(Intent response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnUpdateIntent()", "Response: {0}", customData["json"].ToString()); + _updateIntentTested = true; + } + + private void OnGetIntent(IntentExport response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnGetIntent()", "Response: {0}", customData["json"].ToString()); + _getIntentTested = true; + } + + private void OnCreateIntent(Intent response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnCreateIntent()", "Response: {0}", customData["json"].ToString()); + _createIntentTested = true; + } + + private void OnListIntents(IntentCollection response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnListIntents()", "Response: {0}", customData["json"].ToString()); + _listIntentsTested = true; + } + + private void OnMessage(object response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnMessage()", "Response: {0}", customData["json"].ToString()); + + // Convert resp to fsdata + fsData fsdata = null; + fsResult r = _serializer.TrySerialize(response.GetType(), response, out fsdata); + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + + // Convert fsdata to MessageResponse + MessageResponse messageResponse = new MessageResponse(); + object obj = messageResponse; + r = _serializer.TryDeserialize(fsdata, obj.GetType(), ref obj); + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + + // Set context for next round of messaging + object tempContext = null; + (response as Dictionary).TryGetValue("context", out tempContext); + + if (tempContext != null) + _context = tempContext as Dictionary; + else + Log.Debug("ExampleConversation.OnMessage()", "Failed to get context"); + + // Get intent + object tempIntentsObj = null; + (response as Dictionary).TryGetValue("intents", out tempIntentsObj); + object tempIntentObj = (tempIntentsObj as List)[0]; + object tempIntent = null; + (tempIntentObj as Dictionary).TryGetValue("intent", out tempIntent); + string intent = tempIntent.ToString(); + + Test(_lastIntent != intent); + _lastIntent = intent; + + //messageResponse.Intents != _lastIntent; + //_lastIntent = messageResponse.Intents; + + _messageTested = true; + } + + private void OnUpdateWorkspace(Workspace response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnUpdateWorkspace()", "Response: {0}", customData["json"].ToString()); + _updateWorkspaceTested = true; + } + + private void OnGetWorkspace(WorkspaceExport response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnGetWorkspace()", "Response: {0}", customData["json"].ToString()); + _getWorkspaceTested = true; + } + + private void OnCreateWorkspace(Workspace response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnCreateWorkspace()", "Response: {0}", customData["json"].ToString()); + _createdWorkspaceId = response.WorkspaceId; + _createWorkspaceTested = true; + } + + private void OnListWorkspaces(WorkspaceCollection response, Dictionary customData) + { + Log.Debug("ExampleAssistant.OnListWorkspaces()", "Response: {0}", customData["json"].ToString()); + _listWorkspacesTested = true; + } + + private void OnFail(RESTConnector.Error error, Dictionary customData) + { + if (customData["json"] != null) + Log.Debug("ExampleAssistant.OnFail()", "Response: {0}", customData["json"].ToString()); + if(error != null) + Log.Error("TestAssistant.OnFail()", "Error received: {0}", error.ToString()); + } + } +#endif +} diff --git a/Scripts/UnitTests/TestVisualRecognition.cs.meta b/Scripts/UnitTests/TestAssistantRC.cs.meta similarity index 69% rename from Scripts/UnitTests/TestVisualRecognition.cs.meta rename to Scripts/UnitTests/TestAssistantRC.cs.meta index 1dee05d31..f01037e95 100644 --- a/Scripts/UnitTests/TestVisualRecognition.cs.meta +++ b/Scripts/UnitTests/TestAssistantRC.cs.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 -guid: 47cec80cb476c4bc280e6aac819e3fc6 -timeCreated: 1464993517 -licenseType: Pro +guid: e357664cc40e09f4b9472f85af2eb83e MonoImporter: + externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 diff --git a/Scripts/UnitTests/TestVisualRecognition.cs b/Scripts/UnitTests/TestVisualRecognitionCF.cs similarity index 93% rename from Scripts/UnitTests/TestVisualRecognition.cs rename to Scripts/UnitTests/TestVisualRecognitionCF.cs index a951242b1..301d4c316 100644 --- a/Scripts/UnitTests/TestVisualRecognition.cs +++ b/Scripts/UnitTests/TestVisualRecognitionCF.cs @@ -16,9 +16,9 @@ */ // Uncomment to train a new classifier -#define TRAIN_CLASSIFIER +//#define TRAIN_CLASSIFIER // Uncommnent to delete the trained classifier -#define DELETE_TRAINED_CLASSIFIER +//#define DELETE_TRAINED_CLASSIFIER using UnityEngine; using System.Collections; @@ -32,13 +32,13 @@ namespace IBM.Watson.DeveloperCloud.UnitTests { - public class TestVisualRecognition : UnitTest + public class TestVisualRecognitionCF : UnitTest { private string _apikey; private fsSerializer _serializer = new fsSerializer(); private VisualRecognition _visualRecognition; - private string _visualRecognitionVersionDate = "2016-05-20"; + private string _visualRecognitionVersionDate = "2018-03-19"; private string _classifierID = ""; private string _imageURL = "https://upload.wikimedia.org/wikipedia/commons/e/e9/Official_portrait_of_Barack_Obama.jpg"; @@ -51,7 +51,7 @@ public class TestVisualRecognition : UnitTest #if TRAIN_CLASSIFIER private bool _trainClassifierTested = false; private bool _getClassifierTested = false; - //private bool _getCoreMLModelTested = false; + private bool _getCoreMLModelTested = false; #endif #if DELETE_TRAINED_CLASSIFIER private bool _deleteClassifierTested = false; @@ -133,13 +133,6 @@ public override IEnumerator RunTest() while (!_getClassifierTested) yield return null; - - //// Download Core ML Model - //Log.Debug("TestVisualRecognition.RunTest()", "Attempting to get Core ML Model"); - //if(!_visualRecognition.GetCoreMLModel(OnGetCoreMLModel, OnFail, _classifierID)) - // Log.Debug("TestVisualRecognition.GetCoreMLModel()", "Failed to get core ml model!"); - //while (!_getCoreMLModelTested) - // yield return null; #endif // Classify get @@ -183,7 +176,14 @@ public override IEnumerator RunTest() while (!_isClassifierReady) yield return null; - // Delete classifier by ID + // Download Core ML Model + Log.Debug("TestVisualRecognition.RunTest()", "Attempting to get Core ML Model"); + if (!_visualRecognition.GetCoreMLModel(OnGetCoreMLModel, OnFail, _classifierID)) + Log.Debug("TestVisualRecognition.GetCoreMLModel()", "Failed to get core ml model!"); + while (!_getCoreMLModelTested) + yield return null; + + // Delete classifier by ID Log.Debug("TestVisualRecognition.RunTest()", "Attempting to delete classifier"); if (!_visualRecognition.DeleteClassifier(OnDeleteClassifier, OnFail, _classifierToDelete)) Log.Debug("TestVisualRecognition.DeleteClassifier()", "Failed to delete classifier!"); @@ -264,14 +264,14 @@ private void OnDetectFacesPost(DetectedFaces multipleImages, Dictionary customData) - //{ - // Test(resp != null); - // _getCoreMLModelTested = true; - //} +#if DELETE_TRAINED_CLASSIFIER + private void OnGetCoreMLModel(byte[] resp, Dictionary customData) + { + Test(resp != null); + _getCoreMLModelTested = true; + } #endif - + #if DELETE_TRAINED_CLASSIFIER #region Is Classifier Ready // Checking if classifier is ready before deletion due to a known bug in the Visual Recognition service where @@ -288,7 +288,7 @@ private IEnumerator IsClassifierReady(string classifierId) if (!_visualRecognition.GetClassifier(OnCheckIfClassifierIsReady, OnFailCheckingIfClassifierIsReady, classifierId)) IsClassifierReady(classifierId); } - + private void OnCheckIfClassifierIsReady(ClassifierVerbose response, Dictionary customData) { Log.Debug("TestVisualRecognition.IsClassifierReady()", "Classifier status is {0}", response.status); diff --git a/Scripts/UnitTests/TestVisualRecognitionCF.cs.meta b/Scripts/UnitTests/TestVisualRecognitionCF.cs.meta new file mode 100644 index 000000000..12a014135 --- /dev/null +++ b/Scripts/UnitTests/TestVisualRecognitionCF.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3aa21c46c3b70a48a9f59ab766b471c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/UnitTests/TestVisualRecognitionRC.cs b/Scripts/UnitTests/TestVisualRecognitionRC.cs new file mode 100644 index 000000000..7bdfee173 --- /dev/null +++ b/Scripts/UnitTests/TestVisualRecognitionRC.cs @@ -0,0 +1,329 @@ +/** +* 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. +* +*/ + +// Uncomment to train a new classifier +//#define TRAIN_CLASSIFIER +// Uncommnent to delete the trained classifier +//#define DELETE_TRAINED_CLASSIFIER +// Uncomment to test RC +//#define TEST_RC + +using UnityEngine; +using System.Collections; +using IBM.Watson.DeveloperCloud.Services.VisualRecognition.v3; +using IBM.Watson.DeveloperCloud.Logging; +using IBM.Watson.DeveloperCloud.Utilities; +using FullSerializer; +using System.IO; +using System.Collections.Generic; +using IBM.Watson.DeveloperCloud.Connection; + +namespace IBM.Watson.DeveloperCloud.UnitTests +{ +#if TEST_RC + public class TestVisualRecognitionRC : UnitTest + { + private fsSerializer _serializer = new fsSerializer(); + + private VisualRecognition _visualRecognition; + private string _visualRecognitionVersionDate = "2018-03-19"; + + private string _classifierID = ""; + private string _imageURL = "https://upload.wikimedia.org/wikipedia/commons/e/e9/Official_portrait_of_Barack_Obama.jpg"; + +#if DELETE_TRAINED_CLASSIFIER + private string _classifierToDelete; +#endif + + private bool _getClassifiersTested = false; +#if TRAIN_CLASSIFIER + private bool _trainClassifierTested = false; + private bool _getClassifierTested = false; + private bool _getCoreMLModelTested = false; +#endif +#if DELETE_TRAINED_CLASSIFIER + private bool _deleteClassifierTested = false; +#endif + private bool _classifyGetTested = false; + private bool _classifyPostTested = false; + private bool _detectFacesGetTested = false; + private bool _detectFacesPostTested = false; + + private bool _isClassifierReady = false; + + 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("visual-recognition-iam-sdk")[0].Credentials; + + // Create credential and instantiate service + TokenOptions tokenOptions = new TokenOptions() + { + IamApiKey = credential.IamApikey, + IamUrl = credential.IamUrl + }; + + Credentials credentials = new Credentials(tokenOptions, credential.Url); + + // Wait for tokendata + while (!credentials.HasIamTokenData()) + yield return null; + + _visualRecognition = new VisualRecognition(credentials); + _visualRecognition.VersionDate = _visualRecognitionVersionDate; + + // Get all classifiers + Log.Debug("TestVisualRecognition.RunTest()", "Attempting to get all classifiers"); + if (!_visualRecognition.GetClassifiersBrief(OnGetClassifiers, OnFail)) + Log.Debug("TestVisualRecognition.GetClassifiers()", "Failed to get all classifiers!"); + + while (!_getClassifiersTested) + yield return null; + +#if TRAIN_CLASSIFIER + _isClassifierReady = false; + // Train classifier + Log.Debug("TestVisualRecognition.RunTest()", "Attempting to train classifier"); + string positiveExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/giraffe_positive_examples.zip"; + string negativeExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/negative_examples.zip"; + Dictionary positiveExamples = new Dictionary(); + positiveExamples.Add("giraffe", positiveExamplesPath); + if (!_visualRecognition.TrainClassifier(OnTrainClassifier, OnFail, "unity-test-classifier-ok-to-delete", positiveExamples, negativeExamplesPath)) + Log.Debug("TestVisualRecognition.TrainClassifier()", "Failed to train classifier!"); + + while (!_trainClassifierTested) + yield return null; + + // Find classifier by ID + Log.Debug("TestVisualRecognition.RunTest()", "Attempting to find classifier by ID"); + if (!_visualRecognition.GetClassifier(OnGetClassifier, OnFail, _classifierID)) + Log.Debug("TestVisualRecognition.GetClassifier()", "Failed to get classifier!"); + + while (!_getClassifierTested) + yield return null; +#endif + + // Classify get + Log.Debug("TestVisualRecognition.RunTest()", "Attempting to get classify via URL"); + if (!_visualRecognition.Classify(_imageURL, OnClassifyGet, OnFail)) + Log.Debug("TestVisualRecognition.Classify()", "Classify image failed!"); + + while (!_classifyGetTested) + yield return null; + + // Classify post image + Log.Debug("TestVisualRecognition.RunTest()", "Attempting to classify via image on file system"); + string imagesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/giraffe_to_classify.jpg"; + string[] owners = { "IBM", "me" }; + string[] classifierIDs = { "default", _classifierID }; + if (!_visualRecognition.Classify(OnClassifyPost, OnFail, imagesPath, owners, classifierIDs, 0.5f)) + Log.Debug("TestVisualRecognition.Classify()", "Classify image failed!"); + + while (!_classifyPostTested) + yield return null; + + // Detect faces get + Log.Debug("TestVisualRecognition.RunTest()", "Attempting to detect faces via URL"); + if (!_visualRecognition.DetectFaces(_imageURL, OnDetectFacesGet, OnFail)) + Log.Debug("TestVisualRecognition.DetectFaces()", "Detect faces failed!"); + + while (!_detectFacesGetTested) + yield return null; + + // Detect faces post image + Log.Debug("TestVisualRecognition.RunTest()", "Attempting to detect faces via image"); + string faceExamplePath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/obama.jpg"; + if (!_visualRecognition.DetectFaces(OnDetectFacesPost, OnFail, faceExamplePath)) + Log.Debug("TestVisualRecognition.DetectFaces()", "Detect faces failed!"); + + while (!_detectFacesPostTested) + yield return null; + +#if DELETE_TRAINED_CLASSIFIER + Runnable.Run(IsClassifierReady(_classifierToDelete)); + while (!_isClassifierReady) + yield return null; + + // Download Core ML Model + Log.Debug("TestVisualRecognition.RunTest()", "Attempting to get Core ML Model"); + if (!_visualRecognition.GetCoreMLModel(OnGetCoreMLModel, OnFail, _classifierID)) + Log.Debug("TestVisualRecognition.GetCoreMLModel()", "Failed to get core ml model!"); + while (!_getCoreMLModelTested) + yield return null; + + // Delete classifier by ID + Log.Debug("TestVisualRecognition.RunTest()", "Attempting to delete classifier"); + if (!_visualRecognition.DeleteClassifier(OnDeleteClassifier, OnFail, _classifierToDelete)) + Log.Debug("TestVisualRecognition.DeleteClassifier()", "Failed to delete classifier!"); + + while (!_deleteClassifierTested) + yield return null; +#endif + + Log.Debug("TestVisualRecognition.RunTest()", "Visual Recogition tests complete"); + yield break; + } + + private void OnGetClassifiers(ClassifiersBrief classifiers, Dictionary customData) + { + Log.Debug("TestVisualRecognition.OnGetClassifiers()", "VisualRecognition - GetClassifiers Response: {0}", customData["json"].ToString()); + Test(classifiers != null); + _getClassifiersTested = true; + } + +#if DELETE_TRAINED_CLASSIFIER + private void OnGetClassifier(ClassifierVerbose classifier, Dictionary customData) + { + Log.Debug("TestVisualRecognition.OnGetClassifier()", "VisualRecognition - GetClassifier Response: {0}", customData["json"].ToString()); + Test(classifier != null); + _getClassifierTested = true; + } +#endif + +#if DELETE_TRAINED_CLASSIFIER + private void OnDeleteClassifier(bool success, Dictionary customData) + { + Log.Debug("TestVisualRecognition.OnDeleteClassifier()", "VisualRecognition - DeleteClassifier Response: {0}", success); + Test(success); + _deleteClassifierTested = true; + } +#endif + +#if TRAIN_CLASSIFIER + private void OnTrainClassifier(ClassifierVerbose classifier, Dictionary customData) + { + Log.Debug("TestVisualRecognition.OnTrainClassifier()", "VisualRecognition - TrainClassifier Response: {0}", customData["json"].ToString()); + +#if DELETE_TRAINED_CLASSIFIER + _classifierToDelete = classifier.classifier_id; +#endif + _classifierID = classifier.classifier_id; + Test(classifier != null); + _trainClassifierTested = true; + } +#endif + + private void OnClassifyGet(ClassifiedImages classify, Dictionary customData) + { + Log.Debug("TestVisualRecognition.OnClassifyGet()", "VisualRecognition - ClassifyGet Response: {0}", customData["json"].ToString()); + Test(classify != null); + _classifyGetTested = true; + + } + + private void OnClassifyPost(ClassifiedImages classify, Dictionary customData) + { + Log.Debug("TestVisualRecognition.OnClassifyPost()", "VisualRecognition - ClassifyPost Response: {0}", customData["json"].ToString()); + Test(classify != null); + _classifyPostTested = true; + } + + private void OnDetectFacesGet(DetectedFaces multipleImages, Dictionary customData) + { + Log.Debug("TestVisualRecognition.OnDetectFacesGet()", "VisualRecognition - DetectFacesGet Response: {0}", customData["json"].ToString()); + Test(multipleImages != null); + _detectFacesGetTested = true; + } + + private void OnDetectFacesPost(DetectedFaces multipleImages, Dictionary customData) + { + Log.Debug("TestVisualRecognition.OnDetectFacesPost()", "VisualRecognition - DetectFacesPost Response: {0}", customData["json"].ToString()); + Test(multipleImages != null); + _detectFacesPostTested = true; + } + +#if DELETE_TRAINED_CLASSIFIER + private void OnGetCoreMLModel(byte[] resp, Dictionary customData) + { + Test(resp != null); + _getCoreMLModelTested = true; + } +#endif + +#if DELETE_TRAINED_CLASSIFIER + #region Is Classifier Ready + // Checking if classifier is ready before deletion due to a known bug in the Visual Recognition service where + // if a classifier is deleted before it is `ready` or `failed` the classifier will still exist in object storage + // but will be inaccessable to the user. + private IEnumerator IsClassifierReady(string classifierId) + { + Log.Debug("TestVisualRecognition.IsClassifierReady()", "Checking if classifier is ready in 15 seconds..."); + + yield return new WaitForSeconds(15f); + + Dictionary customData = new Dictionary(); + customData.Add("classifierId", classifierId); + if (!_visualRecognition.GetClassifier(OnCheckIfClassifierIsReady, OnFailCheckingIfClassifierIsReady, classifierId)) + IsClassifierReady(classifierId); + } + + private void OnCheckIfClassifierIsReady(ClassifierVerbose response, Dictionary customData) + { + Log.Debug("TestVisualRecognition.IsClassifierReady()", "Classifier status is {0}", response.status); + + if (response.status == "ready" || response.status == "failed") + { + _isClassifierReady = true; + } + else + { + + Runnable.Run(IsClassifierReady(response.classifier_id)); + } + } + private void OnFailCheckingIfClassifierIsReady(RESTConnector.Error error, Dictionary customData) + { + IsClassifierReady(_classifierToDelete); + } + #endregion +#endif + + private void OnFail(RESTConnector.Error error, Dictionary customData) + { + Log.Error("TestVisualRecognition.OnFail()", "Error received: {0}", error.ToString()); + } + } +#endif +} diff --git a/Scripts/UnitTests/TestVisualRecognitionRC.cs.meta b/Scripts/UnitTests/TestVisualRecognitionRC.cs.meta new file mode 100644 index 000000000..fbfb5c353 --- /dev/null +++ b/Scripts/UnitTests/TestVisualRecognitionRC.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da9d4e72be4c43140a3232b43d8f4328 +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 dbb81cbda..3ca14e48b 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.2.3"; + public const string Version = "watson-apis-unity-sdk/2.3.0"; /// public const string DebugDispalyQuality = "Quality: {0}"; /// diff --git a/Scripts/Utilities/Credentials.cs b/Scripts/Utilities/Credentials.cs index 8b2b8f6bc..c2aae1d65 100644 --- a/Scripts/Utilities/Credentials.cs +++ b/Scripts/Utilities/Credentials.cs @@ -124,13 +124,14 @@ public Credentials(string username, string password, string url = null) } /// - /// Constructor that takes an authentication token created by the user or an ApiKey. + /// Constructor that takes an authentication token created by the user or an ApiKey. + /// If no URL is set then default to the non-IAM Visual Recognition endpoint. /// /// The service endpoint. public Credentials(string apiKey, string url = null) { ApiKey = apiKey; - Url = url; + Url = !string.IsNullOrEmpty(url) ? url : "https://gateway-a.watsonplatform.net/visual-recognition/api"; } /// @@ -140,7 +141,7 @@ public Credentials(string apiKey, string url = null) public Credentials(TokenOptions iamTokenOptions, string serviceUrl) { Url = serviceUrl; - _iamUrl = !string.IsNullOrEmpty(iamTokenOptions.IamUrl) ? iamTokenOptions.IamUrl : "https://iam.ng.bluemix.net/identity/token"; + _iamUrl = !string.IsNullOrEmpty(iamTokenOptions.IamUrl) ? iamTokenOptions.IamUrl : "https://iam.bluemix.net/identity/token"; _iamTokenData = new IamTokenData(); if (!string.IsNullOrEmpty(iamTokenOptions.IamApiKey)) @@ -152,8 +153,7 @@ public Credentials(TokenOptions iamTokenOptions, string serviceUrl) GetToken(); } #endregion - - + #region Get Token /// /// This function sends an access token back through a callback. The source of the token @@ -487,13 +487,31 @@ public bool HasApiKey() } /// - /// Do we have a HasIamTokenData? + /// Do we have IamTokenData? /// /// public bool HasIamTokenData() { return _tokenData != null; } + + /// + /// Do we have an IAM apikey? + /// + /// + public bool HasIamApikey() + { + return !string.IsNullOrEmpty(_iamApiKey); + } + + /// + /// Do we have an IAM authentication token? + /// + /// + public bool HasIamAuthorizationToken() + { + return !string.IsNullOrEmpty(_userAcessToken); + } } /// @@ -563,6 +581,8 @@ public class Credential public string ApiKey { get; set; } [fsProperty("apikey")] public string IamApikey { get; set; } + [fsProperty("iam_url")] + public string IamUrl { get; set; } } ///