From 57bdeb3fcbc875bee4f8dee35c628fc3331e3afe Mon Sep 17 00:00:00 2001 From: Ryan J Baxter Date: Mon, 16 Feb 2015 19:48:13 -0500 Subject: [PATCH] initial commit --- .gitignore | 25 ++ LICENSE | 202 ++++++++++++++ NOTICE | 2 + README.md | 149 +++++++++++ bluemix-cloud-connectors-cloudfoundry/pom.xml | 40 +++ .../creator/CloudantServiceInfoCreator.java | 80 ++++++ .../creator/SendGridServiceInfoCreator.java | 38 +++ .../creator/TwilioServiceInfoCreator.java | 72 +++++ ...loudfoundry.CloudFoundryServiceInfoCreator | 3 + .../CloudantServiceInfoCreatorTest.java | 87 ++++++ .../SendGridServiceInfoCreatorTest.java | 53 ++++ .../creator/TwilioServiceInfoCreatorTest.java | 80 ++++++ bluemix-cloud-connectors-core/pom.xml | 30 +++ .../core/creator/CouchDbInstanceCreator.java | 55 ++++ .../core/creator/TwilioRestClientCreator.java | 33 +++ .../core/info/CloudantServiceInfo.java | 151 +++++++++++ .../core/info/TwilioServiceInfo.java | 102 +++++++ ...work.cloud.service.ServiceConnectorCreator | 2 + .../creator/CouchDbInstanceCreatorTest.java | 52 ++++ .../creator/TwilioRestClientCreatorTest.java | 48 ++++ .../core/info/CloudantServiceInfoTest.java | 76 ++++++ .../core/info/TwilioServiceInfoTest.java | 72 +++++ bluemix-cloud-connectors-local/pom.xml | 40 +++ .../CouchDbLocalConfigServiceInfoCreator.java | 53 ++++ ...SendGridLocalConfigServiceInfoCreator.java | 42 +++ .../TwilioLocalConfigServiceInfoCreator.java | 40 +++ ....localconfig.LocalConfigServiceInfoCreator | 3 + ...chDbLocalConfigServiceInfoCreatorTest.java | 48 ++++ ...GridLocalConfigServiceInfoCreatorTest.java | 55 ++++ ...ilioLocalConfigServiceInfoCreatorTest.java | 46 ++++ pom.xml | 57 ++++ samples/cloudant-liberty/README.MD | 49 ++++ samples/cloudant-liberty/pom.xml | 253 ++++++++++++++++++ .../cloudant/liberty/CloudantBean.java | 38 +++ .../connectors/cloudant/liberty/Status.java | 47 ++++ .../cloudant/liberty/StatusController.java | 71 +++++ .../cloudant/liberty/StatusRepository.java | 29 ++ .../spring-cloud-bootstrap.properties | 15 ++ .../src/main/webapp/WEB-INF/beans.xml | 24 ++ .../src/main/webapp/WEB-INF/ibm-web-ext.xml | 22 ++ .../src/main/webapp/WEB-INF/web.xml | 50 ++++ .../src/main/webapp/css/jumbotron-narrow.css | 94 +++++++ .../src/main/webapp/index.html | 79 ++++++ .../src/main/webapp/js/app.js | 16 ++ .../src/main/webapp/js/service.js | 20 ++ .../src/main/webapp/js/status/status.html | 16 ++ .../src/main/webapp/js/status/status.js | 42 +++ .../src/main/wlp/localserver.xml | 29 ++ .../cloudant-liberty/src/main/wlp/server.xml | 26 ++ samples/cloudant-spring/README.md | 39 +++ samples/cloudant-spring/pom.xml | 192 +++++++++++++ .../net/bluemix/connectors/cloudant/App.java | 55 ++++ .../bluemix/connectors/cloudant/Status.java | 46 ++++ .../connectors/cloudant/StatusRepository.java | 33 +++ .../cloudant/StatusRestController.java | 58 ++++ .../connectors/cloudant/config/Config.java | 45 ++++ .../src/main/resources/application.properties | 1 + .../spring-cloud-bootstrap.properties | 1 + .../resources/static/css/jumbotron-narrow.css | 94 +++++++ .../src/main/resources/static/index.html | 79 ++++++ .../src/main/resources/static/js/app.js | 16 ++ .../src/main/resources/static/js/service.js | 20 ++ .../resources/static/js/status/status.html | 16 ++ .../main/resources/static/js/status/status.js | 42 +++ samples/cloudant/.gitignore | 1 + 65 files changed, 3494 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 NOTICE create mode 100644 README.md create mode 100644 bluemix-cloud-connectors-cloudfoundry/pom.xml create mode 100644 bluemix-cloud-connectors-cloudfoundry/src/main/java/net/bluemix/connectors/cloudfoundry/creator/CloudantServiceInfoCreator.java create mode 100644 bluemix-cloud-connectors-cloudfoundry/src/main/java/net/bluemix/connectors/cloudfoundry/creator/SendGridServiceInfoCreator.java create mode 100644 bluemix-cloud-connectors-cloudfoundry/src/main/java/net/bluemix/connectors/cloudfoundry/creator/TwilioServiceInfoCreator.java create mode 100644 bluemix-cloud-connectors-cloudfoundry/src/main/resources/META-INF/services/org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator create mode 100644 bluemix-cloud-connectors-cloudfoundry/src/test/java/net/bluemix/connectors/cloudfoundry/creator/CloudantServiceInfoCreatorTest.java create mode 100644 bluemix-cloud-connectors-cloudfoundry/src/test/java/net/bluemix/connectors/cloudfoundry/creator/SendGridServiceInfoCreatorTest.java create mode 100644 bluemix-cloud-connectors-cloudfoundry/src/test/java/net/bluemix/connectors/cloudfoundry/creator/TwilioServiceInfoCreatorTest.java create mode 100644 bluemix-cloud-connectors-core/pom.xml create mode 100644 bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/creator/CouchDbInstanceCreator.java create mode 100644 bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/creator/TwilioRestClientCreator.java create mode 100644 bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/info/CloudantServiceInfo.java create mode 100644 bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/info/TwilioServiceInfo.java create mode 100644 bluemix-cloud-connectors-core/src/main/resources/META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator create mode 100644 bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/creator/CouchDbInstanceCreatorTest.java create mode 100644 bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/creator/TwilioRestClientCreatorTest.java create mode 100644 bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/info/CloudantServiceInfoTest.java create mode 100644 bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/info/TwilioServiceInfoTest.java create mode 100644 bluemix-cloud-connectors-local/pom.xml create mode 100644 bluemix-cloud-connectors-local/src/main/java/net/bluemix/connectors/local/CouchDbLocalConfigServiceInfoCreator.java create mode 100644 bluemix-cloud-connectors-local/src/main/java/net/bluemix/connectors/local/SendGridLocalConfigServiceInfoCreator.java create mode 100644 bluemix-cloud-connectors-local/src/main/java/net/bluemix/connectors/local/TwilioLocalConfigServiceInfoCreator.java create mode 100644 bluemix-cloud-connectors-local/src/main/resources/META-INF/services/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator create mode 100644 bluemix-cloud-connectors-local/src/test/java/net/bluemix/connectors/local/CouchDbLocalConfigServiceInfoCreatorTest.java create mode 100644 bluemix-cloud-connectors-local/src/test/java/net/bluemix/connectors/local/SendGridLocalConfigServiceInfoCreatorTest.java create mode 100644 bluemix-cloud-connectors-local/src/test/java/net/bluemix/connectors/local/TwilioLocalConfigServiceInfoCreatorTest.java create mode 100644 pom.xml create mode 100644 samples/cloudant-liberty/README.MD create mode 100644 samples/cloudant-liberty/pom.xml create mode 100644 samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/CloudantBean.java create mode 100644 samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/Status.java create mode 100644 samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/StatusController.java create mode 100644 samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/StatusRepository.java create mode 100644 samples/cloudant-liberty/src/main/resources/spring-cloud-bootstrap.properties create mode 100644 samples/cloudant-liberty/src/main/webapp/WEB-INF/beans.xml create mode 100644 samples/cloudant-liberty/src/main/webapp/WEB-INF/ibm-web-ext.xml create mode 100644 samples/cloudant-liberty/src/main/webapp/WEB-INF/web.xml create mode 100644 samples/cloudant-liberty/src/main/webapp/css/jumbotron-narrow.css create mode 100644 samples/cloudant-liberty/src/main/webapp/index.html create mode 100644 samples/cloudant-liberty/src/main/webapp/js/app.js create mode 100644 samples/cloudant-liberty/src/main/webapp/js/service.js create mode 100644 samples/cloudant-liberty/src/main/webapp/js/status/status.html create mode 100644 samples/cloudant-liberty/src/main/webapp/js/status/status.js create mode 100644 samples/cloudant-liberty/src/main/wlp/localserver.xml create mode 100644 samples/cloudant-liberty/src/main/wlp/server.xml create mode 100644 samples/cloudant-spring/README.md create mode 100644 samples/cloudant-spring/pom.xml create mode 100644 samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/App.java create mode 100644 samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/Status.java create mode 100644 samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/StatusRepository.java create mode 100644 samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/StatusRestController.java create mode 100644 samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/config/Config.java create mode 100644 samples/cloudant-spring/src/main/resources/application.properties create mode 100644 samples/cloudant-spring/src/main/resources/spring-cloud-bootstrap.properties create mode 100644 samples/cloudant-spring/src/main/resources/static/css/jumbotron-narrow.css create mode 100644 samples/cloudant-spring/src/main/resources/static/index.html create mode 100644 samples/cloudant-spring/src/main/resources/static/js/app.js create mode 100644 samples/cloudant-spring/src/main/resources/static/js/service.js create mode 100644 samples/cloudant-spring/src/main/resources/static/js/status/status.html create mode 100644 samples/cloudant-spring/src/main/resources/static/js/status/status.js create mode 100644 samples/cloudant/.gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eeb62ab --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# +# Copyright IBM Corp. 2014 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +.classpath +.project +.settings/ +target/ +*.class + +# Package Files # +*.jar +*.war +*.ear diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7a4a3ea --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..9184666 --- /dev/null +++ b/NOTICE @@ -0,0 +1,2 @@ +This product includes software originally developed by IBM Corporation +Copyright 2014 IBM Corp. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0ac5c5d --- /dev/null +++ b/README.md @@ -0,0 +1,149 @@ +## About +This project is meant to simplify the way Java developers access services +when deploying apps to IBM Bluemix. When leveraging a bound service in an app +deployed to Bluemix you need to do go through a number of steps regardless of the +service you bound. + +1. Access the value of the VCAP_SERVICES environment variable. +2. Parse the returned String into some type of Java object you can work with. +3. Extract the data for the service you are interested in. +4. Extract the credentials for the service you are interested in. +5. Use the services Java client libraries to interact with that service. + +Since these steps are pretty much repeated multiple times across all Java apps it is a great +opportunity to create a library that takes care of writing this mundane code. The +[Spring Cloud Connectors project](http://cloud.spring.io/spring-cloud-connectors/) +already does this for [some services](https://github.com/spring-cloud/spring-cloud-connectors/tree/master/spring-cloud-cloudfoundry-connector) +that are common across all Cloud Foundry deployments. However there are many services in Bluemix +that are not part of this project. This project builds upon the Spring Cloud Connectors +project and provides connectors for the services within Bluemix. + +### Supported Services +In addition to the services supported by the Spring Cloud Connectors project the +Bluemix Cloud Connectors project supports the following services + +* Cloudant - via the [Ektorp library](http://ektorp.org/) +* SendGrid - SendGrid is already supported by the Spring Cloud Connectors project but due to +the way the service credentials are created in VCAP_SERVICES it did not work +* Twilio - via the [Twilio client library](https://www.twilio.com/docs/java/install) + +## When To Use This Project +If you are using the Liberty Runtime in Bluemix you can take advantage of the +[auto-configuration](https://www.ng.bluemix.net/docs/#starters/liberty/index.html#automaticconfigurationofboundservices) +features which may do the same thing as this project so it doesn't make sense to use this +project in your app in that case. However if you are not using the Liberty Runtime and you are using +another Java buildpack to run your application than this library might make sense. Also if you want to +use the Liberty buildpack but want the application to manage the connection to the service than this might +also be a situation when you might want to use this library. In addition when developing locally you can configure +connection to local or remote services via a properties file instead of configuring the server itself. + +## Getting Started + +### Getting The Dependencies + +Add the following dependency to you Maven/Gradle project. + +TODO Add code + +Alternatively you can download the jar from here. + +### Accessing The Service Credentials In A Non-Spring App +In a non-Spring app you can easily access the credentials of a service from a ServiceInfo class. +Here is how you would get a list of ServiceInfos for the services bound to your application. + +``` +CloudFactory cloudFactory = new CloudFactory(); +Cloud cloud = cloudFactory.getCloud(); +List serviceInfos = cloud.getServiceInfos(); +``` + +You can also get a subset of ServiceInfo objects for a specific service type, for example +Cloudant. + +``` +List databaseInfos = cloud.getServiceInfos(CouchDbInstance.class); +``` + +Alternatively you can also get a higher level Java object to work with for a specific service. + +``` +//The serviceId variable should be the name you gave to your service. +String serviceId = "cloudant-db"; +CouchDbInstance couchDb = cloud.getServiceConnector(serviceId, CouchDbInstance.class, null /* default config */); +``` + +For more detailed information on how this works you should read the +[Spring Cloud Connectors documentation](https://github.com/spring-cloud/spring-cloud-connectors/tree/master/spring-cloud-core). + +There is a sample JEE app using the Bluemix Cloud Connectors project in the samples/cloudant-liberty folder. + +### Accessing The Service Credentials In A Spring App +When you are using Spring you can easily create beans for services you have bound to your app in Bluemix. + +``` +public class Config { + + @Configuration + static class CloudConfiguration extends AbstractCloudConfig { + @Bean + public CouchDbInstance couchDbInstance() { + CouchDbInstance instance = connectionFactory().service(CouchDbInstance.class); + return instance; + } + } +} +``` + +This bean can now be injected into other classes and used to access the service bound to your application. +For more detailed information see the +[Spring Cloud Connectors documentation](https://github.com/spring-cloud/spring-cloud-connectors/tree/master/spring-cloud-spring-service-connector). + +There is a sample Spring app using the Bluemix Cloud Connectors project in the samples/cloudant-spring folder. + +### When Running Locally +When building apps for Bluemix, you usually want to also run your application locally during +development. Developers have come up with various ways of achieving this. Some set a VCAP_SERVICES environment +variable on their development machine. Others write code that tries to determine if the application is running +locally or in the cloud. In Spring you can use something like Spring profiles to enable certain configuration beans +when running in the cloud and running locally. + +The Spring Cloud Connectors project has a simple way of allowing developers +to run their Bluemix apps in the cloud and locally without having to write any extra code. You can read more about how this works +in the [Spring Cloud Connectors project](https://github.com/spring-cloud/spring-cloud-connectors/tree/3ec88aba9ed85f2b09d2cafb620ad1d4a28aaa9d/spring-cloud-localconfig-connector). + +In short, create a file called `spring-cloud-bootstrap.properties` in the project and add it to the project classpath. +In that file create a property called `spring.cloud.propertiesFile`. The value of the property should be a path to another +properties file which will contain the credentials to the service to use when running locally. Here is a sample +`spring-cloud-bootstrap.properties` file. + + spring.cloud.propertiesFile: ${user.home}/.config/cloudant-connector-sample/spring-cloud.properties + +The properties file containing the service credentials should contain 2 properties `spring.cloud.appId` and +`spring.cloud.{id}` where {id} is the service ID you are using for your service in the cloud. The `spring.cloud.appId` +property should be a unique id for your app. The `spring.cloud.{id}` should be a URL to your service including any credentials +needed to access the service. Here is a sample + + spring.cloud.appId: cloudant-sample + spring.cloud.cloudant: couchdb://user:pass@localhost:5984 + +#### Cloudant/CouchDB + +The Spring Cloud Connectors project assumes that the `spring.cloud.{id}` is a URL. Unfortunately Cloudant/CouchDB operates over +HTTP so it is hard for the Bluemix Cloud Connectors project to know what connector to use. For that reason you must use the `couchdb` +protocol (which is something we made up), for example `couchdb://user:pass@localhost:5984`. + +#### Twilio + +The Spring Cloud Connectors project assumes that the `spring.cloud.{id}` is a URL. Unfortunately Twilio operates over +HTTP so it is hard for the Bluemix Cloud Connectors project to know what connector to use. For that reason you must use the `twilio` +protocol (which is something we made up), for example `twilio://user:pass@localhost:5984`. + + +## License + +This code is licensed under Apache v2. See the LICENSE file in the root of +the repository. + +## Dependencies + +For a list of 3rd party dependencies that are used see the POM files of the individual projects. \ No newline at end of file diff --git a/bluemix-cloud-connectors-cloudfoundry/pom.xml b/bluemix-cloud-connectors-cloudfoundry/pom.xml new file mode 100644 index 0000000..9916d08 --- /dev/null +++ b/bluemix-cloud-connectors-cloudfoundry/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + net.bluemix + bluemix-cloud-connectors + 0.0.1-SNAPSHOT + + bluemix-cloud-connectors-cloudfoundry + + + + + + + org.springframework.cloud + spring-cloud-cloudfoundry-connector + 1.1.0.RELEASE + + + net.bluemix + bluemix-cloud-connectors-core + 0.0.1-SNAPSHOT + + + \ No newline at end of file diff --git a/bluemix-cloud-connectors-cloudfoundry/src/main/java/net/bluemix/connectors/cloudfoundry/creator/CloudantServiceInfoCreator.java b/bluemix-cloud-connectors-cloudfoundry/src/main/java/net/bluemix/connectors/cloudfoundry/creator/CloudantServiceInfoCreator.java new file mode 100644 index 0000000..df5ea2a --- /dev/null +++ b/bluemix-cloud-connectors-cloudfoundry/src/main/java/net/bluemix/connectors/cloudfoundry/creator/CloudantServiceInfoCreator.java @@ -0,0 +1,80 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudfoundry.creator; + +import java.util.Map; + +import net.bluemix.connectors.core.info.CloudantServiceInfo; + +import org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator; +import org.springframework.cloud.cloudfoundry.Tags; + +/** + * Creates a new {@link CloudantServiceInfo}. + * @author ryanjbaxter + * + */ +public class CloudantServiceInfoCreator extends CloudFoundryServiceInfoCreator { + + /** + * Constructor. + */ + public CloudantServiceInfoCreator() { + super(new Tags(), CloudantServiceInfo.CLOUDANT_SCHEME); + } + + @Override + public boolean accept(Map serviceData) { + boolean result = false; + // Don't really like using the label as the determining factor but that is the only + // unique attribute to identify the service with. + Object obj = serviceData.get("label"); + if(obj instanceof String) { + String label = (String)obj; + result = "cloudantNoSQLDB".equals(label); + } + return result; + } + + @Override + public CloudantServiceInfo createServiceInfo(Map serviceData) { + String id = null; + String username = null; + String password = null; + String host = null; + int port = 0; + String url = null; + Object credObject = serviceData.get("credentials"); + Object idObj = serviceData.get("name"); + if(idObj instanceof String) { id = (String)idObj; } + if(credObject instanceof Map) { + Map credentials = (Map)credObject; + Object usernameObj = credentials.get("username"); + Object passwordObj = credentials.get("password"); + Object hostObj = credentials.get("host"); + Object portObj = credentials.get("port"); + Object urlObj = credentials.get("url"); + if(usernameObj instanceof String) { username = (String)usernameObj; } + if(passwordObj instanceof String) { password = (String)passwordObj; } + if(hostObj instanceof String) { host = (String)hostObj; } + if(portObj instanceof Integer) { port = (Integer)portObj; } + if(urlObj instanceof String) { url = (String)urlObj; } + } + return new CloudantServiceInfo(id, username, password, host, port, url); + } + +} + diff --git a/bluemix-cloud-connectors-cloudfoundry/src/main/java/net/bluemix/connectors/cloudfoundry/creator/SendGridServiceInfoCreator.java b/bluemix-cloud-connectors-cloudfoundry/src/main/java/net/bluemix/connectors/cloudfoundry/creator/SendGridServiceInfoCreator.java new file mode 100644 index 0000000..6d3e30a --- /dev/null +++ b/bluemix-cloud-connectors-cloudfoundry/src/main/java/net/bluemix/connectors/cloudfoundry/creator/SendGridServiceInfoCreator.java @@ -0,0 +1,38 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudfoundry.creator; + +import java.util.Map; + +import org.springframework.cloud.cloudfoundry.SmtpServiceInfoCreator; + + + +/** + * Service info creator for SendGrid. + * In Bluemix SendGrid does not have the URI so we need to change the default + * SmtpServiceInfoCreator accept method. + * @author ryanjbaxter + * + */ +public class SendGridServiceInfoCreator extends SmtpServiceInfoCreator { + @Override + public boolean accept(Map serviceData) { + String label = (String)serviceData.get("label"); + return "sendgrid".equalsIgnoreCase(label); + } +} + diff --git a/bluemix-cloud-connectors-cloudfoundry/src/main/java/net/bluemix/connectors/cloudfoundry/creator/TwilioServiceInfoCreator.java b/bluemix-cloud-connectors-cloudfoundry/src/main/java/net/bluemix/connectors/cloudfoundry/creator/TwilioServiceInfoCreator.java new file mode 100644 index 0000000..f71bb77 --- /dev/null +++ b/bluemix-cloud-connectors-cloudfoundry/src/main/java/net/bluemix/connectors/cloudfoundry/creator/TwilioServiceInfoCreator.java @@ -0,0 +1,72 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudfoundry.creator; + +import java.util.Map; + +import net.bluemix.connectors.core.info.TwilioServiceInfo; + +import org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator; +import org.springframework.cloud.cloudfoundry.Tags; + +/** + * Creates new TwilioServieInfo when Twilio is bound as a service to the application. + * @author ryanjbaxter + * + */ +public class TwilioServiceInfoCreator extends CloudFoundryServiceInfoCreator { + + private static final String TWILIO_API_URI = "https://api.twilio.com"; + + /** + * Constructor. + */ + public TwilioServiceInfoCreator() { + super(new Tags(), "https"); + } + + @Override + public boolean accept(Map serviceData) { + Object credObject = serviceData.get("credentials"); + if(credObject instanceof Map) { + Map credentials = (Map)credObject; + Object urlObj = credentials.get("url"); + if(urlObj instanceof String) { + return TWILIO_API_URI.equals((String)urlObj); + } + } + return false; + } + + @Override + public TwilioServiceInfo createServiceInfo(Map serviceData) { + String accountId = null; + String authToken = null; + String id = null; + Object credObject = serviceData.get("credentials"); + Object idObj = serviceData.get("name"); + if(idObj instanceof String) { id = (String)idObj; } + if(credObject instanceof Map) { + Map credentials = (Map)credObject; + Object accoutIdObj = credentials.get("accountSID"); + Object authTokenObj = credentials.get("authToken"); + if(accoutIdObj instanceof String) { accountId = (String)accoutIdObj; } + if(authTokenObj instanceof String) { authToken = (String)authTokenObj; } + } + return new TwilioServiceInfo(id, accountId, authToken); + } +} + diff --git a/bluemix-cloud-connectors-cloudfoundry/src/main/resources/META-INF/services/org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator b/bluemix-cloud-connectors-cloudfoundry/src/main/resources/META-INF/services/org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator new file mode 100644 index 0000000..18d6160 --- /dev/null +++ b/bluemix-cloud-connectors-cloudfoundry/src/main/resources/META-INF/services/org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator @@ -0,0 +1,3 @@ +net.bluemix.connectors.cloudfoundry.creator.CloudantServiceInfoCreator +net.bluemix.connectors.cloudfoundry.creator.SendGridServiceInfoCreator +net.bluemix.connectors.cloudfoundry.creator.TwilioServiceInfoCreator \ No newline at end of file diff --git a/bluemix-cloud-connectors-cloudfoundry/src/test/java/net/bluemix/connectors/cloudfoundry/creator/CloudantServiceInfoCreatorTest.java b/bluemix-cloud-connectors-cloudfoundry/src/test/java/net/bluemix/connectors/cloudfoundry/creator/CloudantServiceInfoCreatorTest.java new file mode 100644 index 0000000..de4b639 --- /dev/null +++ b/bluemix-cloud-connectors-cloudfoundry/src/test/java/net/bluemix/connectors/cloudfoundry/creator/CloudantServiceInfoCreatorTest.java @@ -0,0 +1,87 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudfoundry.creator; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; +import java.util.Map; + +import net.bluemix.connectors.core.info.CloudantServiceInfo; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class CloudantServiceInfoCreatorTest { + + private CloudantServiceInfoCreator creator; + + @Before + public void setUp() throws Exception { + creator = new CloudantServiceInfoCreator(); + } + + @After + public void tearDown() throws Exception { + creator = null; + } + + @Test + public void testAcceptMapOfStringObject() { + Map emptyProps = new HashMap(); + Map stringProps = new HashMap(); + stringProps.put("label", "cloudantNoSQLDB"); + Map intProps = new HashMap(); + intProps.put("label", 123); + assertFalse(creator.accept(emptyProps)); + assertFalse(creator.accept(intProps)); + assertTrue(creator.accept(stringProps)); + } + + @Test + public void testCreateServiceInfo() { + Map empty = new HashMap(); + Map badTypes = new HashMap(); + badTypes.put("name", 1); + Map badCredTypes = new HashMap(); + badCredTypes.put("username", 1); + badCredTypes.put("password", 1); + badCredTypes.put("host", 1); + badCredTypes.put("url", 1); + badCredTypes.put("port", "1"); + badTypes.put("credentials", badCredTypes); + Map rawInfo = new HashMap(); + rawInfo.put("name", "id"); + Map rawInfoCreds = new HashMap(); + rawInfoCreds.put("username", "username"); + rawInfoCreds.put("password", "password"); + rawInfoCreds.put("host", "host"); + rawInfoCreds.put("url", "url"); + rawInfoCreds.put("port", 443); + rawInfo.put("credentials", rawInfoCreds); + CloudantServiceInfo nullServiceInfo = new CloudantServiceInfo(null, null, null, null, 0, null); + CloudantServiceInfo serviceInfo = new CloudantServiceInfo("id", "username", "password", "host", 443, "url"); + assertEquals(nullServiceInfo, creator.createServiceInfo(empty)); + assertEquals(nullServiceInfo, creator.createServiceInfo(badTypes)); + assertEquals(serviceInfo, creator.createServiceInfo(rawInfo)); + + } + +} + diff --git a/bluemix-cloud-connectors-cloudfoundry/src/test/java/net/bluemix/connectors/cloudfoundry/creator/SendGridServiceInfoCreatorTest.java b/bluemix-cloud-connectors-cloudfoundry/src/test/java/net/bluemix/connectors/cloudfoundry/creator/SendGridServiceInfoCreatorTest.java new file mode 100644 index 0000000..fdf40f2 --- /dev/null +++ b/bluemix-cloud-connectors-cloudfoundry/src/test/java/net/bluemix/connectors/cloudfoundry/creator/SendGridServiceInfoCreatorTest.java @@ -0,0 +1,53 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudfoundry.creator; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class SendGridServiceInfoCreatorTest { + + private SendGridServiceInfoCreator creator; + + @Before + public void setUp() throws Exception { + this.creator = new SendGridServiceInfoCreator(); + } + + @After + public void tearDown() throws Exception { + this.creator = null; + } + + @Test + public void testAccept() { + Map data = new HashMap(); + assertFalse(creator.accept(data)); + data.put("label", "foo"); + assertFalse(creator.accept(data)); + data.put("label", "sendgrid"); + assertTrue(creator.accept(data)); + } + +} + diff --git a/bluemix-cloud-connectors-cloudfoundry/src/test/java/net/bluemix/connectors/cloudfoundry/creator/TwilioServiceInfoCreatorTest.java b/bluemix-cloud-connectors-cloudfoundry/src/test/java/net/bluemix/connectors/cloudfoundry/creator/TwilioServiceInfoCreatorTest.java new file mode 100644 index 0000000..3e175be --- /dev/null +++ b/bluemix-cloud-connectors-cloudfoundry/src/test/java/net/bluemix/connectors/cloudfoundry/creator/TwilioServiceInfoCreatorTest.java @@ -0,0 +1,80 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudfoundry.creator; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; +import java.util.Map; + +import net.bluemix.connectors.core.info.TwilioServiceInfo; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class TwilioServiceInfoCreatorTest { + + private TwilioServiceInfoCreator creator; + + @Before + public void setUp() throws Exception { + this.creator = new TwilioServiceInfoCreator(); + } + + @After + public void tearDown() throws Exception { + this.creator = null; + } + + @Test + public void testAcceptMapOfStringObject() { + Map serviceData = new HashMap(); + Map credData = new HashMap(); + credData.put("url", "http://api.twilio.com"); + serviceData.put("credentials", credData); + assertFalse(creator.accept(serviceData)); + credData.put("url", "https://api.twilio.com"); + assertTrue(creator.accept(serviceData)); + credData.remove("url"); + assertFalse(creator.accept(serviceData)); + } + + @Test + public void testCreateServiceInfo() { + Map empty = new HashMap(); + Map badTypes = new HashMap(); + badTypes.put("name", 1); + Map badCredTypes = new HashMap(); + badCredTypes.put("accountSID", 1); + badCredTypes.put("authToken", 1); + badTypes.put("credentials", badCredTypes); + Map rawInfo = new HashMap(); + rawInfo.put("name", "id"); + Map rawInfoCreds = new HashMap(); + rawInfoCreds.put("accountSID", "abc"); + rawInfoCreds.put("authToken", "123"); + rawInfo.put("credentials", rawInfoCreds); + TwilioServiceInfo nullServiceInfo = new TwilioServiceInfo(null, null, null); + TwilioServiceInfo serviceInfo = new TwilioServiceInfo("id", "abc", "123"); + assertEquals(nullServiceInfo, creator.createServiceInfo(empty)); + assertEquals(nullServiceInfo, creator.createServiceInfo(badTypes)); + assertEquals(serviceInfo, creator.createServiceInfo(rawInfo)); + } +} + diff --git a/bluemix-cloud-connectors-core/pom.xml b/bluemix-cloud-connectors-core/pom.xml new file mode 100644 index 0000000..5ae3550 --- /dev/null +++ b/bluemix-cloud-connectors-core/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + + net.bluemix + bluemix-cloud-connectors + 0.0.1-SNAPSHOT + + bluemix-cloud-connectors-core + + + + + + + \ No newline at end of file diff --git a/bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/creator/CouchDbInstanceCreator.java b/bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/creator/CouchDbInstanceCreator.java new file mode 100644 index 0000000..0334bbd --- /dev/null +++ b/bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/creator/CouchDbInstanceCreator.java @@ -0,0 +1,55 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.core.creator; + +import java.net.MalformedURLException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import net.bluemix.connectors.core.info.CloudantServiceInfo; + +import org.ektorp.CouchDbInstance; +import org.ektorp.http.HttpClient; +import org.ektorp.http.StdHttpClient; +import org.ektorp.impl.StdCouchDbInstance; +import org.springframework.cloud.service.AbstractServiceConnectorCreator; +import org.springframework.cloud.service.ServiceConnectorConfig; + +/** + * Handles creating a CouchDBInstance from the CloudantServiceInfo object. + * @author ryanjbaxter + * + */ +public class CouchDbInstanceCreator extends AbstractServiceConnectorCreator { + + private static final Logger LOG = Logger.getLogger(CouchDbInstanceCreator.class.getName()); + + @Override + public CouchDbInstance create(CloudantServiceInfo serviceInfo, + ServiceConnectorConfig serviceConnectorConfig) { + HttpClient httpClient; + try { + httpClient = new StdHttpClient.Builder() + .url(serviceInfo.getUrl()) + .build(); + return new StdCouchDbInstance(httpClient); + } catch (MalformedURLException e) { + LOG.logp(Level.WARNING, CouchDbInstanceCreator.class.getName(), "create", "Error parsing URL", e); + return null; + } + } +} + diff --git a/bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/creator/TwilioRestClientCreator.java b/bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/creator/TwilioRestClientCreator.java new file mode 100644 index 0000000..e7e8f3d --- /dev/null +++ b/bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/creator/TwilioRestClientCreator.java @@ -0,0 +1,33 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.core.creator; + +import net.bluemix.connectors.core.info.TwilioServiceInfo; + +import org.springframework.cloud.service.AbstractServiceConnectorCreator; +import org.springframework.cloud.service.ServiceConnectorConfig; + +import com.twilio.sdk.TwilioRestClient; + +public class TwilioRestClientCreator extends AbstractServiceConnectorCreator { + + @Override + public TwilioRestClient create(TwilioServiceInfo serviceInfo, + ServiceConnectorConfig serviceConnectorConfig) { + return new TwilioRestClient(serviceInfo.getAccountId(), serviceInfo.getAuthToken()); + } +} + diff --git a/bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/info/CloudantServiceInfo.java b/bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/info/CloudantServiceInfo.java new file mode 100644 index 0000000..25b9d0e --- /dev/null +++ b/bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/info/CloudantServiceInfo.java @@ -0,0 +1,151 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.core.info; +import java.net.URI; +import java.net.URISyntaxException; + +import org.springframework.cloud.service.BaseServiceInfo; + +/** + * Represents the Cloudant VCAP_SERVICE info. + * @author ryanjbaxter + * + */ +public class CloudantServiceInfo extends BaseServiceInfo { + + /** + * Cloudant scheme. + * This is not a real scheme but is needed for local config to work. + */ + public static final String CLOUDANT_SCHEME = "couchdb"; + + private String username; + private String password; + private String host; + private int port; + private String url; + + /** + * Constructor. + * @param id The service id. + * @param username The username for the service. + * @param password The password for the service. + * @param host The host name for the service. + * @param port The port for the service. + * @param url The URL to the service. This should include the username and password. + */ + public CloudantServiceInfo(String id, String username, String password, String host, int port, String url) { + super(id); + this.username = username; + this.password = password; + this.host = host; + this.port = port; + this.url = url; + } + + public CloudantServiceInfo(String id, String url) throws URISyntaxException { + super(id); + URI uri = new URI(url); + this.url = url.replace(CloudantServiceInfo.CLOUDANT_SCHEME, "http"); + this.host = uri.getHost(); + this.port = uri.getPort(); + String serviceInfoString = uri.getUserInfo(); + if(serviceInfoString != null) { + String[] userInfo = serviceInfoString.split(":"); + this.username = userInfo[0]; + this.password = userInfo[1]; + } + } + + /** + * Gets the username. + * @return The username. + */ + @ServiceProperty + public String getUsername() { + return username; + } + + /** + * Gets the password. + * @return The password. + */ + @ServiceProperty + public String getPassword() { + return password; + } + + /** + * Gets the host. + * @return The host. + */ + @ServiceProperty + public String getHost() { + return host; + } + + /** + * Gets the port. + * @return The port. + */ + @ServiceProperty + public int getPort() { + return port; + } + + /** + * Gets the URL. + * @return The URL. + */ + @ServiceProperty + public String getUrl() { + return url; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((host == null) ? 0 : host.hashCode()); + result = prime * result + ((password == null) ? 0 : password.hashCode()); + result = prime * result + port; + result = prime * result + ((url == null) ? 0 : url.hashCode()); + result = prime * result + ((username == null) ? 0 : username.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if(obj == null || !(obj instanceof CloudantServiceInfo)) { + return false; + } + boolean result = false; + CloudantServiceInfo test = (CloudantServiceInfo)obj; + result = test.getHost() != null ? test.getHost().equals(this.getHost()) : test.getHost() == this.getHost(); + result &= test.getPassword() != null ? test.getPassword().equals(this.getPassword()) : test.getPassword() == this.getPassword(); + result &= test.getUsername() != null ? test.getUsername().equals(this.getUsername()) : test.getUsername() == this.getUsername(); + result &= test.getId() != null ? test.getId().equals(this.getId()) : test.getId() == this.getId(); + result &= test.getPort() == this.getPort(); + result &= test.getUrl() != null ? test.getUrl().equals(this.getUrl()) : test.getUrl() == this.getUrl(); + return result; + } + + @Override + public String toString() { + return "CloudantServiceInfo [username=" + username + ", password=" + password + ", host=" + + host + ", port=" + port + ", url=" + url + "]"; + } +} diff --git a/bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/info/TwilioServiceInfo.java b/bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/info/TwilioServiceInfo.java new file mode 100644 index 0000000..73776d7 --- /dev/null +++ b/bluemix-cloud-connectors-core/src/main/java/net/bluemix/connectors/core/info/TwilioServiceInfo.java @@ -0,0 +1,102 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.core.info; + +import org.springframework.cloud.service.UriBasedServiceInfo; + +/** + * Represents service information for Twilio. + * @author ryanjbaxter + * + */ +public class TwilioServiceInfo extends UriBasedServiceInfo { + + private String accountId; + private String authToken; + + /** + * Constructor. + * @param id The ID of the service. + * @param accountId The account ID for the Twilio account. + * @param authToken The auth token for the Twilio account. + */ + public TwilioServiceInfo(String id, String accountId, String authToken) { + super(id, "http", "api.twilio.com", 443, accountId, authToken, ""); + this.accountId = accountId; + this.authToken = authToken; + } + + /** + * Constructor. + * @param id The ID of the service + * @param url The URL to Twilio. + */ + public TwilioServiceInfo(String id, String url) { + super(id, url); + this.accountId = this.getUserName(); + this.authToken = this.getPassword(); + } + + /** + * Gets the account ID. + * @return The account ID. + */ + @ServiceProperty + public String getAccountId() { + return accountId; + } + + /** + * Gets the auth token. + * @return The auth token. + */ + @ServiceProperty + public String getAuthToken() { + return authToken; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((accountId == null) ? 0 : accountId.hashCode()); + result = prime * result + ((authToken == null) ? 0 : authToken.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if(obj == null || !(obj instanceof TwilioServiceInfo)){ + return false; + } else { + TwilioServiceInfo test = (TwilioServiceInfo)obj; + boolean result = false; + result = test.getAccountId() != null ? test.getAccountId().equals(this.getAccountId()) : + test.getAccountId() == this.getAccountId(); + result &= test.getAuthToken() != null ? test.getAuthToken().equals(this.getAuthToken()) : + test.getAuthToken() == this.getAuthToken(); + result &= test.getId() != null ? test.getId().equals(this.getId()) : + test.getId() == this.getId(); + return result; + } + } + + @Override + public String toString() { + return "TwilioServiceInfo [accountId=" + accountId + ", authToken=" + authToken + ", id=" + getId() + "]"; + } +} + diff --git a/bluemix-cloud-connectors-core/src/main/resources/META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator b/bluemix-cloud-connectors-core/src/main/resources/META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator new file mode 100644 index 0000000..fd21b23 --- /dev/null +++ b/bluemix-cloud-connectors-core/src/main/resources/META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator @@ -0,0 +1,2 @@ +net.bluemix.connectors.core.creator.CouchDbInstanceCreator +net.bluemix.connectors.core.creator.TwilioRestClientCreator \ No newline at end of file diff --git a/bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/creator/CouchDbInstanceCreatorTest.java b/bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/creator/CouchDbInstanceCreatorTest.java new file mode 100644 index 0000000..59b8bfb --- /dev/null +++ b/bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/creator/CouchDbInstanceCreatorTest.java @@ -0,0 +1,52 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.core.creator; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import net.bluemix.connectors.core.info.CloudantServiceInfo; + +import org.ektorp.CouchDbInstance; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.cloud.service.ServiceConnectorConfig; + +public class CouchDbInstanceCreatorTest { + + private CouchDbInstanceCreator creator; + + @Before + public void setUp() throws Exception { + creator = new CouchDbInstanceCreator(); + } + + @After + public void tearDown() throws Exception { + creator = null; + } + + @Test + public void testCreate() { + CloudantServiceInfo badUrlServiceInfo = new CloudantServiceInfo("id", "username", "password", "host", 443, "url"); + CloudantServiceInfo serviceInfo = new CloudantServiceInfo("testId", "username", "password", "username.cloudant.com", 443, + "https://username:password@username.cloudant.com"); + assertNull(creator.create(badUrlServiceInfo, new ServiceConnectorConfig(){})); + assertTrue(creator.create(serviceInfo, new ServiceConnectorConfig(){}) instanceof CouchDbInstance); + } + +} + diff --git a/bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/creator/TwilioRestClientCreatorTest.java b/bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/creator/TwilioRestClientCreatorTest.java new file mode 100644 index 0000000..124d978 --- /dev/null +++ b/bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/creator/TwilioRestClientCreatorTest.java @@ -0,0 +1,48 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.core.creator; + +import static org.junit.Assert.assertTrue; +import net.bluemix.connectors.core.info.TwilioServiceInfo; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.twilio.sdk.TwilioRestClient; + +public class TwilioRestClientCreatorTest { + + private TwilioRestClientCreator creator; + + @Before + public void setUp() throws Exception { + this.creator = new TwilioRestClientCreator(); + } + + @After + public void tearDown() throws Exception { + this.creator = null; + } + + @Test + public void testCreate() { + TwilioServiceInfo info = new TwilioServiceInfo("twilio", "AC12345678ac12345678ac123456781234", "1234511c2209d62fab4766fa75435f1e"); + assertTrue(this.creator.create(info, null) instanceof TwilioRestClient); + } + +} + diff --git a/bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/info/CloudantServiceInfoTest.java b/bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/info/CloudantServiceInfoTest.java new file mode 100644 index 0000000..6c9268f --- /dev/null +++ b/bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/info/CloudantServiceInfoTest.java @@ -0,0 +1,76 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.core.info; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class CloudantServiceInfoTest { + + private CloudantServiceInfo serviceInfo; + + @Before + public void setUp() throws Exception { + serviceInfo = new CloudantServiceInfo("testId", "username", "password", "username.cloudant.com", 443, + "https://username:password@username.cloudant.com"); + } + + @After + public void tearDown() throws Exception { + serviceInfo = null; + } + + @Test + public void testGetUsername() { + assertEquals("username", serviceInfo.getUsername()); + } + + @Test + public void testGetPassword() { + assertEquals("password", serviceInfo.getPassword()); + } + + @Test + public void testGetHost() { + assertEquals("username.cloudant.com", serviceInfo.getHost()); + } + + @Test + public void testGetPort() { + assertEquals(443, serviceInfo.getPort()); + } + + @Test + public void testGetUrl() { + assertEquals("https://username:password@username.cloudant.com", serviceInfo.getUrl()); + } + + @Test + public void testEquals() { + assertFalse(serviceInfo.equals(null)); + assertFalse(serviceInfo.equals("test")); + assertFalse(serviceInfo.equals(new CloudantServiceInfo(null, null, null, null, 0, null))); + assertTrue(serviceInfo.equals(new CloudantServiceInfo("testId", "username", "password", "username.cloudant.com", 443, + "https://username:password@username.cloudant.com"))); + } + +} + diff --git a/bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/info/TwilioServiceInfoTest.java b/bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/info/TwilioServiceInfoTest.java new file mode 100644 index 0000000..f11873c --- /dev/null +++ b/bluemix-cloud-connectors-core/src/test/java/net/bluemix/connectors/core/info/TwilioServiceInfoTest.java @@ -0,0 +1,72 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.core.info; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class TwilioServiceInfoTest { + + private TwilioServiceInfo nullInfo; + private TwilioServiceInfo info; + private TwilioServiceInfo urlInfo; + + @Before + public void setUp() throws Exception { + this.nullInfo = new TwilioServiceInfo("twilio", null, null); + this.info = new TwilioServiceInfo("twilio", "abc", "123"); + this.urlInfo = new TwilioServiceInfo("twilio", "https://abc:123@api.twilio.com"); + } + + @After + public void tearDown() throws Exception { + this.nullInfo = null; + this.info = null; + this.urlInfo = null; + } + + @Test + public void testGetAccountId() { + assertNull(nullInfo.getAccountId()); + assertEquals("abc", info.getAccountId()); + assertEquals("abc", info.getAccountId()); + } + + @Test + public void testGetAccountToken() { + assertNull(nullInfo.getAuthToken()); + assertEquals("123", info.getAuthToken()); + assertEquals("123", info.getAuthToken()); + } + + @Test + public void testEquals() { + assertNotEquals(nullInfo, info); + assertNotEquals(nullInfo, null); + assertEquals(info, info); + assertEquals(new TwilioServiceInfo("twilio", "abc", "123"), info); + assertEquals(urlInfo, info); + } + + @Test + public void testToString() { + assertEquals("TwilioServiceInfo [accountId=abc, authToken=123, id=twilio]", info.toString()); + } +} + diff --git a/bluemix-cloud-connectors-local/pom.xml b/bluemix-cloud-connectors-local/pom.xml new file mode 100644 index 0000000..dc9a2f6 --- /dev/null +++ b/bluemix-cloud-connectors-local/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + net.bluemix + bluemix-cloud-connectors + 0.0.1-SNAPSHOT + + bluemix-cloud-connectors-local + + + + + + + org.springframework.cloud + spring-cloud-localconfig-connector + 1.1.0.RELEASE + + + net.bluemix + bluemix-cloud-connectors-core + 0.0.1-SNAPSHOT + + + \ No newline at end of file diff --git a/bluemix-cloud-connectors-local/src/main/java/net/bluemix/connectors/local/CouchDbLocalConfigServiceInfoCreator.java b/bluemix-cloud-connectors-local/src/main/java/net/bluemix/connectors/local/CouchDbLocalConfigServiceInfoCreator.java new file mode 100644 index 0000000..7fbbcba --- /dev/null +++ b/bluemix-cloud-connectors-local/src/main/java/net/bluemix/connectors/local/CouchDbLocalConfigServiceInfoCreator.java @@ -0,0 +1,53 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.local; + +import java.net.URISyntaxException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import net.bluemix.connectors.core.info.CloudantServiceInfo; + +import org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator; + +/** + * Local configuration for Cloudant/CouchDB. + * @author ryanjbaxter + * + */ +public class CouchDbLocalConfigServiceInfoCreator extends LocalConfigServiceInfoCreator { + + private static final Logger LOG = Logger.getLogger(CouchDbLocalConfigServiceInfoCreator.class.getName()); + + /** + * Constructor. + */ + public CouchDbLocalConfigServiceInfoCreator() { + super(CloudantServiceInfo.CLOUDANT_SCHEME); + } + + @Override + public CloudantServiceInfo createServiceInfo(String id, String uri) { + try { + return new CloudantServiceInfo(id, uri); + } catch (URISyntaxException e) { + LOG.logp(Level.WARNING, CouchDbLocalConfigServiceInfoCreator.class.getName(), + "createServiceInfo", "Invalid URI: " + uri, e); + return null; + } + } +} + diff --git a/bluemix-cloud-connectors-local/src/main/java/net/bluemix/connectors/local/SendGridLocalConfigServiceInfoCreator.java b/bluemix-cloud-connectors-local/src/main/java/net/bluemix/connectors/local/SendGridLocalConfigServiceInfoCreator.java new file mode 100644 index 0000000..318eb89 --- /dev/null +++ b/bluemix-cloud-connectors-local/src/main/java/net/bluemix/connectors/local/SendGridLocalConfigServiceInfoCreator.java @@ -0,0 +1,42 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.local; + +import org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator; +import org.springframework.cloud.service.common.SmtpServiceInfo; + +/** + * Creates an SmtpServiceInfo object when the cloud application is running locally. The URI + * must begin with smtp. + * @author ryanjbaxter + * + */ +public class SendGridLocalConfigServiceInfoCreator extends LocalConfigServiceInfoCreator { + + /** + * Constructor. + */ + public SendGridLocalConfigServiceInfoCreator() { + super(SmtpServiceInfo.URI_SCHEME); + } + + @Override + public SmtpServiceInfo createServiceInfo(String id, String uri) { + return new SmtpServiceInfo(id, uri); + } + +} + diff --git a/bluemix-cloud-connectors-local/src/main/java/net/bluemix/connectors/local/TwilioLocalConfigServiceInfoCreator.java b/bluemix-cloud-connectors-local/src/main/java/net/bluemix/connectors/local/TwilioLocalConfigServiceInfoCreator.java new file mode 100644 index 0000000..dd56be2 --- /dev/null +++ b/bluemix-cloud-connectors-local/src/main/java/net/bluemix/connectors/local/TwilioLocalConfigServiceInfoCreator.java @@ -0,0 +1,40 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.local; + +import net.bluemix.connectors.core.info.TwilioServiceInfo; + +import org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator; + +/** + * Local configuration for creating Twilio service info when running locally. + * @author ryanjbaxter + * + */ +public class TwilioLocalConfigServiceInfoCreator extends LocalConfigServiceInfoCreator { + + public TwilioLocalConfigServiceInfoCreator() { + //Fake scheme to identify the service, its only for local configuration anyways so not a big deal + super("twilio"); + } + + @Override + public TwilioServiceInfo createServiceInfo(String id, String uri) { + return new TwilioServiceInfo(id, uri.replace("twilio", "https")); + } + +} + diff --git a/bluemix-cloud-connectors-local/src/main/resources/META-INF/services/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator b/bluemix-cloud-connectors-local/src/main/resources/META-INF/services/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator new file mode 100644 index 0000000..93c9b31 --- /dev/null +++ b/bluemix-cloud-connectors-local/src/main/resources/META-INF/services/org.springframework.cloud.localconfig.LocalConfigServiceInfoCreator @@ -0,0 +1,3 @@ +net.bluemix.connectors.local.CouchDbLocalConfigServiceInfoCreator +net.bluemix.connectors.local.SendGridLocalConfigServiceInfoCreator +net.bluemix.connectors.local.TwilioLocalConfigServiceInfoCreator \ No newline at end of file diff --git a/bluemix-cloud-connectors-local/src/test/java/net/bluemix/connectors/local/CouchDbLocalConfigServiceInfoCreatorTest.java b/bluemix-cloud-connectors-local/src/test/java/net/bluemix/connectors/local/CouchDbLocalConfigServiceInfoCreatorTest.java new file mode 100644 index 0000000..c323e77 --- /dev/null +++ b/bluemix-cloud-connectors-local/src/test/java/net/bluemix/connectors/local/CouchDbLocalConfigServiceInfoCreatorTest.java @@ -0,0 +1,48 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.local; + +import static org.junit.Assert.assertEquals; +import net.bluemix.connectors.core.info.CloudantServiceInfo; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class CouchDbLocalConfigServiceInfoCreatorTest { + + private CouchDbLocalConfigServiceInfoCreator creator; + + @Before + public void setUp() throws Exception { + creator = new CouchDbLocalConfigServiceInfoCreator(); + } + + @After + public void tearDown() throws Exception { + creator = null; + } + + @Test + public void testCreateServiceInfoStringString() { + CloudantServiceInfo info = creator.createServiceInfo("cloudant", "couchdb://user:password@user.cloudant.com"); + assertEquals(new CloudantServiceInfo("cloudant", "user", "password", "user.cloudant.com", -1, "http://user:password@user.cloudant.com"), info); + info = creator.createServiceInfo("cloudant", "couchdb://localhost:5984"); + assertEquals(new CloudantServiceInfo("cloudant", null, null, "localhost", 5984, "http://localhost:5984"), info); + } + +} + diff --git a/bluemix-cloud-connectors-local/src/test/java/net/bluemix/connectors/local/SendGridLocalConfigServiceInfoCreatorTest.java b/bluemix-cloud-connectors-local/src/test/java/net/bluemix/connectors/local/SendGridLocalConfigServiceInfoCreatorTest.java new file mode 100644 index 0000000..890252a --- /dev/null +++ b/bluemix-cloud-connectors-local/src/test/java/net/bluemix/connectors/local/SendGridLocalConfigServiceInfoCreatorTest.java @@ -0,0 +1,55 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.local; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.cloud.service.common.SmtpServiceInfo; + +public class SendGridLocalConfigServiceInfoCreatorTest { + + private SendGridLocalConfigServiceInfoCreator creator; + + @Before + public void setUp() throws Exception { + this.creator = new SendGridLocalConfigServiceInfoCreator(); + } + + @After + public void tearDown() throws Exception { + this.creator = null; + } + + @Test + public void testCreateServiceInfo() { + SmtpServiceInfo info = creator.createServiceInfo("sendgrid", "smtp://user:password@mymail.com"); + assertEquals("mymail.com", info.getHost()); + assertEquals("sendgrid", info.getId()); + assertEquals("password", info.getPassword()); + assertEquals("user", info.getUserName()); + assertEquals(-1, info.getPort()); + assertNull(info.getPath()); + assertNull(info.getQuery()); + assertEquals("smtp", info.getScheme()); + assertEquals("smtp://user:password@mymail.com", info.getUri()); + } + +} + diff --git a/bluemix-cloud-connectors-local/src/test/java/net/bluemix/connectors/local/TwilioLocalConfigServiceInfoCreatorTest.java b/bluemix-cloud-connectors-local/src/test/java/net/bluemix/connectors/local/TwilioLocalConfigServiceInfoCreatorTest.java new file mode 100644 index 0000000..3e04da0 --- /dev/null +++ b/bluemix-cloud-connectors-local/src/test/java/net/bluemix/connectors/local/TwilioLocalConfigServiceInfoCreatorTest.java @@ -0,0 +1,46 @@ +/* + * Copyright IBM Corp. 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.local; + +import static org.junit.Assert.assertEquals; +import net.bluemix.connectors.core.info.TwilioServiceInfo; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class TwilioLocalConfigServiceInfoCreatorTest { + + private TwilioLocalConfigServiceInfoCreator creator; + + @Before + public void setUp() throws Exception { + this.creator = new TwilioLocalConfigServiceInfoCreator(); + } + + @After + public void tearDown() throws Exception { + this.creator = null; + } + + @Test + public void testCreateServiceInfoStringString() { + TwilioServiceInfo info = creator.createServiceInfo("twilio", "twilio://abc:123@api.twilio.com"); + assertEquals(new TwilioServiceInfo("twilio", "http://abc:123@api.twilio.com"), info); + } + +} + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4fae71c --- /dev/null +++ b/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + net.bluemix + bluemix-cloud-connectors + 0.0.1-SNAPSHOT + pom + + bluemix-cloud-connectors-core + bluemix-cloud-connectors-local + bluemix-cloud-connectors-cloudfoundry + + + + + + + + org.springframework.cloud + spring-cloud-core + 1.1.0.RELEASE + + + org.ektorp + org.ektorp + 1.3.0 + + + com.twilio.sdk + twilio-java-sdk + 3.4.1 + + + junit + junit + 4.11 + test + + + + https://github.com/IBM-Bluemix/bluemix-cloud-connectors + + \ No newline at end of file diff --git a/samples/cloudant-liberty/README.MD b/samples/cloudant-liberty/README.MD new file mode 100644 index 0000000..dcedc51 --- /dev/null +++ b/samples/cloudant-liberty/README.MD @@ -0,0 +1,49 @@ +# Liberty Cloudant Connector Sample + +## About +This is a sample demonstrating how to use the Cloudant connector in a Java EE application running on IBM's Websphere Liberty Profile. +The sample application stores status messages in a Cloudant DB. + +## Prereqs +In order to run or deploy this sample application you need to agree to the Liberty Profile +license agreement. You can do this by reading the [License](http://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/downloads/wlp/beta/lafiles/en.html) and creating an environment variable named `LIBERTY_LICENSE` with the D/N value in the license agreement. You will need to complete this step before running the Maven commands to run the application locally or deploying the application to Bluemix. + +## Running Locally +You can run this application locally by either pointing to Cloudant in the cloud or running CouchDB locally. + +Create a file called `spring-cloud.properties` in the directory `${user.home}/.config/cloudant-connector-sample`. + +In the `spring-cloud.properties` file add the following properties + +``` +spring.cloud.appId: cloudant-sample +spring.cloud.connectors-sample: couchdb://user:password50@localhost:5984 +``` + +You can change the `spring.cloud.connectors-sample` property to point to your own Cloudant account or local Couch DB server. +Normally CouchDB/Cloudant URLs use the HTTP protocol, however the Bluemix Cloud Connectors project uses the protocal (in this case couchdb) to identify the connector to use for the service. Essentially you +can take your CouchDB/Cloudant URL and replace the http protooal with couchdb and set that as the value +of `spring.cloud.connectors-sample`. + +## Running With Maven + +After you have created your `spring-cloud.properties` file run `$ mvn -P run`. This will download a Liberty Profile deploy the application and start the server. Once the server is started navigate to [http://localhost:9080](http://localhost:9080). + +## Running In Eclipse +You can also run the sample in Eclipse. You will need to install the [Websphere Developer Tools for Eclipse](https://developer.ibm.com/wasdev/downloads/liberty-profile-using-eclipse/) first. Once they are installed and you setup you Liberty server in Eclipse (see step 3 in the previous link) you will need to add the application to the server in Eclipse. In addition you will need to add the following features to your server.xml. + +``` + jaxrs-1.1 + localConnector-1.0 + cdi-1.0 + servlet-3.1 +``` + +## Deploying To Bluemix +Run the following Maven profile + +``` +$ mvn -P deploy -Dcf.username=myusername -Dcf.password=mypassword -Dorg=bluemixOrg -Dspace=bluemixSpace +``` + +Replace the properties with your Bluemix username and password as well as your organization name and space. \ No newline at end of file diff --git a/samples/cloudant-liberty/pom.xml b/samples/cloudant-liberty/pom.xml new file mode 100644 index 0000000..cf29b77 --- /dev/null +++ b/samples/cloudant-liberty/pom.xml @@ -0,0 +1,253 @@ + + + 4.0.0 + net.bluemix.connectors.cloudant + cloudant-connector-liberty-sample + 0.0.1-SNAPSHOT + war + + + + + + + + sonatype-nexus-snapshots + Sonatype Nexus Snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + true + + + false + + + + + + + + + + Liberty + Liberty Repository + http://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/maven/repository/ + + + + + + + + package + + + + net.wasdev.wlp.maven.plugins + liberty-maven-plugin + 1.1-SNAPSHOT + + + + + + + + + + + com.ibm.tools.target + was-liberty + LATEST + pom + provided + + + net.bluemix + bluemix-cloud-connectors-local + 0.0.1-SNAPSHOT + + + net.bluemix + bluemix-cloud-connectors-cloudfoundry + 0.0.1-SNAPSHOT + + + org.springframework.cloud + spring-cloud-cloudfoundry-connector + 1.1.0.RELEASE + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + 2.4.0 + + + + + + + + + run + + + + net.wasdev.wlp.maven.plugins + liberty-maven-plugin + + + package + + create-server + + + + start-server + package + + run-server + + + 60 + src/main/wlp/localserver.xml + + + + + + ${env.LIBERTY_LICENSE} + 2015.+ + + src/main/wlp/localserver.xml + + 9080 + ../../../../../${project.build.finalName} + + defaultServer + + + + + + + deploy + + + + net.wasdev.wlp.maven.plugins + liberty-maven-plugin + + + create-server + package + + create-server + + + + start-server + package + + start-server + + + 60 + src/main/wlp/server.xml + + + + deploy-app + package + + deploy + + + ${project.build.directory}/${project.build.finalName}.war + + + + stop-server + package + + stop-server + + + 60 + + + + package + + package-server + + + ${project.build.directory}/cloudant-connector-sample.zip + + + + + + ${env.LIBERTY_LICENSE} + 2015.+ + + src/main/wlp/server.xml + + 9080 + + cloudant-connector-sample + usr + + + + org.cloudfoundry + cf-maven-plugin + 1.1.0 + + Bluemix + https://api.ng.bluemix.net + ${org} + ${space} + cloudant-connector-liberty + cloudant-connector-liberty-${randomWord}.mybluemix.net + ${project.build.directory}/cloudant-connector-sample.zip + 512 + + + connectors-sample + Shared + + + + + cloudantNoSQLDB=all + + + + + package + + push + + + + + + + + + \ No newline at end of file diff --git a/samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/CloudantBean.java b/samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/CloudantBean.java new file mode 100644 index 0000000..da6c300 --- /dev/null +++ b/samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/CloudantBean.java @@ -0,0 +1,38 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudant.liberty; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; + +import org.ektorp.CouchDbInstance; +import org.ektorp.impl.StdCouchDbConnector; +import org.springframework.cloud.Cloud; +import org.springframework.cloud.CloudFactory; + +@ApplicationScoped +public class CloudantBean { + + private static Cloud cloud = new CloudFactory().getCloud(); + + @Produces + public StatusRepository statusRepository() { + CouchDbInstance db = cloud.getServiceConnector("connectors-sample", CouchDbInstance.class, null /* default config */); + return new StatusRepository(new StdCouchDbConnector("status", db)); + } + +} + diff --git a/samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/Status.java b/samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/Status.java new file mode 100644 index 0000000..6420947 --- /dev/null +++ b/samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/Status.java @@ -0,0 +1,47 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudant.liberty; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.map.annotate.JsonSerialize; + + +@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties({"id", "revision"}) +public class Status { + @JsonProperty("_id") + private String id; + @JsonProperty("_rev") + private String revision; + private String msg; + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getMsg() { + return msg; + } + public void setMsg(String msg) { + this.msg = msg; + } + public String getRevision() { + return revision; + } +} + diff --git a/samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/StatusController.java b/samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/StatusController.java new file mode 100644 index 0000000..bdd9020 --- /dev/null +++ b/samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/StatusController.java @@ -0,0 +1,71 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudant.liberty; + +import java.util.List; + +import javax.inject.Inject; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +@Path("/status") +public class StatusController { + + @Inject + private StatusRepository repo; + + + @GET + @Produces(MediaType.APPLICATION_JSON) + public List getAll() { + return repo.getAll(); + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Status create(Status status) { + repo.add(status); + return status; + } + + @DELETE + @Path("{id}") + public void delete(@PathParam("id") String id) { + Status status = repo.get(id); + repo.remove(status); + } + + @PUT + @Path("{id}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Status udpate(@PathParam("id") String id, Status status) { + Status update = repo.get(id); + update.setMsg(status.getMsg());; + repo.update(update); + return update; + } + +} + diff --git a/samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/StatusRepository.java b/samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/StatusRepository.java new file mode 100644 index 0000000..b3b2346 --- /dev/null +++ b/samples/cloudant-liberty/src/main/java/net/bluemix/connectors/cloudant/liberty/StatusRepository.java @@ -0,0 +1,29 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudant.liberty; + +import org.ektorp.CouchDbConnector; +import org.ektorp.support.CouchDbRepositorySupport; + +public class StatusRepository extends CouchDbRepositorySupport { + + public StatusRepository(CouchDbConnector connector) { + super(Status.class, connector); + initStandardDesignDocument(); + } + +} + diff --git a/samples/cloudant-liberty/src/main/resources/spring-cloud-bootstrap.properties b/samples/cloudant-liberty/src/main/resources/spring-cloud-bootstrap.properties new file mode 100644 index 0000000..1685ef2 --- /dev/null +++ b/samples/cloudant-liberty/src/main/resources/spring-cloud-bootstrap.properties @@ -0,0 +1,15 @@ +# Copyright IBM Corp. 2014 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +spring.cloud.propertiesFile: ${user.home}/.config/cloudant-connector-sample/spring-cloud.properties \ No newline at end of file diff --git a/samples/cloudant-liberty/src/main/webapp/WEB-INF/beans.xml b/samples/cloudant-liberty/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000..79d67ed --- /dev/null +++ b/samples/cloudant-liberty/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/samples/cloudant-liberty/src/main/webapp/WEB-INF/ibm-web-ext.xml b/samples/cloudant-liberty/src/main/webapp/WEB-INF/ibm-web-ext.xml new file mode 100644 index 0000000..9ddf5a1 --- /dev/null +++ b/samples/cloudant-liberty/src/main/webapp/WEB-INF/ibm-web-ext.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/samples/cloudant-liberty/src/main/webapp/WEB-INF/web.xml b/samples/cloudant-liberty/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..d45158d --- /dev/null +++ b/samples/cloudant-liberty/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,50 @@ + + + + + DeveloperWeek Node-RED Workshop + + javax.ws.rs.core.Application + 1 + + + javax.ws.rs.core.Application + /api/* + + + + Demo + + api + / + /* + /devweek-nodered-workshop-0.0.1-SNAPSHOT/* + GET + PUT + HEAD + TRACE + POST + DELETE + OPTIONS + + + admin + + + \ No newline at end of file diff --git a/samples/cloudant-liberty/src/main/webapp/css/jumbotron-narrow.css b/samples/cloudant-liberty/src/main/webapp/css/jumbotron-narrow.css new file mode 100644 index 0000000..f0971e2 --- /dev/null +++ b/samples/cloudant-liberty/src/main/webapp/css/jumbotron-narrow.css @@ -0,0 +1,94 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* Space out content a bit */ +body { + padding-top: 20px; + padding-bottom: 20px; +} + +/* Everything but the jumbotron gets side spacing for mobile first views */ +.header, +.marketing, +.footer { + padding-right: 15px; + padding-left: 15px; +} + +/* Custom page header */ +.header { + border-bottom: 1px solid #e5e5e5; +} +/* Make the masthead heading the same height as the navigation */ +.header h3 { + padding-bottom: 19px; + margin-top: 0; + margin-bottom: 0; + line-height: 40px; +} + +/* Custom page footer */ +.footer { + padding-top: 19px; + color: #777; + border-top: 1px solid #e5e5e5; +} + +/* Customize container */ +@media (min-width: 768px) { + .container { + max-width: 730px; + } +} +.container-narrow > hr { + margin: 30px 0; +} + +/* Main marketing message and sign up button */ +.jumbotron { + text-align: center; + border-bottom: 1px solid #e5e5e5; +} +.jumbotron .btn { + padding: 14px 24px; + font-size: 21px; +} + +/* Supporting marketing content */ +.marketing { + margin: 40px 0; +} +.marketing p + h4 { + margin-top: 28px; +} + +/* Responsive: Portrait tablets and up */ +@media screen and (min-width: 768px) { + /* Remove the padding we set earlier */ + .header, + .marketing, + .footer { + padding-right: 0; + padding-left: 0; + } + /* Space out the masthead */ + .header { + margin-bottom: 30px; + } + /* Remove the bottom border on the jumbotron for visual effect */ + .jumbotron { + border-bottom: 0; + } +} diff --git a/samples/cloudant-liberty/src/main/webapp/index.html b/samples/cloudant-liberty/src/main/webapp/index.html new file mode 100644 index 0000000..73d34c8 --- /dev/null +++ b/samples/cloudant-liberty/src/main/webapp/index.html @@ -0,0 +1,79 @@ + + + + + + + + + + + + + Cloudant Connector + + + + + + + + + + + + + +
+
+ +

