├── .gitignore ├── Dockerfile ├── couchbase ├── Dockerfile └── configure-node.sh ├── docker-compose.yml ├── pom.xml ├── readme.adoc └── src └── main ├── docker ├── assembly.xml └── images │ └── payara │ └── docker-compose.yml ├── java └── org │ └── couchbase │ └── sample │ └── javaee │ ├── AirlineBean.java │ ├── AirlineResource.java │ ├── Database.java │ └── MyApplication.java └── webapp └── index.jsp /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | .settings/ 4 | nbactions.xml 5 | nb-configuration.xml 6 | /target/ 7 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jboss/wildfly:latest 2 | 3 | COPY target/airlines.war /opt/jboss/wildfly/standalone/deployments/airlines.war 4 | -------------------------------------------------------------------------------- /couchbase/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM couchbase:latest 2 | 3 | COPY configure-node.sh /opt/couchbase 4 | 5 | #HEALTHCHECK --interval=5s --timeout=3s CMD curl --fail http://localhost:8091/pools || exit 1 6 | 7 | CMD ["/opt/couchbase/configure-node.sh"] 8 | 9 | -------------------------------------------------------------------------------- /couchbase/configure-node.sh: -------------------------------------------------------------------------------- 1 | set -x 2 | set -m 3 | 4 | /entrypoint.sh couchbase-server & 5 | 6 | sleep 15 7 | 8 | # Setup index and memory quota 9 | curl -v -X POST http://127.0.0.1:8091/pools/default -d memoryQuota=300 -d indexMemoryQuota=300 10 | 11 | # Setup services 12 | curl -v http://127.0.0.1:8091/node/controller/setupServices -d services=kv%2Cn1ql%2Cindex 13 | 14 | # Setup credentials 15 | curl -v http://127.0.0.1:8091/settings/web -d port=8091 -d username=Administrator -d password=password 16 | 17 | # Setup Memory Optimized Indexes 18 | curl -i -u Administrator:password -X POST http://127.0.0.1:8091/settings/indexes -d 'storageMode=memory_optimized' 19 | 20 | # Load travel-sample bucket 21 | curl -v -u Administrator:password -X POST http://127.0.0.1:8091/sampleBuckets/install -d '["travel-sample"]' 22 | 23 | echo "Type: $TYPE" 24 | 25 | if [ "$TYPE" = "WORKER" ]; then 26 | echo "Sleeping ..." 27 | sleep 15 28 | 29 | #IP=`hostname -s` 30 | IP=`hostname -I | cut -d ' ' -f1` 31 | echo "IP: " $IP 32 | 33 | echo "Auto Rebalance: $AUTO_REBALANCE" 34 | if [ "$AUTO_REBALANCE" = "true" ]; then 35 | couchbase-cli rebalance --cluster=$COUCHBASE_MASTER:8091 --user=Administrator --password=password --server-add=$IP --server-add-username=Administrator --server-add-password=password 36 | else 37 | couchbase-cli server-add --cluster=$COUCHBASE_MASTER:8091 --user=Administrator --password=password --server-add=$IP --server-add-username=Administrator --server-add-password=password 38 | fi; 39 | fi; 40 | 41 | fg 1 42 | 43 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | web: 4 | image: arungupta/couchbase-javaee:travel 5 | environment: 6 | - COUCHBASE_URI=db 7 | ports: 8 | - 8080:8080 9 | - 9990:9990 10 | depends_on: 11 | - db 12 | db: 13 | image: arungupta/couchbase:travel 14 | ports: 15 | - 8091:8091 16 | - 8092:8092 17 | - 8093:8093 18 | - 11210:11210 19 | 20 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | org.couchbase.sample 6 | couchbase-javaee 7 | 1.0-SNAPSHOT 8 | war 9 | 10 | airlines 11 | 12 | 13 | ${project.build.directory}/endorsed 14 | UTF-8 15 | 8091 16 | 4848 17 | admin 18 | glassfish 19 | localhost 20 | 21 | 22 | 23 | 24 | javax 25 | javaee-web-api 26 | 7.0 27 | provided 28 | 29 | 30 | com.couchbase.client 31 | java-client 32 | 2.4.0 33 | 34 | 35 | 36 | 37 | ${project.name} 38 | 39 | 40 | org.apache.maven.plugins 41 | maven-compiler-plugin 42 | 3.6.0 43 | 44 | 1.8 45 | 1.8 46 | 47 | 48 | 49 | org.apache.maven.plugins 50 | maven-war-plugin 51 | 3.0.0 52 | 53 | false 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | docker 62 | 63 | 64 | 65 | org.jolokia 66 | docker-maven-plugin 67 | 0.13.9 68 | 69 | 70 | 71 | ${project.artifactId} 72 | arungupta/${project.artifactId}:travel 73 | 74 | jboss/wildfly 75 | 76 | assembly.xml 77 | /opt/jboss/wildfly/standalone/deployments/ 78 | jboss:jboss:jboss 79 | 80 | 81 | 8080 82 | 83 | 84 | 85 | 86 | 87 | 8080:8080 88 | 89 | 90 | WF 91 | none 92 | cyan 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | docker:build 101 | package 102 | 103 | build 104 | 105 | 106 | 107 | docker:start 108 | install 109 | 110 | push 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | wildfly 120 | 121 | 122 | 123 | org.wildfly.plugins 124 | wildfly-maven-plugin 125 | 1.1.0.Alpha11 126 | 127 | 128 | install 129 | 130 | deploy 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | liberty 140 | 141 | 142 | 143 | net.wasdev.wlp.maven.plugins 144 | liberty-maven-plugin 145 | 1.1 146 | 147 | 148 | install 149 | 150 | deploy 151 | 152 | 153 | 154 | ${project.groupId} 155 | ${project.artifactId} 156 | ${project.version} 157 | war 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | payara 168 | 169 | 170 | 171 | org.codehaus.cargo 172 | cargo-maven2-plugin 173 | 1.4.17 174 | 175 | 176 | install 177 | 178 | redeploy 179 | 180 | 181 | 182 | glassfish4x 183 | remote 184 | 185 | 186 | runtime 187 | 188 | ${payara.username} 189 | ${payara.password} 190 | ${payara.adminPort} 191 | ${payara.hostname} 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | org.glassfish.main.deployment 201 | deployment-client 202 | 4.1.1 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | couchbase 211 | 212 | 213 | 214 | org.codehaus.mojo 215 | exec-maven-plugin 216 | 1.4.0 217 | 218 | 219 | Configure memory 220 | install 221 | 222 | exec 223 | 224 | 225 | curl 226 | 227 | -v 228 | -X 229 | POST 230 | http://${docker.host}:${couchbase.port}/pools/default 231 | -d 232 | memoryQuota=300 233 | -d 234 | indexMemoryQuota=300 235 | 236 | 237 | 238 | 239 | Configure services 240 | install 241 | 242 | exec 243 | 244 | 245 | curl 246 | 247 | -v 248 | -X 249 | POST 250 | http://${docker.host}:${couchbase.port}/node/controller/setupServices 251 | -d 252 | services=kv%2Cn1ql%2Cindex 253 | 254 | 255 | 256 | 257 | Setup credentials 258 | install 259 | 260 | exec 261 | 262 | 263 | curl 264 | 265 | -v 266 | -X 267 | POST 268 | http://${docker.host}:${couchbase.port}/settings/web 269 | -d 270 | port=8091 271 | -d 272 | username=Administrator 273 | -d 274 | password=password 275 | 276 | 277 | 278 | 279 | Set storage mode 280 | install 281 | 282 | exec 283 | 284 | 285 | curl 286 | 287 | -v 288 | -u 289 | Administrator:password 290 | -X 291 | POST 292 | http://${docker.host}:${couchbase.port}/settings/indexes 293 | -d 294 | storageMode=memory_optimized 295 | 296 | 297 | 298 | 299 | Install travel-sample bucket 300 | install 301 | 302 | exec 303 | 304 | 305 | curl 306 | 307 | -v 308 | -u 309 | Administrator:password 310 | -X 311 | POST 312 | http://${docker.host}:${couchbase.port}/sampleBuckets/install 313 | -d 314 | ["travel-sample"] 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | -------------------------------------------------------------------------------- /readme.adoc: -------------------------------------------------------------------------------- 1 | = Couchbase and Java EE 2 | 3 | This workspace will show how to query a Couchbase bucket using simple Java EE application deployed on WildFly. Alternative configuration is also provided to deploy on Payara/GlassFish. 4 | 5 | == Minimum Requirements 6 | 7 | . Docker for Mac 1.13 8 | 9 | == Run Application 10 | 11 | . Start Docker Swarm Mode: `docker swarm init` 12 | . Deploy the application: `docker stack deploy --compose-file=docker-compose.yml webapp` 13 | . Watch the logs: `docker service logs -f webapp_web` 14 | . Wait for the logs to show the message: 15 | + 16 | ``` 17 | webapp_web.1.bunl5fgo4opp@moby | 03:12:40,220 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 10.1.0.Final (WildFly Core 2.2.0.Final) started in 100199ms - Started 443 of 691 services (404 services are lazy, passive or on-demand) 18 | ``` 19 | 20 | Optionally, you may like to build your own image. 21 | 22 | . Build application: `mvn package`. Alternatively, it can be built using Docker: 23 | + 24 | ``` 25 | docker volume create maven 26 | docker run -it --rm -v $PWD:/usr/src -v maven:/root/.m2 -w /usr/src maven:3.3-jdk-8 mvn package 27 | ``` 28 | + 29 | . Build & Push Docker image: `mvn install -Pdocker` 30 | 31 | == Deploy Application to Payara/GlassFish 32 | 33 | ```console 34 | mvn install -Ppayara -Dpayara.hostname=localhost -Dpayara.username=admin -Dpayara.password=glassfish 35 | ``` 36 | 37 | == Access Application 38 | 39 | === Get 10 Airline resources (GET) 40 | 41 | Command: 42 | ``` 43 | curl -v http://localhost:8080/airlines/resources/airline 44 | ``` 45 | 46 | Result: 47 | ``` 48 | * Trying ::1... 49 | * Connected to localhost (::1) port 8080 (#0) 50 | > GET /airlines/resources/airline HTTP/1.1 51 | > Host: localhost:8080 52 | > User-Agent: curl/7.43.0 53 | > Accept: */* 54 | > 55 | < HTTP/1.1 200 OK 56 | < Connection: keep-alive 57 | < X-Powered-By: Undertow/1 58 | < Server: WildFly/10 59 | < Content-Type: application/octet-stream 60 | < Content-Length: 1402 61 | < Date: Wed, 01 Feb 2017 03:04:41 GMT 62 | < 63 | * Connection #0 to host localhost left intact 64 | [{"travel-sample":{"country":"United States","iata":"Q5","callsign":"MILE-AIR","name":"40-Mile Air","icao":"MLA","id":10,"type":"airline"}}, {"travel-sample":{"country":"United States","iata":"TQ","callsign":"TXW","name":"Texas Wings","icao":"TXW","id":10123,"type":"airline"}}, {"travel-sample":{"country":"United States","iata":"A1","callsign":"atifly","name":"Atifly","icao":"A1F","id":10226,"type":"airline"}}, {"travel-sample":{"country":"United Kingdom","iata":null,"callsign":null,"name":"Jc royal.britannica","icao":"JRB","id":10642,"type":"airline"}}, {"travel-sample":{"country":"United States","iata":"ZQ","callsign":"LOCAIR","name":"Locair","icao":"LOC","id":10748,"type":"airline"}}, {"travel-sample":{"country":"United States","iata":"K5","callsign":"SASQUATCH","name":"SeaPort Airlines","icao":"SQH","id":10765,"type":"airline"}}, {"travel-sample":{"country":"United States","iata":"KO","callsign":"ACE AIR","name":"Alaska Central Express","icao":"AER","id":109,"type":"airline"}}, {"travel-sample":{"country":"United Kingdom","iata":"5W","callsign":"FLYSTAR","name":"Astraeus","icao":"AEU","id":112,"type":"airline"}}, {"travel-sample":{"country":"France","iata":"UU","callsign":"REUNION","name":"Air Austral","icao":"REU","id":1191,"type":"airline"}}, {"travel-sample":{"country":"France","iata":"A5","callsign":"AIRLINAIR","name":"Airlinair","icao":"RLA","id":1203,"type":"airline"}}] 65 | ``` 66 | 67 | === Get one Airline resource (GET) 68 | 69 | Command: 70 | ``` 71 | curl -v http://localhost:8080/airlines/resources/airline/137 72 | ``` 73 | 74 | Result: 75 | ``` 76 | * Trying ::1... 77 | * Connected to localhost (::1) port 8080 (#0) 78 | > GET /airlines/resources/airline/137 HTTP/1.1 79 | > Host: localhost:8080 80 | > User-Agent: curl/7.43.0 81 | > Accept: */* 82 | > 83 | < HTTP/1.1 200 OK 84 | < Connection: keep-alive 85 | < X-Powered-By: Undertow/1 86 | < Server: WildFly/10 87 | < Content-Type: application/octet-stream 88 | < Content-Length: 131 89 | < Date: Wed, 01 Feb 2017 03:05:02 GMT 90 | < 91 | * Connection #0 to host localhost left intact 92 | {"travel-sample":{"country":"France","iata":"AF","callsign":"AIRFRANS","name":"Air France","icao":"AFR","id":137,"type":"airline"}} 93 | ``` 94 | 95 | === Create a new Airline resource (POST) 96 | 97 | Command: 98 | ``` 99 | curl -v -H "Content-Type: application/json" -X POST -d '{"country":"France","iata":"A5","callsign":"AIRLINAIR","name":"Airlinair","icao":"RLA","type":"airline"}' http://localhost:8080/airlines/resources/airline 100 | ``` 101 | 102 | Result: 103 | ``` 104 | * Trying ::1... 105 | * Connected to localhost (::1) port 8080 (#0) 106 | > POST /airlines/resources/airline HTTP/1.1 107 | > Host: localhost:8080 108 | > User-Agent: curl/7.43.0 109 | > Accept: */* 110 | > Content-Type: application/json 111 | > Content-Length: 104 112 | > 113 | * upload completely sent off: 104 out of 104 bytes 114 | < HTTP/1.1 200 OK 115 | < Connection: keep-alive 116 | < X-Powered-By: Undertow/1 117 | < Server: WildFly/10 118 | < Content-Type: application/octet-stream 119 | < Content-Length: 117 120 | < Date: Wed, 01 Feb 2017 03:05:18 GMT 121 | < 122 | * Connection #0 to host localhost left intact 123 | {"country":"France","iata":"A5","callsign":"AIRLINAIR","name":"Airlinair","icao":"RLA","id":"19810","type":"airline"} 124 | ``` 125 | 126 | === Update an existing Airline resource (PUT) 127 | 128 | Command: 129 | ``` 130 | curl -v -H "Content-Type: application/json" -X PUT -d '{"country":"France","iata":"A5","callsign":"AIRLINAIR","name":"Airlin Air","icao":"RLA","type":"airline","id": "19810"}' http://localhost:8080/airlines/resources/airline/19810 131 | ``` 132 | 133 | Result: 134 | ``` 135 | * Trying ::1... 136 | * Connected to localhost (::1) port 8080 (#0) 137 | > PUT /airlines/resources/airline/19810 HTTP/1.1 138 | > Host: localhost:8080 139 | > User-Agent: curl/7.43.0 140 | > Accept: */* 141 | > Content-Type: application/json 142 | > Content-Length: 119 143 | > 144 | * upload completely sent off: 119 out of 119 bytes 145 | < HTTP/1.1 200 OK 146 | < Connection: keep-alive 147 | < X-Powered-By: Undertow/1 148 | < Server: WildFly/10 149 | < Content-Type: application/octet-stream 150 | < Content-Length: 118 151 | < Date: Wed, 01 Feb 2017 03:05:41 GMT 152 | < 153 | * Connection #0 to host localhost left intact 154 | {"country":"France","iata":"A5","callsign":"AIRLINAIR","name":"Airlin Air","icao":"RLA","id":"19810","type":"airline"} 155 | ``` 156 | 157 | === Delete an existing Airline resource (DELETE) 158 | 159 | Command: 160 | ``` 161 | curl -v -X DELETE http://localhost:8080/airlines/resources/airline/19810 162 | ``` 163 | 164 | Result: 165 | ``` 166 | * Trying ::1... 167 | * Connected to localhost (::1) port 8080 (#0) 168 | > DELETE /airlines/resources/airline/19810 HTTP/1.1 169 | > Host: localhost:8080 170 | > User-Agent: curl/7.43.0 171 | > Accept: */* 172 | > 173 | < HTTP/1.1 200 OK 174 | < Connection: keep-alive 175 | < X-Powered-By: Undertow/1 176 | < Server: WildFly/10 177 | < Content-Type: application/octet-stream 178 | < Content-Length: 136 179 | < Date: Wed, 01 Feb 2017 03:05:57 GMT 180 | < 181 | * Connection #0 to host localhost left intact 182 | {"travel-sample":{"country":"France","iata":"A5","callsign":"AIRLINAIR","name":"Airlin Air","icao":"RLA","id":"19810","type":"airline"}} 183 | ``` 184 | -------------------------------------------------------------------------------- /src/main/docker/assembly.xml: -------------------------------------------------------------------------------- 1 | 4 | ${project.artifactId} 5 | 6 | 7 | 8 | ${project.groupId}:${project.artifactId} 9 | 10 | . 11 | ${project.name}.war 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/docker/images/payara/docker-compose.yml: -------------------------------------------------------------------------------- 1 | mycouchbase: 2 | image: couchbase/server 3 | ports: 4 | - 8091:8091 5 | - 8092:8092 6 | - 8093:8093 7 | - 11210:11210 8 | mypayara: 9 | image: payaradocker/payaraserver:4.1.1.154 10 | command: /bin/bash -c './asadmin start-domain payaradomain && while kill -0 $(cat ../domains/payaradomain/config/pid); do sleep 0.5; done' 11 | ports: 12 | - 8080:8080 13 | - 4848:4848 -------------------------------------------------------------------------------- /src/main/java/org/couchbase/sample/javaee/AirlineBean.java: -------------------------------------------------------------------------------- 1 | package org.couchbase.sample.javaee; 2 | 3 | import com.couchbase.client.deps.com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.couchbase.client.deps.com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.couchbase.client.java.document.JsonDocument; 6 | import com.couchbase.client.java.document.json.JsonObject; 7 | import java.io.IOException; 8 | import java.util.logging.Level; 9 | import java.util.logging.Logger; 10 | 11 | /** 12 | * @author arungupta 13 | */ 14 | public class AirlineBean { 15 | private String country; 16 | private String iata; 17 | private String callsign; 18 | private String name; 19 | private String icao; 20 | private String id; 21 | private final String type = "airline"; 22 | 23 | public String getCountry() { 24 | return country; 25 | } 26 | 27 | public void setCountry(String country) { 28 | this.country = country; 29 | } 30 | 31 | public String getIata() { 32 | return iata; 33 | } 34 | 35 | public void setIata(String iata) { 36 | this.iata = iata; 37 | } 38 | 39 | public String getCallsign() { 40 | return callsign; 41 | } 42 | 43 | public void setCallsign(String callsign) { 44 | this.callsign = callsign; 45 | } 46 | 47 | public String getName() { 48 | return name; 49 | } 50 | 51 | public void setName(String name) { 52 | this.name = name; 53 | } 54 | 55 | public String getIcao() { 56 | return icao; 57 | } 58 | 59 | public void setIcao(String icao) { 60 | this.icao = icao; 61 | } 62 | 63 | public String getId() { 64 | return id; 65 | } 66 | 67 | public void setId(String id) { 68 | this.id = id; 69 | } 70 | 71 | public String getType() { 72 | return type; 73 | } 74 | 75 | static JsonDocument toJson(AirlineBean bean, long counter) throws JsonProcessingException { 76 | ObjectMapper mapper = new ObjectMapper(); 77 | bean.setId(String.valueOf(counter)); 78 | String json = mapper.writeValueAsString(bean); 79 | 80 | return JsonDocument.create("airline_" + bean.getId(), JsonObject.fromJson(json)); 81 | } 82 | 83 | static JsonDocument toJson(AirlineBean bean) throws JsonProcessingException { 84 | ObjectMapper mapper = new ObjectMapper(); 85 | String json = mapper.writeValueAsString(bean); 86 | 87 | return JsonDocument.create("airline_" + bean.getId(), JsonObject.fromJson(json)); 88 | } 89 | 90 | static AirlineBean fromJson(JsonDocument json) throws IOException { 91 | ObjectMapper mapper = new ObjectMapper(); 92 | return mapper.readValue(json.content().toString(), AirlineBean.class); 93 | } 94 | 95 | @Override 96 | public String toString() { 97 | try { 98 | return toJson(this).content().toString(); 99 | } catch (JsonProcessingException ex) { 100 | Logger.getLogger(AirlineBean.class.getName()).log(Level.SEVERE, null, ex); 101 | } 102 | return null; 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/org/couchbase/sample/javaee/AirlineResource.java: -------------------------------------------------------------------------------- 1 | package org.couchbase.sample.javaee; 2 | 3 | import com.couchbase.client.deps.com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.couchbase.client.java.document.JsonDocument; 5 | import com.couchbase.client.java.document.JsonLongDocument; 6 | import com.couchbase.client.java.query.N1qlQuery; 7 | import com.couchbase.client.java.query.N1qlQueryResult; 8 | import javax.ws.rs.GET; 9 | import javax.ws.rs.Path; 10 | import javax.ws.rs.PathParam; 11 | import static com.couchbase.client.java.query.Select.select; 12 | import static com.couchbase.client.java.query.dsl.Expression.i; 13 | import javax.inject.Inject; 14 | import javax.ws.rs.Consumes; 15 | import javax.ws.rs.DELETE; 16 | import javax.ws.rs.POST; 17 | import javax.ws.rs.PUT; 18 | 19 | /** 20 | * @author Arun Gupta 21 | */ 22 | @Path("airline") 23 | public class AirlineResource { 24 | 25 | @Inject Database database; 26 | 27 | @GET 28 | public String getAll() { 29 | System.out.println("GET: all"); 30 | N1qlQuery query = N1qlQuery 31 | .simple(select("*") 32 | .from(i(database.getBucket().name())) 33 | .limit(10)); 34 | // N1qlQuery query = N1qlQuery.simple("SELECT * FROM `travel-sample` LIMIT 10"); 35 | System.out.println(query.statement().toString()); 36 | N1qlQueryResult result = database.getBucket().query(query); 37 | System.err.println(result.errors()); 38 | System.out.println(result.toString()); 39 | return result.allRows().toString(); 40 | } 41 | 42 | @GET 43 | @Path("{id}") 44 | public String getAirline(@PathParam("id") String id) { 45 | System.out.println("GET: " + id); 46 | // N1qlQuery query = N1qlQuery 47 | // .simple(select("*") 48 | // .from(i(database.getBucket().name())) 49 | // .where(x("id").eq(id))); 50 | // N1qlQuery query = N1qlQuery.simple("SELECT * from `travel-sample` WHERE id = " + id); 51 | 52 | N1qlQuery query = N1qlQuery.simple("SELECT * from `travel-sample` USE KEYS [\"airline_" + id + "\"]"); 53 | System.out.println(query.statement().toString()); 54 | N1qlQueryResult result = database.getBucket().query(query); 55 | if (result.finalSuccess() && !result.allRows().isEmpty()) { 56 | return result.allRows().get(0).toString(); 57 | } 58 | 59 | return null; 60 | } 61 | 62 | @POST 63 | @Consumes("application/json") 64 | public String addAirline(AirlineBean airline) throws JsonProcessingException { 65 | System.out.println("POST: " + airline.toString()); 66 | JsonLongDocument id = database.getBucket().counter("airline_sequence", 1); 67 | JsonDocument document = database.getBucket().insert(AirlineBean.toJson(airline, id.content())); 68 | return document.content().toString(); 69 | } 70 | 71 | @PUT 72 | @Path("{id}") 73 | public String updateAirline(AirlineBean airline) throws JsonProcessingException { 74 | System.out.println("PUT: " + airline.toString()); 75 | JsonDocument document = database.getBucket().replace(AirlineBean.toJson(airline)); 76 | 77 | return document.content().toString(); 78 | } 79 | 80 | @DELETE 81 | @Path("{id}") 82 | public String delete(@PathParam("id")String id) { 83 | String airline = getAirline(id); 84 | System.out.println("DELETE: " + airline); 85 | database.getBucket().remove("airline_" + id); 86 | 87 | return airline; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/org/couchbase/sample/javaee/Database.java: -------------------------------------------------------------------------------- 1 | package org.couchbase.sample.javaee; 2 | 3 | import com.couchbase.client.java.Bucket; 4 | import com.couchbase.client.java.CouchbaseCluster; 5 | import com.couchbase.client.java.document.JsonLongDocument; 6 | import com.couchbase.client.java.query.N1qlQuery; 7 | import com.couchbase.client.java.query.N1qlQueryResult; 8 | import javax.annotation.PostConstruct; 9 | import javax.annotation.PreDestroy; 10 | import javax.ejb.Singleton; 11 | import javax.ejb.Startup; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | /** 15 | * @author Arun Gupta 16 | */ 17 | @Singleton 18 | @Startup 19 | public class Database { 20 | 21 | CouchbaseCluster cluster; 22 | Bucket bucket; 23 | 24 | @PostConstruct 25 | public void init() { 26 | long travelSampleCount = 31591; 27 | 28 | N1qlQuery query = N1qlQuery.simple("SELECT count(*) as count FROM `travel-sample`"); 29 | N1qlQueryResult result = null; 30 | long count = 0; 31 | while (result == null || count != travelSampleCount) { 32 | try { 33 | result = getBucket().query(query); 34 | if (result.finalSuccess()) { 35 | count = result.allRows().get(0).value().getLong("count"); 36 | } else { 37 | System.out.println("Travel sample bucket not ready ..."); 38 | } 39 | } catch (com.couchbase.client.core.ServiceNotAvailableException ex) { 40 | System.out.println("Query service not up ..."); 41 | } 42 | try { 43 | System.out.println("Sleeping for 3 secs (waiting for Query service or bucket to be loaded) ..."); 44 | Thread.sleep(3000); 45 | } catch (Exception e) { 46 | System.out.println("Thread sleep Exception: " + e.getMessage()); 47 | } 48 | } 49 | System.out.println(count + " number of JSON documents in bucket."); 50 | 51 | query = N1qlQuery.simple("SELECT MAX(id) + 1 as counterInit FROM `travel-sample` where type=\"airline\""); 52 | result = getBucket().query(query); 53 | while (!result.finalSuccess()) { 54 | try { 55 | System.out.println("Sleeping for 3 secs (waiting for indexes) ..."); 56 | Thread.sleep(3000); 57 | } catch (Exception e) { 58 | System.out.println("Thread sleep Exception: " + e.getMessage()); 59 | } 60 | result = getBucket().query(query); 61 | } 62 | 63 | long counterInit = result.allRows().get(0).value().getLong("counterInit"); 64 | bucket.insert(JsonLongDocument.create("airline_sequence", counterInit)); 65 | } 66 | 67 | @PreDestroy 68 | public void stop() { 69 | bucket.close(); 70 | cluster.disconnect(); 71 | } 72 | 73 | public CouchbaseCluster getCluster() { 74 | if (null != cluster) { 75 | return cluster; 76 | } 77 | 78 | String host = System.getProperty("COUCHBASE_URI"); 79 | if (host == null) { 80 | host = System.getenv("COUCHBASE_URI"); 81 | } 82 | if (host == null) { 83 | throw new RuntimeException("Hostname is null"); 84 | } 85 | System.out.println("env: " + host); 86 | cluster = CouchbaseCluster.create(host); 87 | return cluster; 88 | } 89 | 90 | public Bucket getBucket() { 91 | if (null != bucket) { 92 | return bucket; 93 | } 94 | 95 | while (null == bucket) { 96 | System.out.println("Trying to connect to the database"); 97 | try { 98 | bucket = getCluster().openBucket("travel-sample", 2L, TimeUnit.MINUTES); 99 | } catch (Exception e) { 100 | System.out.println("travel-sample bucket not ready yet ..."); 101 | } 102 | try { 103 | System.out.println("Sleeping for 3 secs (waiting for travel-sample bucket) ..."); 104 | Thread.sleep(3000); 105 | } catch (Exception e) { 106 | System.out.println("Thread sleep Exception: " + e.getMessage()); 107 | } 108 | } 109 | System.out.println("Bucket found!"); 110 | return bucket; 111 | } 112 | 113 | public static String getBucketName() { 114 | return "travel-sample"; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/org/couchbase/sample/javaee/MyApplication.java: -------------------------------------------------------------------------------- 1 | package org.couchbase.sample.javaee; 2 | 3 | import java.util.Collections; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | import javax.ws.rs.ApplicationPath; 7 | import javax.ws.rs.core.Application; 8 | 9 | /** 10 | * @author Arun Gupta 11 | */ 12 | @ApplicationPath("resources") 13 | public class MyApplication extends Application { 14 | 15 | final Set> classes = new HashSet<>(); 16 | 17 | @Override 18 | public Set> getClasses() { 19 | classes.add(AirlineResource.class); 20 | return Collections.unmodifiableSet(classes); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@page contentType="text/html" pageEncoding="UTF-8"%> 2 | 4 | 5 | 6 | 7 | 8 | JSP Page 9 | 10 | 11 |

Hello World!

12 | 13 | 14 | --------------------------------------------------------------------------------