package fr.pilato.demo.sql2nosql.webapp; import com.couchbase.client.CouchbaseClient; import com.couchbase.client.protocol.views.*; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import fr.pilato.demo.sql2nosql.model.bean.Person; import fr.pilato.demo.sql2nosql.model.helper.PersonGenerator; import fr.pilato.demo.sql2nosql.webapp.util.ConnectionManager; import fr.pilato.demo.sql2nosql.webapp.util.KeyUtil; import fr.pilato.demo.sql2nosql.webapp.util.ViewUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; /** * Person RESTFul API * * @author David Pilato */ @Controller @RequestMapping("/1/person") public class PersonService { public final static String KEY_PERSON_PREFIX = "person"; public final static String PERSON_DSGN_DOC = "person_view"; public final static String PERSON_BY_NAME_VIEW = "by_name"; public final static String LAST_CHAR = "\\uefff"; final Logger logger = LoggerFactory.getLogger(PersonService.class); CouchbaseClient client = ConnectionManager.getInstance(); ObjectMapper mapper = new ObjectMapper(); private static final int numPersons = 1000; @RequestMapping(method = RequestMethod.GET, value = "/") public @ResponseBody ArrayList getAll() { return search(null); } /* @RequestMapping(method = RequestMethod.GET, value = "/{id}") public @ResponseBody Person get(@PathVariable String id) { Person person = personDao.get(Integer.valueOf(id)); if (logger.isDebugEnabled()) logger.debug("get({})={}", id, person); return person; } */ @RequestMapping(method = RequestMethod.GET, value = "/{id}") public @ResponseBody String get(@PathVariable String id) { String person = (String)client.get( KeyUtil.getKey(KEY_PERSON_PREFIX, id) ); if (logger.isDebugEnabled()) logger.debug("get({})={}", id, person); return person; } /* @RequestMapping(method = RequestMethod.PUT, value = "/") public @ResponseBody String create(@RequestBody String json) { if (logger.isDebugEnabled()) logger.debug("create({})", json); ObjectMapper mapper = new ObjectMapper(); try { Person person = mapper.readValue(json, Person.class); if (logger.isDebugEnabled()) logger.debug("After Jackson parsing: {}", person); if (person != null) { person = personDao.save(person); if (logger.isDebugEnabled()) logger.debug("Person saved: {}", person); return String.valueOf(person.getId()); } } catch (IOException e) { logger.error("Error while saving json", e); } return ""; } */ @RequestMapping(method = RequestMethod.PUT, value = "/") public @ResponseBody String create(@RequestBody String json) { if (logger.isDebugEnabled()) logger.debug("create({})", json); String key = KeyUtil.nextValue(KEY_PERSON_PREFIX); client.set(key, 0, json); return key; } @RequestMapping(method = RequestMethod.PUT, value = "/{id}") public @ResponseBody String update(@PathVariable String id, @RequestBody String json) { if (logger.isDebugEnabled()) logger.debug("update({})", json); client.replace(KeyUtil.getKey(KEY_PERSON_PREFIX, id), 0, json); return ""; } @RequestMapping(method = RequestMethod.DELETE, value = "/{id}") public @ResponseBody String delete(@PathVariable String id) { if (logger.isDebugEnabled()) logger.debug("Person: {}", id); if (id != null) { client.delete(KeyUtil.getKey(KEY_PERSON_PREFIX, id)); if (logger.isDebugEnabled()) logger.debug("Person deleted: {}", id); } return ""; } @RequestMapping(method = {RequestMethod.POST, RequestMethod.GET}, value = "/_search") public @ResponseBody ArrayList> search() { return search(null); } @RequestMapping(method = {RequestMethod.POST, RequestMethod.GET}, value = "/_search", params = "q") public @ResponseBody ArrayList> search(@RequestParam String q) { ArrayList> result = new ArrayList>(); try { View view = client.getView(PERSON_DSGN_DOC, PERSON_BY_NAME_VIEW); Query query = new Query(); query.setIncludeDocs(true); if (q != null) { query.setRange(q, q + LAST_CHAR); } query.setLimit(10); ViewResponse viewResponse = client.query(view, query); for (ViewRow row : viewResponse) { HashMap parsedDoc = mapper.readValue( (String)row.getDocument(), HashMap.class ) ; //HashMap parsedDoc = gson.fromJson( (String)row.getDocument(), HashMap.class); result.add( parsedDoc ); } } catch (InvalidViewException e) { logger.info("View does now exist... creating it"); ViewUtil.createViews(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (JsonParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } @RequestMapping(method = RequestMethod.POST, value = "/_init") public @ResponseBody String init() throws IOException { return init(numPersons-1); } @RequestMapping(method = RequestMethod.POST, value = "/_init", params = "size") public @ResponseBody String init(@RequestParam(required = false, defaultValue = ""+(numPersons - 1)) Integer size) throws IOException { if (logger.isDebugEnabled()) logger.debug("Initializing database for {} persons", size); Person joe = PersonGenerator.personGenerator("Joe Smith"); sendToCouchbase(joe); Person john = PersonGenerator.personGenerator("John Wilson"); sendToCouchbase(john); // We generate numPersons persons for (int i = 0; i < size - 1; i++) { sendToCouchbase(PersonGenerator.personGenerator()); } // create the view try { client.getView(PERSON_DSGN_DOC, PERSON_BY_NAME_VIEW); } catch (InvalidViewException e) { ViewUtil.createViews(); } return ""; } private void sendToCouchbase(Person person) throws JsonProcessingException { String key = KeyUtil.nextValue(KEY_PERSON_PREFIX); int internalId = Integer.parseInt(key.substring(key.indexOf(KeyUtil.KEY_SEPARATOR) + 1)); person.setId(internalId); String json = mapper.writeValueAsString(person); client.set(key, 0, json); } }