Cloudant Connector

+
+ +
+

Sample

+

Sample demonstrating how to use the Cloudant connector.

+
+ +
+ + + +
+ + + + + + + + + + + + diff --git a/samples/cloudant-liberty/src/main/webapp/js/app.js b/samples/cloudant-liberty/src/main/webapp/js/app.js new file mode 100644 index 0000000..684f665 --- /dev/null +++ b/samples/cloudant-liberty/src/main/webapp/js/app.js @@ -0,0 +1,16 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +angular.module('cloudantApp', ['ngRoute', 'cloudantApp.status']); \ No newline at end of file diff --git a/samples/cloudant-liberty/src/main/webapp/js/service.js b/samples/cloudant-liberty/src/main/webapp/js/service.js new file mode 100644 index 0000000..54de353 --- /dev/null +++ b/samples/cloudant-liberty/src/main/webapp/js/service.js @@ -0,0 +1,20 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var services = angular.module('cloudantApp.services', ['ngResource']); + +services.factory('StatusService', function($resource) { + return $resource('api/status/:id', {id : "@id"}); +}); \ No newline at end of file diff --git a/samples/cloudant-liberty/src/main/webapp/js/status/status.html b/samples/cloudant-liberty/src/main/webapp/js/status/status.html new file mode 100644 index 0000000..e017e36 --- /dev/null +++ b/samples/cloudant-liberty/src/main/webapp/js/status/status.html @@ -0,0 +1,16 @@ +
+ + + + +
+
+
+

