#include <glite/jp/context.h>
#include "conf.h"
#include "db_ops.h"
+#include "ws_is_typeref.h"
+#include <stdsoap2.h>
+#include "soap_version.h"
+#include "jpis_H.h"
-static const char *get_opt_string = "s:dq:c:k:C:V:nm:p:i:o:";
+extern SOAP_NMAC struct Namespace jpis__namespaces[];
+
+static const char *get_opt_string = "dq:c:k:C:V:nm:p:i:o:x:";
static struct option opts[] = {
- {"is-server", 1, NULL, 's'},
{"debug", 0, NULL, 'd'},
{"query-type", 1, NULL, 'q'},
{"cert", 1, NULL, 'c'},
{"port", 1, NULL, 'p'},
{"pidfile", 1, NULL, 'i'},
{"logfile", 1, NULL, 'o'},
+ {"config", 1, NULL, 'x'},
{NULL, 0, NULL, 0}
};
-
+static int read_conf(glite_jp_is_conf *conf, char *conf_file);
+static int dump_conf(void);
static void usage(char *me)
{
fprintf(stderr,"usage: %s [option]\n"
- "\t-s, --ps-server\t primary storage server address (http://hostname:port)\n"
"\t-d, --debug\t don't run as daemon, additional diagnostics\n"
"\t-q, --query-type hist/cont/both (default history)\n"
"\t-k, --key\t private key file\n"
"\t-p, --port\t port to listen\n"
"\t-i, --pidfile\t file to store master pid\n"
"\t-o, --logfile\t file to store logs\n"
+ "\t-x, --config\t file with server configuration\n"
"\n"
,me);
}
int glite_jp_get_conf(int argc, char **argv, char *config_file, glite_jp_is_conf **configuration)
{
- char *env, *ps = NULL, *qt = NULL;;
+ char *ps = NULL, *qt = NULL, *conf_file = NULL;
int opt;
glite_jp_is_conf *conf;
while ((opt = getopt_long(argc,argv,get_opt_string,opts,NULL)) != EOF) switch (opt) {
- case 's': ps = optarg; break;
case 'd': conf->debug = 1; break;
case 'q': qt = optarg; break;
case 'c': conf->server_cert = optarg; break;
case 'p': conf->port = optarg; break;
case 'i': conf->pidfile = optarg; break;
case 'o': conf->logfile = optarg; break;
+ case 'x': conf_file = optarg; break;
default : usage(argv[0]); exit(0); break;
}
- if (!ps) {
- fprintf(stderr,"No JP PrimaryStrorage server specified, default feeds skipped. (not fatal)\n");
- }
if (!conf->cs) {
fprintf(stderr,"DB contact string not specified! "\
"Using build-in default: %s \n", GLITE_JP_IS_DEFAULTCS);
"Using build-in default: %s \n", GLITE_JPIS_DEFAULT_PORT_STR);
}
- // prefixes & attributes defined in:
- // lb.server/build/jp_job_attrs.h (created when build plugin)
- // jp.common/interface/known_attr.h
-
- conf->attrs = calloc(19, sizeof(*conf->attrs));
- conf->attrs[0] = strdup("http://egee.cesnet.cz/en/Schema/JP/System:owner");
- conf->attrs[1] = strdup("http://egee.cesnet.cz/en/Schema/JP/System:jobId");
- conf->attrs[2] = strdup("http://egee.cesnet.cz/en/Schema/JP/System:regtime");
- conf->attrs[3] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:user");
- conf->attrs[4] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:aTag");
- conf->attrs[5] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:eNodes");
- conf->attrs[6] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:RB");
- conf->attrs[7] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:CE");
- conf->attrs[8] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:UIHost");
- conf->attrs[9] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:CPUTime");
- conf->attrs[10] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:NProc");
- conf->attrs[11] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus");
- conf->attrs[12] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusDate");
- conf->attrs[13] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:retryCount");
- conf->attrs[14] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:jobType");
- conf->attrs[15] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:nsubjobs");
- conf->attrs[16] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:lastStatusHistory");
- conf->attrs[17] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:fullStatusHistory");
-
- conf->indexed_attrs = calloc(8, sizeof(*conf->indexed_attrs));
- conf->indexed_attrs[0] = strdup("http://egee.cesnet.cz/en/Schema/JP/System:owner");
- conf->indexed_attrs[1] = strdup("http://egee.cesnet.cz/en/Schema/JP/System:jobId");
- conf->indexed_attrs[2] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:user");
- conf->indexed_attrs[3] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus");
- conf->indexed_attrs[4] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:UIHost");
- conf->indexed_attrs[5] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:CE");
- conf->indexed_attrs[6] = strdup("http://egee.cesnet.cz/en/Schema/LB/Attributes:RB");
-
- // XXX: some plugin names should come here in future
- conf->plugins = NULL;
-
- if (!ps) {
- // No JP PrimaryStrorage server specified in $GLITE_JPIS_PS -> skip feeds
- conf->feeds = calloc(1, sizeof(*(conf->feeds)));
- *configuration = conf;
- return 0;
- }
-
- /* ask for one feed */
- conf->feeds = calloc(2, sizeof(*(conf->feeds)));
-
- conf->feeds[0] = calloc(1, sizeof(**(conf->feeds)));
- conf->feeds[0]->PS_URL = strdup(ps);
-
- // all job since Epoche
- conf->feeds[0]->query = calloc(2,sizeof(*conf->feeds[0]->query));
- conf->feeds[0]->query[0] = calloc(2,sizeof(**conf->feeds[0]->query));
- conf->feeds[0]->query[0][0].attr = strdup("http://egee.cesnet.cz/en/Schema/JP/System:regtime");
- conf->feeds[0]->query[0][0].op = GLITE_JP_QUERYOP_GREATER;
- conf->feeds[0]->query[0][0].value = strdup("0");
-
- if (qt && !strcmp(qt,"both")) {
- conf->feeds[0]->history = 1;
- conf->feeds[0]->continuous = 1;
- }
- else if ( qt && (!strcmp(qt,"continuous") || !strcmp(qt,"cont")) ) {
- conf->feeds[0]->history = 0;
- conf->feeds[0]->continuous = 1;
- }
- else if ( qt && (!strcmp(qt,"history") || !strcmp(qt,"hist")) ) {
- conf->feeds[0]->history = 1;
- conf->feeds[0]->continuous = 0;
+ if (!conf_file) {
+ fprintf(stderr,"JP IS configuration file must be specified! "\
+ "Exiting.\n");
+ return 1;
}
else {
- usage(argv[0]);
- exit(0);
+ read_conf(conf, conf_file);
}
- conf->feeds[1] = NULL;
-
*configuration = conf;
return 0;
vprintf(fmt, ap);
va_end(ap);
}
+
+/*
+ * Reads configuration from XML conf. file
+ */
+static int read_conf(glite_jp_is_conf *conf, char *conf_file)
+{
+ struct soap soap;
+ struct _jpelem__ServerConfigurationResponse out;
+ int fd, i;
+
+
+ if ((fd = open(conf_file, 0)) < 0) {
+ fprintf(stderr, "error opening %s: %s\n", conf_file, strerror(errno));
+ return 1;
+ }
+
+ soap_init(&soap);
+ soap_set_namespaces(&soap, jpis__namespaces);
+
+ soap_begin(&soap);
+ soap.recvfd = fd;
+ soap_begin_recv(&soap);
+ memset(&out, 0, sizeof(out));
+
+ if (!soap_get__jpelem__ServerConfigurationResponse(&soap, &out, "ServerConfiguration", NULL)) {
+ soap_end_recv(&soap);
+ soap_end(&soap);
+ return EINVAL;
+ }
+ soap_end_recv(&soap);
+
+ if (out.__sizeattrs) {
+ conf->attrs = calloc(out.__sizeattrs + 1, sizeof(*conf->attrs));
+ for (i=0; i < out.__sizeattrs; i++) {
+ conf->attrs[i] = strdup(out.attrs[i]);
+ }
+ }
+ if (out.__sizeindexedAttrs) {
+ conf->indexed_attrs = calloc(out.__sizeindexedAttrs + 1, sizeof(*conf->indexed_attrs));
+ for (i=0; i < out.__sizeindexedAttrs; i++) {
+ conf->indexed_attrs[i] = strdup(out.indexedAttrs[i]);
+ }
+ }
+ if (out.__sizeplugins) {
+ conf->plugins = calloc(out.__sizeplugins + 1, sizeof(*conf->plugins));
+ for (i=0; i < out.__sizeplugins; i++) {
+ conf->plugins[i] = strdup(out.plugins[i]);
+ }
+ }
+ if (out.__sizefeeds) {
+ conf->feeds = calloc(out.__sizefeeds + 1, sizeof(*conf->feeds));
+ for (i=0; i < out.__sizefeeds; i++) {
+ conf->feeds[i] = calloc(1, sizeof(*conf->feeds[i]));
+ conf->feeds[i]->PS_URL=strdup(out.feeds[i]->primaryServer);
+
+ if (out.feeds[i]->__sizecondition) {
+ glite_jpis_SoapToPrimaryQueryConds(&soap, out.feeds[i]->__sizecondition,
+ out.feeds[i]->condition, &conf->feeds[i]->query);
+ }
+
+ conf->feeds[i]->history = out.feeds[0]->history;
+ conf->feeds[i]->continuous = out.feeds[0]->continuous;
+ }
+ }
+
+ soap_destroy(&soap);
+ soap_end(&soap);
+ soap_done(&soap);
+
+ return 0;
+}
+
+/*
+ * Just helper function - used only once for first generation
+ * of XML example configuration (which was then reedited in hand)
+ */
+static int dump_conf(void) {
+ int retval;
+ struct _jpelem__ServerConfigurationResponse out;
+ struct soap soap;
+
+
+ soap_init(&soap);
+ soap_set_namespaces(&soap, jpis__namespaces);
+
+ soap.sendfd = STDOUT_FILENO;
+ soap_begin_send(&soap);
+ soap_default__jpelem__ServerConfigurationResponse(&soap, &out);
+
+ out.__sizeattrs = 2;
+ out.attrs = calloc(2, sizeof(*out.attrs));
+ out.attrs[0] = strdup("atrr1");
+ out.attrs[1] = strdup("atrr2");
+
+ out.__sizeindexedAttrs = 2;
+ out.indexedAttrs = calloc(2, sizeof(*out.indexedAttrs));
+ out.indexedAttrs[0] = strdup("idxAtrr1");
+ out.indexedAttrs[1] = strdup("idxAtrr2");
+
+ out.__sizeplugins = 2;
+ out.plugins = calloc(2, sizeof(*out.plugins));
+ out.plugins[0] = strdup("plugin1");
+ out.plugins[1] = strdup("plugin2");
+
+ out.__sizefeeds = 1;
+ out.feeds = calloc(1, sizeof(*out.feeds));
+ out.feeds[0] = calloc(1, sizeof(*out.feeds[0]));
+ out.feeds[0]->primaryServer = strdup("PrimaryServer");
+ out.feeds[0]->__sizecondition = 1;
+ out.feeds[0]->condition = calloc(1, sizeof(*(out.feeds[0]->condition)) );
+ out.feeds[0]->condition[0] = calloc(1, sizeof(*(out.feeds[0]->condition[0])) );
+ out.feeds[0]->condition[0]->attr = strdup("queryAttr");
+ out.feeds[0]->condition[0]->op = jptype__queryOp__EQUAL;
+ out.feeds[0]->condition[0]->origin = jptype__attrOrig__SYSTEM;
+ out.feeds[0]->condition[0]->value = calloc(1, sizeof(*(out.feeds[0]->condition[0]->value)) );
+ out.feeds[0]->condition[0]->value->string = strdup("attrValue");
+ out.feeds[0]->history = 1;
+ out.feeds[0]->continuous = 0;
+
+ soap_serialize__jpelem__ServerConfigurationResponse(&soap, &out);
+ retval = soap_put__jpelem__ServerConfigurationResponse(&soap, &out, "jpelem:ServerConfiguration", NULL);
+ soap_end_send(&soap);
+ soap_free(&soap);
+ soap_end(&soap);
+
+ return retval;
+}
+
assert(in); assert(out);
- qr = calloc(in->__sizerecord, sizeof(*qr));
+ qr = calloc(in->__sizerecord + 1, sizeof(*qr));
for (i=0; i < in->__sizerecord; i++) {
qr[i].attr = strdup(in->attr);
}
/**
- * Translate JP query conditions from soap to C query_rec
+ * Translate JP index query conditions from soap to C query_rec
*
* \param IN Soap structure
* \param OUT array of glite_jp_query_rec_t query records
return 0;
}
+
+
+static int SoapToPrimaryQueryCond(
+ struct soap *soap,
+ struct jptype__primaryQuery *in,
+ glite_jp_query_rec_t **out)
+{
+ glite_jp_query_rec_t *qr;
+ int i;
+
+
+ assert(in); assert(out);
+ qr = calloc(2, sizeof(*qr));
+
+ qr[0].attr = strdup(in->attr);
+ glite_jpis_SoapToQueryOp(in->op, &(qr[0].op));
+
+ switch (qr[0].op) {
+ case GLITE_JP_QUERYOP_EXISTS:
+ break;
+
+ case GLITE_JP_QUERYOP_WITHIN:
+ SoapToQueryRecordVal(soap, in->value2, &(qr[0].binary),
+ &(qr[0].size2), &(qr[0].value2));
+ // fall through
+ default:
+ if ( SoapToQueryRecordVal(soap, in->value, &(qr[0].binary),
+ &(qr[0].size), &(qr[0].value)) ) {
+ *out = NULL;
+ return 1;
+ }
+ break;
+ }
+
+ glite_jpis_SoapToAttrOrig(soap, in->origin, &(qr[0].origin) );
+
+ *out = qr;
+
+ return 0;
+}
+
+
+
+/**
+ * Translate JP primary query conditions from soap to C query_rec
+ *
+ * \param IN Soap structure
+ * \param OUT array of glite_jp_query_rec_t query records
+ */
+int glite_jpis_SoapToPrimaryQueryConds(
+ struct soap *soap,
+ int size,
+ struct jptype__primaryQuery **in,
+ glite_jp_query_rec_t ***out)
+{
+ glite_jp_query_rec_t **qr;
+ int i;
+
+ assert(in); assert(out);
+ qr = calloc(size+1, sizeof(*qr));
+
+ for (i=0; i<size; i++) {
+ if ( SoapToPrimaryQueryCond(soap, in[i], &(qr[i])) ) {
+ *out = NULL;
+ return 1;
+ }
+ }
+
+ *out = qr;
+
+ return 0;
+}