├── .bumpversion.cfg ├── .github ├── CODE_OF_CONDUCT.md ├── Contributing.md ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── stale.yml ├── .gitignore ├── .releaserc ├── .salesforcedx.yaml ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── MIGRATION-V5.md ├── README.md ├── RELEASES.md ├── appscan ├── ASOC.sh ├── Configfile ├── Makefile ├── app.json └── getJson.py ├── assets └── server.key.enc ├── config ├── DocumentsFTest │ ├── documents │ │ ├── Public_Documents-meta.xml │ │ └── Public_Documents │ │ │ ├── cap047_wav.wav │ │ │ ├── cap047_wav.wav-meta.xml │ │ │ ├── sample1_wav.wav │ │ │ ├── sample1_wav.wav-meta.xml │ │ │ ├── sample1_webm.webm │ │ │ ├── sample1_webm.webm-meta.xml │ │ │ ├── sound_with_pause_wav.wav │ │ │ └── sound_with_pause_wav.wav-meta.xml │ └── package.xml ├── SFDXService │ └── sfdx-deploy-config.json ├── project-scratch-def.json └── remoteSiteEndpoint │ ├── IBMWatsonPlatform.remoteSite │ ├── WatsonAPIVisualRecognition.remoteSite │ ├── WatsonDC.remoteSite │ ├── WatsonDiscovery.remoteSite │ ├── WatsonIAM.remoteSite │ ├── WatsonTextToSpeech.remoteSite │ ├── package.xml │ └── remoteSiteSettings │ ├── .DS_Store │ ├── WatsonAPIVisualRecognition.remoteSite │ ├── WatsonDC.remoteSite │ ├── WatsonDiscovery.remoteSite │ ├── WatsonIAM.remoteSite │ └── WatsonTextToSpeech.remoteSite ├── force-app └── main │ ├── default │ └── classes │ │ ├── IBMAssistantV1.cls │ │ ├── IBMAssistantV1.cls-meta.xml │ │ ├── IBMAssistantV1Models.cls │ │ ├── IBMAssistantV1Models.cls-meta.xml │ │ ├── IBMAssistantV1Test.cls │ │ ├── IBMAssistantV1Test.cls-meta.xml │ │ ├── IBMAssistantV2.cls │ │ ├── IBMAssistantV2.cls-meta.xml │ │ ├── IBMAssistantV2Models.cls │ │ ├── IBMAssistantV2Models.cls-meta.xml │ │ ├── IBMAssistantV2Test.cls │ │ ├── IBMAssistantV2Test.cls-meta.xml │ │ ├── IBMCompareComplyV1.cls │ │ ├── IBMCompareComplyV1.cls-meta.xml │ │ ├── IBMCompareComplyV1Models.cls │ │ ├── IBMCompareComplyV1Models.cls-meta.xml │ │ ├── IBMCompareComplyV1Test.cls │ │ ├── IBMCompareComplyV1Test.cls-meta.xml │ │ ├── IBMDiscoveryV1.cls │ │ ├── IBMDiscoveryV1.cls-meta.xml │ │ ├── IBMDiscoveryV1Models.cls │ │ ├── IBMDiscoveryV1Models.cls-meta.xml │ │ ├── IBMDiscoveryV1Test.cls │ │ ├── IBMDiscoveryV1Test.cls-meta.xml │ │ ├── IBMDiscoveryV2.cls │ │ ├── IBMDiscoveryV2.cls-meta.xml │ │ ├── IBMDiscoveryV2Models.cls │ │ ├── IBMDiscoveryV2Models.cls-meta.xml │ │ ├── IBMDiscoveryV2Test.cls │ │ ├── IBMDiscoveryV2Test.cls-meta.xml │ │ ├── IBMLanguageTranslatorV3.cls │ │ ├── IBMLanguageTranslatorV3.cls-meta.xml │ │ ├── IBMLanguageTranslatorV3Models.cls │ │ ├── IBMLanguageTranslatorV3Models.cls-meta.xml │ │ ├── IBMLanguageTranslatorV3Test.cls │ │ ├── IBMLanguageTranslatorV3Test.cls-meta.xml │ │ ├── IBMNaturalLanguageClassifierV1.cls │ │ ├── IBMNaturalLanguageClassifierV1.cls-meta.xml │ │ ├── IBMNaturalLanguageClassifierV1Models.cls │ │ ├── IBMNaturalLanguageClassifierV1Models.cls-meta.xml │ │ ├── IBMNaturalLanguageClassifierV1Test.cls │ │ ├── IBMNaturalLanguageClassifierV1Test.cls-meta.xml │ │ ├── IBMNaturalLanguageUnderstandingV1.cls │ │ ├── IBMNaturalLanguageUnderstandingV1.cls-meta.xml │ │ ├── IBMNaturalLanguageUnderstandingV1Models.cls │ │ ├── IBMNaturalLanguageUnderstandingV1Models.cls-meta.xml │ │ ├── IBMNaturalLanguageUnderstandingV1Test.cls │ │ ├── IBMNaturalLanguageUnderstandingV1Test.cls-meta.xml │ │ ├── IBMPersonalityInsightsV3.cls │ │ ├── IBMPersonalityInsightsV3.cls-meta.xml │ │ ├── IBMPersonalityInsightsV3Models.cls │ │ ├── IBMPersonalityInsightsV3Models.cls-meta.xml │ │ ├── IBMPersonalityInsightsV3Test.cls │ │ ├── IBMPersonalityInsightsV3Test.cls-meta.xml │ │ ├── IBMSpeechToTextV1.cls │ │ ├── IBMSpeechToTextV1.cls-meta.xml │ │ ├── IBMSpeechToTextV1Models.cls │ │ ├── IBMSpeechToTextV1Models.cls-meta.xml │ │ ├── IBMSpeechToTextV1Test.cls │ │ ├── IBMSpeechToTextV1Test.cls-meta.xml │ │ ├── IBMTextToSpeechV1.cls │ │ ├── IBMTextToSpeechV1.cls-meta.xml │ │ ├── IBMTextToSpeechV1Models.cls │ │ ├── IBMTextToSpeechV1Models.cls-meta.xml │ │ ├── IBMTextToSpeechV1Test.cls │ │ ├── IBMTextToSpeechV1Test.cls-meta.xml │ │ ├── IBMToneAnalyzerV3.cls │ │ ├── IBMToneAnalyzerV3.cls-meta.xml │ │ ├── IBMToneAnalyzerV3Models.cls │ │ ├── IBMToneAnalyzerV3Models.cls-meta.xml │ │ ├── IBMToneAnalyzerV3Test.cls │ │ ├── IBMToneAnalyzerV3Test.cls-meta.xml │ │ ├── IBMVisualRecognitionV3.cls │ │ ├── IBMVisualRecognitionV3.cls-meta.xml │ │ ├── IBMVisualRecognitionV3Models.cls │ │ ├── IBMVisualRecognitionV3Models.cls-meta.xml │ │ ├── IBMVisualRecognitionV3Test.cls │ │ ├── IBMVisualRecognitionV3Test.cls-meta.xml │ │ ├── IBMVisualRecognitionV4.cls │ │ ├── IBMVisualRecognitionV4.cls-meta.xml │ │ ├── IBMVisualRecognitionV4Models.cls │ │ ├── IBMVisualRecognitionV4Models.cls-meta.xml │ │ ├── IBMVisualRecognitionV4Test.cls │ │ ├── IBMVisualRecognitionV4Test.cls-meta.xml │ │ ├── IBMWatsonAbstractToken.cls │ │ ├── IBMWatsonAbstractToken.cls-meta.xml │ │ ├── IBMWatsonAuthenticator.cls │ │ ├── IBMWatsonAuthenticator.cls-meta.xml │ │ ├── IBMWatsonAuthenticatorBase.cls │ │ ├── IBMWatsonAuthenticatorBase.cls-meta.xml │ │ ├── IBMWatsonBasicAuthenticator.cls │ │ ├── IBMWatsonBasicAuthenticator.cls-meta.xml │ │ ├── IBMWatsonBasicAuthenticatorTest.cls │ │ ├── IBMWatsonBasicAuthenticatorTest.cls-meta.xml │ │ ├── IBMWatsonBearerTokenAuthenticator.cls │ │ ├── IBMWatsonBearerTokenAuthenticator.cls-meta.xml │ │ ├── IBMWatsonBearerTokenAuthenticatorTest.cls │ │ ├── IBMWatsonBearerTokenAuthenticatorTest.cls-meta.xml │ │ ├── IBMWatsonCP4DAuthenticatorTest.cls │ │ ├── IBMWatsonCP4DAuthenticatorTest.cls-meta.xml │ │ ├── IBMWatsonCP4DToken.cls │ │ ├── IBMWatsonCP4DToken.cls-meta.xml │ │ ├── IBMWatsonCP4DTokenResponse.cls │ │ ├── IBMWatsonCP4DTokenResponse.cls-meta.xml │ │ ├── IBMWatsonCP4DTokenTest.cls │ │ ├── IBMWatsonCP4DTokenTest.cls-meta.xml │ │ ├── IBMWatsonClient.cls │ │ ├── IBMWatsonClient.cls-meta.xml │ │ ├── IBMWatsonCloudPakForDataAuthenticator.cls │ │ ├── IBMWatsonCloudPakForDataAuthenticator.cls-meta.xml │ │ ├── IBMWatsonConfigBasedAuthFactoryTest.cls │ │ ├── IBMWatsonConfigBasedAuthFactoryTest.cls-meta.xml │ │ ├── IBMWatsonConfigBasedAuthenticatorFactory.cls │ │ ├── IBMWatsonConfigBasedAuthenticatorFactory.cls-meta.xml │ │ ├── IBMWatsonCredentialUtils.cls │ │ ├── IBMWatsonCredentialUtils.cls-meta.xml │ │ ├── IBMWatsonCredentialUtilsTest.cls │ │ ├── IBMWatsonCredentialUtilsTest.cls-meta.xml │ │ ├── IBMWatsonDynamicModel.cls │ │ ├── IBMWatsonDynamicModel.cls-meta.xml │ │ ├── IBMWatsonDynamicResponseModel.cls │ │ ├── IBMWatsonDynamicResponseModel.cls-meta.xml │ │ ├── IBMWatsonDynamicResponseModelTest.cls │ │ ├── IBMWatsonDynamicResponseModelTest.cls-meta.xml │ │ ├── IBMWatsonFile.cls │ │ ├── IBMWatsonFile.cls-meta.xml │ │ ├── IBMWatsonFormBody.cls │ │ ├── IBMWatsonFormBody.cls-meta.xml │ │ ├── IBMWatsonGenericModel.cls │ │ ├── IBMWatsonGenericModel.cls-meta.xml │ │ ├── IBMWatsonHttpHeaders.cls │ │ ├── IBMWatsonHttpHeaders.cls-meta.xml │ │ ├── IBMWatsonHttpMediaType.cls │ │ ├── IBMWatsonHttpMediaType.cls-meta.xml │ │ ├── IBMWatsonHttpStatus.cls │ │ ├── IBMWatsonHttpStatus.cls-meta.xml │ │ ├── IBMWatsonIAMAuthenticator.cls │ │ ├── IBMWatsonIAMAuthenticator.cls-meta.xml │ │ ├── IBMWatsonIAMAuthenticatorTest.cls │ │ ├── IBMWatsonIAMAuthenticatorTest.cls-meta.xml │ │ ├── IBMWatsonIAMToken.cls │ │ ├── IBMWatsonIAMToken.cls-meta.xml │ │ ├── IBMWatsonJSONUtil.cls │ │ ├── IBMWatsonJSONUtil.cls-meta.xml │ │ ├── IBMWatsonJSONUtilTest.cls │ │ ├── IBMWatsonJSONUtilTest.cls-meta.xml │ │ ├── IBMWatsonJSONWebToken.cls │ │ ├── IBMWatsonJSONWebToken.cls-meta.xml │ │ ├── IBMWatsonJSONWebTokenTest.cls │ │ ├── IBMWatsonJSONWebTokenTest.cls-meta.xml │ │ ├── IBMWatsonMapModel.cls │ │ ├── IBMWatsonMapModel.cls-meta.xml │ │ ├── IBMWatsonMediaType.cls │ │ ├── IBMWatsonMediaType.cls-meta.xml │ │ ├── IBMWatsonMockHttpResponse.cls │ │ ├── IBMWatsonMockHttpResponse.cls-meta.xml │ │ ├── IBMWatsonMockResponses.cls │ │ ├── IBMWatsonMockResponses.cls-meta.xml │ │ ├── IBMWatsonMultipartBody.cls │ │ ├── IBMWatsonMultipartBody.cls-meta.xml │ │ ├── IBMWatsonNoAuthAuthenticator.cls │ │ ├── IBMWatsonNoAuthAuthenticator.cls-meta.xml │ │ ├── IBMWatsonNoAuthAuthenticatorTest.cls │ │ ├── IBMWatsonNoAuthAuthenticatorTest.cls-meta.xml │ │ ├── IBMWatsonOptionsModel.cls │ │ ├── IBMWatsonOptionsModel.cls-meta.xml │ │ ├── IBMWatsonRequest.cls │ │ ├── IBMWatsonRequest.cls-meta.xml │ │ ├── IBMWatsonRequestBody.cls │ │ ├── IBMWatsonRequestBody.cls-meta.xml │ │ ├── IBMWatsonRequestBuilder.cls │ │ ├── IBMWatsonRequestBuilder.cls-meta.xml │ │ ├── IBMWatsonResponse.cls │ │ ├── IBMWatsonResponse.cls-meta.xml │ │ ├── IBMWatsonResponseModel.cls │ │ ├── IBMWatsonResponseModel.cls-meta.xml │ │ ├── IBMWatsonResponseModelTest.cls │ │ ├── IBMWatsonResponseModelTest.cls-meta.xml │ │ ├── IBMWatsonService.cls │ │ ├── IBMWatsonService.cls-meta.xml │ │ ├── IBMWatsonServiceExceptions.cls │ │ ├── IBMWatsonServiceExceptions.cls-meta.xml │ │ ├── IBMWatsonServiceTest.cls │ │ ├── IBMWatsonServiceTest.cls-meta.xml │ │ ├── IBMWatsonTokenRequestBasedAuthenticator.cls │ │ ├── IBMWatsonTokenRequestBasedAuthenticator.cls-meta.xml │ │ ├── IBMWatsonTokenServerResponse.cls │ │ ├── IBMWatsonTokenServerResponse.cls-meta.xml │ │ ├── IBMWatsonValidator.cls │ │ └── IBMWatsonValidator.cls-meta.xml │ └── test │ ├── IBMAssistantV1FTests.cls │ ├── IBMAssistantV1FTests.cls-meta.xml │ ├── IBMAssistantV2FTests.cls │ ├── IBMAssistantV2FTests.cls-meta.xml │ ├── IBMCompareComplyV1FTests.cls │ ├── IBMCompareComplyV1FTests.cls-meta.xml │ ├── IBMDiscoveryV1FTests.cls │ ├── IBMDiscoveryV1FTests.cls-meta.xml │ ├── IBMNaturalLanguageClassifierV1FTests.cls │ ├── IBMNaturalLanguageClassifierV1FTests.cls-meta.xml │ ├── IBMNaturalLanguageUnderstandingV1FTest.cls │ ├── IBMNaturalLanguageUnderstandingV1FTest.cls-meta.xml │ ├── IBMPersonalityInsightsV3FTest.cls │ ├── IBMPersonalityInsightsV3FTest.cls-meta.xml │ ├── IBMSpeechToTextV1FTest.cls │ ├── IBMSpeechToTextV1FTest.cls-meta.xml │ ├── IBMTextToSpeechV1FTest.cls │ ├── IBMTextToSpeechV1FTest.cls-meta.xml │ ├── IBMToneAnalyzerV3FTest.cls │ ├── IBMToneAnalyzerV3FTest.cls-meta.xml │ ├── IBMVisualRecognitionV3FTest.cls │ ├── IBMVisualRecognitionV3FTest.cls-meta.xml │ ├── IBMVisualRecognitionV4FTests.cls │ └── IBMVisualRecognitionV4FTests.cls-meta.xml ├── install ├── ant-contrib-1.0b3.jar ├── ant-salesforce.jar ├── build.properties ├── build.xml ├── deploy.sh ├── package.xml ├── sfdx-deploy-service.sh └── test-in-scratch-org.sh ├── package-lock.json └── sfdx-project.json /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 5.3.0 3 | commit = True 4 | message = Bump version: {current_version} -> {new_version} 5 | 6 | [bumpversion:file:force-app/main/default/classes/IBMWatsonService.cls] 7 | search = private static final String SDK_VERSION = '{current_version}' 8 | replace = private static final String SDK_VERSION = '{new_version}' 9 | 10 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at loganpatino10@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /.github/Contributing.md: -------------------------------------------------------------------------------- 1 | ## Questions 2 | 3 | If you are having difficulties using the APIs or have a question about the IBM Watson Services, 4 | please ask a question on [dW Answers][dw] or [Stack Overflow][stackoverflow]. 5 | 6 | ## Issues 7 | 8 | If you encounter an issue with the Salesforce SDK, you are welcome to submit a [bug report](https://github.com/watson-developer-cloud/salesforce-sdk/issues). 9 | Before that, please search for similar issues. It's possible somebody has encountered this issue already. 10 | 11 | # Pull Requests 12 | 13 | If you want to contribute to the repository, here's a quick guide: 14 | 1. Fork the repository 15 | 2. Develop and [deploy your code changes to your Salesforce org](https://github.com/watson-developer-cloud/salesforce-sdk#installation) 16 | 3. Ensure all tests pass 17 | 4. Commit your changes: 18 | * Commits should follow the [Angular commit message guidelines](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-guidelines). This is because our release tool uses this format for determining release versions and generating changelogs. To make this easier, we recommend using the [Commitizen CLI](https://github.com/commitizen/cz-cli) with the `cz-conventional-changelog` adapter. 19 | 5. Push to your fork and submit a pull request to the **master** branch 20 | 21 | # Deploy, Develop and Test 22 | 23 | If you want to contribute to the repository, here's a quick guide for making update: 24 | 1. Save the code from your fork to local machine using `git clone` 25 | 2. A salesforce.com development org (environment) is needed to deploy, develop and test code updates. 26 | 3. Deployment scripts “build.properties” and “build.xml” are provided in the package you saved locally from GitHub. You need salesforce [ant migration tool](https://developer.salesforce.com/docs/atlas.en-us.daas.meta/daas/meta_development.htm) to deploy the code to your developer org. 27 | 4. Thorough testing is required to avoid any errors or issues. 28 | 5. Make sure that unit test code is added for all the changes. This is required for deployment and quality of code. Minimum 75% code coverage is required. It is recommended that you write unit test for all the code if possible. 29 | 30 | 31 | # Developer's Certificate of Origin 1.1 32 | 33 | By making a contribution to this project, I certify that: 34 | 35 | (a) The contribution was created in whole or in part by me and I 36 | have the right to submit it under the open source license 37 | indicated in the file; or 38 | 39 | (b) The contribution is based upon previous work that, to the best 40 | of my knowledge, is covered under an appropriate open source 41 | license and I have the right under that license to submit that 42 | work with modifications, whether created in whole or in part 43 | by me, under the same open source license (unless I am 44 | permitted to submit under a different license), as indicated 45 | in the file; or 46 | 47 | (c) The contribution was provided directly to me by some other 48 | person who certified (a), (b) or (c) and I have not modified 49 | it. 50 | 51 | (d) I understand and agree that this project and the contribution 52 | are public and that a record of the contribution (including all 53 | personal information I submit with it, including my sign-off) is 54 | maintained indefinitely and may be redistributed consistent with 55 | this project or the open source license(s) involved. 56 | 57 | ## Coding Guidelines 58 | 59 | Salesforce has very comprehensive [developer guide](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dev_guide.htm). Please refer to it for any development-related questions or information. Our code is following the [Salesforce best practices](https://developer.salesforce.com/page/Apex_Code_Best_Practices). Please follow the Apex coding best practices before updating the code. 60 | 61 | For code styling we recommend: https://github.com/PolarisProject/salesforceStyleGuide 62 | 63 | Please follow the Salesforce guidelines for unit testing. The links to unit test guide lines are provided below. This SDK contains unit test code that provides examples for writing unit tests and how to use the SDK to connect to the Watson APIs. 64 | 65 | * [Writing unit tests](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing.htm) 66 | * [running unit tests](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_unit_tests_running.htm) 67 | * [REST callout specific unit tests](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restful_http_testing.htm) 68 | 69 | ## Additional Resources 70 | 71 | * [General GitHub documentation](https://help.github.com/) 72 | * [GitHub pull request documentation](https://help.github.com/send-pull-requests/) 73 | 74 | [dw]: https://developer.ibm.com/answers/questions/ask/?topics=watson 75 | [stackoverflow]: http://stackoverflow.com/questions/ask?tags=ibm-watson 76 | [Maven]: https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html 77 | [Gradle]: https://docs.gradle.org/current/userguide/installation.html -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Remember, an issue is not the place to ask questions. You can use [Stack Overflow](http://stackoverflow.com/questions/tagged/ibm-watson) for that, or you may want to start a discussion on the [dW Answers](https://developer.ibm.com/answers/questions/ask/?topics=watson). 2 | 3 | Before you open an issue, please check if a similar issue already exists or has been closed before. 4 | 5 | ### When reporting a bug, please be sure to include the following 6 | 7 | - [ ] Salesforce version 8 | - [ ] SDK version 9 | - [ ] Steps to reproduce 10 | - [ ] Expected behavior 11 | - [ ] Actual behavior 12 | 13 | ### When you open an issue for a feature request, please add as much detail as possible 14 | 15 | - [ ] A descriptive title starting with the service name: Assistant, Discovery... 16 | - [ ] A description of the problem you're trying to solve 17 | - [ ] A suggested solution if possible 18 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Summary 2 | 3 | Provide a general description of the code changes in your pull 4 | request... were there any bugs you had fixed? If so, mention them. If 5 | these bugs have open GitHub issues, be sure to tag them here as well, 6 | to keep the conversation linked together. 7 | 8 | ## Other Information 9 | 10 | If there's anything else that's important and relevant to your pull 11 | request, mention that information here. 12 | 13 | Thanks for contributing! -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has had no 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | server.key 2 | .sfdx 3 | .idea 4 | .vscode 5 | mdapioutput 6 | *.orig 7 | *.rej 8 | .project 9 | .pre-commit-config.yaml 10 | .secrets.baseline 11 | *.py -------------------------------------------------------------------------------- /.releaserc: -------------------------------------------------------------------------------- 1 | { 2 | "branch": "master", 3 | "debug": true, 4 | "plugins": [ 5 | "@semantic-release/commit-analyzer", 6 | "@semantic-release/release-notes-generator", 7 | "@semantic-release/changelog", 8 | [ 9 | "@semantic-release/exec", 10 | { 11 | "prepareCmd": "bumpversion --current-version ${lastRelease.version} --new-version ${nextRelease.version} --verbose --allow-dirty patch" 12 | } 13 | ], 14 | [ 15 | "@semantic-release/git", 16 | { 17 | "message": "docs(release): Add release notes for ${nextRelease.version}" 18 | } 19 | ], 20 | "@semantic-release/github" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /.salesforcedx.yaml: -------------------------------------------------------------------------------- 1 | scratch-org-def: config/project-scratch-def.json 2 | assign-permset: true 3 | run-apex-tests: true 4 | delete-scratch-org: false 5 | show-scratch-org-url: true -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: true 2 | dist: trusty 3 | cache: false 4 | language: python 5 | before_install: 6 | - sudo apt-get update 7 | - sudo apt-get install python 8 | install: 9 | - export URL=https://developer.salesforce.com/media/salesforce-cli/sfdx-linux-amd64.tar.xz 10 | - export SFDX_AUTOUPDATE_DISABLE=true 11 | - export SFDX_USE_GENERIC_UNIX_KEYCHAIN=true 12 | - export SFDX_DOMAIN_RETRY=300 13 | - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && openssl aes-256-cbc -K $encrypted_3025427bf292_key -iv $encrypted_3025427bf292_iv -in assets/server.key.enc -out assets/server.key -d || true' 14 | - mkdir sfdx 15 | - wget -qO- $URL | tar xJ -C sfdx --strip-components 1 16 | - "./sfdx/install" 17 | - export PATH=./sfdx/$(pwd):$PATH 18 | - mv force-app/main/test/* force-app/main/default/classes 19 | - pip install bumpversion 20 | - 'if [ "${TRAVIS_TAG}" = "${TRAVIS_BRANCH}" ]; then cd appscan; make asoc-tool; cd ../; fi' 21 | # before_script: 22 | # - 'if [ "${TRAVIS_TAG}" = "${TRAVIS_BRANCH}" ]; then chmod a+x ./appscan/ASOC.sh; fi' 23 | script: true 24 | # - "./install/test-in-scratch-org.sh" 25 | # - 'if [ "${TRAVIS_TAG}" = "${TRAVIS_BRANCH}" ]; then ./appscan/ASOC.sh; fi' 26 | # after_success: 27 | # - sfdx force:org:delete -u ciorg -p 28 | # after_failure: 29 | # - sfdx force:org:delete -u ciorg -p 30 | before_deploy: 31 | - nvm install 12 32 | - npm install @semantic-release/exec 33 | - npm install @semantic-release/git 34 | - npm install @semantic-release/changelog 35 | deploy: 36 | - provider: script 37 | skip_cleanup: true 38 | script: npx semantic-release -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 IBM Corp. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /RELEASES.md: -------------------------------------------------------------------------------- 1 | ## Releasing 2 | Releases happen automatically after successful builds in the `master` branch. If no release happens, it could be that there wasn't a commit merged which triggered one of the [semantic-release default release rules](https://github.com/semantic-release/commit-analyzer/blob/master/lib/default-release-rules.js). -------------------------------------------------------------------------------- /appscan/ASOC.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd appscan 4 | make generate-irx 5 | make upload-file 6 | make run-scan 7 | cd ../ 8 | -------------------------------------------------------------------------------- /appscan/Configfile: -------------------------------------------------------------------------------- 1 | # URLs to the CISO APIs 2 | LOGIN_URL ?= 'https://appscan.ibmcloud.com/api/V2/Account/ApiKeyLogin' 3 | UPLOAD_URL ?= 'https://appscan.ibmcloud.com/api/v2/FileUpload' 4 | GET_APP_URL ?= 'https://appscan.ibmcloud.com/api/V2/Apps?$$$$filter=Name%20eq%20' 5 | STATIC_SCAN_URL ?= 'https://appscan.ibmcloud.com/api/v2/Scans/StaticAnalyzer' 6 | CREATE_APP_URL ?= 'https://appscan.ibmcloud.com/api/V2/Apps' 7 | GET_ASSET_GROUP_URL ?= 'https://appscan.ibmcloud.com/api/V2/AssetGroups' 8 | 9 | APPSCAN_CLIENT_URL ?= https://appscan.ibmcloud.com/api/SCX/StaticAnalyzer/SAClientUtil?os= 10 | OS ?= linux 11 | APPSCAN_TOOL := $(APPSCAN_CLIENT_URL)$(OS) 12 | 13 | GIT_REPO ?= git@github.com:watson-developer-cloud/salesforce-sdk.git 14 | 15 | PROJECT_NAME ?= salesforce-sdk 16 | 17 | # Headers added to curl command 18 | CONTENT_HEADER_JSON := --header 'Content-Type: application/json' 19 | ACCEPT_HEADER_JSON := --header 'Accept: application/json' -------------------------------------------------------------------------------- /appscan/Makefile: -------------------------------------------------------------------------------- 1 | include Configfile 2 | 3 | # This will configure a 32-bit architecture on top of a 64-bit linux machine 4 | config-arch: 5 | sudo dpkg --add-architecture i386 6 | sudo apt-get update 7 | sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 8 | 9 | # Gets the ASoC Client Tool and configures it 10 | asoc-tool: config-arch 11 | $(eval DIR := $(shell pwd)) 12 | curl -o $(HOME)/client.zip $(APPSCAN_TOOL) 13 | mkdir $(HOME)/client ; mkdir $(HOME)/tool 14 | unzip -qq $(HOME)/client.zip -d $(HOME)/client 15 | cd $(HOME)/client ; ls | xargs -I {} sh -c "cp -r {}/* $(HOME)/tool" 16 | rm -rf client 17 | 18 | # Clone repo 19 | clone-repo: 20 | git clone $(GIT_REPO) 21 | 22 | # Generates the irx file for icp-cert-manager 23 | generate-irx: 24 | cd $(TRAVIS_BUILD_DIR) 25 | $(HOME)/tool/bin/appscan.sh prepare -oso 26 | 27 | # Login to the AppScan API 28 | api-login: 29 | curl -o $(HOME)/token.json -X POST $(CONTENT_HEADER_JSON) $(ACCEPT_HEADER_JSON) -d '{"KeyId":"$(ASOC_APIKEY)", "KeySecret":"$(ASOC_SECRET)"}' $(LOGIN_URL) 30 | 31 | # Uploads the irx file to the AppScan API 32 | upload-file: api-login 33 | $(eval TOKE := $(shell python getJson.py $(HOME)/token.json "Token")) 34 | $(eval AUTH := --header 'Authorization: Bearer $(TOKE)') 35 | $(eval FILE := fileToUpload=@$(shell pwd)/$(notdir $(shell find $(pwd) -maxdepth 2 -name '*.irx' -print))) 36 | 37 | curl -o $(HOME)/file.json -X POST --header 'Content-Type: multipart/form-data' $(ACCEPT_HEADER_JSON) $(AUTH) -F $(FILE) $(UPLOAD_URL) 38 | 39 | # Checks to see if Cert-Manager-Application already exists. 40 | # TODO: Error with the url, will come back to this later. 41 | get-app: 42 | $(eval TOKE := $(shell python getJson.py $(HOME)/token.json "Token")) 43 | $(eval AUTH := --header 'Authorization: Bearer $(TOKE)') 44 | $(eval URL := $(GET_APP_URL)'$(APP_NAME)''') 45 | 46 | curl -X GET $(ACCEPT_HEADER_JSON) $(AUTH) $(URL) 47 | 48 | # Assume we have an existing application, then we'll simply run the static scan 49 | run-scan: 50 | $(eval TOKE := $(shell python getJson.py $(HOME)/token.json "Token")) 51 | $(eval AUTH := --header 'Authorization: Bearer $(TOKE)') 52 | $(eval FILE_ID := "$(shell python getJson.py $(HOME)/file.json "FileId")") 53 | $(eval APP_ID := "$(shell python getJson.py app.json "Id")") 54 | 55 | curl -X POST $(CONTENT_HEADER_JSON) $(ACCEPT_HEADER_JSON) $(AUTH) -d '{"ARSAFileId": $(FILE_ID), "ApplicationFileId": $(FILE_ID), "ScanName": "$(TRAVIS_TAG):$(TRAVIS_JOB_NUMBER):$(TRAVIS_COMMIT)", "EnableMailNotification": false, "Locale": "en-US", "AppId": $(APP_ID), "Execute": true, "Personal": false}' $(STATIC_SCAN_URL) 56 | 57 | get-asset-group: 58 | $(eval TOKE := $(shell python getJson.py $(HOME)/token.json "Token")) 59 | $(eval AUTH := --header 'Authorization: Bearer $(TOKE)') 60 | 61 | curl -o asset.json -X GET $(ACCEPT_HEADER_JSON) $(AUTH) $(GET_ASSET_GROUP_URL) 62 | 63 | # Create the application only if the application doesn't already exist. 64 | create-app: get-asset-group 65 | $(eval ASSET_GROUP_ID := "$(shell python getJson.py asset.json "Id")") 66 | $(eval TOKE := $(shell python getJson.py $(HOME)/token.json "Token")) 67 | $(eval AUTH := --header 'Authorization: Bearer $(TOKE)') 68 | 69 | curl -o app.json -X POST $(CONTENT_HEADER_JSON) $(ACCEPT_HEADER_JSON) $(AUTH) -d '{"Name": $(APP_NAME), "AssetGroupId": $(ASSET_GROUP_ID), "BusinessImpact": "Unspecified"}' $(CREATE_APP_URL) -------------------------------------------------------------------------------- /appscan/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "Id": "e9eb5066-bc85-4dee-9d30-95c8b37088c3", 3 | "AssetGroupName": "IBM Watson and Cloud Platform", 4 | "DateCreated": null, 5 | "LastUpdated": null, 6 | "LastComment": null, 7 | "RiskRating": "Unknown", 8 | "CreatedBy": null, 9 | "CriticalIssues": 0, 10 | "HighIssues": 0, 11 | "MediumIssues": 0, 12 | "LowIssues": 0, 13 | "IssuesInProgress": 0, 14 | "MaxSeverity": "Undetermined", 15 | "RR_MaxSeverity": 0, 16 | "NewIssues": 0, 17 | "OpenIssues": 0, 18 | "TotalIssues": 0, 19 | "OverallCompliance": null, 20 | "ComplianceStatuses": [], 21 | "CanBeDeleted": true, 22 | "LockedToSubscription": false, 23 | "Name": "Watson Salesforce SDK", 24 | "AssetGroupId": null, 25 | "BusinessImpact": "Unspecified", 26 | "Url": null, 27 | "Description": null, 28 | "BusinessUnit": null, 29 | "Type": null, 30 | "Technology": null, 31 | "TestingStatus": "NotStarted", 32 | "Hosts": null, 33 | "CollateralDamagePotential": "NotDefined", 34 | "TargetDistribution": "NotDefined", 35 | "ConfidentialityRequirement": "NotDefined", 36 | "IntegrityRequirement": "NotDefined", 37 | "AvailabilityRequirement": "NotDefined", 38 | "Tester": null, 39 | "BusinessOwner": null, 40 | "DevelopmentContact": null, 41 | "PreferredOfferingType": "None" 42 | } 43 | -------------------------------------------------------------------------------- /appscan/getJson.py: -------------------------------------------------------------------------------- 1 | import json 2 | import sys 3 | 4 | def main(): 5 | data = load_data() 6 | printFields(data) 7 | 8 | def load_data(): 9 | data = "" 10 | filename = sys.argv[1] 11 | with open(filename, "r") as read: 12 | data = json.load(read) 13 | if isinstance(data, list): 14 | data = data[0] 15 | return data 16 | 17 | def printFields(data): 18 | fields = sys.argv[2:] 19 | for i in fields: 20 | print(data[i]) 21 | 22 | main() 23 | -------------------------------------------------------------------------------- /assets/server.key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/watson-developer-cloud/salesforce-sdk/67dc90db608a031971d3c12940c729ec152accdd/assets/server.key.enc -------------------------------------------------------------------------------- /config/DocumentsFTest/documents/Public_Documents-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Public 4 | Public Documents 5 | ReadWrite 6 | 7 | -------------------------------------------------------------------------------- /config/DocumentsFTest/documents/Public_Documents/cap047_wav.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/watson-developer-cloud/salesforce-sdk/67dc90db608a031971d3c12940c729ec152accdd/config/DocumentsFTest/documents/Public_Documents/cap047_wav.wav -------------------------------------------------------------------------------- /config/DocumentsFTest/documents/Public_Documents/cap047_wav.wav-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | cap047.wav 5 | false 6 | 7 | -------------------------------------------------------------------------------- /config/DocumentsFTest/documents/Public_Documents/sample1_wav.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/watson-developer-cloud/salesforce-sdk/67dc90db608a031971d3c12940c729ec152accdd/config/DocumentsFTest/documents/Public_Documents/sample1_wav.wav -------------------------------------------------------------------------------- /config/DocumentsFTest/documents/Public_Documents/sample1_wav.wav-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | sample1.wav 5 | false 6 | 7 | -------------------------------------------------------------------------------- /config/DocumentsFTest/documents/Public_Documents/sample1_webm.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/watson-developer-cloud/salesforce-sdk/67dc90db608a031971d3c12940c729ec152accdd/config/DocumentsFTest/documents/Public_Documents/sample1_webm.webm -------------------------------------------------------------------------------- /config/DocumentsFTest/documents/Public_Documents/sample1_webm.webm-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | sample1.webm 5 | true 6 | 7 | -------------------------------------------------------------------------------- /config/DocumentsFTest/documents/Public_Documents/sound_with_pause_wav.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/watson-developer-cloud/salesforce-sdk/67dc90db608a031971d3c12940c729ec152accdd/config/DocumentsFTest/documents/Public_Documents/sound_with_pause_wav.wav -------------------------------------------------------------------------------- /config/DocumentsFTest/documents/Public_Documents/sound_with_pause_wav.wav-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | sound-with-pause.wav 5 | true 6 | 7 | -------------------------------------------------------------------------------- /config/DocumentsFTest/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Public_Documents 5 | Public_Documents/cap047_wav 6 | Public_Documents/sample1_wav 7 | Public_Documents/sample1_webm 8 | Public_Documents/sound_with_pause_wav 9 | Document 10 | 11 | 39.0 12 | 13 | -------------------------------------------------------------------------------- /config/project-scratch-def.json: -------------------------------------------------------------------------------- 1 | { 2 | "edition": "Developer" 3 | } -------------------------------------------------------------------------------- /config/remoteSiteEndpoint/IBMWatsonPlatform.remoteSite: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | true 5 | https://gateway.watsonplatform.net 6 | 7 | -------------------------------------------------------------------------------- /config/remoteSiteEndpoint/WatsonAPIVisualRecognition.remoteSite: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | true 5 | https://gateway-a.watsonplatform.net 6 | 7 | -------------------------------------------------------------------------------- /config/remoteSiteEndpoint/WatsonDC.remoteSite: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | true 5 | https://gateway-wdc.watsonplatform.net 6 | 7 | -------------------------------------------------------------------------------- /config/remoteSiteEndpoint/WatsonDiscovery.remoteSite: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | true 5 | https://gateway.watsonplatform.net/discovery/api/v1/environments 6 | 7 | -------------------------------------------------------------------------------- /config/remoteSiteEndpoint/WatsonIAM.remoteSite: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | true 5 | https://iam.cloud.ibm.com 6 | 7 | -------------------------------------------------------------------------------- /config/remoteSiteEndpoint/WatsonTextToSpeech.remoteSite: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | true 5 | https://stream.watsonplatform.net 6 | 7 | -------------------------------------------------------------------------------- /config/remoteSiteEndpoint/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | * 5 | RemoteSiteSetting 6 | 7 | 41.0 8 | 9 | -------------------------------------------------------------------------------- /config/remoteSiteEndpoint/remoteSiteSettings/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/watson-developer-cloud/salesforce-sdk/67dc90db608a031971d3c12940c729ec152accdd/config/remoteSiteEndpoint/remoteSiteSettings/.DS_Store -------------------------------------------------------------------------------- /config/remoteSiteEndpoint/remoteSiteSettings/WatsonAPIVisualRecognition.remoteSite: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | true 5 | https://gateway-a.watsonplatform.net 6 | 7 | -------------------------------------------------------------------------------- /config/remoteSiteEndpoint/remoteSiteSettings/WatsonDC.remoteSite: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | true 5 | https://gateway-wdc.watsonplatform.net 6 | 7 | -------------------------------------------------------------------------------- /config/remoteSiteEndpoint/remoteSiteSettings/WatsonDiscovery.remoteSite: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | true 5 | https://gateway.watsonplatform.net/discovery/api/v1/environments 6 | 7 | -------------------------------------------------------------------------------- /config/remoteSiteEndpoint/remoteSiteSettings/WatsonIAM.remoteSite: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | true 5 | https://iam.cloud.ibm.com 6 | 7 | -------------------------------------------------------------------------------- /config/remoteSiteEndpoint/remoteSiteSettings/WatsonTextToSpeech.remoteSite: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | true 5 | https://stream.watsonplatform.net 6 | 7 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMAssistantV1.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMAssistantV1Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMAssistantV1Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMAssistantV2.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMAssistantV2Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMAssistantV2Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMCompareComplyV1.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMCompareComplyV1Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMCompareComplyV1Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMDiscoveryV1.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMDiscoveryV1Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMDiscoveryV1Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMDiscoveryV2.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMDiscoveryV2Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMDiscoveryV2Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMLanguageTranslatorV3.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMLanguageTranslatorV3Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMLanguageTranslatorV3Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMNaturalLanguageClassifierV1.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMNaturalLanguageClassifierV1Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMNaturalLanguageClassifierV1Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMNaturalLanguageUnderstandingV1.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMNaturalLanguageUnderstandingV1Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMNaturalLanguageUnderstandingV1Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMPersonalityInsightsV3.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMPersonalityInsightsV3Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMPersonalityInsightsV3Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMSpeechToTextV1.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMSpeechToTextV1Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMSpeechToTextV1Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMTextToSpeechV1.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMTextToSpeechV1Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMTextToSpeechV1Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMToneAnalyzerV3.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMToneAnalyzerV3Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMToneAnalyzerV3Test.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | @isTest 15 | private class IBMToneAnalyzerV3Test { 16 | private static String VERSION; 17 | private static String HEADER_KEY; 18 | private static String HEADER_VAL; 19 | 20 | private static IBMToneAnalyzerV3 service; 21 | 22 | static { 23 | VERSION = '2017-09-21'; 24 | HEADER_KEY = 'Header-Key'; 25 | HEADER_VAL = 'header_val'; 26 | service = new IBMToneAnalyzerV3(VERSION, new IBMWatsonNoAuthAuthenticator()); 27 | } 28 | 29 | /** 30 | * Test Analyze general purpose tone. 31 | * 32 | */ 33 | static testMethod void testTone() { 34 | String body = IBMWatsonMockResponses.toneAnalysis(); 35 | IBMWatsonMockHttpResponse mockResponse = new IBMWatsonMockHttpResponse(200, 'Success', body, null); 36 | Test.setMock(HttpCalloutMock.class, mockResponse); 37 | Test.startTest(); 38 | IBMToneAnalyzerV3Models.ToneInput toneInput = new IBMToneAnalyzerV3Models.ToneInputBuilder() 39 | .text('We have a better product. We can do better selling by having more campaigns') 40 | .build(); 41 | //you can add more attributes using following builder method. This step is not necessary 42 | toneInput = toneInput.newBuilder().build(); 43 | IBMToneAnalyzerV3Models.ToneOptions options = new IBMToneAnalyzerV3Models.ToneOptionsBuilder() 44 | .text('We have a better product. We need to do better selling') 45 | .html('We have a better product. We need to do better selling') 46 | .addTones('social') 47 | .tones(new List{'social'}) 48 | .sentences(false) 49 | .contentLanguage('en') 50 | .acceptLanguage('en') 51 | .toneInput(toneInput) 52 | .addHeader(HEADER_KEY, HEADER_VAL) 53 | .build(); 54 | //you can add more attributes using following builder method. This step is not necessary 55 | options = options.newBuilder().build(); 56 | IBMToneAnalyzerV3Models.ToneAnalysis resp = service.tone(options); 57 | System.assertEquals(resp.getDocumentTone().getWarning(), 'string'); 58 | System.assertEquals(resp.getDocumentTone().getTones()[0].getScore(),0); 59 | System.assertEquals(resp.getDocumentTone().getTones()[0].getToneId(), 'string'); 60 | System.assertEquals(resp.getDocumentTone().getTones()[0].getToneName(), 'string'); 61 | System.assertEquals(resp.getSentencesTone()[0].getSentenceId(),0); 62 | System.assertEquals(resp.getSentencesTone()[0].getText(), 'string'); 63 | System.assertEquals(resp.getSentencesTone()[0].getInputFrom(),0); 64 | System.assertEquals(resp.getSentencesTone()[0].getInputTo(),0); 65 | System.assertEquals(resp.getSentencesTone()[0].getToneCategories()[0].getCategoryId(), 'string'); 66 | System.assertEquals(resp.getSentencesTone()[0].getToneCategories()[0].getCategoryName(), 'string'); 67 | Test.stopTest(); 68 | } 69 | 70 | /** 71 | * Test analyze customer engagement tone. 72 | * 73 | */ 74 | static testMethod void testToneChat() { 75 | String body = IBMWatsonMockResponses.utteranceAnalyses(); 76 | IBMWatsonMockHttpResponse mockResponse = new IBMWatsonMockHttpResponse(200, 'Success', body, null); 77 | Test.setMock(HttpCalloutMock.class, mockResponse); 78 | Test.startTest(); 79 | 80 | IBMToneAnalyzerV3Models.Utterance utterance = new IBMToneAnalyzerV3Models.UtteranceBuilder() 81 | .text('We have a better product. We can do better selling by having more campaigns') 82 | .user('test user') 83 | .build(); 84 | //you can add more attributes using following builder method. This step is not necessary 85 | utterance = utterance.newBuilder().build(); 86 | IBMToneAnalyzerV3Models.ToneChatOptions options = new IBMToneAnalyzerV3Models.ToneChatOptionsBuilder() 87 | .addUtterances(utterance) 88 | .acceptLanguage('en') 89 | .contentLanguage('en') 90 | .addHeader(HEADER_KEY, HEADER_VAL) 91 | .build(); 92 | //you can add more attributes using following builder method. This step is not necessary 93 | options = options.newBuilder().build(); 94 | IBMToneAnalyzerV3Models.UtteranceAnalyses resp = service.toneChat(options); 95 | System.assertEquals(resp.getWarning(), 'string'); 96 | System.assertEquals(resp.getUtterancesTone()[0].getUtteranceId(), 0); 97 | System.assertEquals(resp.getUtterancesTone()[0].getUtteranceText(), 'string'); 98 | System.assertEquals(resp.getUtterancesTone()[0].getError(), 'string'); 99 | System.assertEquals(resp.getUtterancesTone()[0].getTones()[0].getScore(),0); 100 | System.assertEquals(resp.getUtterancesTone()[0].getTones()[0].getToneId(), 'string'); 101 | System.assertEquals(resp.getUtterancesTone()[0].getTones()[0].getToneName(), 'string'); 102 | Test.stopTest(); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMToneAnalyzerV3Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMVisualRecognitionV3.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMVisualRecognitionV3Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMVisualRecognitionV3Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMVisualRecognitionV4.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMVisualRecognitionV4Models.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMVisualRecognitionV4Test.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonAbstractToken.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * This class defines a common base class for tokens returned by a token server. 16 | */ 17 | public abstract class IBMWatsonAbstractToken extends IBMWatsonResponseModel { 18 | public abstract boolean isTokenValid(); 19 | public abstract String getAccessToken(); 20 | } 21 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonAbstractToken.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonAuthenticator.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public interface IBMWatsonAuthenticator { 15 | 16 | /** 17 | * Returns the authentication type associated with the IBMWatsonAuthenticator instance. 18 | * 19 | * @return a string representing the authentication type (e.g. "iam", "basic", "cp4d", etc.) 20 | */ 21 | String authenticationType(); 22 | 23 | /** 24 | * Perform the necessary authentication steps for the specified request. 25 | * 26 | * @param requestBuilder the IBMWatsonRequest.Builder instance to authenticate 27 | */ 28 | void authenticate(IBMWatsonRequest.Builder requestBuilder); 29 | 30 | /** 31 | * Validates the current set of configuration information in the IBMWatsonAuthenticator. 32 | */ 33 | void validate(); 34 | } 35 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonAuthenticator.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonAuthenticatorBase.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * This is a common base class used with the various IBMWatsonAuthenticator implementations. 16 | */ 17 | public virtual class IBMWatsonAuthenticatorBase { 18 | 19 | /** 20 | * Common error messages. 21 | */ 22 | public static final String ERRORMSG_PROP_MISSING = 'The {0} property is required but was not specified.'; 23 | public static final String ERRORMSG_PROP_INVALID = 24 | 'The {0} property is invalid. Please remove any surrounding \'{\', \'}\', or \" characters.'; 25 | public static final String ERRORMSG_REQ_FAILED = 'Error while fetching access token from token service.'; 26 | 27 | /** 28 | * Returns a "Basic" Authorization header value for the specified username and password. 29 | * @param username the username 30 | * @param password the password 31 | * @return the Authorization header value in the form "Basic <encoded username and password>" 32 | */ 33 | public static String constructBasicAuthHeader(String username, String password) { 34 | if (String.isNotBlank(username) && String.isNotBlank(password)) { 35 | Blob authBlob = Blob.valueOf(username + ':' + password); 36 | return 'Basic ' + EncodingUtil.base64Encode(authBlob); 37 | } 38 | return null; 39 | } 40 | 41 | /** 42 | * Returns a "Bearer" Authorization header value for the specified bearer token. 43 | * @param bearerToken the token value to be included in the header 44 | * @return the Authorization header value in the form "Bearer <bearerToken>" 45 | */ 46 | public static String constructBearerTokenAuthHeader(String bearerToken) { 47 | if (String.isNotBlank(bearerToken)) { 48 | return 'Bearer ' + bearerToken; 49 | } 50 | return null; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonAuthenticatorBase.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonBasicAuthenticator.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * This class implements support for Basic Authentication. 16 | * The main purpose of this authenticator is to construct the Authorization header, 17 | * and then add it to each outgoing REST API request. 18 | */ 19 | public class IBMWatsonBasicAuthenticator extends IBMWatsonAuthenticatorBase implements IBMWatsonAuthenticator { 20 | private String username; 21 | private String password; 22 | 23 | // The cached value of the Authorization header. 24 | private String authHeader; 25 | 26 | // Force the use of non-default constructors 27 | private IBMWatsonBasicAuthenticator() {} 28 | 29 | /** 30 | * Construct an IBMWatsonBasicAuthenticator instance with the specified username and password. 31 | * These values are used to construct an Authorization header value that will be included 32 | * in outgoing REST API requests. 33 | * 34 | * @param username the basic auth username 35 | * @param password the basic auth password 36 | */ 37 | public IBMWatsonBasicAuthenticator(String username, String password) { 38 | init(username, password); 39 | } 40 | 41 | /** 42 | * Construct a BasicAuthenticator using properties retrieved from the specified Map. 43 | * 44 | * @param config a map containing the username and password values 45 | */ 46 | public IBMWatsonBasicAuthenticator(Map config) { 47 | init(config.get(IBMWatsonCredentialUtils.PROP_NAME_USERNAME), config.get(IBMWatsonCredentialUtils.PROP_NAME_PASSWORD)); 48 | } 49 | 50 | private void init(String username, String password) { 51 | this.username = username; 52 | this.password = password; 53 | this.validate(); 54 | 55 | this.authHeader = constructBasicAuthHeader(username, password); 56 | } 57 | 58 | public String getUsername() { 59 | return this.username; 60 | } 61 | 62 | public String getPassword() { 63 | return this.password; 64 | } 65 | 66 | public String authenticationType() { 67 | return IBMWatsonCredentialUtils.AUTH_TYPE_BASIC; 68 | } 69 | 70 | public void authenticate(IBMWatsonRequest.Builder requestBuilder) { 71 | requestBuilder.addHeader(IBMWatsonHttpHeaders.AUTHORIZATION, this.authHeader); 72 | } 73 | 74 | public void validate() { 75 | if (String.isBlank(username)) { 76 | throw new IBMWatsonServiceExceptions.IllegalArgumentException(String.format(ERRORMSG_PROP_MISSING, new String[]{ 'username' })); 77 | } 78 | 79 | if (String.isBlank(password)) { 80 | throw new IBMWatsonServiceExceptions.IllegalArgumentException(String.format(ERRORMSG_PROP_MISSING, new String[]{ 'password' })); 81 | } 82 | 83 | if (IBMWatsonCredentialUtils.hasBadStartOrEndChar(username)) { 84 | throw new IBMWatsonServiceExceptions.IllegalArgumentException(String.format(ERRORMSG_PROP_INVALID, new String[]{ 'username' })); 85 | } 86 | 87 | if (IBMWatsonCredentialUtils.hasBadStartOrEndChar(password)) { 88 | throw new IBMWatsonServiceExceptions.IllegalArgumentException(String.format(ERRORMSG_PROP_INVALID, new String[]{ 'password' })); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonBasicAuthenticator.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonBasicAuthenticatorTest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | @isTest 15 | private class IBMWatsonBasicAuthenticatorTest { 16 | static testMethod void testSuccess() { 17 | Test.startTest(); 18 | String username = 'test-username'; 19 | String password = 'test-password'; 20 | 21 | IBMWatsonBasicAuthenticator authenticator = new IBMWatsonBasicAuthenticator(username, password); 22 | System.assertEquals(IBMWatsonCredentialUtils.AUTH_TYPE_BASIC, authenticator.authenticationType()); 23 | System.assertEquals(username, authenticator.getUsername()); 24 | System.assertEquals(password, authenticator.getPassword()); 25 | 26 | IBMWatsonRequest.Builder builder = new IBMWatsonRequest.Builder().url('https://test.com'); 27 | authenticator.authenticate(builder); 28 | IBMWatsonRequest request = builder.build(); 29 | 30 | String authHeader = request.header(IBMWatsonHttpHeaders.AUTHORIZATION); 31 | System.assert(authHeader != null); 32 | System.assertEquals('Basic ' + EncodingUtil.base64Encode(Blob.valueOf(username + ':' + password)), authHeader); 33 | Test.stopTest(); 34 | } 35 | 36 | static testMethod void testInvalidUsername() { 37 | Test.startTest(); 38 | try { 39 | IBMWatsonBasicAuthenticator authenticator = new IBMWatsonBasicAuthenticator('{bad-username}', 'good-password'); 40 | } catch (IBMWatsonServiceExceptions.IllegalArgumentException e) { 41 | System.assert(e != null); 42 | } 43 | Test.stopTest(); 44 | } 45 | 46 | static testMethod void testInvalidPassword() { 47 | Test.startTest(); 48 | try { 49 | IBMWatsonBasicAuthenticator authenticator = new IBMWatsonBasicAuthenticator('good-username', '{bad-password}'); 50 | } catch (IBMWatsonServiceExceptions.IllegalArgumentException e) { 51 | System.assert(e != null); 52 | } 53 | Test.stopTest(); 54 | } 55 | 56 | static testMethod void testMissingUsername() { 57 | Test.startTest(); 58 | try { 59 | IBMWatsonBasicAuthenticator authenticator = new IBMWatsonBasicAuthenticator(null, 'good-password'); 60 | } catch (IBMWatsonServiceExceptions.IllegalArgumentException e) { 61 | System.assert(e != null); 62 | } 63 | Test.stopTest(); 64 | } 65 | 66 | static testMethod void testMissingPassword() { 67 | Test.startTest(); 68 | try { 69 | IBMWatsonBasicAuthenticator authenticator = new IBMWatsonBasicAuthenticator('good-username', null); 70 | } catch (IBMWatsonServiceExceptions.IllegalArgumentException e) { 71 | System.assert(e != null); 72 | } 73 | Test.stopTest(); 74 | } 75 | 76 | static testMethod void testEmptyUsername() { 77 | Test.startTest(); 78 | try { 79 | IBMWatsonBasicAuthenticator authenticator = new IBMWatsonBasicAuthenticator('', 'good-password'); 80 | } catch (IBMWatsonServiceExceptions.IllegalArgumentException e) { 81 | System.assert(e != null); 82 | } 83 | Test.stopTest(); 84 | } 85 | 86 | static testMethod void testEmptyPassword() { 87 | Test.startTest(); 88 | try { 89 | IBMWatsonBasicAuthenticator authenticator = new IBMWatsonBasicAuthenticator('good-username', ''); 90 | } catch (IBMWatsonServiceExceptions.IllegalArgumentException e) { 91 | System.assert(e != null); 92 | } 93 | Test.stopTest(); 94 | } 95 | 96 | static testMethod void testMissingUsernameMap() { 97 | Test.startTest(); 98 | Map props = new Map(); 99 | props.put(IBMWatsonCredentialUtils.PROP_NAME_PASSWORD, 'good-password'); 100 | try { 101 | IBMWatsonBasicAuthenticator authenticator = new IBMWatsonBasicAuthenticator(props); 102 | } catch (IBMWatsonServiceExceptions.IllegalArgumentException e) { 103 | System.assert(e != null); 104 | } 105 | Test.stopTest(); 106 | } 107 | 108 | static testMethod void testInvalidUsernameMap() { 109 | Test.startTest(); 110 | Map props = new Map(); 111 | props.put(IBMWatsonCredentialUtils.PROP_NAME_USERNAME, '{bad-username}'); 112 | props.put(IBMWatsonCredentialUtils.PROP_NAME_PASSWORD, 'good-password'); 113 | try { 114 | IBMWatsonBasicAuthenticator authenticator = new IBMWatsonBasicAuthenticator(props); 115 | } catch (IBMWatsonServiceExceptions.IllegalArgumentException e) { 116 | System.assert(e != null); 117 | } 118 | Test.stopTest(); 119 | } 120 | 121 | static testMethod void testGoodMapConfig() { 122 | Test.startTest(); 123 | String username = 'good-username'; 124 | String password = 'good-password'; 125 | Map props = new Map(); 126 | props.put(IBMWatsonCredentialUtils.PROP_NAME_USERNAME, username); 127 | props.put(IBMWatsonCredentialUtils.PROP_NAME_PASSWORD, password); 128 | IBMWatsonBasicAuthenticator authenticator = new IBMWatsonBasicAuthenticator(props); 129 | System.assertEquals(IBMWatsonCredentialUtils.AUTH_TYPE_BASIC, authenticator.authenticationType()); 130 | System.assertEquals(username, authenticator.getUsername()); 131 | System.assertEquals(password, authenticator.getPassword()); 132 | Test.stopTest(); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonBasicAuthenticatorTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonBearerTokenAuthenticator.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * This class provides an IBMWatsonAuthenticator implementation that supports a user-supplied Bearer Token value. 16 | * The main purpose of this authenticator is to construct the Authorization header with the user-supplied 17 | * token, then add the header to each outgoing REST API request. 18 | */ 19 | public class IBMWatsonBearerTokenAuthenticator extends IBMWatsonAuthenticatorBase implements IBMWatsonAuthenticator { 20 | private String bearerToken; 21 | 22 | // The cached value of the Authorization header. 23 | private String authHeader; 24 | 25 | // Force the use of non-default constructors 26 | private IBMWatsonBearerTokenAuthenticator() {} 27 | 28 | /** 29 | * Construct an IBMWatsonBearerTokenAuthenticator instance with the specified access token. 30 | * The token value will be used to construct an Authorization header that will be included 31 | * in outgoing REST API requests. 32 | * 33 | * @param bearerToken the access token value 34 | */ 35 | public IBMWatsonBearerTokenAuthenticator(String bearerToken) { 36 | this.setBearerToken(bearerToken); 37 | } 38 | 39 | /** 40 | * Construct an IBMWatsonBearerTokenAuthenticator using properties retrieved from the specified Map. 41 | * 42 | * @param config a map containing the access token value 43 | */ 44 | public IBMWatsonBearerTokenAuthenticator(Map config) { 45 | this.setBearerToken(config.get(IBMWatsonCredentialUtils.PROP_NAME_BEARER_TOKEN)); 46 | } 47 | 48 | /** 49 | * @return the access token configured for this authenticator 50 | */ 51 | public String getBearerToken() { 52 | return this.bearerToken; 53 | } 54 | 55 | /** 56 | * Sets the bearer token value to be used by this authenticator. 57 | * @param bearerToken the new bearer token value 58 | */ 59 | public void setBearerToken(String bearerToken) { 60 | this.bearerToken = bearerToken; 61 | this.validate(); 62 | 63 | // Cache the Authorization header value. 64 | this.authHeader = constructBearerTokenAuthHeader(this.bearerToken); 65 | } 66 | 67 | public String authenticationType() { 68 | return IBMWatsonCredentialUtils.AUTH_TYPE_BEARER_TOKEN; 69 | } 70 | 71 | public void authenticate(IBMWatsonRequest.Builder requestBuilder) { 72 | requestBuilder.addHeader(IBMWatsonHttpHeaders.AUTHORIZATION, this.authHeader); 73 | } 74 | 75 | public void validate() { 76 | if (String.isBlank(bearerToken)) { 77 | throw new IBMWatsonServiceExceptions.IllegalArgumentException(String.format(ERRORMSG_PROP_MISSING, new String[]{ 'bearerToken' })); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonBearerTokenAuthenticator.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonBearerTokenAuthenticatorTest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | @isTest 15 | private class IBMWatsonBearerTokenAuthenticatorTest { 16 | static testMethod void testSuccess() { 17 | Test.startTest(); 18 | String token = 'abc-123'; 19 | 20 | IBMWatsonBearerTokenAuthenticator authenticator = new IBMWatsonBearerTokenAuthenticator(token); 21 | System.assertEquals(IBMWatsonCredentialUtils.AUTH_TYPE_BEARER_TOKEN, authenticator.authenticationType()); 22 | System.assertEquals(token, authenticator.getBearerToken()); 23 | 24 | IBMWatsonRequest.Builder builder = new IBMWatsonRequest.Builder().url('https://test.com'); 25 | authenticator.authenticate(builder); 26 | IBMWatsonRequest request = builder.build(); 27 | 28 | String authHeader = request.header(IBMWatsonHttpHeaders.AUTHORIZATION); 29 | System.assert(authHeader != null); 30 | System.assertEquals('Bearer ' + token, authHeader); 31 | 32 | // change token and verify again 33 | token = 'xyz-789'; 34 | authenticator.setBearerToken(token); 35 | builder = new IBMWatsonRequest.Builder().url('https://test.com'); 36 | authenticator.authenticate(builder); 37 | request = builder.build(); 38 | authHeader = request.header(IBMWatsonHttpHeaders.AUTHORIZATION); 39 | System.assert(authHeader != null); 40 | System.assertEquals('Bearer ' + token, authHeader); 41 | Test.stopTest(); 42 | } 43 | 44 | static testMethod void testMissingBearerToken() { 45 | Test.startTest(); 46 | try { 47 | IBMWatsonBearerTokenAuthenticator authenticator = new IBMWatsonBearerTokenAuthenticator((String) null); 48 | } catch (IBMWatsonServiceExceptions.IllegalArgumentException e) { 49 | System.assert(e != null); 50 | } 51 | Test.stopTest(); 52 | } 53 | 54 | static testMethod void testEmptyBearerToken() { 55 | Test.startTest(); 56 | try { 57 | IBMWatsonBearerTokenAuthenticator authenticator = new IBMWatsonBearerTokenAuthenticator(''); 58 | } catch (IBMWatsonServiceExceptions.IllegalArgumentException e) { 59 | System.assert(e != null); 60 | } 61 | Test.stopTest(); 62 | } 63 | 64 | static testMethod void testMissingBearerTokenMap() { 65 | Test.startTest(); 66 | Map props = new Map(); 67 | try { 68 | IBMWatsonBearerTokenAuthenticator authenticator = new IBMWatsonBearerTokenAuthenticator(props); 69 | } catch (IBMWatsonServiceExceptions.IllegalArgumentException e) { 70 | System.assert(e != null); 71 | } 72 | Test.stopTest(); 73 | } 74 | 75 | static testMethod void testEmptyBearerTokenMap() { 76 | Test.startTest(); 77 | Map props = new Map(); 78 | props.put(IBMWatsonCredentialUtils.PROP_NAME_BEARER_TOKEN, ''); 79 | try { 80 | IBMWatsonBearerTokenAuthenticator authenticator = new IBMWatsonBearerTokenAuthenticator(props); 81 | } catch (IBMWatsonServiceExceptions.IllegalArgumentException e) { 82 | System.assert(e != null); 83 | } 84 | Test.stopTest(); 85 | } 86 | 87 | static testMethod void testGoodMapConfig() { 88 | Test.startTest(); 89 | String token = 'abc-123'; 90 | Map props = new Map(); 91 | props.put(IBMWatsonCredentialUtils.PROP_NAME_BEARER_TOKEN, token); 92 | IBMWatsonBearerTokenAuthenticator authenticator = new IBMWatsonBearerTokenAuthenticator(props); 93 | System.assertEquals(IBMWatsonCredentialUtils.AUTH_TYPE_BEARER_TOKEN, authenticator.authenticationType()); 94 | System.assertEquals(token, authenticator.getBearerToken()); 95 | Test.stopTest(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonBearerTokenAuthenticatorTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonCP4DAuthenticatorTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonCP4DToken.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * This class holds relevant info re: a CP4D access token for use by the IBMWatsonCloudPakForDataAuthenticator class. 16 | */ 17 | public class IBMWatsonCP4DToken extends IBMWatsonAbstractToken { 18 | public String accessToken; 19 | public Long expirationTimeInMillis; 20 | 21 | /** 22 | * This ctor is used to store a user-managed access token which will never expire. 23 | * @param accessToken the user-managed access token 24 | */ 25 | public IBMWatsonCP4DToken(String accessToken) { 26 | this.accessToken = accessToken; 27 | this.expirationTimeInMillis = -1; 28 | } 29 | 30 | /** 31 | * This ctor will extract the CP4D access token from the specified IBMWatsonCP4DTokenResponse instance, 32 | * and compute the expiration time as "80% of the timeToLive added to the issued-at time". 33 | * This means that we'll trigger the acquisition of a new token shortly before it is set to expire. 34 | * @param response the IBMWatsonCP4DTokenResponse instance 35 | */ 36 | public IBMWatsonCP4DToken(IBMWatsonCP4DTokenResponse response) { 37 | this.accessToken = response.getAccessToken(); 38 | 39 | // To compute the expiration time, we'll need to crack open the accessToken value 40 | // which is a JWToken (Json Web Token) instance. 41 | IBMWatsonJSONWebToken jwt = new IBMWatsonJSONWebToken(this.accessToken); 42 | 43 | Long iat = jwt.getPayload().getIssuedAt(); 44 | Long exp = jwt.getPayload().getExpiresAt(); 45 | if (iat != null && exp != null) { 46 | Long ttl = exp - iat; 47 | this.expirationTimeInMillis = (iat + (Long) (0.8 * ttl)) * 1000; 48 | } else { 49 | throw new IBMWatsonServiceExceptions.ResponseException('Properties "iat" and "exp" MUST be present within the encoded access token'); 50 | } 51 | } 52 | 53 | /** 54 | * Returns true iff this object holds a valid non-expired access token. 55 | * @return true if token is valid and not expired, false otherwise 56 | */ 57 | public override boolean isTokenValid() { 58 | return !String.isBlank(this.accessToken) 59 | && (this.expirationTimeInMillis < 0 || System.now().getTime() <= this.expirationTimeInMillis); 60 | } 61 | 62 | public override String getAccessToken() { 63 | return this.accessToken; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonCP4DToken.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonCP4DTokenResponse.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * This class models a response received from the CP4D "get token" API. 16 | */ 17 | public class IBMWatsonCP4DTokenResponse extends IBMWatsonResponseModel implements IBMWatsonTokenServerResponse { 18 | private String username; 19 | private String role; 20 | private String[] permissions; 21 | private String sub; 22 | private String iss; 23 | private String aud; 24 | private String uid; 25 | private String accessToken; 26 | private String message; 27 | 28 | public String getUsername() { 29 | return username; 30 | } 31 | public void setUsername(String username) { 32 | this.username = username; 33 | } 34 | public String getRole() { 35 | return role; 36 | } 37 | public void setRole(String role) { 38 | this.role = role; 39 | } 40 | public String[] getPermissions() { 41 | return permissions; 42 | } 43 | public void setPermissions(String[] permissions) { 44 | this.permissions = permissions; 45 | } 46 | public String getSub() { 47 | return sub; 48 | } 49 | public void setSub(String sub) { 50 | this.sub = sub; 51 | } 52 | public String getIss() { 53 | return iss; 54 | } 55 | public void setIss(String iss) { 56 | this.iss = iss; 57 | } 58 | public String getAud() { 59 | return aud; 60 | } 61 | public void setAud(String aud) { 62 | this.aud = aud; 63 | } 64 | public String getUid() { 65 | return uid; 66 | } 67 | public void setUid(String uid) { 68 | this.uid = uid; 69 | } 70 | public String getAccessToken() { 71 | return accessToken; 72 | } 73 | public void setAccessToken(String accessToken) { 74 | this.accessToken = accessToken; 75 | } 76 | public String getMessage() { 77 | return message; 78 | } 79 | public void setMessage(String message) { 80 | this.message = message; 81 | } 82 | 83 | public override Object deserialize(String jsonString, Map jsonMap, Type classType) { 84 | if (jsonMap == null) { 85 | return null; 86 | } 87 | 88 | // replace any names that are different between the API and SDK 89 | Map propertyNameMapping = new Map { 90 | 'access_token' => 'accessToken' 91 | }; 92 | jsonString = IBMWatsonJSONUtil.replaceKeyNamesInString(jsonString, propertyNameMapping); 93 | jsonMap = IBMWatsonJSONUtil.replaceKeyNamesInMap(jsonMap, propertyNameMapping); 94 | 95 | IBMWatsonCP4DTokenResponse ret = (IBMWatsonCP4DTokenResponse) super.deserialize(jsonString, jsonMap, classType); 96 | 97 | return ret; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonCP4DTokenResponse.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonCP4DTokenTest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | @isTest 15 | private class IBMWatsonCP4DTokenTest { 16 | static testMethod void testConstructorAccessToken() { 17 | Test.startTest(); 18 | String accessToken = 'access-token'; 19 | IBMWatsonCP4DToken tokenModel = new IBMWatsonCP4DToken(accessToken); 20 | System.assert(tokenModel.isTokenValid()); 21 | Test.stopTest(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonCP4DTokenTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonClient.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public class IBMWatsonClient { 15 | private static final Integer REQUEST_TIMEOUT = 120000; 16 | 17 | private IBMWatsonClient() { 18 | // This is a utility class - no instantiation allowed. 19 | } 20 | 21 | /** 22 | * Executes the IBMWatsonRequest and returns an IBMWatsonResponse. 23 | */ 24 | public static IBMWatsonResponse executeRequest(IBMWatsonRequest wreq) { 25 | // build the httpRequest 26 | HttpRequest request = toHttpRequest(wreq); 27 | 28 | // Execute the httpRequest 29 | Http http = new Http(); 30 | HTTPResponse httpResponse = http.send(request); 31 | 32 | // Creates an IBMWatsonResponse based on the service URL and HttpResponse 33 | return new IBMWatsonResponse(request.getEndpoint(), httpResponse); 34 | } 35 | 36 | private static HttpRequest toHttpRequest(IBMWatsonRequest request) { 37 | HttpRequest httpRequest = new HttpRequest(); 38 | 39 | // Set request headers 40 | for (String name : request.getAllHeaders().keySet()) { 41 | httpRequest.setHeader(name, request.getAllHeaders().get(name)); 42 | } 43 | 44 | // Set request body 45 | if (request.getMethod().equals('POST') || request.getMethod().equals('PUT')) { 46 | if (request.getBody() instanceof IBMWatsonMultipartBody) { 47 | IBMWatsonMultipartBody multipartBody = (IBMWatsonMultipartBody) request.getBody(); 48 | if (multipartBody.form64() != null) { 49 | String form64 = multipartBody.form64(); 50 | httpRequest.setBodyAsBlob(EncodingUtil.base64Decode(form64)); 51 | httpRequest.setHeader('Content-Length', String.valueof(form64.length())); 52 | } else { 53 | Blob multipartBodyBlob = multipartBody.multipartBody(); 54 | httpRequest.setBodyAsBlob(multipartBodyBlob); 55 | httpRequest.setHeader('Content-Length', String.valueof(multipartBody.contentLength())); 56 | } 57 | } else if (request.getBody().contentType.toString().contains(IBMWatsonHttpMediaType.APPLICATION_JSON)) { 58 | httpRequest.setBody(request.getBody().content); 59 | } else { 60 | if (request.getBody().content != null) { 61 | httpRequest.setBody(request.getBody().content); 62 | } else { 63 | httpRequest.setBody(request.getBody().blobContent.toString()); 64 | } 65 | } 66 | } 67 | 68 | httpRequest.setMethod(request.getMethod()); 69 | httpRequest.setEndpoint(request.getUrl().toExternalForm()); 70 | httpRequest.setTimeout(REQUEST_TIMEOUT); 71 | return httpRequest; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonClient.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonCloudPakForDataAuthenticator.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonConfigBasedAuthFactoryTest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | @isTest 15 | private class IBMWatsonConfigBasedAuthFactoryTest { 16 | static testMethod void testCreateNoauth() { 17 | Test.startTest(); 18 | Map props = new Map(); 19 | props.put(IBMWatsonCredentialUtils.PROP_NAME_AUTH_TYPE, IBMWatsonCredentialUtils.AUTH_TYPE_NO_AUTH); 20 | 21 | IBMWatsonAuthenticator authenticator = IBMWatsonConfigBasedAuthenticatorFactory.createAuthenticator(props); 22 | System.assert(authenticator instanceof IBMWatsonNoAuthAuthenticator); 23 | Test.stopTest(); 24 | } 25 | 26 | static testMethod void testCreateBasic() { 27 | Test.startTest(); 28 | Map props = new Map(); 29 | props.put(IBMWatsonCredentialUtils.PROP_NAME_AUTH_TYPE, IBMWatsonCredentialUtils.AUTH_TYPE_BASIC); 30 | props.put(IBMWatsonCredentialUtils.PROP_NAME_USERNAME, 'username'); 31 | props.put(IBMWatsonCredentialUtils.PROP_NAME_PASSWORD, 'password'); 32 | 33 | IBMWatsonAuthenticator authenticator = IBMWatsonConfigBasedAuthenticatorFactory.createAuthenticator(props); 34 | System.assert(authenticator instanceof IBMWatsonBasicAuthenticator); 35 | Test.stopTest(); 36 | } 37 | 38 | static testMethod void testCreateIAM() { 39 | Test.startTest(); 40 | Map props = new Map(); 41 | props.put(IBMWatsonCredentialUtils.PROP_NAME_AUTH_TYPE, IBMWatsonCredentialUtils.AUTH_TYPE_IAM); 42 | props.put(IBMWatsonCredentialUtils.PROP_NAME_APIKEY, 'apikey'); 43 | 44 | IBMWatsonAuthenticator authenticator = IBMWatsonConfigBasedAuthenticatorFactory.createAuthenticator(props); 45 | System.assert(authenticator instanceof IBMWatsonIAMAuthenticator); 46 | Test.stopTest(); 47 | } 48 | 49 | static testMethod void testCreateCP4D() { 50 | Test.startTest(); 51 | Map props = new Map(); 52 | props.put(IBMWatsonCredentialUtils.PROP_NAME_AUTH_TYPE, IBMWatsonCredentialUtils.AUTH_TYPE_CP4D); 53 | props.put(IBMWatsonCredentialUtils.PROP_NAME_URL, 'url'); 54 | props.put(IBMWatsonCredentialUtils.PROP_NAME_USERNAME, 'username'); 55 | props.put(IBMWatsonCredentialUtils.PROP_NAME_PASSWORD, 'password'); 56 | 57 | IBMWatsonAuthenticator authenticator = IBMWatsonConfigBasedAuthenticatorFactory.createAuthenticator(props); 58 | System.assert(authenticator instanceof IBMWatsonCloudPakForDataAuthenticator); 59 | Test.stopTest(); 60 | } 61 | 62 | static testMethod void testCreateBearerToken() { 63 | Test.startTest(); 64 | Map props = new Map(); 65 | props.put(IBMWatsonCredentialUtils.PROP_NAME_AUTH_TYPE, IBMWatsonCredentialUtils.AUTH_TYPE_BEARER_TOKEN); 66 | props.put(IBMWatsonCredentialUtils.PROP_NAME_BEARER_TOKEN, 'token'); 67 | 68 | IBMWatsonAuthenticator authenticator = IBMWatsonConfigBasedAuthenticatorFactory.createAuthenticator(props); 69 | System.assert(authenticator instanceof IBMWatsonBearerTokenAuthenticator); 70 | Test.stopTest(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonConfigBasedAuthFactoryTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonConfigBasedAuthenticatorFactory.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * This class serves as an IBMWatsonAuthenticator factory. 16 | * It will detect and use various configuration sources in order to produce an IBMWatsonAuthenticator instance. 17 | */ 18 | public class IBMWatsonConfigBasedAuthenticatorFactory { 19 | 20 | // hidden since this is a utility class 21 | private IBMWatsonConfigBasedAuthenticatorFactory() {} 22 | 23 | /** 24 | * Retrieves authentication configuration information for the specified cloud service, 25 | * and returns an IBMWatsonAuthenticator instance, or null if the configuration information could not be found. 26 | * 27 | * @param serviceName the name of the cloud service whose authentication information should be retrieved 28 | * @return an IBMWatsonAuthenticator that reflects the properties that were found in the various config sources 29 | */ 30 | public static IBMWatsonAuthenticator getAuthenticator(String serviceName) { 31 | IBMWatsonAuthenticator authenticator = null; 32 | 33 | // Check to see if this service has any properties defined in a credential file. 34 | Map authProps = IBMWatsonCredentialUtils.getFileCredentialsAsMap(serviceName); 35 | 36 | // Now create an authenticator from the map. 37 | if (!authProps.isEmpty()) { 38 | authenticator = createAuthenticator(authProps); 39 | } 40 | 41 | return authenticator; 42 | } 43 | 44 | /** 45 | * Instantiates an IBMWatsonAuthenticator that reflects the properties contains in the specified Map. 46 | * 47 | * @param props a Map containing configuration properties 48 | * @return an IBMWatsonAuthenticator instance 49 | */ 50 | public static IBMWatsonAuthenticator createAuthenticator(Map props) { 51 | IBMWatsonAuthenticator authenticator = null; 52 | 53 | // If auth type was not specified, we'll use "iam" as the default. 54 | String authType = props.get(IBMWatsonCredentialUtils.PROP_NAME_AUTH_TYPE); 55 | if (String.isBlank(authType)) { 56 | authType = IBMWatsonCredentialUtils.AUTH_TYPE_IAM; 57 | } 58 | 59 | if (authType.equalsIgnoreCase(IBMWatsonCredentialUtils.AUTH_TYPE_NO_AUTH)) { 60 | authenticator = new IBMWatsonNoAuthAuthenticator(); 61 | } else if (authType.equalsIgnoreCase(IBMWatsonCredentialUtils.AUTH_TYPE_BASIC)) { 62 | authenticator = new IBMWatsonBasicAuthenticator(props); 63 | } else if (authType.equalsIgnoreCase(IBMWatsonCredentialUtils.AUTH_TYPE_IAM)) { 64 | authenticator = new IBMWatsonIAMAuthenticator(props); 65 | } else if (authType.equalsIgnoreCase(IBMWatsonCredentialUtils.AUTH_TYPE_CP4D)) { 66 | authenticator = new IBMWatsonCloudPakForDataAuthenticator(props); 67 | } else if (authType.equalsIgnoreCase(IBMWatsonCredentialUtils.AUTH_TYPE_BEARER_TOKEN)) { 68 | authenticator = new IBMWatsonBearerTokenAuthenticator(props); 69 | } 70 | 71 | return authenticator; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonConfigBasedAuthenticatorFactory.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonCredentialUtils.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public class IBMWatsonCredentialUtils { 15 | private static final String BASIC = 'Basic '; 16 | private static final String CREDENTIAL_FILE_NAME = 'ibm_credentials'; 17 | 18 | /** 19 | * Valid authentication types. 20 | */ 21 | public static final String AUTH_TYPE_BASIC = 'basic'; 22 | public static final String AUTH_TYPE_NO_AUTH = 'noauth'; 23 | public static final String AUTH_TYPE_IAM = 'iam'; 24 | public static final String AUTH_TYPE_CP4D = 'cp4d'; 25 | public static final String AUTH_TYPE_BEARER_TOKEN = 'bearerToken'; 26 | 27 | /** 28 | * Constants which define the names of external config properties (e.g. credential file). 29 | */ 30 | public static final String PROP_NAME_AUTH_TYPE = 'AUTH_TYPE'; 31 | public static final String PROP_NAME_USERNAME = 'USERNAME'; 32 | public static final String PROP_NAME_PASSWORD = 'PASSWORD'; 33 | public static final String PROP_NAME_BEARER_TOKEN = 'BEARER_TOKEN'; 34 | public static final String PROP_NAME_URL = 'AUTH_URL'; 35 | public static final String PROP_NAME_APIKEY = 'APIKEY'; 36 | public static final String PROP_NAME_CLIENT_ID = 'CLIENT_ID'; 37 | public static final String PROP_NAME_CLIENT_SECRET = 'CLIENT_SECRET'; 38 | 39 | 40 | private IBMWatsonCredentialUtils() { 41 | // This is a utility class - no instantiation allowed. 42 | } 43 | 44 | public static String toBasicAuth(String username, String password) { 45 | Blob blobValue = Blob.valueOf(username + ':' + password); 46 | return BASIC + EncodingUtil.base64Encode(blobValue); 47 | } 48 | 49 | /** 50 | * Returns true if the supplied value begins or ends with curly brackets or quotation marks. 51 | * 52 | * @param credentialValue the credential value to check 53 | * @return true if the value starts or ends with these characters and is therefore invalid 54 | */ 55 | public static Boolean hasBadStartOrEndChar(String credentialValue) { 56 | return credentialValue.startsWith('{') 57 | || credentialValue.startsWith('"') 58 | || credentialValue.endsWith('}') 59 | || credentialValue.endsWith('"'); 60 | } 61 | 62 | private static String getCredentialFileBody() { 63 | String fileContents = null; 64 | try { 65 | StaticResource credentialFileResource = [SELECT Id, Body FROM StaticResource WHERE Name = :CREDENTIAL_FILE_NAME LIMIT 1]; 66 | fileContents = credentialFileResource.Body.toString(); 67 | } catch (QueryException e) { 68 | System.debug(System.LoggingLevel.INFO, 'Could not find credential file in Static Resources'); 69 | } 70 | return fileContents; 71 | } 72 | 73 | public static Map parseCredentialFile(String serviceName, String fileContents) { 74 | Map props = new Map(); 75 | 76 | String[] lineList = fileContents.split('\r\n'); 77 | for (String line : lineList) { 78 | String[] keyAndVal = line.split('='); 79 | String lowercaseKey = keyAndVal[0].toLowerCase(); 80 | Integer serviceNameLength = serviceName.length(); 81 | 82 | if (lowercaseKey.contains(serviceName)) { 83 | String credentialType = lowercaseKey.substring(serviceNameLength + 1); 84 | String credentialValue = keyAndVal[1]; 85 | if (String.isNotBlank(credentialType) && String.isNotBlank(credentialValue)) { 86 | props.put(credentialType.toUpperCase(), credentialValue); 87 | } 88 | } 89 | } 90 | 91 | return props; 92 | } 93 | 94 | public static Map getFileCredentialsAsMap(String serviceName) { 95 | Map fileCredentials = new Map(); 96 | String fileContents = getCredentialFileBody(); 97 | 98 | if (fileContents != null) { 99 | fileCredentials = parseCredentialFile(serviceName, fileContents); 100 | } 101 | 102 | return fileCredentials; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonCredentialUtils.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonCredentialUtilsTest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | @isTest 15 | private class IBMWatsonCredentialUtilsTest { 16 | private static String testCredentialFileContents = 'DISCOVERY_USERNAME=disco_username\r\n' 17 | + 'DISCOVERY_PASSWORD=disco_password\r\n' 18 | + 'NATURAL_LANGUAGE_CLASSIFIER_APIKEY=nlc_apikey'; 19 | 20 | static testMethod void testHasBadStartOrEndChar() { 21 | // valid 22 | System.assert(!IBMWatsonCredentialUtils.hasBadStartOrEndChar('this_is_fine')); 23 | 24 | // starting bracket 25 | System.assert(IBMWatsonCredentialUtils.hasBadStartOrEndChar('{bad_username')); 26 | System.assert(IBMWatsonCredentialUtils.hasBadStartOrEndChar('{{still_bad')); 27 | 28 | // ending bracket 29 | System.assert(IBMWatsonCredentialUtils.hasBadStartOrEndChar('invalid}')); 30 | System.assert(IBMWatsonCredentialUtils.hasBadStartOrEndChar('also_invalid}}')); 31 | 32 | // starting quote 33 | System.assert(IBMWatsonCredentialUtils.hasBadStartOrEndChar('"not_allowed_either')); 34 | System.assert(IBMWatsonCredentialUtils.hasBadStartOrEndChar('""still_not')); 35 | 36 | // ending quote 37 | System.assert(IBMWatsonCredentialUtils.hasBadStartOrEndChar('nope"')); 38 | System.assert(IBMWatsonCredentialUtils.hasBadStartOrEndChar('sorry""')); 39 | } 40 | 41 | static testMethod void testParsingCredentialFileNoService() { 42 | Map serviceCredentials = IBMWatsonCredentialUtils.parseCredentialFile('assistant', testCredentialFileContents); 43 | System.assert(serviceCredentials.isEmpty()); 44 | } 45 | 46 | static testMethod void testParsingCredentialFileUsernameAndPassword() { 47 | String expectedUsername = 'disco_username'; 48 | String expectedPassword = 'disco_password'; 49 | 50 | Map serviceCredentials = IBMWatsonCredentialUtils.parseCredentialFile('discovery', testCredentialFileContents); 51 | System.assertEquals(expectedUsername, serviceCredentials.get(IBMWatsonCredentialUtils.PROP_NAME_USERNAME)); 52 | System.assertEquals(expectedPassword, serviceCredentials.get(IBMWatsonCredentialUtils.PROP_NAME_PASSWORD)); 53 | } 54 | 55 | static testMethod void testParsingCredentialFileApikey() { 56 | String expectedApikey = 'nlc_apikey'; 57 | 58 | Map serviceCredentials = IBMWatsonCredentialUtils.parseCredentialFile('natural_language_classifier', testCredentialFileContents); 59 | System.assertEquals(expectedApikey, serviceCredentials.get(IBMWatsonCredentialUtils.PROP_NAME_APIKEY)); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonCredentialUtilsTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonDynamicModel.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public virtual class IBMWatsonDynamicModel extends IBMWatsonGenericModel { 15 | private Map additionalProperties; 16 | 17 | public Object get(String key) { 18 | if (additionalProperties == null) { 19 | additionalProperties = new Map(); 20 | } 21 | return additionalProperties.get(key); 22 | } 23 | 24 | public void put(String key, Object val) { 25 | if (additionalProperties == null) { 26 | additionalProperties = new Map(); 27 | } 28 | additionalProperties.put(key, val); 29 | } 30 | 31 | public Map getDynamicProperties() { 32 | return this.additionalProperties; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonDynamicModel.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonDynamicResponseModel.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2018, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public virtual class IBMWatsonDynamicResponseModel extends IBMWatsonResponseModel { 15 | private Map additionalProperties; 16 | 17 | public Object get(String key) { 18 | if (additionalProperties == null) { 19 | additionalProperties = new Map(); 20 | } 21 | return additionalProperties.get(key); 22 | } 23 | 24 | public void put(String key, Object val) { 25 | if (additionalProperties == null) { 26 | additionalProperties = new Map(); 27 | } 28 | additionalProperties.put(key, val); 29 | } 30 | 31 | public Map getDynamicProperties() { 32 | return this.additionalProperties; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonDynamicResponseModel.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonDynamicResponseModelTest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | @isTest 15 | private class IBMWatsonDynamicResponseModelTest { 16 | private class TestModel extends IBMWatsonDynamicResponseModel {} 17 | 18 | static testMethod void testAdditionalProps() { 19 | Test.startTest(); 20 | 21 | String testKey = 'key'; 22 | String testVal = 'val'; 23 | TestModel testModel = new TestModel(); 24 | 25 | testModel.put(testKey, testVal); 26 | System.assertEquals(testVal, testModel.get(testKey)); 27 | System.assert(testModel.getDynamicProperties().size() == 1); 28 | 29 | Test.stopTest(); 30 | } 31 | 32 | static testMethod void testGetEmptyAdditionalProps() { 33 | Test.startTest(); 34 | 35 | TestModel testModel = new TestModel(); 36 | Object nullResponse = testModel.get('nonexistent key'); 37 | System.assert(nullResponse == null); 38 | 39 | Test.stopTest(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonDynamicResponseModelTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonFile.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public class IBMWatsonFile { 15 | 16 | private String name; 17 | private String description; 18 | private String contentType; 19 | private Long bodyLength; 20 | private Blob body; 21 | 22 | /** 23 | * File Builder. 24 | */ 25 | public class FileBuilder { 26 | 27 | private String name; 28 | private String description; 29 | private String contentType; 30 | private Long bodyLength; 31 | private Blob body; 32 | 33 | /** 34 | * Instantiates a new builder. 35 | */ 36 | public FileBuilder() { 37 | } 38 | 39 | /** 40 | * Set the file name. 41 | * 42 | * @param name the file name 43 | * @return the FileBuilder builder 44 | */ 45 | public FileBuilder name(String name) { 46 | this.name = name; 47 | return this; 48 | } 49 | 50 | 51 | /** 52 | * Set the file information based on the Attachment. 53 | * 54 | * @param attach the attachment 55 | * @return the FileBuilder builder 56 | */ 57 | public FileBuilder attachment(Attachment attach) { 58 | this.name = attach.name; 59 | this.body = attach.Body; 60 | this.description = attach.Description; 61 | this.contentType = attach.ContentType; 62 | return this; 63 | } 64 | 65 | /** 66 | * Set the file description if any. 67 | * 68 | * @param Description the file description 69 | * @return the FileBuilder builder 70 | */ 71 | public FileBuilder description(String description) { 72 | this.description = description; 73 | return this; 74 | } 75 | 76 | /** 77 | * Set the file content type. 78 | * 79 | * @param ContentType the file content type 80 | * @return the FileBuilder builder 81 | */ 82 | public FileBuilder contentType(String contentType) { 83 | this.contentType = contentType; 84 | return this; 85 | } 86 | 87 | /** 88 | * Set the file body as a blob type (base64). 89 | * 90 | * @param Body the file base64 content 91 | * @return the FileBuilder builder 92 | */ 93 | public FileBuilder body(Blob body) { 94 | this.body = body; 95 | this.bodyLength = body != null ? body.size() : -1; 96 | return this; 97 | } 98 | 99 | /** 100 | * Builds a IBMWatsonFile. 101 | * 102 | * @return the IBMWatsonFile 103 | */ 104 | public IBMWatsonFile build() { 105 | return new IBMWatsonFile(this); 106 | } 107 | } 108 | 109 | private IBMWatsonFile(FileBuilder builder) { 110 | this.name = builder.name; 111 | this.description = builder.description; 112 | this.contentType = builder.contentType; 113 | this.bodyLength = builder.bodyLength; 114 | this.body = builder.body; 115 | } 116 | 117 | 118 | public String name() { 119 | return this.name; 120 | } 121 | 122 | public String description() { 123 | return this.description; 124 | } 125 | 126 | public String contentType() { 127 | return this.contentType; 128 | } 129 | 130 | public Long bodyLength() { 131 | return this.bodyLength; 132 | } 133 | 134 | public Blob body() { 135 | return this.body; 136 | } 137 | 138 | public String bodyAsString() { 139 | if (this.body != null) { 140 | return this.body.toString(); 141 | } 142 | return null; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonFile.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonFormBody.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2018, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public class IBMWatsonFormBody extends IBMWatsonRequestBody { 15 | 16 | private static final String ENCODING_SCHEME = 'UTF-8'; 17 | private static final String CONTENT_TYPE = 'application/x-www-form-urlencoded'; 18 | 19 | private List names; 20 | private List values; 21 | 22 | private IBMWatsonFormBody(Builder builder) { 23 | this.names = builder.names; 24 | this.values = builder.values; 25 | this.contentType = IBMWatsonMediaType.parse(CONTENT_TYPE); 26 | writeContent(); 27 | } 28 | 29 | private void writeContent() { 30 | this.content = ''; 31 | for (Integer i = 0; i < names.size(); i++) { 32 | if (i > 0) { 33 | content += '&'; 34 | } 35 | this.content += names.get(i) + '=' + values.get(i); 36 | } 37 | } 38 | 39 | public class Builder { 40 | private List names = new List(); 41 | private List values = new List(); 42 | 43 | public Builder add(String name, String value) { 44 | names.add(EncodingUtil.urlEncode(name, ENCODING_SCHEME)); 45 | values.add(EncodingUtil.urlEncode(value, ENCODING_SCHEME)); 46 | return this; 47 | } 48 | 49 | public IBMWatsonFormBody build() { 50 | return new IBMWatsonFormBody(this); 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonFormBody.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonGenericModel.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public virtual class IBMWatsonGenericModel { 15 | 16 | /** 17 | * Allows user to see the JSON string by default for easier debugging. 18 | * 19 | * @return serialized String form of this 20 | */ 21 | public virtual override String toString() { 22 | // get Map representation and raise additional props 23 | Map objectMap = (Map) JSON.deserializeUntyped(JSON.serialize(this, true)); 24 | objectMap = IBMWatsonJSONUtil.raiseAdditionalProperties(objectMap); 25 | 26 | // pretty print formatting 27 | return JSON.serializePretty(objectMap); 28 | } 29 | 30 | /** 31 | * Allows comparison of custom models based on their serialized String form. 32 | * 33 | * @param obj the object this is being compared to 34 | * 35 | * @return Boolean indicating whether or not the two objects are equal 36 | */ 37 | public Boolean equals(Object obj) { 38 | if ((obj == null)) { 39 | return false; 40 | } 41 | 42 | IBMWatsonGenericModel other = (IBMWatsonGenericModel) obj; 43 | 44 | return this.toString().equals(other.toString()); 45 | } 46 | 47 | public virtual Object deserialize(String jsonString, Map jsonMap, Type classType) { 48 | if (jsonMap == null) { 49 | return null; 50 | } 51 | 52 | Object ret; 53 | if (jsonString.equals('null')) { 54 | ret = classType.newInstance(); 55 | } 56 | else { 57 | ret = JSON.deserialize(jsonString, classType); 58 | } 59 | 60 | return ret; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonGenericModel.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonHttpHeaders.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonHttpMediaType.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonHttpStatus.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonIAMAuthenticator.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonIAMAuthenticatorTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonIAMToken.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2018, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * Represents response from IAM API. 16 | */ 17 | public class IBMWatsonIAMToken extends IBMWatsonAbstractToken implements IBMWatsonTokenServerResponse { 18 | private String accessToken; 19 | private String refreshToken; 20 | private String tokenType; 21 | private Long expiresIn; 22 | private Long expiration; 23 | 24 | public Long getExpiresIn() { 25 | return expiresIn; 26 | } 27 | 28 | public Long getExpiration() { 29 | return expiration; 30 | } 31 | 32 | public override Object deserialize(String jsonString, Map jsonMap, Type classType) { 33 | if (jsonMap == null) { 34 | return null; 35 | } 36 | 37 | // replace any names that are different between the API and SDK 38 | Map propertyNameMapping = new Map { 39 | 'access_token' => 'accessToken', 40 | 'refresh_token' => 'refreshToken', 41 | 'token_type' => 'tokenType', 42 | 'expires_in' => 'expiresIn' 43 | }; 44 | jsonString = IBMWatsonJSONUtil.replaceKeyNamesInString(jsonString, propertyNameMapping); 45 | jsonMap = IBMWatsonJSONUtil.replaceKeyNamesInMap(jsonMap, propertyNameMapping); 46 | 47 | IBMWatsonIAMToken ret = (IBMWatsonIAMToken) super.deserialize(jsonString, jsonMap, classType); 48 | 49 | return ret; 50 | } 51 | 52 | /** 53 | * Returns true iff this object holds a valid non-expired access token. 54 | * @return true if token is valid and not expired, false otherwise 55 | */ 56 | public override boolean isTokenValid() { 57 | if (getAccessToken() == null || getExpiresIn() == null || getExpiration() == null) { 58 | return false; 59 | } 60 | 61 | Double fractionOfTimeToLive = 0.8; 62 | Long timeToLive = getExpiresIn(); 63 | Long expirationTime = getExpiration(); 64 | Double refreshTime = expirationTime - (timeToLive * (1.0 - fractionOfTimeToLive)); 65 | Double currentTime = Math.floor(System.now().getTime() / 1000); 66 | 67 | return currentTime < refreshTime; 68 | } 69 | 70 | public override String getAccessToken() { 71 | return this.accessToken; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonIAMToken.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonJSONUtil.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /* 15 | * Utility class to handle any special JSON serialization/deserialization beyond the 16 | * scope of the default JSON methods. 17 | */ 18 | public class IBMWatsonJSONUtil { 19 | 20 | /** 21 | * Replaces top-level keys in a map based on the provided mapping. 22 | * 23 | * @param jsonMap the map on which key substitution will be performed 24 | * @param nameMapping Map containing names to replace and the value to use instead 25 | * 26 | * @return the map with keys replaced 27 | */ 28 | public static Map replaceKeyNamesInMap(Map jsonMap, Map nameMapping) { 29 | for (String key : jsonMap.keySet()) { 30 | if (nameMapping.containsKey(key)) { 31 | String replacementKey = nameMapping.get(key); 32 | jsonMap.put(replacementKey, jsonMap.get(key)); 33 | jsonMap.remove(key); 34 | } 35 | } 36 | return jsonMap; 37 | } 38 | 39 | /** 40 | * Replaces top-level keys in a JSON string based on the provided mapping. 41 | * 42 | * @param jsonString the string on which key substitution will be performed 43 | * @param nameMapping Map containing names to replace and the value to use instead 44 | * 45 | * @return the string with keys replaced 46 | */ 47 | public static String replaceKeyNamesInString(String jsonString, Map nameMapping) { 48 | Map jsonMap = (Map) JSON.deserializeUntyped(jsonString); 49 | jsonMap = replaceKeyNamesInMap(jsonMap, nameMapping); 50 | return JSON.serialize(jsonMap); 51 | } 52 | 53 | /** 54 | * Brings additional properties on dynamic models up one JSON level so that they can 55 | * be processed properly by the service. 56 | * 57 | * @param jsonMap Map representation of the JSON request 58 | * 59 | * @return Map representing the JSON request with moved additional properties 60 | */ 61 | public static Map raiseAdditionalProperties(Map jsonMap) { 62 | Map additionalProperties = (Map) jsonMap.get('additionalProperties'); 63 | if (additionalProperties != null) { 64 | for (String key : additionalProperties.keySet()) { 65 | jsonMap.put(key, additionalProperties.get(key)); 66 | } 67 | jsonMap.remove('additionalProperties'); 68 | } 69 | 70 | for (String key : jsonMap.keySet()) { 71 | Object jsonSection = jsonMap.get(key); 72 | if (jsonSection instanceof Map) { 73 | Map raisedSection = raiseAdditionalProperties((Map) jsonSection); 74 | jsonMap.put(key, raisedSection); 75 | } 76 | if (jsonSection instanceof List) { 77 | List raisedSection = raiseAdditionalPropertiesList((List) jsonSection); 78 | jsonMap.put(key, raisedSection); 79 | } 80 | } 81 | 82 | return jsonMap; 83 | } 84 | 85 | /** 86 | * Helper function for the public method to specifically handle JSON arrays. 87 | * 88 | * @param jsonList List representation of the current JSON array 89 | * 90 | * @return List with any nested additional properties brought up a level 91 | */ 92 | private static List raiseAdditionalPropertiesList(List jsonList) { 93 | List modifiedList = new List(); 94 | for (Object val : jsonList) { 95 | if (val instanceof Map) { 96 | modifiedList.add(raiseAdditionalProperties((Map) val)); 97 | } else { 98 | modifiedList.add(val); 99 | } 100 | } 101 | return modifiedList; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonJSONUtil.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonJSONUtilTest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | @isTest 15 | private class IBMWatsonJSONUtilTest { 16 | static testMethod void testReplaceKeyNamesInMap() { 17 | String mockJson = '{"foo":"bar","go":"bucks"}'; 18 | Map mockObject = (Map) JSON.deserializeUntyped(mockJson); 19 | Map propertyMapping = new Map { 'foo' => 'oof' }; 20 | String expectedJson = '{"oof":"bar","go":"bucks"}'; 21 | Map expectedMap = (Map) JSON.deserializeUntyped(expectedJson); 22 | 23 | Map actualMap = IBMWatsonJSONUtil.replaceKeyNamesInMap(mockObject, propertyMapping); 24 | 25 | System.assert(expectedMap.equals(actualMap)); 26 | } 27 | 28 | static testMethod void testReplaceKeyNamesInString() { 29 | String mockJson = '{"foo":"bar","go":"bucks"}'; 30 | Map propertyMapping = new Map { 'foo' => 'oof' }; 31 | String expectedJson = '{"oof":"bar","go":"bucks"}'; 32 | Map expectedMap = (Map) JSON.deserializeUntyped(expectedJson); 33 | 34 | Map actualMap = (Map) JSON.deserializeUntyped(IBMWatsonJSONUtil.replaceKeyNamesInString(mockJson, propertyMapping)); 35 | 36 | System.assert(expectedMap.equals(actualMap)); 37 | } 38 | 39 | /** 40 | * Test that additional properties are brought up a level as expected with flat JSON. 41 | */ 42 | static testMethod void testRaiseAdditionalPropertiesFlat() { 43 | String mockJson = '{"foo":"bar","additionalProperties":{"drink": "coffee"}}'; 44 | Map mockObject = (Map) JSON.deserializeUntyped(mockJson); 45 | String expectedJson = '{"foo":"bar","drink":"coffee"}'; 46 | Map expectedMap = (Map) JSON.deserializeUntyped(expectedJson); 47 | 48 | Map actualMap = IBMWatsonJSONUtil.raiseAdditionalProperties(mockObject); 49 | 50 | System.assert(expectedMap.equals(actualMap)); 51 | } 52 | 53 | /** 54 | * Test that additional properties are brought up a level as expected with nested JSON. 55 | */ 56 | static testMethod void testRaiseAdditionalPropertiesNested() { 57 | String mockJson = '{"foo":"bar","ohio":{"city":"columbus","additionalProperties": {"very":"cool"}}}'; 58 | Map mockObject = (Map) JSON.deserializeUntyped(mockJson); 59 | String expectedJson = '{"foo":"bar","ohio":{"city":"columbus","very":"cool"}}'; 60 | Map expectedMap = (Map) JSON.deserializeUntyped(expectedJson); 61 | 62 | Map actualMap = IBMWatsonJSONUtil.raiseAdditionalProperties(mockObject); 63 | 64 | System.assert(expectedMap.equals(actualMap)); 65 | } 66 | 67 | /** 68 | * Test that additional properties are brought up a level as expected with JSON containing an array. 69 | */ 70 | static testMethod void testRaiseAdditionalPropertiesList() { 71 | String mockJson = '{"foo":"bar","teams":[{"soccer":"crew","basketball":{"name": "cavaliers","additionalProperties":{"king":"lebron"}}}]}'; 72 | Map mockObject = (Map) JSON.deserializeUntyped(mockJson); 73 | String expectedJson = '{"foo":"bar","teams":[{"soccer":"crew","basketball":{"name": "cavaliers","king":"lebron"}}]}'; 74 | Map expectedMap = (Map) JSON.deserializeUntyped(expectedJson); 75 | 76 | Map actualMap = IBMWatsonJSONUtil.raiseAdditionalProperties(mockObject); 77 | 78 | System.assert(expectedMap.equals(actualMap)); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonJSONUtilTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonJSONWebToken.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public class IBMWatsonJSONWebToken { 15 | private Map header; 16 | private Payload payload; 17 | 18 | /** 19 | * Ctor which accepts the encoded JWT as a string. This ctor will parse 20 | * the JWT into its header and payload parts 21 | * @param encodedToken a string representing the encoded JWT. 22 | */ 23 | public IBMWatsonJSONWebToken(String encodedToken) { 24 | // Split the encoded jwt string into the header, payload, and signature 25 | String[] decodedParts = encodedToken.split('\\.'); 26 | 27 | String tokenJson; 28 | 29 | // Decode and parse the header. 30 | tokenJson = EncodingUtil.base64Decode(decodedParts[0]).toString(); 31 | header = (Map) JSON.deserializeUntyped(tokenJson); 32 | 33 | // Decode and parse the body. 34 | tokenJson = EncodingUtil.base64Decode(decodedParts[1]).toString(); 35 | payload = (Payload) JSON.deserialize(tokenJson, Payload.class); 36 | } 37 | 38 | public Map getHeader() { 39 | return header; 40 | } 41 | 42 | public Payload getPayload() { 43 | return payload; 44 | } 45 | 46 | public class Payload { 47 | private Long iat; 48 | private Long exp; 49 | private String sub; 50 | private String iss; 51 | private String aud; 52 | private String uid; 53 | private String username; 54 | private String role; 55 | 56 | public Payload() {} 57 | 58 | /** 59 | * Returns the "Issued At" ("iat") value within this JsonWebToken. 60 | * @return the iat value 61 | */ 62 | public Long getIssuedAt() { 63 | return iat; 64 | } 65 | 66 | /** 67 | * Returns the "Expires At" ("exp") value within this JsonWebToken. 68 | * @return the exp value 69 | */ 70 | public Long getExpiresAt() { 71 | return exp; 72 | } 73 | 74 | /** 75 | * Returns the "Subject" ("sub") value with this JsonWebToken. 76 | * @return the sub value 77 | */ 78 | public String getSubject() { 79 | return sub; 80 | } 81 | 82 | /** 83 | * Returns the "Issuer" ("iss") value with this JsonWebToken. 84 | * @return the iss value 85 | */ 86 | public String getIssuer() { 87 | return iss; 88 | } 89 | 90 | /** 91 | * Returns the "Audience" ("aud") value with this JsonWebToken. 92 | * @return the aud value 93 | */ 94 | public String getAudience() { 95 | return aud; 96 | } 97 | 98 | /** 99 | * Returns the "Userid" ("uid") value with this JsonWebToken. 100 | * @return the uid value 101 | */ 102 | public String getUserId() { 103 | return uid; 104 | } 105 | 106 | /** 107 | * Returns the "Username" ("username") value with this JsonWebToken. 108 | * @return the username value 109 | */ 110 | public String getUsername() { 111 | return username; 112 | } 113 | 114 | /** 115 | * Returns the "Role" ("role") value with this JsonWebToken. 116 | * @return the role value 117 | */ 118 | public String getRole() { 119 | return role; 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonJSONWebToken.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonJSONWebTokenTest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | @isTest 15 | private class IBMWatsonJSONWebTokenTest { 16 | private static String encodedToken = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6IkFkbWluIiwicGVybWlzc2lvbnMiOlsiYWRtaW5pc3RyYXRvciIsIm1hbmFnZV9jYXRhbG9nIiwiYWNjZXNzX2NhdGFsb2ciLCJtYW5hZ2VfcG9saWNpZXMiLCJhY2Nlc3NfcG9saWNpZXMiLCJ2aXJ0dWFsaXplX3RyYW5zZm9ybSIsImNhbl9wcm92aXNpb24iLCJkZXBsb3ltZW50X2FkbWluIl0sInN1YiI6ImFkbWluIiwiaXNzIjoiS05PWFNTTyIsImF1ZCI6IkRTWCIsInVpZCI6Ijk5OSIsImlhdCI6MTU1OTMyODk1NSwiZXhwIjo5OTk5OTk5OTk5OTk5OTk5OTl9.GE-ML3JWmI3oB0z5mjMG3jFtYVVA5bQCsOTOOj9ab7PcgJc1mA5hn1sONkO0JAFADhUoAgpG4KgQef5tjnCSrtl1tbnDuhaP1DH4QKMCZOkWrKyfQ2X8P1jhyJmV-KpE4wuTrGdMoMVj4wVRZwnxMRSK6LhV6pIzyOLLYR21zcW_2KcKWxCYfIC7tiM1d2PSM5nWa_5Vb068F8PtdiFUElEYHYKrvmwpV57_k2jpXoY6zw8PDcIiWQe3g20w6vCB6zWhxbcFWyjMg1tPOZHgTNNskPShHQBbtZFsSrc7rkNPzttKF70m7_JqrRYUZDNN8TmuR9uyitwxEFkr2L0WDQ'; 17 | 18 | static testMethod void testConstructor() { 19 | IBMWatsonJSONWebToken jwt = new IBMWatsonJSONWebToken(encodedToken); 20 | System.assert(jwt.getHeader() != null); 21 | System.assert(jwt.getPayload() != null); 22 | System.assert(jwt.getPayload().getExpiresAt() != null); 23 | System.assert(jwt.getPayload().getIssuedAt() != null); 24 | System.assert(jwt.getPayload().getAudience() != null); 25 | System.assert(jwt.getPayload().getIssuer() != null); 26 | System.assert(jwt.getPayload().getRole() != null); 27 | System.assert(jwt.getPayload().getSubject() != null); 28 | System.assert(jwt.getPayload().getUserId() != null); 29 | System.assert(jwt.getPayload().getUsername() != null); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonJSONWebTokenTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonMapModel.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * Class used to represent model properties of type Map, since the base deserializer can't handle 16 | * deserializing that type. 17 | */ 18 | public class IBMWatsonMapModel extends IBMWatsonDynamicModel { 19 | 20 | public override Object deserialize(String jsonString, Map jsonMap, Type classType) { 21 | if (jsonMap == null) { 22 | return null; 23 | } 24 | 25 | IBMWatsonMapModel ret = (IBMWatsonMapModel) super.deserialize(jsonString, jsonMap, classType); 26 | 27 | Set baseProps = ((Map) JSON.deserializeUntyped(JSON.serialize(this))).keySet(); 28 | 29 | for (String key : jsonMap.keySet()) { 30 | if (!baseProps.contains(key)) { 31 | ret.put(key, jsonMap.get(key)); 32 | } 33 | } 34 | 35 | return ret; 36 | } 37 | 38 | public Map replacePropertyNames() { 39 | // get map representation of current model 40 | Map jsonMap = (Map) JSON.deserializeUntyped(JSON.serialize(this)); 41 | 42 | jsonMap = IBMWatsonJSONUtil.raiseAdditionalProperties(jsonMap); 43 | 44 | return jsonMap; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonMapModel.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonMediaType.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public class IBMWatsonMediaType { 15 | 16 | private static final String TOKEN = '([a-zA-Z0-9-!#$%&\'*+.^_`{|}~]+)'; 17 | private static final String QUOTED = '"([^"]*)"'; 18 | private static final System.Pattern TYPE_SUBTYPE = System.Pattern.compile(TOKEN + '/' + TOKEN); 19 | private static final System.Pattern PARAMETER = System.Pattern.compile(';\\s*(?:' + TOKEN + '=(?:' + TOKEN + '|' + QUOTED + '))?'); 20 | 21 | private final String mediaType; 22 | public final String typeM {public get; private set;} 23 | public final String subtype {public get; private set;} 24 | public final String charset {public get; private set;} 25 | 26 | private IBMWatsonMediaType(String mediaType, String typeM, String subtype, String charset) { 27 | this.mediaType = mediaType; 28 | this.typeM = typeM; 29 | this.subtype = subtype; 30 | this.charset = charset; 31 | } 32 | 33 | /** 34 | * Returns a media type for {@code string}, or null if {@code string} is not a well-formed media 35 | * type. 36 | */ 37 | public static IBMWatsonMediaType parse(String str) { 38 | Matcher typeSubtypeMatcher = TYPE_SUBTYPE.matcher(str); 39 | if (!typeSubtypeMatcher.lookingAt()) return null; 40 | String typeStr = typeSubtypeMatcher.group(1).toLowerCase('en'); 41 | String subtype = typeSubtypeMatcher.group(2).toLowerCase('en'); 42 | String charset = null; 43 | Matcher parameterMatcher = PARAMETER.matcher(str); 44 | for (integer s = typeSubtypeMatcher.end(); s < str.length(); s = parameterMatcher.end()) { 45 | parameterMatcher.region(s, str.length()); 46 | if (!parameterMatcher.lookingAt()) { 47 | return null; // This is not a well-formed media type. 48 | } 49 | String name; 50 | if (parameterMatcher.groupCount() > 0) { 51 | name = parameterMatcher.group(1); 52 | } 53 | if (name == null || !name.equalsIgnoreCase('charset')) continue; 54 | String charsetParameter; 55 | String token; 56 | if (parameterMatcher.groupCount() > 1) { 57 | token = parameterMatcher.group(2); 58 | } 59 | if (token != null) { 60 | // If the token is 'single-quoted' it's invalid! But we're lenient and strip the quotes. 61 | charsetParameter = (token.startsWith('\'') && token.endsWith('\'') && token.length() > 2) 62 | ? token.substring(1, token.length() - 1) 63 | : token; 64 | } else { 65 | // Value is "double-quoted". That's valid and our regex group already strips the quotes. 66 | charsetParameter = parameterMatcher.group(3); 67 | } 68 | if (charset != null && !charsetParameter.equalsIgnoreCase(charset)) { 69 | return null; // Multiple different charsets! 70 | } 71 | charset = charsetParameter; 72 | } 73 | return new IBMWatsonMediaType(str, typeStr, subtype, charset); 74 | } 75 | 76 | /** 77 | * Returns the encoded media type, like "text/plain; charset=utf-8", appropriate for use in a 78 | * Content-Type header. 79 | */ 80 | public override String toString() { 81 | return mediaType; 82 | } 83 | 84 | public boolean equals(Object other) { 85 | return other instanceof IBMWatsonMediaType && ((IBMWatsonMediaType) other).mediaType.equals(mediaType); 86 | } 87 | 88 | 89 | public integer hashCode() { 90 | return mediaType.hashCode(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonMediaType.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonMockHttpResponse.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public class IBMWatsonMockHttpResponse implements HttpCalloutMock { 15 | protected Integer code; 16 | protected String status; 17 | protected String bodyAsString; 18 | protected Blob bodyAsBlob; 19 | protected Map responseHeaders; 20 | 21 | public IBMWatsonMockHttpResponse(Integer code, String status, String body, Map responseHeaders) { 22 | this.code = code; 23 | this.status = status; 24 | this.bodyAsString = body; 25 | this.bodyAsBlob = null; 26 | this.responseHeaders = responseHeaders; 27 | } 28 | 29 | public HTTPResponse respond(HTTPRequest req) { 30 | HttpResponse resp = new HttpResponse(); 31 | resp.setStatusCode(code); 32 | resp.setStatus(status); 33 | if (bodyAsBlob != null) { 34 | resp.setBodyAsBlob(bodyAsBlob); 35 | } else { 36 | resp.setBody(bodyAsString); 37 | } 38 | 39 | if (responseHeaders != null) { 40 | for (String key : responseHeaders.keySet()) { 41 | resp.setHeader(key, responseHeaders.get(key)); 42 | } 43 | } 44 | return resp; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonMockHttpResponse.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonMockResponses.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonMultipartBody.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonNoAuthAuthenticator.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public class IBMWatsonNoAuthAuthenticator implements IBMWatsonAuthenticator { 15 | public IBMWatsonNoAuthAuthenticator() {} 16 | 17 | public String authenticationType() { 18 | return IBMWatsonCredentialUtils.AUTH_TYPE_NO_AUTH; 19 | } 20 | 21 | public void authenticate(IBMWatsonRequest.Builder requestBuilder) { 22 | // do nothing 23 | } 24 | 25 | public void validate() {} 26 | } 27 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonNoAuthAuthenticator.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonNoAuthAuthenticatorTest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | @isTest 15 | private class IBMWatsonNoAuthAuthenticatorTest { 16 | static testMethod void testAuthenticationType() { 17 | Test.startTest(); 18 | IBMWatsonNoauthAuthenticator authenticator = new IBMWatsonNoauthAuthenticator(); 19 | authenticator.authenticate(new IBMWatsonRequest.Builder()); 20 | System.assertEquals(IBMWatsonCredentialUtils.AUTH_TYPE_NO_AUTH, authenticator.authenticationType()); 21 | Test.stopTest(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonNoAuthAuthenticatorTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonOptionsModel.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2018, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public virtual class IBMWatsonOptionsModel { 15 | public Map requestHeaders = new Map(); 16 | 17 | /** 18 | * Gets the internal request headers. 19 | */ 20 | public Map requestHeaders() { 21 | return this.requestHeaders; 22 | } 23 | 24 | public virtual Map getSdkToApiMapping() { 25 | return new Map(); 26 | } 27 | 28 | public virtual Map getApiToSdkMapping() { 29 | return new Map(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonOptionsModel.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonRequest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public class IBMWatsonRequest { 15 | 16 | private final URL url; 17 | private final String method; 18 | private final Map headers; 19 | private final IBMWatsonRequestBody body; 20 | 21 | private IBMWatsonRequest(Builder builder) { 22 | if (builder == null) { 23 | throw new IBMWatsonServiceExceptions.IllegalArgumentException('builder cannot be null'); 24 | } 25 | 26 | this.url = builder.url; 27 | this.method = builder.method; 28 | this.headers = new Map(); 29 | this.headers.putAll(builder.headers); 30 | if (builder.body != null) { 31 | this.body = builder.body.clone(); 32 | } 33 | } 34 | 35 | public URL getUrl() { 36 | return this.url; 37 | } 38 | 39 | public String getMethod() { 40 | return this.method; 41 | } 42 | 43 | public Map getAllHeaders() { 44 | return this.headers; 45 | } 46 | 47 | public String header(String name) { 48 | return headers.get(name); 49 | } 50 | 51 | public List getHeadersByName(String name) { 52 | List headerValues = new List(); 53 | if (headers != null && !headers.isEmpty()) { 54 | for (String headerName: headers.keySet()) { 55 | if (String.isNotBlank(headerName) && headerName.equalsIgnoreCase(name)) { 56 | headerValues.add(headers.get(headerName)); 57 | } 58 | } 59 | } 60 | return headerValues; 61 | } 62 | 63 | public IBMWatsonRequestBody getBody() { 64 | return this.body; 65 | } 66 | 67 | public Builder newBuilder() { 68 | return new Builder(this); 69 | } 70 | 71 | public override String toString() { 72 | return 'Request{method=' + method + ', url=' + url + '}'; 73 | } 74 | 75 | public class Builder { 76 | private URL url; 77 | private String method; 78 | private Map headers; 79 | private IBMWatsonRequestBody body; 80 | 81 | public Builder() { 82 | this.method = 'GET'; 83 | this.headers = new map(); 84 | } 85 | 86 | Builder(IBMWatsonRequest request) { 87 | this.url = request.url; 88 | this.method = request.method; 89 | this.body = request.body; 90 | this.headers = new Map(); 91 | this.headers.putAll(request.headers); 92 | } 93 | 94 | public Builder url(URL url) { 95 | if (url == null) { 96 | throw new IBMWatsonServiceExceptions.IllegalArgumentException('url == null'); 97 | } 98 | 99 | this.url = url; 100 | return this; 101 | } 102 | 103 | /** 104 | * Sets the URL target of this request. 105 | * 106 | * @throws IllegalArgumentException if {@code url} is not a valid HTTP or HTTPS URL. Avoid this 107 | * exception by calling {@link HttpUrl#parse}; it returns null for invalid URLs. 108 | */ 109 | public Builder url(String url) { 110 | if (url == null) { 111 | throw new IBMWatsonServiceExceptions.IllegalArgumentException('url == null'); 112 | } 113 | 114 | URL parsed = new URL(url); 115 | if (parsed == null) { 116 | throw new IBMWatsonServiceExceptions.IllegalArgumentException('unexpected url: ' + url); 117 | } 118 | return url(parsed); 119 | } 120 | 121 | /** 122 | * Adds a header with {@code name} and {@code value}. Prefer this method for multiply-valued 123 | * headers like "Cookie". 124 | * 125 | *