There are currently no questions, the page will update automatically as new questions come in.

+
+ + + + +
{{status.msg}} +
\ No newline at end of file diff --git a/samples/cloudant-liberty/src/main/webapp/js/status/status.js b/samples/cloudant-liberty/src/main/webapp/js/status/status.js new file mode 100644 index 0000000..c3fda64 --- /dev/null +++ b/samples/cloudant-liberty/src/main/webapp/js/status/status.js @@ -0,0 +1,42 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +angular.module('cloudantApp.status', ['cloudantApp.services']) +.config(['$routeProvider', function ($routeProvider) { + $routeProvider.otherwise({ + templateUrl: 'js/status/status.html', + controller: 'StatusController' + }); +}]) +.controller('StatusController', ['$scope', 'StatusService', function($scope, StatusService) { + $scope.status = {}; + $scope.statuses = StatusService.query(); + $scope.submit = function() { + StatusService.save($scope.status).$promise.then(function(savedStatus) { + $scope.statuses.push(savedStatus); + $scope.status.msg = ''; + }, function(err) { + console.error(err); + }); + }; + + $scope.delete = function(status, index) { + StatusService.delete({id:status.id}).$promise.then(function() { + $scope.statuses.splice(index, 1); + }, function(err) { + console.error(err); + }) + }; +}]); \ No newline at end of file diff --git a/samples/cloudant-liberty/src/main/wlp/localserver.xml b/samples/cloudant-liberty/src/main/wlp/localserver.xml new file mode 100644 index 0000000..ab1dbab --- /dev/null +++ b/samples/cloudant-liberty/src/main/wlp/localserver.xml @@ -0,0 +1,29 @@ + + + + jaxrs-1.1 + localConnector-1.0 + cdi-1.0 + servlet-3.1 + + + + + + \ No newline at end of file diff --git a/samples/cloudant-liberty/src/main/wlp/server.xml b/samples/cloudant-liberty/src/main/wlp/server.xml new file mode 100644 index 0000000..8eb7dd4 --- /dev/null +++ b/samples/cloudant-liberty/src/main/wlp/server.xml @@ -0,0 +1,26 @@ + + + + jaxrs-1.1 + localConnector-1.0 + cdi-1.0 + servlet-3.1 + + + + + \ No newline at end of file diff --git a/samples/cloudant-spring/README.md b/samples/cloudant-spring/README.md new file mode 100644 index 0000000..74b7131 --- /dev/null +++ b/samples/cloudant-spring/README.md @@ -0,0 +1,39 @@ +# Spring Cloudant Connector Sample + +## About +This is a sample demonstrating how to use the Cloudant connector in a Spring Boot application. +The sample application stores status messages in a Cloudant DB. + +## Running Locally +You can run this application locally by either pointing to Cloudant in the cloud or running CouchDB locally. + +Create a file called `spring-cloud.properties` in the directory `${user.home}/.config/cloudant-connector-sample`. + +In the `spring-cloud.properties` file add the following properties + +``` +spring.cloud.appId: cloudant-sample +spring.cloud.connectors-sample: couchdb://user:password50@localhost:5984 +``` + +You can change the `spring.cloud.connectors-sample` property to point to your own Cloudant account or local Couch DB server. +Normally CouchDB/Cloudant URLs use the HTTP protocol, however the Bluemix Cloud Connectors project uses the protocal (in this case couchdb) to identify the connector to use for the service. Essentially you +can take your CouchDB/Cloudant URL and replace the http protooal with couchdb and set that as the value +of `spring.cloud.connectors-sample`. + +## Running With Maven +After you have created your `spring-cloud.properties` file run `$ mvn -P run`. +Once the server is started navigate to [http://localhost:8080](http://localhost:8080). + +## Running In Eclipse +Right click on `App.java` and select Run As -> Java Application. +Once the server is started navigate to [http://localhost:8080](http://localhost:8080). + + +## Deploying To Bluemix +Run the following Maven profile +``` +mvn -P deploy -Dusername=bluemixUsername -Dpassword=bluemixPassword -Dorg=bluemixOrg -Dspace=bluemixSpace +``` + +Replace the properties with your Bluemix username and password as well as your organization name and space. \ No newline at end of file diff --git a/samples/cloudant-spring/pom.xml b/samples/cloudant-spring/pom.xml new file mode 100644 index 0000000..66f5b78 --- /dev/null +++ b/samples/cloudant-spring/pom.xml @@ -0,0 +1,192 @@ + + + 4.0.0 + net.bluemix.connectors.cloudant + cloudant-connector-spring-sample + 0.0.1-SNAPSHOT + + ${packaging.type} + + + + + + + org.springframework.boot + spring-boot-starter-parent + 1.1.8.RELEASE + + + + + + + UTF-8 + net.bluemix.connectors.cloudant.App + 1.7 + jar + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-cloudfoundry-connector + 1.1.0.RELEASE + + + net.bluemix + bluemix-cloud-connectors-local + 0.0.1-SNAPSHOT + + + net.bluemix + bluemix-cloud-connectors-cloudfoundry + 0.0.1-SNAPSHOT + + + org.springframework.cloud + spring-cloud-spring-service-connector + 1.1.0.RELEASE + + + + + + + + + deploy + + war + + + + + org.springframework.boot + spring-boot-starter-tomcat + provided + + + + + + org.cloudfoundry + cf-maven-plugin + 1.0.5 + + https://api.ng.bluemix.net + ${username} + ${password} + cloudant-connector-sample + ${org} + ${space} + 1 + 512 + cloudant-connector-sample-${randomWord}.mybluemix.net + + + status-db + Shared + + + + + + cloud + + + + + package + + push + + + + + + maven-clean-plugin + 2.5 + + + auto-clean + initialize + + clean + + + + + + + + + run + + + + org.springframework.boot + spring-boot-maven-plugin + + + package + + run + + + + + + maven-clean-plugin + 2.5 + + + auto-clean + initialize + + clean + + + + + + + + + + + + + + + package + + + org.springframework.boot + spring-boot-maven-plugin + + + + \ No newline at end of file diff --git a/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/App.java b/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/App.java new file mode 100644 index 0000000..465468b --- /dev/null +++ b/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/App.java @@ -0,0 +1,55 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudant; + +import org.ektorp.CouchDbConnector; +import org.ektorp.CouchDbInstance; +import org.ektorp.impl.StdCouchDbConnector; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; +import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; +import org.springframework.boot.context.embedded.MimeMappings; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan +@EnableAutoConfiguration +public class App implements EmbeddedServletContainerCustomizer { + + public static void main(String[] args) throws Exception { + SpringApplication.run(App.class, args); + } + + @Override + public void customize(ConfigurableEmbeddedServletContainer container) { + //Enabled UTF-8 as the default character encoding for static HTML resources. + //If you would like to disable this comment out the 3 lines below or change + //the encoding to whatever you would like. + MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT); + mappings.add("html", "text/html;charset=utf-8"); + container.setMimeMappings(mappings ); + } + + @Bean + public CouchDbConnector couchDbConnector(CouchDbInstance couchDbInstance) { + CouchDbConnector connector = new StdCouchDbConnector("status", couchDbInstance); + connector.createDatabaseIfNotExists(); + return connector; + } +} \ No newline at end of file diff --git a/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/Status.java b/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/Status.java new file mode 100644 index 0000000..c44a320 --- /dev/null +++ b/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/Status.java @@ -0,0 +1,46 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudant; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.annotate.JsonWriteNullProperties; + +@JsonWriteNullProperties(false) +@JsonIgnoreProperties({"id", "revision"}) +public class Status { + @JsonProperty("_id") + private String id; + @JsonProperty("_rev") + private String revision; + private String msg; + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getMsg() { + return msg; + } + public void setMsg(String msg) { + this.msg = msg; + } + public String getRevision() { + return revision; + } +} + diff --git a/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/StatusRepository.java b/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/StatusRepository.java new file mode 100644 index 0000000..35236a6 --- /dev/null +++ b/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/StatusRepository.java @@ -0,0 +1,33 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudant; + +import org.ektorp.CouchDbConnector; +import org.ektorp.support.CouchDbRepositorySupport; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class StatusRepository extends CouchDbRepositorySupport { + + @Autowired + public StatusRepository(CouchDbConnector connector) { + super(Status.class, connector); + initStandardDesignDocument(); + } + +} + diff --git a/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/StatusRestController.java b/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/StatusRestController.java new file mode 100644 index 0000000..3f891c7 --- /dev/null +++ b/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/StatusRestController.java @@ -0,0 +1,58 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudant; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/status") +public class StatusRestController { + + @Autowired + private StatusRepository repo; + + @RequestMapping(method=RequestMethod.GET) + public List getAll() { + return repo.getAll(); + } + + @RequestMapping(method=RequestMethod.POST) + public Status create(@RequestBody Status status) { + repo.add(status); + return status; + } + + @RequestMapping(method=RequestMethod.DELETE, value="{id}") + public void delete(@PathVariable String id) { + repo.remove(repo.get(id)); + } + + @RequestMapping(method=RequestMethod.PUT, value="{id}") + public Status update(@RequestBody Status status, @PathVariable String id) { + Status update = repo.get(id); + update.setMsg(status.getMsg()); + repo.update(update); + return update; + } +} + diff --git a/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/config/Config.java b/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/config/Config.java new file mode 100644 index 0000000..50c28ae --- /dev/null +++ b/samples/cloudant-spring/src/main/java/net/bluemix/connectors/cloudant/config/Config.java @@ -0,0 +1,45 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.bluemix.connectors.cloudant.config; + +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import org.ektorp.CouchDbInstance; +import org.springframework.cloud.config.java.AbstractCloudConfig; +import org.springframework.cloud.config.java.ServiceScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +public class Config { + + @Configuration + //@Profile("cloud") + @ServiceScan + static class CloudConfiguration extends AbstractCloudConfig { + // If you don't want to rely on @ServiceScan finding bound services and creating + // the right beans you can uncomment the methods below. + + @Bean + public CouchDbInstance couchDbInstance() throws NamingException { + CouchDbInstance instance = connectionFactory().service(CouchDbInstance.class); + return instance; +// return (CouchDbInstance) new InitialContext().lookup("java:comp/env/couchdb/status-db"); + } + + } +} \ No newline at end of file diff --git a/samples/cloudant-spring/src/main/resources/application.properties b/samples/cloudant-spring/src/main/resources/application.properties new file mode 100644 index 0000000..231c3f7 --- /dev/null +++ b/samples/cloudant-spring/src/main/resources/application.properties @@ -0,0 +1 @@ +# Add Spring configuration properties to this file diff --git a/samples/cloudant-spring/src/main/resources/spring-cloud-bootstrap.properties b/samples/cloudant-spring/src/main/resources/spring-cloud-bootstrap.properties new file mode 100644 index 0000000..8cba53c --- /dev/null +++ b/samples/cloudant-spring/src/main/resources/spring-cloud-bootstrap.properties @@ -0,0 +1 @@ +spring.cloud.propertiesFile: ${user.home}/.config/cloudant-connector-sample/spring-cloud.properties \ No newline at end of file diff --git a/samples/cloudant-spring/src/main/resources/static/css/jumbotron-narrow.css b/samples/cloudant-spring/src/main/resources/static/css/jumbotron-narrow.css new file mode 100644 index 0000000..f0971e2 --- /dev/null +++ b/samples/cloudant-spring/src/main/resources/static/css/jumbotron-narrow.css @@ -0,0 +1,94 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* Space out content a bit */ +body { + padding-top: 20px; + padding-bottom: 20px; +} + +/* Everything but the jumbotron gets side spacing for mobile first views */ +.header, +.marketing, +.footer { + padding-right: 15px; + padding-left: 15px; +} + +/* Custom page header */ +.header { + border-bottom: 1px solid #e5e5e5; +} +/* Make the masthead heading the same height as the navigation */ +.header h3 { + padding-bottom: 19px; + margin-top: 0; + margin-bottom: 0; + line-height: 40px; +} + +/* Custom page footer */ +.footer { + padding-top: 19px; + color: #777; + border-top: 1px solid #e5e5e5; +} + +/* Customize container */ +@media (min-width: 768px) { + .container { + max-width: 730px; + } +} +.container-narrow > hr { + margin: 30px 0; +} + +/* Main marketing message and sign up button */ +.jumbotron { + text-align: center; + border-bottom: 1px solid #e5e5e5; +} +.jumbotron .btn { + padding: 14px 24px; + font-size: 21px; +} + +/* Supporting marketing content */ +.marketing { + margin: 40px 0; +} +.marketing p + h4 { + margin-top: 28px; +} + +/* Responsive: Portrait tablets and up */ +@media screen and (min-width: 768px) { + /* Remove the padding we set earlier */ + .header, + .marketing, + .footer { + padding-right: 0; + padding-left: 0; + } + /* Space out the masthead */ + .header { + margin-bottom: 30px; + } + /* Remove the bottom border on the jumbotron for visual effect */ + .jumbotron { + border-bottom: 0; + } +} diff --git a/samples/cloudant-spring/src/main/resources/static/index.html b/samples/cloudant-spring/src/main/resources/static/index.html new file mode 100644 index 0000000..73d34c8 --- /dev/null +++ b/samples/cloudant-spring/src/main/resources/static/index.html @@ -0,0 +1,79 @@ + + + + + + + + + + + + + Cloudant Connector + + + + + + + + + + + + + +
+
+ +

