@Override public UUID saveStatement(Statement statement) throws Exception { HTTPRequest request = new HTTPRequest(); request.setRequestContent( new ByteArrayBuffer(statement.toJSON(this.getVersion(), this.usePrettyJSON()), "UTF-8")); String url = this.getEndpoint() + "statements"; if (statement.getId() == null) { request.setMethod(HttpMethods.POST); } else { request.setMethod(HttpMethods.PUT); url += "?statementId=" + statement.getId().toString(); } request.setURL(url); HTTPResponse response = this.sendRequest(request); int status = response.getStatus(); // TODO: handle 409 conflict, etc. if (status == 204) { return statement.getId(); } else if (status == 200) { String content = request.getResponseContent(); return UUID.fromString( Mapper.getInstance().readValue(content, ArrayNode.class).get(0).textValue()); } throw new UnexpectedHTTPResponse(response); }
@Override public List<String> saveStatements(List<Statement> statements) throws Exception { List<String> statementIds = new ArrayList<String>(); if (statements.size() == 0) { return statementIds; } ArrayNode rootNode = Mapper.getInstance().createArrayNode(); for (Statement statement : statements) { rootNode.add(statement.toJSONNode(version)); } HTTPRequest request = new HTTPRequest(); request.setRequestContent( new ByteArrayBuffer( Mapper.getWriter(this.usePrettyJSON()).writeValueAsString(rootNode), "UTF-8")); request.setMethod(HttpMethods.POST); request.setURL(this.getEndpoint() + "statements"); HTTPResponse response = this.sendRequest(request); int status = response.getStatus(); if (status == 200) { String content = request.getResponseContent(); Iterator it = Mapper.getInstance().readValue(content, ArrayNode.class).elements(); while (it.hasNext()) { statementIds.add(((JsonNode) it.next()).textValue()); } return statementIds; } throw new UnexpectedHTTPResponse(response); }
private ProfileKeysLRSResponse getProfileKeys( String resource, HashMap<String, String> queryParams) { HTTPRequest request = new HTTPRequest(); request.setMethod(HttpMethods.GET); request.setResource(resource); request.setQueryParams(queryParams); HTTPResponse response = makeSyncRequest(request); ProfileKeysLRSResponse lrsResponse = new ProfileKeysLRSResponse(request, response); if (response.getStatus() == 200) { lrsResponse.setSuccess(true); try { Iterator it = Mapper.getInstance().readValue(response.getContent(), ArrayNode.class).elements(); lrsResponse.setContent(new ArrayList<String>()); while (it.hasNext()) { lrsResponse.getContent().add(it.next().toString()); } } catch (Exception ex) { lrsResponse.setErrMsg("Exception: " + ex.toString()); lrsResponse.setSuccess(false); } } else { lrsResponse.setSuccess(false); } return lrsResponse; }
@Override public StatementsResult moreStatements(String moreURL) throws Exception { if (moreURL == null) { return null; } // // moreURL is relative to the endpoint's server root // URL endpoint = this.getEndpoint(); String url = endpoint.getProtocol() + "://" + endpoint.getHost() + (endpoint.getPort() == -1 ? "" : endpoint.getPort()) + moreURL; HTTPRequest request = new HTTPRequest(); request.setURL(url); HTTPResponse response = this.sendRequest(request); if (response.getStatus() == 200) { return new StatementsResult(new StringOfJSON(response.getContent())); } throw new UnexpectedHTTPResponse(response); }
private StatementLRSResponse getStatement(String id, String paramName) { HTTPRequest request = new HTTPRequest(); request.setMethod(HttpMethods.GET); request.setResource("statements"); request.setQueryParams(new HashMap<String, String>()); request.getQueryParams().put(paramName, id); HTTPResponse response = makeSyncRequest(request); int status = response.getStatus(); StatementLRSResponse lrsResponse = new StatementLRSResponse(request, response); if (status == 200) { lrsResponse.setSuccess(true); try { lrsResponse.setContent(new Statement(new StringOfJSON(response.getContent()))); } catch (Exception ex) { lrsResponse.setErrMsg("Exception: " + ex.toString()); lrsResponse.setSuccess(false); } } else { lrsResponse.setSuccess(false); } return lrsResponse; }
@Override public AboutLRSResponse about() { HTTPRequest request = new HTTPRequest(); request.setMethod(HttpMethods.GET); request.setResource("about"); HTTPResponse response = makeSyncRequest(request); int status = response.getStatus(); AboutLRSResponse lrsResponse = new AboutLRSResponse(request, response); if (status == 200) { lrsResponse.setSuccess(true); try { lrsResponse.setContent(new About(response.getContent())); } catch (Exception ex) { lrsResponse.setErrMsg("Exception: " + ex.toString()); lrsResponse.setSuccess(false); } } else { lrsResponse.setSuccess(false); } return lrsResponse; }
private LRSResponse updateDocument( String resource, Map<String, String> queryParams, Document document) { HTTPRequest request = new HTTPRequest(); request.setMethod(HttpMethods.POST); request.setResource(resource); request.setQueryParams(queryParams); request.setContentType(document.getContentType()); request.setContent(document.getContent()); if (document.getEtag() != null) { request.setHeaders(new HashMap<String, String>()); request.getHeaders().put("If-Match", document.getEtag()); } HTTPResponse response = makeSyncRequest(request); LRSResponse lrsResponse = new LRSResponse(request, response); if (response.getStatus() == 204) { lrsResponse.setSuccess(true); } else { lrsResponse.setSuccess(false); } return lrsResponse; }
@Override public State retrieveState(String id, String activityId, Agent agent, UUID registration) throws Exception { HashMap<String, String> params = new HashMap<String, String>(); params.put("stateId", id); params.put("activityId", activityId); params.put("agent", agent.toJSON(this.getVersion(), this.usePrettyJSON())); if (registration != null) { params.put("registration", registration.toString()); } String queryString = "?"; Boolean first = true; for (Map.Entry<String, String> parameter : params.entrySet()) { queryString += (first ? "" : "&") + URLEncoder.encode(parameter.getKey(), "UTF-8") + "=" + URLEncoder.encode(parameter.getValue(), "UTF-8").replace("+", "%20"); first = false; } HTTPRequest request = new HTTPRequest(); request.setURL(this.getEndpoint() + "activities/state" + queryString); HTTPResponse response = this.sendRequest(request); int status = response.getStatus(); if (status == 200) { return new State(id, response.getContentBytes(), activityId, agent, registration); } else if (status == 404) { return null; } throw new UnexpectedHTTPResponse(response); }
@Override public StatementsResultLRSResponse saveStatements(List<Statement> statements) { StatementsResultLRSResponse lrsResponse = new StatementsResultLRSResponse(); if (statements.isEmpty()) { lrsResponse.setSuccess(true); return lrsResponse; } ArrayNode rootNode = Mapper.getInstance().createArrayNode(); for (Statement statement : statements) { rootNode.add(statement.toJSONNode(getVersion())); } lrsResponse.setRequest(new HTTPRequest()); lrsResponse.getRequest().setResource("statements"); lrsResponse.getRequest().setMethod(HttpMethods.POST); lrsResponse.getRequest().setContentType("application/json"); try { lrsResponse .getRequest() .setContent(Mapper.getWriter(this.usePrettyJSON()).writeValueAsBytes(rootNode)); } catch (JsonProcessingException ex) { lrsResponse.setErrMsg("Exception: " + ex.toString()); return lrsResponse; } HTTPResponse response = makeSyncRequest(lrsResponse.getRequest()); int status = response.getStatus(); lrsResponse.setResponse(response); if (status == 200) { lrsResponse.setSuccess(true); lrsResponse.setContent(new StatementsResult()); try { Iterator it = Mapper.getInstance().readValue(response.getContent(), ArrayNode.class).elements(); for (int i = 0; it.hasNext(); ++i) { lrsResponse.getContent().getStatements().add(statements.get(i)); lrsResponse .getContent() .getStatements() .get(i) .setId(UUID.fromString(((JsonNode) it.next()).textValue())); } } catch (Exception ex) { lrsResponse.setErrMsg("Exception: " + ex.toString()); lrsResponse.setSuccess(false); } } else { lrsResponse.setSuccess(false); } return lrsResponse; }
@Override public StatementsResultLRSResponse queryStatements(StatementsQueryInterface query) { // Setup empty query object if null was passed in if (query == null) { query = (this.getVersion() == TCAPIVersion.V095) ? new com.rusticisoftware.tincan.v095.StatementsQuery() : new StatementsQuery(); } // Choke if the query parameters don't match the LRS version if (this.getVersion() != query.getVersion()) { throw new IncompatibleTCAPIVersion( "Attempted to issue " + this.getVersion() + " query using a " + query.getVersion() + " set of query parameters."); } StatementsResultLRSResponse lrsResponse = new StatementsResultLRSResponse(); lrsResponse.setRequest(new HTTPRequest()); lrsResponse.getRequest().setMethod(HttpMethods.GET); lrsResponse.getRequest().setResource("statements"); try { lrsResponse.getRequest().setQueryParams(query.toParameterMap()); } catch (IOException ex) { lrsResponse.setErrMsg("Exception: " + ex.toString()); return lrsResponse; } HTTPResponse response = makeSyncRequest(lrsResponse.getRequest()); lrsResponse.setResponse(response); if (response.getStatus() == 200) { lrsResponse.setSuccess(true); try { lrsResponse.setContent(new StatementsResult(new StringOfJSON(response.getContent()))); } catch (Exception ex) { lrsResponse.setErrMsg("Exception: " + ex.toString()); lrsResponse.setSuccess(false); } } else { lrsResponse.setSuccess(false); } return lrsResponse; }
private Statement retrieveStatement(String id, String paramName) throws Exception { HTTPRequest request = new HTTPRequest(); request.setURL(this.getEndpoint() + "statements?" + paramName + "=" + id); HTTPResponse response = this.sendRequest(request); int status = response.getStatus(); if (status == 200) { return new Statement(new StringOfJSON(response.getContent())); } else if (status == 404) { return null; } throw new UnexpectedHTTPResponse(response); }
private LRSResponse getDocument( String resource, Map<String, String> queryParams, Document document) { HTTPRequest request = new HTTPRequest(); request.setMethod(HttpMethods.GET); request.setResource(resource); request.setQueryParams(queryParams); HTTPResponse response = makeSyncRequest(request); LRSResponse lrsResponse = new LRSResponse(request, response); if (response.getStatus() == 200) { document.setContent(response.getContentBytes()); document.setContentType(response.getContentType()); document.setTimestamp(response.getLastModified()); document.setEtag(response.getEtag()); lrsResponse.setSuccess(true); } else if (response.getStatus() == 404) { lrsResponse.setSuccess(true); } else { lrsResponse.setSuccess(false); } return lrsResponse; }
@Override public StatementsResult queryStatements(StatementsQueryInterface query) throws Exception { // Setup empty query object if null was passed in if (query == null) { query = (this.getVersion() == TCAPIVersion.V095) ? new com.rusticisoftware.tincan.v095.StatementsQuery() : new StatementsQuery(); } // Choke if the query parameters don't match the LRS version if (this.getVersion() != query.getVersion()) { throw new IncompatibleTCAPIVersion( "Attempted to issue " + this.getVersion() + " query using a " + query.getVersion() + " set of query parameters."); } // Build query string HashMap<String, String> params = query.toParameterMap(); StringBuilder queryString = new StringBuilder(); Boolean first = true; for (Map.Entry<String, String> parameter : params.entrySet()) { queryString.append( (first ? "?" : "&") + URLEncoder.encode(parameter.getKey(), "UTF-8") + "=" + URLEncoder.encode(parameter.getValue(), "UTF-8").replace("+", "%20")); first = false; } HTTPRequest request = new HTTPRequest(); request.setURL(this.getEndpoint() + "statements" + queryString.toString()); HTTPResponse response = this.sendRequest(request); if (response.getStatus() == 200) { return new StatementsResult(new StringOfJSON(response.getContent())); } throw new UnexpectedHTTPResponse(response); }
private LRSResponse deleteDocument(String resource, Map<String, String> queryParams) { HTTPRequest request = new HTTPRequest(); request.setMethod(HttpMethods.DELETE); request.setResource(resource); request.setQueryParams(queryParams); HTTPResponse response = makeSyncRequest(request); LRSResponse lrsResponse = new LRSResponse(request, response); if (response.getStatus() == 204) { lrsResponse.setSuccess(true); } else { lrsResponse.setSuccess(false); } return lrsResponse; }
@Override public StatementsResultLRSResponse moreStatements(String moreURL) { if (moreURL == null) { return null; } // moreURL is relative to the endpoint's server root URL endpoint = this.getEndpoint(); String url = endpoint.getProtocol() + "://" + endpoint.getHost() + (endpoint.getPort() == -1 ? "" : ":" + endpoint.getPort()) + moreURL; HTTPRequest request = new HTTPRequest(); request.setResource(url); request.setMethod(HttpMethods.GET); HTTPResponse response = makeSyncRequest(request); StatementsResultLRSResponse lrsResponse = new StatementsResultLRSResponse(request, response); if (response.getStatus() == 200) { lrsResponse.setSuccess(true); try { lrsResponse.setContent(new StatementsResult(new StringOfJSON(response.getContent()))); } catch (Exception ex) { lrsResponse.setErrMsg("Exception: " + ex.toString()); lrsResponse.setSuccess(false); } } else { lrsResponse.setSuccess(false); } return lrsResponse; }
@Override public void saveState(State state, String activityId, Agent agent, UUID registration) throws Exception { HashMap<String, String> params = new HashMap<String, String>(); params.put("stateId", state.getId()); params.put("activityId", activityId); params.put("agent", agent.toJSON(this.getVersion(), this.usePrettyJSON())); if (registration != null) { params.put("registration", registration.toString()); } String queryString = "?"; Boolean first = true; for (Map.Entry<String, String> parameter : params.entrySet()) { queryString += (first ? "" : "&") + URLEncoder.encode(parameter.getKey(), "UTF-8") + "=" + URLEncoder.encode(parameter.getValue(), "UTF-8").replace("+", "%20"); first = false; } HTTPRequest request = new HTTPRequest(); request.setMethod(HttpMethods.PUT); request.setURL(this.getEndpoint() + "activities/state" + queryString); request.setRequestContent(new ByteArrayBuffer(state.getContents())); // TODO: need to set the 'updated' property based on header HTTPResponse response = this.sendRequest(request); int status = response.getStatus(); if (status == 204) { return; } throw new UnexpectedHTTPResponse(response); }
private HTTPResponse makeSyncRequest(HTTPRequest req) { String url; if (req.getResource().toLowerCase().startsWith("http")) { url = req.getResource(); } else { url = this.getEndpoint().toString(); if (!url.endsWith("/") && !req.getResource().startsWith("/")) { url += "/"; } url += req.getResource(); } if (req.getQueryParams() != null) { String qs = ""; for (Map.Entry entry : req.getQueryParams().entrySet()) { if (!"".equals(qs)) { qs += "&"; } try { qs += URLEncoder.encode(entry.getKey().toString(), "UTF-8") + "=" + URLEncoder.encode(entry.getValue().toString(), "UTF-8"); } catch (UnsupportedEncodingException ex) { } } if (!"".equals(qs)) { url += "?" + qs; } } // Overload some of an ContentExchange object's functions with anonymous inner functions // Access the HTTPResponse variable via a closure final HTTPResponse response = new HTTPResponse(); ContentExchange webReq = new ContentExchange() { protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException { super.onResponseStatus(version, status, reason); response.setStatus(status); response.setStatusMsg(reason.toString()); } @Override protected void onResponseHeader(Buffer name, Buffer value) throws IOException { super.onResponseHeader(name, value); response.setHeader(name.toString(), value.toString()); } @Override protected void onResponseComplete() throws IOException { super.onResponseComplete(); response.setContentBytes(this.getResponseContentBytes()); } }; webReq.setURL(url); webReq.setMethod(req.getMethod()); webReq.addRequestHeader("X-Experience-API-Version", this.getVersion().toString()); if (this.getAuth() != null) { webReq.addRequestHeader("Authorization", this.getAuth()); } if (req.getHeaders() != null) { for (Map.Entry entry : req.getHeaders().entrySet()) { webReq.addRequestHeader(entry.getKey().toString(), entry.getValue().toString()); } } if (req.getContentType() != null) { webReq.setRequestContentType(req.getContentType()); } else { webReq.setRequestContentType("application/octet-stream"); } if (req.getContent() != null) { webReq.setRequestContent(new ByteArrayBuffer(req.getContent())); } try { httpClient().send(webReq); // Waits until the exchange is terminated int exchangeState = webReq.waitForDone(); if (exchangeState != HttpExchange.STATUS_COMPLETED) { throw new FailedHTTPExchange(exchangeState); } } catch (Exception ex) { response.setStatus(400); response.setStatusMsg("Exception in RemoteLRS.makeSyncRequest(): " + ex); } return response; }