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/Scripts/Services/VisualRecognition/v3/VisualRecognition.cs b/Scripts/Services/VisualRecognition/v3/VisualRecognition.cs index 9ee9feca4..14d06f0e3 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-a.watsonplatform.net/visual-recognition/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; 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..f39828c2b 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(); 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/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; } } ///