Cloudant Connector

+
+ +
+

Sample

+

Sample demonstrating how to use the Cloudant connector.

+
+ +
+ + + +
+ + + + + + + + + + + + diff --git a/samples/cloudant-spring/src/main/resources/static/js/app.js b/samples/cloudant-spring/src/main/resources/static/js/app.js new file mode 100644 index 0000000..684f665 --- /dev/null +++ b/samples/cloudant-spring/src/main/resources/static/js/app.js @@ -0,0 +1,16 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +angular.module('cloudantApp', ['ngRoute', 'cloudantApp.status']); \ No newline at end of file diff --git a/samples/cloudant-spring/src/main/resources/static/js/service.js b/samples/cloudant-spring/src/main/resources/static/js/service.js new file mode 100644 index 0000000..c44d453 --- /dev/null +++ b/samples/cloudant-spring/src/main/resources/static/js/service.js @@ -0,0 +1,20 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var services = angular.module('cloudantApp.services', ['ngResource']); + +services.factory('StatusService', function($resource) { + return $resource('/api/status/:id', {id : "@id"}); +}); \ No newline at end of file diff --git a/samples/cloudant-spring/src/main/resources/static/js/status/status.html b/samples/cloudant-spring/src/main/resources/static/js/status/status.html new file mode 100644 index 0000000..e017e36 --- /dev/null +++ b/samples/cloudant-spring/src/main/resources/static/js/status/status.html @@ -0,0 +1,16 @@ +
+ + + + +
+
+
+