Note that for some headers including {@code Content-Length} and {@code Content-Encoding}, 126 | * OkHttp may replace {@code value} with a header derived from the request body. 127 | */ 128 | public Builder addHeader(String name, String value) { 129 | headers.put(name, value); 130 | return this; 131 | } 132 | 133 | public Builder method(String method, IBMWatsonRequestBody body) { 134 | if (String.isBlank(method)) { 135 | throw new IBMWatsonServiceExceptions.IllegalArgumentException('method == empty'); 136 | } 137 | this.method = method; 138 | this.body = body; 139 | return this; 140 | } 141 | 142 | public IBMWatsonRequest build() { 143 | if (url == null) { 144 | throw new IBMWatsonServiceExceptions.IllegalArgumentException('url == null'); 145 | } 146 | return new IBMWatsonRequest(this); 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonRequest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonRequestBody.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public virtual class IBMWatsonRequestBody { 15 | 16 | public IBMWatsonMediaType contentType {get;set;} 17 | public Long contentSize {get;set;} 18 | public String content {get;set;} 19 | public Blob blobContent {get;set;} 20 | public String name {get;set;} 21 | 22 | private static final String UTF_8 = 'UTF-8'; 23 | 24 | public IBMWatsonRequestBody() { 25 | name = ''; 26 | } 27 | 28 | public IBMWatsonMediaType bodyContentType() { 29 | return contentType; 30 | } 31 | 32 | public Boolean hasBase64Data() { 33 | return blobContent != null; 34 | } 35 | 36 | public static IBMWatsonRequestBody create() { 37 | IBMWatsonRequestBody reqBody = new IBMWatsonRequestBody(); 38 | reqBody.contentSize = 0; 39 | reqBody.content = null; 40 | reqBody.contentType = null; 41 | return reqBody; 42 | } 43 | 44 | public static IBMWatsonRequestBody create(String content, IBMWatsonMediaType contentType) { 45 | IBMWatsonRequestBody reqBody = new IBMWatsonRequestBody(); 46 | String charset = UTF_8; 47 | if (contentType != null) { 48 | charset = contentType.charset; 49 | if (String.isBlank(charset)) { 50 | charset = UTF_8; 51 | contentType = IBMWatsonMediaType.parse(contentType + '; charset=utf-8'); 52 | } 53 | } 54 | reqBody.contentSize = (String.isNotBlank(content)) ? content.length() : 0; 55 | reqBody.contentType = contentType; 56 | reqBody.content = content; 57 | return reqBody; 58 | } 59 | 60 | public static IBMWatsonRequestBody create(IBMWatsonFile fileContent, String contentType) { 61 | IBMWatsonMediaType mediaType = (contentType != null) ? IBMWatsonMediaType.parse(contentType) : IBMWatsonHttpMediaType.BINARY_FILE; 62 | return create(fileContent, mediaType); 63 | } 64 | 65 | public static IBMWatsonRequestBody create(IBMWatsonFile fileContent, IBMWatsonMediaType mediaType) { 66 | IBMWatsonRequestBody reqBody = new IBMWatsonRequestBody(); 67 | reqBody.contentSize = (fileContent != null) ? fileContent.bodyLength() : 0; 68 | reqBody.contentType = mediaType; 69 | reqBody.blobContent = fileContent.body(); 70 | reqBody.name = fileContent.name(); 71 | return reqBody; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonRequestBody.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonRequestBuilder.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonResponse.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public with sharing class IBMWatsonResponse { 15 | private static final String ERRORS_KEY = 'errors'; 16 | private static final String MESSAGE_STRING = 'message'; 17 | private static final String ERROR_STRING = 'error'; 18 | 19 | private final String errorMessage; 20 | private final String contentType; 21 | private final String globalTransactionId; 22 | private final String url; 23 | private final HttpResponse httpResponse; 24 | 25 | public IBMWatsonResponse(String url, HttpResponse httpResponse) { 26 | this.httpResponse = httpResponse; 27 | 28 | this.url = url; 29 | this.contentType = this.getHeader(IBMWatsonHttpHeaders.CONTENT_TYPE); 30 | this.globalTransactionId = this.getHeader(IBMWatsonHttpHeaders.X_GLOBAL_TRANSACTION_ID); 31 | 32 | if (!isSuccessful()) { 33 | this.errorMessage = getErrorMessage(httpResponse.getBody()); 34 | } 35 | } 36 | 37 | public String getBody() { 38 | return this.httpResponse.getBody(); 39 | } 40 | 41 | public Blob getBodyAsBlob() { 42 | return this.httpResponse.getBodyAsBlob(); 43 | } 44 | 45 | public String getHeader(String key) { 46 | // we'll try the lowercase key too as a fallback 47 | String lowerCaseKey = key.toLowerCase(); 48 | 49 | String headerVal = this.httpResponse.getHeader(key); 50 | if (headerVal == null) { 51 | headerVal = this.httpResponse.getHeader(lowerCaseKey); 52 | } 53 | 54 | return headerVal; 55 | } 56 | 57 | public String[] getHeaderKeys() { 58 | return this.httpResponse.getHeaderKeys(); 59 | } 60 | 61 | public Integer getStatusCode() { 62 | return this.httpResponse.getStatusCode(); 63 | } 64 | 65 | public String getStatus() { 66 | return this.httpResponse.getStatus(); 67 | } 68 | 69 | public Boolean isSuccessful() { 70 | return (this.getStatusCode() >= 200 && this.getStatusCode() < 300); 71 | } 72 | 73 | private String getErrorMessage(String errorResponse) { 74 | String error = errorResponse; 75 | try { 76 | Map responseMap = (Map) JSON.deserializeUntyped(errorResponse); 77 | if (responseMap.containsKey(ERRORS_KEY)) { 78 | List> errorList = (List>) responseMap.get(ERRORS_KEY); 79 | error = errorList[0].get(MESSAGE_STRING); 80 | } else if (responseMap.containsKey(ERROR_STRING)) { 81 | error = (String) responseMap.get(ERROR_STRING); 82 | } else if (responseMap.containsKey(MESSAGE_STRING)) { 83 | error = (String) responseMap.get(MESSAGE_STRING); 84 | } 85 | } catch (Exception e) { 86 | // Ignore any kind of exception parsing the json and use fallback String version of response 87 | } 88 | 89 | return error; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonResponse.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonResponseModel.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2018, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public virtual class IBMWatsonResponseModel extends IBMWatsonGenericModel { 15 | private Map headers = new Map(); 16 | 17 | /** 18 | * Allows user to see the JSON string by default for easier debugging. 19 | * 20 | * @return serialized String form of this 21 | */ 22 | public override String toString() { 23 | // remove response headers from string representation 24 | Map fullJsonMap = (Map) JSON.deserializeUntyped(JSON.serialize(this, true)); 25 | fullJsonMap.remove('headers'); 26 | 27 | // raise additional props 28 | fullJsonMap = IBMWatsonJSONUtil.raiseAdditionalProperties(fullJsonMap); 29 | 30 | // pretty print formatting 31 | return JSON.serializePretty(fullJsonMap); 32 | } 33 | 34 | /** 35 | * Gets the response headers attached to this response model. 36 | */ 37 | public Map getHeaders() { 38 | return this.headers; 39 | } 40 | 41 | /** 42 | * Adds a header to this response model. 43 | * 44 | * Meant to only be used internally to populate response headers from the IBMWatsonService class. 45 | */ 46 | public void addHeader(String name, String value) { 47 | if (this.headers == null) { 48 | this.headers = new Map(); 49 | } 50 | this.headers.put(name, value); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonResponseModel.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonResponseModelTest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | @isTest 15 | private class IBMWatsonResponseModelTest { 16 | private class TestModel extends IBMWatsonResponseModel { 17 | private String team; 18 | 19 | public TestModel() { 20 | team = 'buckeyes'; 21 | } 22 | } 23 | 24 | static testMethod void testEquals() { 25 | Test.startTest(); 26 | 27 | TestModel testModel1 = new TestModel(); 28 | TestModel testModel2 = new TestModel(); 29 | System.assert(testModel1.equals(testModel2)); 30 | 31 | Test.stopTest(); 32 | } 33 | 34 | static testMethod void testHeaders() { 35 | Test.startTest(); 36 | 37 | String headerKey = 'key'; 38 | String headerVal = 'val'; 39 | TestModel testModel = new TestModel(); 40 | testModel.addHeader(headerKey, headerVal); 41 | System.assert(testModel.getHeaders().size() == 1); 42 | System.assertEquals(headerVal, testModel.getHeaders().get(headerKey)); 43 | 44 | Test.stopTest(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonResponseModelTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonService.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonServiceExceptions.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonServiceTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonTokenRequestBasedAuthenticator.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * This class serves as a common base class for IBMWatsonAuthenticator implementations that interact with a Token Server 16 | * via a REST interface. 17 | * This base class allows for the configuration of the following properties: 18 | * username/password - if specified, these values will be used to build a basic auth Authorization header 19 | * to be sent with requests to the Token Server. 20 | * headers - a Map of keys/values that will be set as headers on requests sent to the Token Server. 21 | */ 22 | public abstract class IBMWatsonTokenRequestBasedAuthenticator extends IBMWatsonAuthenticatorBase implements IBMWatsonAuthenticator { 23 | private String username; 24 | private String password; 25 | private Map headers; 26 | 27 | // The cached value of the Authorization header. 28 | private String authHeader; 29 | 30 | public void setBasicAuthInfo(String username, String password) { 31 | this.username = username; 32 | this.password = password; 33 | this.authHeader = constructBasicAuthHeader(this.username, this.password); 34 | } 35 | 36 | /** 37 | * @return the basic auth username configured for this IBMWatsonAuthenticator 38 | */ 39 | public String getUsername() { 40 | return this.username; 41 | } 42 | 43 | /** 44 | * @return the basic auth password configured for this IBMWatsonAuthenticator 45 | */ 46 | public String getPassword() { 47 | return this.password; 48 | } 49 | 50 | /** 51 | * Returns the set of user-supplied headers configured for this IBMWatsonAuthenticator. 52 | * 53 | * @return a Map containing the configured headers 54 | */ 55 | public Map getHeaders() { 56 | return headers; 57 | } 58 | 59 | /** 60 | * Sets a Map of key/value pairs which will be sent as HTTP headers in any interactions with the Token Server. 61 | * 62 | * @param headers the user-supplied headers to be included in Token Server interactions 63 | */ 64 | public void setHeaders(Map headers) { 65 | this.headers = headers; 66 | } 67 | 68 | public abstract String authenticationType(); 69 | public abstract void authenticate(IBMWatsonRequest.Builder requestBuilder); 70 | public abstract void validate(); 71 | 72 | public IBMWatsonTokenServerResponse invokeRequest(IBMWatsonRequest request, Type targetTokenType) { 73 | IBMWatsonRequest.Builder requestBuilder = request.newBuilder(); 74 | 75 | // If present, set the Authorization header to be sent to the token server. 76 | if (String.isNotBlank(this.authHeader)) { 77 | requestBuilder.addHeader(IBMWatsonHttpHeaders.AUTHORIZATION, this.authHeader); 78 | } 79 | 80 | // Now add any user-supplied headers to the request. 81 | if (this.headers != null && !this.headers.isEmpty()) { 82 | for (String headerKey : this.headers.keySet()) { 83 | requestBuilder.addHeader(headerKey, this.headers.get(headerKey)); 84 | } 85 | } 86 | 87 | // Send request 88 | IBMWatsonResponse response = IBMWatsonClient.executeRequest(requestBuilder.build()); 89 | 90 | if (response.isSuccessful() && String.isNotBlank(response.getBody())) { 91 | Map jsonMap = (Map) JSON.deserializeUntyped(response.getBody()); 92 | String jsonString = JSON.serialize(jsonMap); 93 | Object targetObject = targetTokenType.newInstance(); 94 | return (IBMWatsonTokenServerResponse) ((IBMWatsonResponseModel) targetObject).deserialize(jsonString, jsonMap, targetTokenType); 95 | } else { 96 | Map responseMap = (Map) JSON.deserializeUntyped(response.getBody()); 97 | String errorMessage = responseMap.get('errorMessage').toString(); 98 | if (errorMessage == null) { 99 | errorMessage = IBMWatsonAuthenticatorBase.ERRORMSG_REQ_FAILED; 100 | } 101 | Integer statusCode = response.getStatusCode(); 102 | throw new IBMWatsonServiceExceptions.ResponseException(statusCode, errorMessage, response); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonTokenRequestBasedAuthenticator.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonTokenServerResponse.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2019, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public interface IBMWatsonTokenServerResponse {} 15 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonTokenServerResponse.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonValidator.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * This class assists in validating arguments. 16 | * If an argument value is deemed invalid, an IllegalArgumentException is thrown. 17 | */ 18 | public class IBMWatsonValidator { 19 | 20 | private IBMWatsonValidator() { 21 | // This is a utility class - no instantiation allowed. 22 | } 23 | 24 | /** 25 | * Validates that the argument condition is true; otherwise throwing an exception with the specified 26 | * message. This method is useful when validating according to an arbitrary boolean expression, such as validating a 27 | * primitive number or using your own custom validation expression. 28 | * 29 | * 30 | * @param expression the boolean expression to check 31 | * @param message the exception message if invalid 32 | * @throws IllegalArgumentException if expression is false 33 | */ 34 | public static void isTrue(boolean expression, String message) { 35 | if (!expression) { 36 | throw new IBMWatsonServiceExceptions.IllegalArgumentException(message); 37 | } 38 | } 39 | 40 | /** 41 | * Validates that the specified argument array is neither null nor a length of zero (no elements); 42 | * otherwise throwing an exception with the specified message. 43 | * 44 | * @param array the array to check 45 | * @param message the exception message if invalid 46 | * @throws IllegalArgumentException if the array is empty 47 | */ 48 | public static void notEmpty(List a, String message) { 49 | if (a == null || a.isEmpty() ) { 50 | throw new IBMWatsonServiceExceptions.IllegalArgumentException(message); 51 | } 52 | } 53 | 54 | /** 55 | * Validator that the specified argument string is neither null nor a length of zero (no characters); 56 | * otherwise throwing an exception with the specified message. 57 | * 58 | * @param string the string to check 59 | * @param message the exception message if invalid 60 | * @throws IllegalArgumentException if the string is empty 61 | */ 62 | public static void notEmpty(String str, String message) { 63 | if ((str == null) || (str.length() == 0)) { 64 | throw new IBMWatsonServiceExceptions.IllegalArgumentException(message); 65 | } 66 | } 67 | 68 | /** 69 | * Validates that the specified argument is not null; otherwise throwing an exception with the specified 70 | * message. 71 | * 72 | * @param object the object to check 73 | * @param message the exception message if invalid 74 | */ 75 | public static void notNull(Object obj, String message) { 76 | if (obj == null) { 77 | throw new IBMWatsonServiceExceptions.IllegalArgumentException(message); 78 | } 79 | } 80 | 81 | /** 82 | * Validates that the specified argument is null; otherwise throwing an exception with the specified 83 | * message. 84 | * 85 | * @param object the object to check 86 | * @param message the exception message if invalid 87 | */ 88 | public static void isNull(Object obj, String message) { 89 | if (obj != null) { 90 | throw new IBMWatsonServiceExceptions.IllegalArgumentException(message); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /force-app/main/default/classes/IBMWatsonValidator.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/test/IBMAssistantV1FTests.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/test/IBMAssistantV2FTests.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2018, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public with sharing class IBMAssistantV2FTests { 15 | private static String URL = 'https://gateway.watsonplatform.net/assistant/api'; 16 | private static String VERSION = '2019-02-28'; 17 | 18 | public static void runAllTests(String apiKey, String assistantId) { 19 | IBMWatsonAuthenticator authenticator = new IBMWatsonIAMAuthenticator(apiKey); 20 | IBMAssistantV2 service = new IBMAssistantV2(VERSION, authenticator); 21 | service.setServiceURL(URL); 22 | 23 | IBMAssistantV2Models.SessionResponse sessionResponse = testCreateSession(service, assistantId); 24 | String sessionId = sessionResponse.getSessionId(); 25 | testMesssage(service, assistantId, sessionId); 26 | testDeleteSession(service, assistantId, sessionId); 27 | } 28 | 29 | public static IBMAssistantV2Models.SessionResponse testCreateSession(IBMAssistantV2 service, String assistantId) { 30 | IBMAssistantV2Models.CreateSessionOptions createSessionOptions = new IBMAssistantV2Models.CreateSessionOptionsBuilder() 31 | .assistantId(assistantId) 32 | .build(); 33 | IBMAssistantV2Models.SessionResponse response = service.createSession(createSessionOptions); 34 | 35 | System.debug('IBMAssistantV2FTests.testCreateSession(): ' + response); 36 | return response; 37 | } 38 | 39 | public static void testMesssage(IBMAssistantV2 service, String assistantId, String sessionId) { 40 | List messages = new List { 41 | 'I want some pizza.', 42 | 'I\'d like 3 pizzas.', 43 | 'Large' 44 | }; 45 | IBMAssistantV2Models.MessageContext context = new IBMAssistantV2Models.MessageContext(); 46 | 47 | for (String message : messages) { 48 | IBMAssistantV2Models.MessageInputOptions inputOptions = new IBMAssistantV2Models.MessageInputOptionsBuilder() 49 | .debug(true) 50 | .build(); 51 | IBMAssistantV2Models.MessageInput input = new IBMAssistantV2Models.MessageInputBuilder() 52 | .text(message) 53 | .options(inputOptions) 54 | .messageType('text') 55 | .build(); 56 | IBMAssistantV2Models.MessageOptions messageOptions = new IBMAssistantV2Models.MessageOptionsBuilder() 57 | .assistantId(assistantId) 58 | .sessionId(sessionId) 59 | .input(input) 60 | .context(context) 61 | .build(); 62 | IBMAssistantV2Models.MessageResponse response = service.message(messageOptions); 63 | 64 | System.debug('IBMAssistantV2FTests.testMessage() single response: ' + response); 65 | context = response.getContext(); 66 | } 67 | } 68 | 69 | public static void testDeleteSession(IBMAssistantV2 service, String assistantId, String sessionId) { 70 | IBMAssistantV2Models.DeleteSessionOptions deleteSessionOptions = new IBMAssistantV2Models.DeleteSessionOptionsBuilder() 71 | .assistantId(assistantId) 72 | .sessionId(sessionId) 73 | .build(); 74 | service.deleteSession(deleteSessionOptions); 75 | 76 | System.debug('IBMAssistantV2FTests.testDeleteSession() completed successfully'); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /force-app/main/test/IBMAssistantV2FTests.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | -------------------------------------------------------------------------------- /force-app/main/test/IBMCompareComplyV1FTests.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/test/IBMDiscoveryV1FTests.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/test/IBMNaturalLanguageClassifierV1FTests.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/test/IBMNaturalLanguageUnderstandingV1FTest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public with sharing class IBMNaturalLanguageUnderstandingV1FTest { 15 | private static String URL = 'https://gateway.watsonplatform.net/natural-language-understanding/api'; 16 | private static String VERSION = '2019-07-12'; 17 | // Make sure the named credentials below is defined 18 | private static String NAMED_CREDENTIALS = 'callout:watson_natural_language_understanding_v1'; 19 | 20 | public static void runAllTests(String apiKey) { 21 | IBMWatsonAuthenticator authenticator = new IBMWatsonIAMAuthenticator(apiKey); 22 | IBMNaturalLanguageUnderstandingV1 service = new IBMNaturalLanguageUnderstandingV1(VERSION, authenticator); 23 | service.setServiceURL(URL); 24 | 25 | testAnalyze(service); 26 | testListModels(service); 27 | } 28 | 29 | /** 30 | * Test Analyze text, HTML, or a public webpage. 31 | * 32 | */ 33 | public static IBMNaturalLanguageUnderstandingV1Models.AnalysisResults testAnalyze(IBMNaturalLanguageUnderstandingV1 service) { 34 | IBMNaturalLanguageUnderstandingV1Models.ConceptsOptions concepts = new IBMNaturalLanguageUnderstandingV1Models.ConceptsOptionsBuilder() 35 | .xlimit(8) 36 | .build(); 37 | concepts = concepts.newBuilder().build(); 38 | 39 | IBMNaturalLanguageUnderstandingV1Models.EmotionOptions emotion = new IBMNaturalLanguageUnderstandingV1Models.EmotionOptionsBuilder() 40 | .document(true) 41 | .targets(new List{'apples', 'oranges'}) 42 | .build(); 43 | emotion = emotion.newBuilder().build(); 44 | 45 | IBMNaturalLanguageUnderstandingV1Models.EntitiesOptions entities = new IBMNaturalLanguageUnderstandingV1Models.EntitiesOptionsBuilder() 46 | .xlimit(50) 47 | .sentiment(false) 48 | .emotion(true) 49 | .build(); 50 | entities = entities.newBuilder().build(); 51 | 52 | IBMNaturalLanguageUnderstandingV1Models.KeywordsOptions keywords = new IBMNaturalLanguageUnderstandingV1Models.KeywordsOptionsBuilder() 53 | .xlimit(50) 54 | .sentiment(false) 55 | .emotion(false) 56 | .build(); 57 | keywords = keywords.newBuilder().build(); 58 | 59 | IBMNaturalLanguageUnderstandingV1Models.RelationsOptions relations = new IBMNaturalLanguageUnderstandingV1Models.RelationsOptionsBuilder() 60 | .model('en-news') 61 | .build(); 62 | relations = relations.newBuilder().build(); 63 | 64 | IBMNaturalLanguageUnderstandingV1Models.SemanticRolesOptions semanticRoles = new IBMNaturalLanguageUnderstandingV1Models.SemanticRolesOptionsBuilder() 65 | .xlimit(50) 66 | .keywords(false) 67 | .entities(false) 68 | .build(); 69 | semanticRoles = semanticRoles.newBuilder().build(); 70 | 71 | IBMNaturalLanguageUnderstandingV1Models.SentimentOptions sentiment = new IBMNaturalLanguageUnderstandingV1Models.SentimentOptionsBuilder() 72 | .document(true) 73 | .targets(new List{''}) 74 | .build(); 75 | 76 | IBMNaturalLanguageUnderstandingV1Models.CategoriesOptions categories = new IBMNaturalLanguageUnderstandingV1Models.CategoriesOptionsBuilder() 77 | .explanation(true) 78 | .build(); 79 | 80 | IBMNaturalLanguageUnderstandingV1Models.MetadataOptions metadata = new IBMNaturalLanguageUnderstandingV1Models.MetadataOptionsBuilder().build(); 81 | 82 | IBMNaturalLanguageUnderstandingV1Models.Features features = new IBMNaturalLanguageUnderstandingV1Models.FeaturesBuilder() 83 | .concepts(concepts) 84 | .emotion(emotion) 85 | .entities(entities) 86 | .keywords(keywords) 87 | .metadata(metadata) 88 | .relations(relations) 89 | .semanticRoles(semanticRoles) 90 | .categories(categories) 91 | .sentiment(sentiment) 92 | .build(); 93 | 94 | IBMNaturalLanguageUnderstandingV1Models.AnalyzeOptions options = new IBMNaturalLanguageUnderstandingV1Models.AnalyzeOptionsBuilder() 95 | .html( 'Fruits

Apples and Oranges

I love apples! I don\'t like oranges.

') 96 | .features(features) 97 | .clean(true) 98 | .fallbackToRaw(true) 99 | .returnAnalyzedText(false) 100 | .limitTextCharacters(100) 101 | .language('en') 102 | .build(); 103 | 104 | IBMNaturalLanguageUnderstandingV1Models.AnalysisResults resp = service.analyze(options); 105 | System.debug('IBMNaturalLanguageUnderstandingV1FTest.testAnalyze(): ' + resp); 106 | return resp; 107 | } 108 | 109 | public static IBMNaturalLanguageUnderstandingV1Models.ListModelsResults testListModels(IBMNaturalLanguageUnderstandingV1 service) { 110 | IBMNaturalLanguageUnderstandingV1Models.ListModelsOptions options = new IBMNaturalLanguageUnderstandingV1Models.ListModelsOptionsBuilder() 111 | .build(); 112 | 113 | IBMNaturalLanguageUnderstandingV1Models.ListModelsResults resp = service.listModels(options); 114 | System.debug('IBMNaturalLanguageUnderstandingV1FTest.testListModels(): ' + resp); 115 | return resp; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /force-app/main/test/IBMNaturalLanguageUnderstandingV1FTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/test/IBMPersonalityInsightsV3FTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/test/IBMSpeechToTextV1FTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/test/IBMTextToSpeechV1FTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/test/IBMToneAnalyzerV3FTest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public with sharing class IBMToneAnalyzerV3FTest { 15 | private static String NAMED_CREDENTIALS = 'callout:watson_tone_analyzer_v3'; 16 | private static String VERSION = '2017-09-21'; 17 | private static String URL = 'https://gateway-wdc.watsonplatform.net/tone-analyzer/api'; 18 | 19 | public static void runAllTests(String apiKey) { 20 | IBMWatsonAuthenticator authenticator = new IBMWatsonIAMAuthenticator(apiKey); 21 | IBMToneAnalyzerV3 service = new IBMToneAnalyzerV3(VERSION, authenticator); 22 | service.setServiceURL(URL); 23 | 24 | testTone(service); 25 | testToneWithToneInput(service); 26 | testToneChat(service); 27 | } 28 | 29 | /** 30 | * Test analyze general purpose tone. 31 | * 32 | */ 33 | public static IBMToneAnalyzerV3Models.ToneAnalysis testTone(IBMToneAnalyzerV3 service) { 34 | IBMToneAnalyzerV3Models.ToneOptions options = new IBMToneAnalyzerV3Models.ToneOptionsBuilder() 35 | .text('We have a better product. We need to do better selling') 36 | .addTones('social') 37 | .sentences(false) 38 | .contentLanguage('en') 39 | .acceptLanguage('en') 40 | .build(); 41 | 42 | IBMToneAnalyzerV3Models.ToneAnalysis resp = service.tone(options); 43 | System.debug('IBMToneAnalyzerV3FTest.testTone(): ' + resp); 44 | return resp; 45 | } 46 | 47 | /** 48 | * Test analyze general purpose tone with tone input. 49 | * 50 | */ 51 | public static IBMToneAnalyzerV3Models.ToneAnalysis testToneWithToneInput(IBMToneAnalyzerV3 service) { 52 | IBMToneAnalyzerV3Models.ToneInput toneInput = new IBMToneAnalyzerV3Models.ToneInputBuilder() 53 | .text('We have a better product. We can do better selling by having more campaigns') 54 | .build(); 55 | 56 | IBMToneAnalyzerV3Models.ToneOptions options = new IBMToneAnalyzerV3Models.ToneOptionsBuilder() 57 | .toneInput(toneInput) 58 | .build(); 59 | 60 | IBMToneAnalyzerV3Models.ToneAnalysis resp = service.tone(options); 61 | System.debug('IBMToneAnalyzerV3FTest.testTone(): ' + resp); 62 | return resp; 63 | } 64 | 65 | /** 66 | * Test analyze customer engagement tone. 67 | * 68 | */ 69 | public static IBMToneAnalyzerV3Models.UtteranceAnalyses testToneChat(IBMToneAnalyzerV3 service) { 70 | IBMToneAnalyzerV3Models.Utterance utterance = new IBMToneAnalyzerV3Models.UtteranceBuilder() 71 | .text('We have a better product. We can do better selling by having more campaigns') 72 | .user('test user') 73 | .build(); 74 | 75 | IBMToneAnalyzerV3Models.ToneChatOptions options = new IBMToneAnalyzerV3Models.ToneChatOptionsBuilder() 76 | .addUtterances(utterance) 77 | .build(); 78 | 79 | IBMToneAnalyzerV3Models.UtteranceAnalyses resp = service.toneChat(options); 80 | System.debug('IBMToneAnalyzerV3FTest.testToneChat(): ' + resp); 81 | return resp; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /force-app/main/test/IBMToneAnalyzerV3FTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/test/IBMVisualRecognitionV3FTest.cls: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright IBM Corp. 2017, 2020. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 | * the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | public with sharing class IBMVisualRecognitionV3FTest { 15 | private static String URL = 'https://gateway.watsonplatform.net/visual-recognition/api'; 16 | private static String VERSION = '2018-03-19'; 17 | 18 | public static void runAllTests(String iamApiKey) { 19 | IBMWatsonAuthenticator authenticator = new IBMWatsonIAMAuthenticator(iamApiKey); 20 | IBMVisualRecognitionV3 service = new IBMVisualRecognitionV3(VERSION, authenticator); 21 | service.setServiceURL(URL); 22 | 23 | testClassify(service); 24 | } 25 | 26 | /** 27 | * Test Analyze text, HTML, or a public webpage. 28 | * 29 | */ 30 | public static IBMVisualRecognitionV3Models.ClassifiedImages testClassify(IBMVisualRecognitionV3 service) { 31 | IBMVisualRecognitionV3Models.ClassifyOptions options = new IBMVisualRecognitionV3Models.ClassifyOptionsBuilder() 32 | .url('https://watson-test-resources.mybluemix.net/resources/car.png') 33 | .build(); 34 | IBMVisualRecognitionV3Models.ClassifiedImages resp = service.classify(options); 35 | System.debug('IBMVisualRecognitionV3FTest.testClassify(): ' + resp); 36 | return resp; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /force-app/main/test/IBMVisualRecognitionV3FTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/test/IBMVisualRecognitionV4FTests.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /install/ant-contrib-1.0b3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/watson-developer-cloud/salesforce-sdk/67dc90db608a031971d3c12940c729ec152accdd/install/ant-contrib-1.0b3.jar -------------------------------------------------------------------------------- /install/ant-salesforce.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/watson-developer-cloud/salesforce-sdk/67dc90db608a031971d3c12940c729ec152accdd/install/ant-salesforce.jar -------------------------------------------------------------------------------- /install/build.properties: -------------------------------------------------------------------------------- 1 | # build.properties 2 | 3 | # Specify the login credentials for the desired Salesforce organization 4 | sf.username = #pragma: whitelist secret 5 | sf.password = #pragma: whitelist secret 6 | 7 | # Use 'https://login.salesforce.com' for production or developer edition (the default if not specified). 8 | # Use 'https://test.salesforce.com for sandbox. 9 | sf.serverurl = https://login.salesforce.com 10 | 11 | sf.maxPoll = 20 12 | # If your network requires an HTTP proxy, see http://ant.apache.org/manual/proxy.html for configuration. -------------------------------------------------------------------------------- /install/build.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /install/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ "{$TRAVIS_BRANCH}" = "master" ]; then 4 | ant -buildfile $TRAVIS_BUILD_DIR/install/build.xml deployWatson 5 | fi -------------------------------------------------------------------------------- /install/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | * 5 | ApexClass 6 | 7 | 41.0 8 | 9 | -------------------------------------------------------------------------------- /install/sfdx-deploy-service.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ $# -eq 0 ]; then 4 | echo "Usage: $0 -c -s [service] -u [username]"; 5 | echo ""; 6 | echo "-c Deploy core files"; 7 | echo "-s Service to deploy, available services are:"; 8 | echo " * assistant" 9 | echo " * discovery"; 10 | echo " * language-translator"; 11 | echo " * natural-language-classifier"; 12 | echo " * natural-language-understanding"; 13 | echo " * personality-insights"; 14 | echo " * speech-to-text"; 15 | echo " * text-to-speech"; 16 | echo " * tone-analyzer"; 17 | echo " * visual-recognition"; 18 | echo "-u Username associated with scratch org"; 19 | echo ""; 20 | echo "# Using the -c option to include the core files as part of this deployment"; 21 | echo "# by default the core files are not included"; 22 | echo "Example: $0 -c -s discovery -u myusername@organization.net" 23 | echo ""; 24 | exit 1; 25 | fi 26 | 27 | echo -e "executing script..." 28 | 29 | POSITIONAL=() 30 | 31 | while [[ $# -gt 0 ]] 32 | do 33 | key="$1" 34 | 35 | # parse arguments 36 | case $key in 37 | -c|--coresdk) 38 | DEPLOY_CORE="Y" 39 | shift # past argument 40 | shift # past value 41 | ;; 42 | -s|--service) 43 | WATSON_SERVICE="$2" 44 | shift # past argument 45 | shift # past value 46 | ;; 47 | -u|--username) 48 | SFDX_USERNAME="$2" 49 | shift # past argument 50 | shift # past value 51 | ;; 52 | *) # unknown option 53 | POSITIONAL+=("$1") # save it in an array for later 54 | shift # past argument 55 | ;; 56 | esac 57 | done 58 | set -- "${POSITIONAL[@]}" # restore positional parameters 59 | 60 | apex_classes=() 61 | apex_classes_metadata=() 62 | 63 | echo "loading dependencies for $WATSON_SERVICE service" 64 | apex_classes=(`cat ../config/SFDXService/sfdx-deploy-config.json | jq --arg WATSON_SERVICE "$WATSON_SERVICE" '.watsonServices[] | select(.name == $WATSON_SERVICE).apexClasses[] | .fileName'`) 65 | apex_classes_metadata=(`cat ../config/SFDXService/sfdx-deploy-config.json | jq --arg WATSON_SERVICE "$WATSON_SERVICE" '.watsonServices[] | select(.name == $WATSON_SERVICE).apexClasses[] | .metadata'`) 66 | 67 | # api version 68 | sourceApiVersion=`cat ../config/SFDXService/sfdx-deploy-config.json | jq '.sourceApiVersion'` 69 | 70 | echo "sourceApiVersion=$sourceApiVersion" 71 | 72 | # deploy directory 73 | if [ ! -d ../sfdx-deploy/classes ]; then 74 | echo "creating deployment directory..." 75 | mkdir -p ../sfdx-deploy/classes; 76 | else 77 | echo "cleaning deployment directory" 78 | rm -r ../sfdx-deploy 79 | mkdir -p ../sfdx-deploy/classes; 80 | fi; 81 | 82 | # copy core files 83 | if [[ $DEPLOY_CORE && ${DEPLOY_CORE-x} ]]; then 84 | for cf in ../force-app/main/default/classes/IBMWatson*; do 85 | cp $cf ../sfdx-deploy/classes 86 | done 87 | fi; 88 | 89 | # copy apex classes for the service 90 | for t in "${apex_classes[@]}" 91 | do 92 | cp ../force-app/main/default/classes/${t//\"} ../sfdx-deploy/classes 93 | done 94 | # copy metadata for apex classes 95 | for t in "${apex_classes_metadata[@]}" 96 | do 97 | cp ../force-app/main/default/classes/${t//\"} ../sfdx-deploy/classes 98 | done 99 | cat >../sfdx-deploy/package.xml < 101 | 102 | 103 | * 104 | ApexClass 105 | 106 | ${sourceApiVersion//\"} 107 | 108 | EOF 109 | 110 | sfdx force:config:set defaultusername=$SFDX_USERNAME 111 | sfdx force:mdapi:deploy -d ../sfdx-deploy -w 5 -f ../sfdx-deploy/servicePackage.zip 112 | -------------------------------------------------------------------------------- /install/test-in-scratch-org.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" ]; then 4 | sfdx force:auth:jwt:grant --clientid $CONSUMER_KEY --jwtkeyfile assets/server.key --username $USERNAME --setdefaultdevhubusername -a HubOrg 5 | sfdx force:org:create -v HubOrg -s -f config/project-scratch-def.json -a ciorg 6 | sfdx force:source:push -u ciorg 7 | sfdx force:mdapi:deploy -d config/remoteSiteEndpoint -w 1 8 | sfdx force:mdapi:deploy -d config/DocumentsFTest -w 1 9 | sfdx force:apex:test:run -u ciorg -c -r human 10 | 11 | echo "IBMDiscoveryV1FTests.runAllTests('$DISCOVERY_API_KEY');" > DiscoveryTestRunner.apex 12 | $(sfdx force:apex:execute -f DiscoveryTestRunner.apex --json | jq -e -r '.result.compiled == true and .result.success == true') && echo “Success” || exit 1 13 | rm DiscoveryTestRunner.apex 14 | 15 | echo "IBMPersonalityInsightsV3FTest.runAllTests('$PERSONALITY_INSIGHTS_API_KEY');" > PersonalityInsightsTestRunner.apex 16 | $(sfdx force:apex:execute -f PersonalityInsightsTestRunner.apex --json | jq -e -r '.result.compiled == true and .result.success == true') && echo “Success” || exit 1 17 | rm PersonalityInsightsTestRunner.apex 18 | 19 | echo "IBMToneAnalyzerV3FTest.runAllTests('$TONE_ANALYZER_API_KEY');" > ToneAnalyzerTestRunner.apex 20 | $(sfdx force:apex:execute -f ToneAnalyzerTestRunner.apex --json | jq -e -r '.result.compiled == true and .result.success == true') && echo “Success” || exit 1 21 | rm ToneAnalyzerTestRunner.apex 22 | 23 | echo "IBMNaturalLanguageUnderstandingV1FTest.runAllTests('$NLU_API_KEY');" > NLUTestRunner.apex 24 | $(sfdx force:apex:execute -f NLUTestRunner.apex --json | jq -e -r '.result.compiled == true and .result.success == true') && echo “Success” || exit 1 25 | rm NLUTestRunner.apex 26 | 27 | echo "IBMNaturalLanguageClassifierV1FTests.runAllTests('$NLC_API_KEY');" > NLCTestRunner.apex 28 | $(sfdx force:apex:execute -f NLCTestRunner.apex --json | jq -e -r '.result.compiled == true and .result.success == true') && echo “Success” || exit 1 29 | rm NLCTestRunner.apex 30 | 31 | echo "IBMTextToSpeechV1FTest.runAllTests('$TEXT_TO_SPEECH_API_KEY');" > TextToSpeechTestRunner.apex 32 | $(sfdx force:apex:execute -f TextToSpeechTestRunner.apex --json | jq -e -r '.result.compiled == true and .result.success == true') && echo “Success” || exit 1 33 | rm TextToSpeechTestRunner.apex 34 | 35 | echo "IBMSpeechToTextV1FTest.runAllTests('$SPEECH_TO_TEXT_API_KEY');" > SpeechToTextTestRunner.apex 36 | $(sfdx force:apex:execute -f SpeechToTextTestRunner.apex --json | jq -e -r '.result.compiled == true and .result.success == true') && echo “Success” || exit 1 37 | rm SpeechToTextTestRunner.apex 38 | 39 | echo "IBMAssistantV2FTests.runAllTests('$ASSISTANT_V2_API_KEY', '$ASSISTANT_V2_ASSISTANT_ID');" > AssistantV2TestRunner.apex 40 | $(sfdx force:apex:execute -f AssistantV2TestRunner.apex --json | jq -e -r '.result.compiled == true and .result.success == true') && echo “Success” || exit 1 41 | rm AssistantV2TestRunner.apex 42 | 43 | echo "IBMVisualRecognitionV3FTest.runAllTests('$VISUAL_RECOGNITION_IAM_API_KEY');" > VisualRecognitionV3TestRunner.apex 44 | $(sfdx force:apex:execute -f VisualRecognitionV3TestRunner.apex --json | jq -e -r '.result.compiled == true and .result.success == true') && echo “Success” || exit 1 45 | rm VisualRecognitionV3TestRunner.apex 46 | 47 | echo "IBMCompareComplyV1FTests.runAllTests('$COMPARE_AND_COMPLY_IAM_API_KEY');" > CompareComplyTestRunner.apex 48 | $(sfdx force:apex:execute -f CompareComplyTestRunner.apex --json | jq -e -r '.result.compiled == true and .result.success == true') && echo "Success" || exit 1 49 | rm CompareComplyTestRunner.apex 50 | 51 | echo "IBMVisualRecognitionV4FTests.runAllTests('$VISUAL_RECOGNITION_IAM_API_KEY');" > VisualRecognitionV4TestRunner.apex 52 | $(sfdx force:apex:execute -f VisualRecognitionV4TestRunner.apex --json | jq -e -r '.result.compiled == true and .result.success == true') && echo "Success" || exit 1 53 | rm VisualRecognitionV4TestRunner.apex 54 | 55 | echo "Deploy to main organization" 56 | sfdx force:org:delete -u ciorg -p 57 | mv install/package.xml force-app/main/default 58 | "./install/deploy.sh" 59 | else 60 | echo -e "Not running integration tests for build $TRAVIS_BUILD_NUMBER ($TRAVIS_JOB_NUMBER) on branch $TRAVIS_BRANCH of repo $TRAVIS_REPO_SLUG" 61 | fi -------------------------------------------------------------------------------- /sfdx-project.json: -------------------------------------------------------------------------------- 1 | { 2 | "packageDirectories": [ 3 | { 4 | "path": "force-app/main/default/classes", 5 | "default": true 6 | } 7 | ], 8 | "namespace": "", 9 | "sfdcLoginUrl": "https://login.salesforce.com", 10 | "sourceApiVersion": "41.0" 11 | } 12 | --------------------------------------------------------------------------------