API 2.0 in wording: geautomatiseerd testen ondersteunen

svn path=/Website/trunk/; revision=21937
This commit is contained in:
Jos Groot Lipman
2014-06-18 12:48:46 +00:00
parent 65f7cab900
commit 896c7f7ab0
8 changed files with 137 additions and 19 deletions

View File

@@ -47,6 +47,7 @@ api2 = {
oRs.Close();
}
/* global */ user = new Perslid(user_key);
CheckForLogging(Request.QueryString("logging")); // Nu pas kan autorisatie via user gecontrolerd worden
// Impersonate?
var IMPERS;
@@ -85,8 +86,6 @@ api2 = {
},
process: function _process(model)
{
CheckForLogging(Request.QueryString("logging"));
Session.Codepage = 65001; // We doen *uitsluitend* utf-8
Response.Charset = 'utf-8';
@@ -140,7 +139,35 @@ api2 = {
}
var key = getQParamInt("id", -1); // Voor POST/PUT/DELETE
var result = model["REST_" + method]( { filter: api2.qs2json(), include: getQParamArray("include", []) }, jsondata, key );
if (getQParamSafe("format", "json") == "api")
{
// TODO: Onderstaande in een of ander standaardformaat opleveren?
var result = { id: model.records_name,
methods: [],
includes: [],
filters: [] };
for (var i in model.includes)
result.includes.push(i);
if ("REST_GET" in model)
result.methods.push("GET");
if ("REST_PUT" in model)
result.methods.push("PUT");
if ("REST_POST" in model)
result.methods.push("POST");
if ("REST_DELETE" in model)
result.methods.push("DELETE");
for (var i in model.fields) // TODO: Misschien beter via een (beknopt) field-object?
{ // TODO: We missen hard-coded filters als reservableequipment/allowedinroom nu nog
if (model.fields[i].filter)
result.filters.push({ id: model.fields[i].name,
filter: model.fields[i].filter,
type: model.fields[i].typ
});
}
}
else
var result = model["REST_" + method]( { filter: api2.qs2json(), include: getQParamArray("include", []) }, jsondata, key );
switch (method)
{
@@ -438,12 +465,12 @@ __Log("newval="+newval);
var inckey = incdata[j]["id"]; // Die moet er zijn
if (!inckey || inckey < 0 || params.isNew)
{
//__DoLog("Ik zou moeten inserten");
__Log("Nu ga ik een '{0}' toevoegen".format(incname));
incmodel.REST_POST(params, incdata[j], the_key);
}
else if (inckey in existing_includes)
{
//__DoLog("Ik zou '{0}' {1} moeten updaten".format(incname, inckey));
__Log("Nu ga ik '{0}' {1} updaten".format(incname, inckey));
incmodel.REST_PUT(params, incdata[j], inckey);
existing_includes[inckey].found = true;
}
@@ -613,6 +640,12 @@ __Log("newval="+newval);
switch (format)
{
case "api":
{
var str_antwoord = JSON.stringify(data, null, getQParam("pretty","0")=="1"?2:0);
Response.ContentType = "application/json";
break;
}
case "json":
var result = { };
if (single)

27
APPL/API2/api_apis.asp Normal file
View File

@@ -0,0 +1,27 @@
<%@ language = "JavaScript" %>
<% /*
$Revision$
$Id$
File: api_apis.asp
Description: META API
Parameters:
Context: Door een remote systeem (geen persoon) om info uit FACILITOR te halen aan te roepen
Notes:
*/
DOCTYPE_Disable = true;
ANONYMOUS_Allowed = 1; // Eigenlijk niet waar. We regelen echter alles zelf
THIS_FILE = "appl/api/api_apis.asp";
// Session("logging")=1;
%>
<!-- #include file="../Shared/common.inc" -->
<!-- #include file="./api2.inc" -->
<!-- #include file="../Shared/json2.js" -->
<!-- #include file="./model_apis.inc" -->
<%
api2.process(model_apis);
%>

62
APPL/API2/model_apis.inc Normal file
View File

@@ -0,0 +1,62 @@
<% /*
$Revision$
$Id$
File: model_apis.inc
Description: Api model. Dit bestand heeft niets met interfacing te maken
maar werkt uitsluitend op JSON-data
Parameters:
Context:
Notes:
*/
%>
<%
model_apis =
{
table: null,
primary: null,
records_name: "apis",
record_name: "api",
fields: [],
REST_GET: function _GET(params)
{
var autfunction = "WEB_PRSSYS"; // is dit niet erg streng?
params.authparams = user.checkAutorisation(autfunction, null, null, true); // pessimistisch
var api2_names = [];
var fullpath = Server.MapPath("./appl/api2");
var objFso = new ActiveXObject("Scripting.FileSystemObject");
var objFiles = objFso.GetFolder(fullpath);
var allFiles = new Enumerator(objFiles.files);
for (; !allFiles.atEnd(); allFiles.moveNext())
{
var attFile = allFiles.item();
var ext = objFso.GetExtensionName(attFile);
if ((attFile.name.indexOf("api_") == 0) && (ext == "asp"))
{
var name = attFile.name.substring(4, attFile.name.indexOf(".asp"))
api2_names.push({ id: name });
}
// Graag zou ik er ook info instoppen over het model zelf.
// Dan moet ik echter alle model_xxxx.inc bestanden includen wat ik niet wil.
// Daarom moet je zelf maar /api2/xxxx.api aanroepen voor de details
}
return api2_names;
},
PUT: function (params) /* update api */
{
},
POST: function (params) /* new api */
{
},
DELETE: function (params) /* delete api */
{
}
}
%>

View File

@@ -74,7 +74,7 @@ model_appointments =
+ " FROM " + query.tables.join(", ")
+ " WHERE " + query.wheres.join(" AND " )
+ " ORDER BY bez_afspraak_datum, bez_afspraak.bez_afspraak_key";
__DoLog(sql);
var json = api2.sql2json (params, sql, model_appointments );
return json;
@@ -120,7 +120,6 @@ __DoLog(sql);
wheres.push("(bez_afspraak_contact_key = " + user_key // Altijd fe vooralnog
+ " OR bez_afspraak_host_key = " + user_key + ")");
var bezUpd = buildTrackingUpdate("bez_afspraak", wheres.join(" AND " ), fields, { noValidateToken: true });
__DoLog(bezUpd.sql);
Oracle.Execute(bezUpd.sql);
var beztrack = api2.process_includes(params, model_appointments, jsondata, the_key);
@@ -148,7 +147,6 @@ __DoLog(sql);
var bezIns = buildInsert("bez_afspraak", fields, { noValidateToken: true });
var afs_key = bezIns.sequences["bez_afspraak_key"];
__DoLog(bezIns.sql);
Oracle.Execute(bezIns.sql);
var beztrack = api2.process_includes(params, model_appointments, jsondata, afs_key);
@@ -165,7 +163,6 @@ __DoLog(sql);
var sql = "DELETE FROM bez_afspraak"
+ " WHERE " + wheres.join(" AND " );
__DoLog(sql);
Oracle.Execute(sql);
// Geen tracking (mogelijk) omdat het record echt is verwijderd
}

View File

@@ -51,10 +51,10 @@ model_reservationconsumables =
// TODO: Add authorization
var query = api2.sqlfields(params, model_reservationconsumables);
query.wheres.push("res_rsv_deel_verwijder IS NULL");
query.wheres.push("res_rsv_artikel_verwijder IS NULL");
query.tables.push("res_rsv_ruimte");
query.wheres.push("res_rsv_ruimte.res_rsv_ruimte_key = res_rsv_deel.res_rsv_ruimte_key");
query.wheres.push("res_rsv_ruimte.res_rsv_ruimte_key = res_rsv_artikel.res_rsv_ruimte_key");
query.wheres.push(user_key + " IN (res_rsv_ruimte_host_key, res_rsv_ruimte_contact_key)"); // Altijd fe vooralnog
query.wheres.push("res_rsv_ruimte_van BETWEEN SYSDATE - " + S("facilitiespast_res") + " AND SYSDATE + " + S("facilitiesfuture_res"));
@@ -64,7 +64,7 @@ model_reservationconsumables =
var sql = "SELECT " + query.selects.join(", ")
+ " FROM " + query.tables.join(", ")
+ " WHERE " + query.wheres.join(" AND " )
+ " ORDER BY res_rsv_deel_key";
+ " ORDER BY res_rsv_artikel_key";
var json = api2.sql2json (params, sql, model_reservationconsumables);
return json;
},

View File

@@ -68,7 +68,7 @@ model_reservationequipment =
var json = api2.sql2json (params, sql, model_reservationequipment);
return json;
},
PUT: function (params, jsondata, the_key) /* update reservable equipment */
REST_PUT: function (params, jsondata, the_key) /* update reservable equipment */
{
var rsv_deel_key = the_key;
var fields = api2.update_fields(params, model_reservationequipment, jsondata); // Build updater
@@ -84,8 +84,7 @@ model_reservationequipment =
var oRs = Oracle.Execute(sql);
oRs.Close();
__DoLog(fields[0].val);
__Log(fields[0].val);
var resUpd = buildTrackingUpdate("res_rsv_deel", wheres.join(" AND " ), fields, { noValidateToken: true });
var check_fail_sql = " if res.dirty_level_all(" + rsv_deel_key + ") <> 0 then"
+ " raise_application_error (-20000, 'res_m999 " + L("lcl_res_fe_no_dirty") + "');"
@@ -96,7 +95,6 @@ model_reservationequipment =
+ " res.set_delen_clean (" + rsv_deel_key + "); " //Anderen clean geworden?
+ check_fail_sql
+ "END;";
__DoLog(sql);
var err = Oracle.Execute(sql, true);
if (err.friendlyMsg)
abort_with_warning(err.friendlyMsg);
@@ -114,6 +112,7 @@ model_reservationequipment =
_analyze_fields: function (fields, params, jsondata) /* analyseer inkomende data, common voor PUT en POST */
/* res_ruimte+config wordt bijvoorbeeld omgezet in res_ruimte_opstel_key */
{
__Logj("data="+jsondata.reservationequipment);
if ("reservation" in jsondata.reservationequipment)
{
// De reservering moet bestaan.
@@ -140,7 +139,7 @@ model_reservationequipment =
+ " WHERE res_deel_key = " + res_deel_key;
var oRs = Oracle.Execute(sql);
if (oRs.eof)
api2.error(500, "Unknown equipment in input";
api2.error(500, "Unknown equipment in input");
oRs.Close();
}
else // moet er een res_deel zijn

View File

@@ -14,10 +14,10 @@ RewriteHeader FCLT-REWRITER ^$ 1.00
RewriteBase ON
# /api2/buildings/1234.xml?apikey=apikey123 /default.asp?api2=buildings&format=xml&id=1234&apikey=apikey123
RewriteRule ^/api2/([a-z]+)/(\d+)\.(xml|json|html)/? /default.asp?api2=$1&format=$3&id=$2 [QSA]
RewriteRule ^/api2/([a-z]+)/(\d+)\.(xml|json|html|api)/? /default.asp?api2=$1&format=$3&id=$2 [QSA]
# /api2/buildings.xml?apikey=apikey123 /default.asp?api2=buildings&format=xml&apikey=apikey123
RewriteRule ^/api2/([a-z]+)\.(xml|json|html)/? /default.asp?api2=$1&format=$2 [QSA]
RewriteRule ^/api2/([a-z]+)\.(xml|json|html|api)/? /default.asp?api2=$1&format=$2 [QSA]
# /melding/1234 /appl/mld/mld_melding.asp?mld_key=1234
# Geeft relatieve pad problemen