1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-08 04:58:40 +03:00

r20538: Web Application Framework

- correct an error message in the JSON-RPC server

- provide a common RPC request function

- make it easier to have multiple pending RPC requests.  this allows an
  application-specified request to return "not logged in"; authentication
  information to be requested and sent; and the original request to be
  reissued.

- in statistics module, if a time is provided as zero, leave it blank rather
  than displaying 1 Jan 1970.  this showed up in the last_used_at field in the
  SMB status report.

- clean up makefile: remove no-longer-used hard-coded path and install target;
  remove "chmod" and "nice" commands which were part of the original skeleton,
  since that is not deemed appropriate for samba makefiles
(This used to be commit 339ee73ce2809905f608b1003cc645231f256420)
This commit is contained in:
Derrell Lipman 2007-01-05 04:33:38 +00:00 committed by Gerald (Jerry) Carter
parent 02db88bb88
commit 9698b2c282
6 changed files with 175 additions and 93 deletions

View File

@ -450,7 +450,7 @@ if (valid)
if (! valid)
{
error.setError(jsonrpc.Constant.ErrorCode.MethodNotFound,
"Method `" + method + "` not found.");
"Method `" + jsonInput.method + "` not found.");
error.Send();
return;
}

View File

@ -10,7 +10,6 @@ OPTIMIZESTRINGS = false
OPTIMIZEVARIABLES = false
SOURCELOADER=
NICE=10
LOCALINSTALLDIR = /usr/local/samba/share/swat/apps/swat
###################################################################################
@ -116,7 +115,7 @@ distclean: realclean
###################################################################################
generate-script-source:
@chmod u+x $(GENERATOR) && nice -n $(NICE) $(GENERATOR) \
@$(GENERATOR) \
--script-input $(FRAMEWORK)/source/class \
--source-script-path ../$(FRAMEWORK)/source/class \
--script-input $(API)/source/class \
@ -136,7 +135,7 @@ generate-script-source:
# --resource-output defined for one set, it must be defined for each set
#
generate-script-build:
@chmod u+x $(GENERATOR) && nice -n $(NICE) $(GENERATOR) \
@$(GENERATOR) \
--script-input $(FRAMEWORK)/source/class \
--resource-input $(FRAMEWORK)/source/resource \
--resource-output build/resource \
@ -155,7 +154,7 @@ generate-script-build:
--add-new-lines
generate-api-build:
@chmod u+x $(GENERATOR) && nice -n $(NICE) $(GENERATOR) \
@$(GENERATOR) \
--script-input $(FRAMEWORK)/source/class \
--resource-input $(FRAMEWORK)/source/resource \
--resource-output api/resource/qooxdoo \
@ -172,7 +171,7 @@ generate-api-build:
--cache-directory $(CACHE)
generate-api-data:
@chmod u+x $(GENERATOR) && nice -n $(NICE) $(GENERATOR) \
@$(GENERATOR) \
--script-input $(FRAMEWORK)/source/class \
--script-input $(API)/source/class \
--script-input source/class \
@ -181,7 +180,7 @@ generate-api-data:
--cache-directory $(CACHE)
generate-pretty:
@chmod u+x $(GENERATOR) && nice -n $(NICE) $(GENERATOR) \
@$(GENERATOR) \
--script-input source/class \
--script-input $(FRAMEWORK)/source/class \
--include-without-dependencies api.* \
@ -189,7 +188,7 @@ generate-pretty:
--cache-directory $(CACHE)
generate-fix:
@chmod u+x $(GENERATOR) && nice -n $(NICE) $(GENERATOR) \
@$(GENERATOR) \
--script-input source/class \
--script-input $(FRAMEWORK)/source/class \
--include-without-dependencies api.* \
@ -234,14 +233,3 @@ info-source:
@echo "****************************************************************************"
@echo " GENERATING SWAT WEB APPLICATION SOURCE"
@echo "****************************************************************************"
###################################################################################
# INSTALL TARGETS (for developer use only)
###################################################################################
install:
@echo "****************************************************************************"
@echo " INSTALLING SWAT"
@echo "****************************************************************************"
@echo " * Installing swat files..."
@rsync -av --exclude=crystalsvg --delete build/ $(LOCALINSTALLDIR)

View File

