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
*
* - PUT : create a new person
*
- DELETE : remove a person
*
* @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);
}
}