Skip to content

Commit

Permalink
Servlet to get the list of clients. Fixes #11
Browse files Browse the repository at this point in the history
  • Loading branch information
phtrivier committed Apr 11, 2013
1 parent 0e98fe2 commit 546fdf6
Show file tree
Hide file tree
Showing 13 changed files with 539 additions and 38 deletions.
28 changes: 24 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ You can start connecting your M3DA client on the TCP port 44900 (IANA official p
REST READ API
--------

You can see all the received data for a given client by GETing the URL : http://127.0.0.1:8080/data/{client identifier}
You can see all the received data for a given client by GETing the URL : http://127.0.0.1:8080/clients/{client identifier}/data

The client identifier is the value of "agent.config.agent.deviceId" in your mihini installation.

Examples :
> GET http://127.0.0.1:8080/data/01121979
> GET http://127.0.0.1:8080/clients/01121979/data
RESULT :

Expand Down Expand Up @@ -62,12 +62,12 @@ RESULT :
REST WRITE API
--------

You can push data to a given client by POSTing to the following URL : http://127.0.0.1:8080/data/{client identifier}
You can push data to a given client by POSTing to the following URL : http://127.0.0.1:8080/clients/{client identifier}/data

The client identifier is the value of "agent.config.agent.deviceId" in your mihini installation.

Examples :
> POST http://127.0.0.1:8080/data/01121979
> POST http://127.0.0.1:8080/clients/01121979/data
Content :

Expand All @@ -82,3 +82,23 @@ Content :
}]
}
```

REST CLIENTS API
--------

You can get the list of connect client by GETing the URL : http://127.0.0.1:8080/clients .
You'll received the list of "in" clients (those that sent data) and "out" clients (those for which data is waiting to be pushed on the server.)

Example:
> POST http://127.0.0.1:8080/clients/01121979/data

This comment has been minimized.

Copy link
@kartben

kartben Apr 11, 2013

should be:
GET http://127.0.0.1:8080/clients
no?

This comment has been minimized.

Copy link
@phtrivier

phtrivier Apr 11, 2013

Author

Yes, I fixed that in later commits (I had to do a couple other changes, I rushed the README a bit... it should be okay on master.)

This comment has been minimized.

Copy link
@kartben

kartben Apr 11, 2013

ahhh. perfect, thanks!

Content :
```javascript
{
"in"" : ["12131", "client1", "foobar"],
"out" : ["12131", "other-client"]
}
```
23 changes: 16 additions & 7 deletions server/src/main/java/m3da/server/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
package m3da.server;

import m3da.server.api.mapping.Store2JsonDataMapper;
import m3da.server.services.clients.JClientsService;
import m3da.server.services.data.JDataService;
import m3da.server.servlet.ClientsServlet;
import m3da.server.servlet.DataServlet;
import m3da.server.store.InMemoryStoreService;
import m3da.server.store.StoreService;
Expand Down Expand Up @@ -48,25 +51,31 @@ public static void main(String[] args) throws Exception {
root.setResourceBase(webappDirLocation);
root.setParentLoaderPriority(true);

StoreService service = new InMemoryStoreService(10);
StoreService storeService = new InMemoryStoreService(10);
Store2JsonDataMapper store2jsonMapper = new Store2JsonDataMapper();
ObjectMapper jacksonMapper = new ObjectMapper();

ServletHolder servletHolder = new ServletHolder(new DataServlet(service, store2jsonMapper, jacksonMapper));
root.addServlet(servletHolder, "/data/*");

JDataService dataService = new JDataService(storeService, store2jsonMapper);
JClientsService clientsService = new JClientsService(storeService);

ServletHolder dataServletHolder = new ServletHolder(new DataServlet(dataService, jacksonMapper));
root.addServlet(dataServletHolder, "/data/*");

ServletHolder clientsServletHolder = new ServletHolder(new ClientsServlet(dataService, clientsService, jacksonMapper));
root.addServlet(clientsServletHolder, "/clients/*");

server.setHandler(root);

server.start();

service.start();
storeService.start();

M3daTcpServer tcpServer = new M3daTcpServer(2, 30, 44900, 4, 8, service);
M3daTcpServer tcpServer = new M3daTcpServer(2, 30, 44900, 4, 8, storeService);
tcpServer.start();
server.join();

tcpServer.stop();
service.stop();
storeService.stop();

}

Expand Down
38 changes: 38 additions & 0 deletions server/src/main/java/m3da/server/api/json/JClients.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package m3da.server.api.json;

import java.util.List;

/**
* JSON Bean for list of connected clients.
*/
public class JClients {

List<String> in;
List<String> out;

/**
* @return the ids of clients that have recently sent data.
*/
public List<String> getIn() {
return in;
}

public void setIn(List<String> in) {
this.in = in;
}

/**
* @return the ids of client for which there is still some
* data to send.
*/
public List<String> getOut() {
return out;
}

public void setOut(List<String> out) {
this.out = out;
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package m3da.server.services.clients;

import java.util.ArrayList;
import java.util.List;

import m3da.server.api.json.JClients;
import m3da.server.store.StoreService;

/**
* Service to get JSON bean for the Clients servlet.
*/
public class JClientsService {

private StoreService storeService;

public JClientsService(StoreService storeService) {
this.storeService = storeService;
}

public JClients getClients() {
JClients res = new JClients();

List<String> in = new ArrayList<String>(storeService.incomingClientIds());
List<String> out = new ArrayList<String>(storeService.outgoingClientIds());

res.setIn(in);
res.setOut(out);

return res;
}

}
37 changes: 37 additions & 0 deletions server/src/main/java/m3da/server/services/data/JDataService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package m3da.server.services.data;

import java.util.List;
import java.util.Map;

import m3da.server.api.json.JSystemReadData;
import m3da.server.api.json.JSystemWriteSettings;
import m3da.server.api.mapping.Store2JsonDataMapper;
import m3da.server.store.Envelope;
import m3da.server.store.Message;
import m3da.server.store.StoreService;

/**
* Service to get JSON Bean for data servlet.
*
*/
public class JDataService {

private Store2JsonDataMapper store2JsonMapper;
private StoreService store;

public JDataService(StoreService store, Store2JsonDataMapper store2JsonMapper) {
this.store = store;
this.store2JsonMapper = store2JsonMapper;
}

public Map<String, List<JSystemReadData>> lastReceivedData(String system) {
Map<Long, Envelope> data = store.lastReceivedData(system);
return this.store2JsonMapper.mapReceivedData(data);
}

public void enqueueReceivedData(String system, JSystemWriteSettings settings) {
List<Message> newData = store2JsonMapper.mapDataToSend(settings);
store.enqueueDataToSend(system, newData);
}

}
101 changes: 101 additions & 0 deletions server/src/main/java/m3da/server/servlet/ClientsServlet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package m3da.server.servlet;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.MatchResult;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import m3da.server.api.json.JClients;
import m3da.server.api.json.JSystemReadData;
import m3da.server.api.json.JSystemWriteSettings;
import m3da.server.services.clients.JClientsService;
import m3da.server.services.data.JDataService;

import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Servlet for "clients" API
*
* <ul>
* <li>GET /clients (list of clients)</li>
* <li>GET /clients/1/data (last received data)</li>
* <li>POST /clients/1/data (send data)</li>
* </ul>
*
*/
@SuppressWarnings("serial")
public class ClientsServlet extends JsonServlet {

public static final String ERROR_NO_CLIENT = "No client in path";

private static final Logger LOG = LoggerFactory
.getLogger(ClientsServlet.class);
private JDataService dataService;
private JClientsService clientsService;

public ClientsServlet(JDataService dataService,
JClientsService clientsService, ObjectMapper jacksonMapper) {
super(jacksonMapper);
this.dataService = dataService;
this.clientsService = clientsService;
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.setResponseContentType(resp);
String pathInfo = req.getPathInfo();
if (StringUtils.isBlank(pathInfo)) {
JClients jClients = this.clientsService.getClients();
this.jacksonMapper.writeValue(resp.getWriter(), jClients);
} else {
String clientId = getClientId(pathInfo);
if (clientId == null) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ERROR_NO_CLIENT);
} else {
Map<String, List<JSystemReadData>> jData = this.dataService
.lastReceivedData(clientId);
this.jacksonMapper.writeValue(resp.getWriter(), jData);
}
}
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.setResponseContentType(resp);

String clientId = getClientId(req.getPathInfo());
if (clientId == null) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ERROR_NO_CLIENT);
} else {
JSystemWriteSettings settings = this.jacksonMapper.readValue(
req.getInputStream(), JSystemWriteSettings.class);
this.dataService.enqueueReceivedData(clientId, settings);
}

}

private String getClientId(String pathInfo) {
String res = null;
Scanner scanner = new Scanner(pathInfo);
String match = scanner.findInLine("/(\\w+)/data");

This comment has been minimized.

Copy link
@kartben

kartben Apr 16, 2013

this is causing issue #16 i think

if (match != null) {
MatchResult result = scanner.match();
res = result.group(1);
}
return res;
}

}
35 changes: 14 additions & 21 deletions server/src/main/java/m3da/server/servlet/DataServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import m3da.server.api.json.JSystemReadData;
import m3da.server.api.json.JSystemWriteSettings;
import m3da.server.api.mapping.Store2JsonDataMapper;
import m3da.server.services.data.JDataService;
import m3da.server.store.Envelope;
import m3da.server.store.Message;
import m3da.server.store.StoreService;
Expand All @@ -30,21 +30,20 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Servlet for legacy "data" servlet. "clients" API should be used instead.
*
*/
@SuppressWarnings("serial")
public class DataServlet extends HttpServlet {
public class DataServlet extends JsonServlet {

private static final Logger LOG = LoggerFactory.getLogger(DataServlet.class);

private StoreService store;

private Store2JsonDataMapper store2JsonMapper;

private ObjectMapper jacksonMapper;

public DataServlet(StoreService store, Store2JsonDataMapper store2JsonMapper, ObjectMapper jasksonMapper) {
this.store = store;
this.store2JsonMapper = store2JsonMapper;
this.jacksonMapper = jasksonMapper;
private JDataService dataService;

public DataServlet(JDataService dataService, ObjectMapper jasksonMapper) {
super(jasksonMapper);
this.dataService = dataService;
}

@Override
Expand All @@ -58,8 +57,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se
system = system.substring(1);
LOG.info("system " + system);

Map<Long, Envelope> data = store.lastReceivedData(system);
Map<String, List<JSystemReadData>> json = this.store2JsonMapper.mapReceivedData(data);
Map<String, List<JSystemReadData>> json = this.dataService.lastReceivedData(system);

this.jacksonMapper.writeValue(resp.getWriter(), json);
}
Expand All @@ -73,14 +71,9 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
return;
}
system = system.substring(1);
JSystemWriteSettings settings = this.jacksonMapper.readValue(req.getInputStream(), JSystemWriteSettings.class);

List<Message> newData = store2JsonMapper.mapDataToSend(settings);
store.enqueueDataToSend(system, newData);
}

private void setResponseContentType(HttpServletResponse resp) {
resp.setContentType("application/json;charset=utf-8");
JSystemWriteSettings settings = this.jacksonMapper.readValue(req.getInputStream(), JSystemWriteSettings.class);
this.dataService.enqueueReceivedData(system, settings);
}

}

0 comments on commit 546fdf6

Please sign in to comment.