@ -14,6 +14,9 @@
qx.OO.defineClass("swat.module.AbstractModuleFsm", qx.core.Object, function()
{
qx.core.Object.call(this);
// Create an array for pushing request objects
this._requests = [ ];
});
@ -26,6 +29,7 @@ qx.Proto.buildFsm = function(module)
qx.Proto.addAwaitRpcResultState = function(module)
{
var fsm = module.fsm;
var _this = this;
/*
* State: AwaitRpcResult
@ -107,7 +111,7 @@ qx.Proto.addAwaitRpcResultState = function(module)
"onentry" :
function(fsm, state)
{
// If we're coming from some other start...
// If we're coming from some other state...
if (fsm.getPreviousState() != "State_AwaitRpcResult")
{
// ... then push the previous state onto the state stack
@ -147,7 +151,7 @@ qx.Proto.addAwaitRpcResultState = function(module)
function(fsm, event)
{
// Get the request object
var request = fsm.getObject("swat.module.fsmUtils.request");
var request = _this.getCurrentRpcRequest();
// Issue an abort for the pending request
request.abort();
@ -170,7 +174,7 @@ qx.Proto.addAwaitRpcResultState = function(module)
function(fsm, event)
{
// Get the request object
var request = fsm.getObject("swat.module.fsmUtils.request");
var request = _this.getCurrentRpcRequest();
// Generate the result for a completed request
request.setUserData("result",
@ -197,7 +201,7 @@ qx.Proto.addAwaitRpcResultState = function(module)
function(fsm, event)
{
// Get the request object
var request = fsm.getObject("swat.module.fsmUtils.request");
var request = _this.getCurrentRpcRequest();
// Generate the result for a completed request
request.setUserData("result",
@ -209,3 +213,111 @@ qx.Proto.addAwaitRpcResultState = function(module)
});
state.addTransition(trans);
};
/**
* Issue a remote procedure call.
*
* @param fsm {qx.util.fsm.FiniteStateMachine}
* The finite state machine issuing this remote procedure call.
*
* @param service {String}
* The name of the remote service which provides the specified method.
*
* @param method {String}
* The name of the method within the specified service.
*
* @param params {Array}
* The parameters to be passed to the specified method.
*
* @return {qx.io.remote.Request}
* The request object for the just-issued RPC request.
*/
qx.Proto.callRpc = function(fsm, service, method, params)
{
// Create an object to hold a copy of the parameters. (We need a
// qx.core.Object() to be able to store this in the finite state machine.)
var o = new qx.core.Object();
// copy the parameters; we'll prefix our copy with additional params
o.allParams = params.slice(0);
// prepend the method
o.allParams.unshift(method);
// prepend the flag indicating to coalesce failure events
o.allParams.unshift(true);
// prepend the service name
o.allParams.unshift(service);
// Save the complete parameter list in case authentication fails and we need
// to reissue the request.
fsm.addObject("swat.module.rpc_params", o);
// Retrieve the RPC object */
var rpc = fsm.getObject("swat.module.rpc");
// Set the service name
rpc.setServiceName(o.allParams[0]);
// Issue the request, skipping the already-specified service name
var request =
qx.io.remote.Rpc.prototype.callAsyncListeners.apply(rpc,
o.allParams.slice(1));
// Make the request object available to the AwaitRpcResult state
this.pushRpcRequest(request);
// Give 'em what they came for
return request;
};
/**
* Push an RPC request onto the request stack.
*
* @param request {qx.io.remote.Request}
* The just-issued request
*/
qx.Proto.pushRpcRequest = function(request)
{
this._requests.push(request);
};
/**
* Retrieve the most recent RPC request from the request stack and pop the
* stack.
*
* @return {qx.io.remote.Request}
* The request from the top of the request stack
*/
qx.Proto.popRpcRequest = function()
{
if (this._requests.length == 0)
{
throw new Error("Attempt to pop an RPC request when list is empty.");
}
var request = this._requests.pop();
return request;
};
/**
* Retrieve the most recent RPC request.
*
* @return {qx.io.remote.Request}
* The request at the top of the request stack
*/
qx.Proto.getCurrentRpcRequest = function()
{
if (this._requests.length == 0)
{
throw new Error("Attempt to retrieve an RPC request when list is empty.");
}
return this._requests[this._requests.length - 1];
};

View File

@ -20,6 +20,7 @@ function()
qx.Proto.buildFsm = function(module)
{
var fsm = module.fsm;
var _this = this;
/*
* State: Idle
@ -42,10 +43,7 @@ qx.Proto.buildFsm = function(module)
if (fsm.getPreviousState() == "State_AwaitRpcResult")
{
// Yup. Display the result. We need to get the request object
var request = fsm.getObject("swat.module.fsmUtils.request");
// We don't need the request object to be saved any more
fsm.removeObject("swat.module.fsmUtils.request");
var request = _this.popRpcRequest();
// Display the result
var gui = swat.module.ldbbrowse.Gui.getInstance();
@ -107,9 +105,6 @@ qx.Proto.buildFsm = function(module)
"ontransition" :
function(fsm, event)
{
// Obtain the RPC object
var rpc = fsm.getObject("swat.module.rpc");
// Get our module descriptor
var module = fsm.getObject("swat.module.module");
@ -128,21 +123,21 @@ qx.Proto.buildFsm = function(module)
// We want all attributes
var attributes = [ "*" ];
rpc.setServiceName("samba.ldb");
var request = rpc.callAsyncListeners(true, // coalesce failure events
"search",
dbHandle,
searchExpr,
baseDN,
scope,
attributes);
// Issue a Search call
var request = _this.callRpc(fsm,
"samba.ldb",
"search",
[
dbHandle,
searchExpr,
baseDN,
scope,
attributes
]);
// When we get the result, we'll need to know what type of request
// we made.
request.setUserData("requestType", "find");
// Save the request object
fsm.addObject("swat.module.fsmUtils.request", request);
}
});
state.addTransition(trans);
@ -207,23 +202,23 @@ qx.Proto.buildFsm = function(module)
// Build the search expression
var searchExpr = "(objectclass=*)";
// Obtain the RPC object
var rpc = fsm.getObject("swat.module.rpc");
// Get our module descriptor
var module = fsm.getObject("swat.module.module");
// Retrieve the database handle
var dbHandle = module.dbHandle;
rpc.setServiceName("samba.ldb");
var request = rpc.callAsyncListeners(true, // coalesce failure events
"search",
dbHandle,
searchExpr,
baseDN,
scope,
attributes);
// Issue a Get Statistics call
var request = _this.callRpc(fsm,
"samba.ldb",
"search",
[
dbHandle,
searchExpr,
baseDN,
scope,
attributes
]);
// When we get the result, we'll need to know what type of request
// we made.
@ -232,9 +227,6 @@ qx.Proto.buildFsm = function(module)
// We'll also need some of our parameters
request.setUserData("parent", parent);
request.setUserData("attributes", attributes);
// Save the request object
fsm.addObject("swat.module.fsmUtils.request", request);
}
});
state.addTransition(trans);
@ -306,30 +298,27 @@ qx.Proto.buildFsm = function(module)
// Build the search expression
var searchExpr = "(objectclass=*)";
// Obtain the RPC object
var rpc = fsm.getObject("swat.module.rpc");
// Get our module descriptor
var module = fsm.getObject("swat.module.module");
// Retrieve the database handle
var dbHandle = module.dbHandle;
rpc.setServiceName("samba.ldb");
var request = rpc.callAsyncListeners(true, // coalesce failure events
"search",
dbHandle,
searchExpr,
baseDN,
scope,
attributes);
// Issue a Get Statistics call
var request = _this.callRpc(fsm,
"samba.ldb",
"search",
[
dbHandle,
searchExpr,
baseDN,
scope,
attributes
]);
// When we get the result, we'll need to know what type of request
// we made.
request.setUserData("requestType", "tree_selection_changed");
// Save the request object
fsm.addObject("swat.module.fsmUtils.request", request);
}
});
state.addTransition(trans);
@ -351,23 +340,18 @@ qx.Proto.buildFsm = function(module)
"ontransition" :
function(fsm, event)
{
// Obtain the RPC object
var rpc = fsm.getObject("swat.module.rpc");
// Obtain the name of the database to be connected to
var dbName = fsm.getObject("dbName").getValue();
rpc.setServiceName("samba.ldb");
var request = rpc.callAsyncListeners(true, // coalesce failure events
"connect",
dbName);
// Issue a Get Statistics call
var request = _this.callRpc(fsm,
"samba.ldb",
"connect",
[ dbName ]);
// When we get the result, we'll need to know what type of request
// we made.
request.setUserData("requestType", "database_name_changed");
// Save the request object
fsm.addObject("swat.module.fsmUtils.request", request);
}
});
state.addTransition(trans);

View File

@ -45,7 +45,7 @@ qx.Class._stopTimer = function(fsm)
qx.Proto.buildFsm = function(module)
{
var fsm = module.fsm;
var thisClass = this;
var _this = this;
/*
* State: Idle
@ -67,10 +67,7 @@ qx.Proto.buildFsm = function(module)
if (fsm.getPreviousState() == "State_AwaitRpcResult")
{
// Yup. Display the result. We need to get the request object
var request = fsm.getObject("swat.module.fsmUtils.request");
// We don't need the request object to be saved any more
fsm.removeObject("swat.module.fsmUtils.request");
var request = _this.popRpcRequest();
// Display the result
var gui = swat.module.statistics.Gui.getInstance();
@ -141,15 +138,11 @@ qx.Proto.buildFsm = function(module)
"ontransition" :
function(fsm, event)
{
var rpc = fsm.getObject("swat.module.rpc");
rpc.setServiceName("samba.management");
var request = rpc.callAsyncListeners(true, // coalesce failure events
"get_statistics",
true,
true);
// Make the request object available to the AwaitRpcResult state
fsm.addObject("swat.module.fsmUtils.request", request);
// Issue a Get Statistics call
_this.callRpc(fsm,
"samba.management",
"get_statistics",
[ true, true ]);
}
});
state.addTransition(trans);

View File

@ -366,6 +366,11 @@ qx.Proto.displayData = function(module, result)
// Create a function for formatting dates
var dateFormat = function(unixepoch)
{
if (unixepoch == 0)
{
return "";
}
var d = new Date(unixepoch * 1000);
return (d.getFullYear() + "-" +
("0" + (d.getMonth() + 1)).substr(-2) + "-" +