There are currently no questions, the page will update automatically as new questions come in.

+
+ + + + +
{{status.msg}} +
\ No newline at end of file diff --git a/samples/cloudant-spring/src/main/resources/static/js/status/status.js b/samples/cloudant-spring/src/main/resources/static/js/status/status.js new file mode 100644 index 0000000..c3fda64 --- /dev/null +++ b/samples/cloudant-spring/src/main/resources/static/js/status/status.js @@ -0,0 +1,42 @@ +/* + * Copyright IBM Corp. 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +angular.module('cloudantApp.status', ['cloudantApp.services']) +.config(['$routeProvider', function ($routeProvider) { + $routeProvider.otherwise({ + templateUrl: 'js/status/status.html', + controller: 'StatusController' + }); +}]) +.controller('StatusController', ['$scope', 'StatusService', function($scope, StatusService) { + $scope.status = {}; + $scope.statuses = StatusService.query(); + $scope.submit = function() { + StatusService.save($scope.status).$promise.then(function(savedStatus) { + $scope.statuses.push(savedStatus); + $scope.status.msg = ''; + }, function(err) { + console.error(err); + }); + }; + + $scope.delete = function(status, index) { + StatusService.delete({id:status.id}).$promise.then(function() { + $scope.statuses.splice(index, 1); + }, function(err) { + console.error(err); + }) + }; +}]); \ No newline at end of file diff --git a/samples/cloudant/.gitignore b/samples/cloudant/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/samples/cloudant/.gitignore @@ -0,0 +1 @@ +/bin/