daemon:=glite-jp-indexd
examples:=glite-jpis-test glite-jpis-client
test:=run-test.sh
-test_files:=dump1.sql simple_query.in simple_query.out complex_query.in complex_query.out authz.out jobid_query.in jobid_query.out origin_query.in origin_query.out exists_query.in exists_query.out
+test_files:=dump1.sql simple_query.in simple_query.out complex_query.in complex_query.out authz.out jobid_query.in jobid_query.out origin_query.in origin_query.out exists_query.in exists_query.out within_query.in within_query.out
MANS1:=glite-jpis-client.1
MANS8:=glite-jp-indexd.8
${INSTALL} -m 755 ${top_srcdir}/config/startup ${PREFIX}/etc/init.d/glite-jp-indexd
${INSTALL} -m 755 ${top_srcdir}/config/glite-jp-index-dbsetup.sql ${PREFIX}/etc
${INSTALL} -m 755 ${top_srcdir}/config/glite-jpis-config.xml ${PREFIX}/etc
+ ${INSTALL} -m 755 ${top_srcdir}/config/glite-jpis-test-config.xml ${PREFIX}/etc
${INSTALL} -m 644 ${top_srcdir}/doc/README ${HTMLS} ${PREFIX}/share/doc/${package}-${version}
${INSTALL} -m 644 ${MANS1} ${PREFIX}/share/man/man1
${INSTALL} -m 644 ${MANS8} ${PREFIX}/share/man/man8
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<jpelem:ServerConfiguration xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jptype="http://glite.org/wsdl/types/jp" xmlns:jpsrv="http://glite.org/wsdl/services/jp" xmlns:jpelem="http://glite.org/wsdl/elements/jp">
+
+ <!-- List of attributes IS want to receive from PS's -->
+ <attrs>http://egee.cesnet.cz/en/Schema/JP/System:owner</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/JP/System:jobId</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/JP/System:regtime</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:user</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:aTag</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:eNodes</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:RB</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:CE</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:UIHost</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:CPUTime</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:NProc</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusDate</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:retryCount</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:jobType</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:nsubjobs</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:lastStatusHistory</attrs>
+ <attrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:fullStatusHistory</attrs>
+
+
+ <!-- List of attributes IS will index -->
+ <indexedAttrs>http://egee.cesnet.cz/en/Schema/JP/System:owner</indexedAttrs>
+ <indexedAttrs>http://egee.cesnet.cz/en/Schema/JP/System:jobId</indexedAttrs>
+ <indexedAttrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:user</indexedAttrs>
+ <indexedAttrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:CE</indexedAttrs>
+ <indexedAttrs>http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus</indexedAttrs>
+
+ <!-- List of type plugins -->
+ <plugins></plugins>
+</jpelem:ServerConfiguration>
{jptype__queryOp__UNEQUAL, "<>"},
{jptype__queryOp__LESS, "<"},
{jptype__queryOp__GREATER, ">"},
- {jptype__queryOp__WITHIN, "in"},
- {jptype__queryOp__EXISTS, "exists"},
+ {jptype__queryOp__WITHIN, "WITHIN"},
+ {jptype__queryOp__EXISTS, "EXISTS"},
{0, "unknown"}
};
}
if (rec->value2) {
if (!rec->value) fprintf(out, "-");
- fprintf(out, " ");
+ fprintf(out, " AND ");
value_print(out, rec->value2);
}
fprintf(out, "\n");
Conditions:
http://egee.cesnet.cz/en/Schema/LB/Attributes:CE
origin IS ANY
- value exists
+ value EXISTS
Attributes:
http://egee.cesnet.cz/en/Schema/JP/System:owner
http://egee.cesnet.cz/en/Schema/JP/System:jobId
# requires running mysql
#
+LC_ALL=C
+
usage() {
cat <<EOF
GLITE_HOST_KEY..................path to host key
GLITE_JPIS_TEST_PIDFILE.........pidfile (default \`pwd\`/glite-jp-indexd.pid)
GLITE_JPIS_TEST_LOGFILE.........logfile (default \`pwd\`/glite-jp-indexd.log)
+ GLITE_JPIS_TEST_CONFIG..........config file (default \$GLITE_LOCATION/etc/
+ glite-jpis-test-config.xml)
GLITE_JPIS_TEST_PORT............index server port
GLITE_JPIS_TEST_DB..............connection string
(default jpis/@localhost:jpis1test,
GLITE_JPIS_TEST_PORT=${GLITE_JPIS_TEST_PORT:-"10000"}
GLITE_JPIS_TEST_PIDFILE=${GLITE_JPIS_TEST_PIDFILE:-"/tmp/glite-jp-indexd.pid"}
GLITE_JPIS_TEST_LOGFILE=${GLITE_JPIS_TEST_LOGFILE:-"/tmp/glite-jp-indexd.log"}
- GLITE_JPIS_TEST_CONFIG=${GLITE_JPIS_TEST_CONFIG:-"$GLITE_LOCATION/etc/glite-jpis-config.xml"}
+ GLITE_JPIS_TEST_CONFIG=${GLITE_JPIS_TEST_CONFIG:-"$GLITE_LOCATION/etc/glite-jpis-test-config.xml"}
if [ -z "$GLITE_JPIS_TEST_DB" ]; then
GLITE_JPIS_TEST_DB="jpis/@localhost:jpis1test"
import_db() {
# import database
echo -n "D"
- # delay (if JP IS downloads something...)
- sleep 1
cat $1 | sed "s/jpis1test/$DB_NAME/" | mysql -u $DB_USER -h $DB_HOST
if [ x"$?" != x"0" ]; then
echo "FAILED to import database."
drop_db;
exit 1
fi
- if [ ! -s "${GLITE_JPIS_TEST_PIDFILE}" ]; then
- sleep 1
- fi
+ i=0
+ while [ ! -s "${GLITE_JPIS_TEST_PIDFILE}" -a $i -lt 20 ]; do
+ sleep 0.1
+ i=$(($i+1))
+ done
if [ ! -s "${GLITE_JPIS_TEST_PIDFILE}" ]; then
echo "Can't startup index server."
+ kill_is;
drop_db;
exit 1
fi
ret=1
i=0
while [ x"$ret" != x"0" -a $i -lt 20 ]; do
- LC_ALL=C netstat -tap 2>/dev/null | grep "\<$GLITE_JPIS_TEST_PORT\>" > /dev/null
+ netstat -tap 2>/dev/null | grep "\<$GLITE_JPIS_TEST_PORT\>" > /dev/null
ret=$?
i=$(($i+1))
- LC_ALL=C sleep 0.1
+ sleep 0.1
done
+ if [ x"$ret" != x"0" ]; then
+ echo "Index server not started."
+ kill_is;
+ drop_db;
+ exit 1;
+ fi
echo -n "S "
}
drop_db;
kill_is;
-echo -n "Query jobId test........... "
+echo -n "Query jobId test..... "
create_db;
run_is "-n";
import_db $GLITE_LOCATION/examples/query-tests/dump1.sql;
drop_db;
kill_is;
-echo -n "Origin test........... "
+echo -n "Origin test.......... "
create_db;
run_is "-n";
import_db $GLITE_LOCATION/examples/query-tests/dump1.sql;
drop_db;
kill_is;
-echo -n "EXISTS operation test........... "
+echo -n "EXISTS test.......... "
create_db;
run_is "-n";
import_db $GLITE_LOCATION/examples/query-tests/dump1.sql;
run_test_query $GLITE_LOCATION/examples/query-tests/exists_query.in $GLITE_LOCATION/examples/query-tests/exists_query.out;
drop_db;
kill_is;
+
+echo -n "WITHIN test.......... "
+create_db;
+run_is "-n";
+import_db $GLITE_LOCATION/examples/query-tests/dump1.sql;
+run_test_query $GLITE_LOCATION/examples/query-tests/within_query.in $GLITE_LOCATION/examples/query-tests/exists_query.out;
+drop_db;
+kill_is;
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<jpisclient:QueryJobs xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jptype="http://glite.org/wsdl/types/jp" xmlns:jpsrv="http://glite.org/wsdl/services/jp" xmlns:jpelem="http://glite.org/wsdl/elements/jp" xmlns:jpisclient="http://glite.org/xsd/types/jpisclient">
+
+ <conditions>
+ <attr>http://egee.cesnet.cz/en/Schema/LB/Attributes:CE</attr>
+ <record>
+ <op>WITHIN</op>
+ <value><string>VOCA</string></value>
+ <value2><string>VOCI</string></value2>
+ </record>
+ </conditions>
+
+ <attributes>http://egee.cesnet.cz/en/Schema/JP/System:owner</attributes>
+ <attributes>http://egee.cesnet.cz/en/Schema/JP/System:jobId</attributes>
+ <attributes>http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus</attributes>
+ <attributes>http://egee.cesnet.cz/en/Schema/LB/Attributes:user</attributes>
+ <attributes>http://egee.cesnet.cz/en/Schema/LB/Attributes:CE</attributes>
+
+</jpisclient:QueryJobs>
--- /dev/null
+query: using JPIS http://localhost:12002
+
+Conditions:
+ http://egee.cesnet.cz/en/Schema/LB/Attributes:CE
+ origin IS ANY
+ value WITHIN VOCA AND VOCI
+Attributes:
+ http://egee.cesnet.cz/en/Schema/JP/System:owner
+ http://egee.cesnet.cz/en/Schema/JP/System:jobId
+ http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus
+ http://egee.cesnet.cz/en/Schema/LB/Attributes:user
+ http://egee.cesnet.cz/en/Schema/LB/Attributes:CE
+
+OK
+Result 1 jobs:
+ jobid = https://localhost:7846/pokus1, owner = /O=CESNET/O=Masaryk University/CN=Milos Mulac
+ http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus
+ value = Done
+ origin = FILE (no detail)
+ time = Thu Jan 1 02:00:01 1970
+ http://egee.cesnet.cz/en/Schema/LB/Attributes:user
+ value = CertSubj
+ origin = FILE (no detail)
+ time = Thu Jan 1 02:00:01 1970
+ http://egee.cesnet.cz/en/Schema/LB/Attributes:CE
+ value = VOCE
+ origin = FILE (no detail)
+ time = Thu Jan 1 02:00:01 1970
case GLITE_JP_QUERYOP_UNEQUAL:
qop = strdup("!=");
break;
+// FIXME: has index the same metrics?
+ case GLITE_JP_QUERYOP_GREATER:
+ qop = strdup(">");
+ break;
+ case GLITE_JP_QUERYOP_LESS:
+ qop = strdup("<");
+ break;
+ case GLITE_JP_QUERYOP_WITHIN:
+ qop = strdup("BETWEEN");
+ break;
default:
// unsupported query operator
return(1);
}
+static char *get_sql_stringvalue(glite_jpis_context_t ctx, struct jptype__stringOrBlob *value) {
+ if (!value) return NULL;
+ if (!GSOAP_ISSTRING(value)) return NULL;
+ return GSOAP_STRING(value);
+}
+
+
+static int get_sql_indexvalue(char **sql, struct soap *soap, glite_jpis_context_t ctx, struct jptype__indexQuery *condition, struct jptype__stringOrBlob *value) {
+ glite_jp_attrval_t attr;
+
+ *sql = NULL;
+ if (!value) return 0;
+ memset(&attr, 0, sizeof attr);
+ attr.name = condition->attr;
+ if (GSOAP_ISSTRING(value)) {
+ attr.value = GSOAP_STRING(value);
+ attr.binary = 0;
+ } else if (GSOAP_ISBLOB(value)) {
+ attr.value = GSOAP_BLOB(value)->__ptr;
+ attr.size = GSOAP_BLOB(value)->__size;
+ attr.binary = 1;
+ } else return 0;
+ glite_jpis_SoapToAttrOrig(soap, condition->origin, &(attr.origin));
+
+ *sql = glite_jp_attrval_to_db_index(ctx->jpctx, &attr, 255);
+ return 0;
+}
+
+
+static int get_sql_cond(char **sql, const char *attr_md5, enum jptype__queryOp op, char *value, char *value2) {
+ char *s, *qop, *column;
+
+ *sql = NULL;
+ if (get_op(op, &qop) != 0) return 0;
+ if (attr_md5) trio_asprintf(&column, "attr_%|Ss.value", attr_md5);
+ else asprintf(&column, "jobs.dg_jobid");
+ trio_asprintf(sql, "%s %s \"%|Ss\"", column, qop, value);
+ free(column);
+ free(qop);
+ if (op == jptype__queryOp__WITHIN) {
+ if (!value) {
+ free(*sql);
+ *sql = NULL;
+ return EINVAL;
+ }
+ trio_asprintf(&s, "%s AND \"%|Ss\"", *sql, value2);
+ free(*sql); *sql = s;
+ }
+ return 0;
+}
+
+
static char *get_sql_or(struct soap *soap, glite_jpis_context_t ctx, struct jptype__indexQuery *condition, const char *attr_md5) {
struct jptype__indexQueryRecord *record;
- glite_jp_attrval_t attr;
- char *qop, *sql, *s;
+ char *sql, *cond, *s = NULL, *value, *value2;
int j;
sql = strdup("");
if (record->op == jptype__queryOp__EXISTS) {
/* no additional conditions needed when existing is enough */
} else {
- if (get_op(record->op, &qop)) return NULL;
-
- memset(&attr, 0, sizeof(attr));
- attr.name = condition->attr;
- if (GSOAP_ISSTRING(record->value)) {
- attr.value = GSOAP_STRING(record->value);
- attr.binary = 0;
- } else {
- attr.value = GSOAP_BLOB(record->value)->__ptr;
- attr.size = GSOAP_BLOB(record->value)->__size;
- attr.binary = 1;
- }
- glite_jpis_SoapToAttrOrig(soap,
- condition->origin, &(attr.origin));
if (strcmp(condition->attr, GLITE_JP_ATTR_JOBID) == 0) {
- trio_asprintf(&s,"%s%sjobs.dg_jobid %s \"%|Ss\"",
- sql, (sql[0] ? " OR " : ""), qop, attr.value);
+ value = get_sql_stringvalue(ctx, record->value);
+ if (!value) goto err;
+ value2 = get_sql_stringvalue(ctx, record->value2);
+ if (get_sql_cond(&cond, attr_md5, record->op, value, value2) != 0) goto err;
} else {
- trio_asprintf(&s,"%s%sattr_%|Ss.value %s \"%|Ss\"",
- sql, (sql[0] ? " OR " : ""), attr_md5, qop,
- glite_jp_attrval_to_db_index(ctx->jpctx, &attr, 255));
+ get_sql_indexvalue(&value, soap, ctx, condition, record->value);
+ get_sql_indexvalue(&value2, soap, ctx, condition, record->value2);
+ get_sql_cond(&cond, attr_md5, record->op, value, value2);
+ free(value);
+ free(value2);
+ if (!cond) goto err;
}
- free(qop);
+ trio_asprintf(&s,"%s%s%s", sql, (sql[0] ? " OR " : ""), cond);
+ free(cond);
free(sql); sql = s;
}
}
return sql;
+err:
+ free(sql);
+ free(s);
+ return NULL;
}
*qwhere = NULL, *query = NULL, *res[2],
**jids = NULL, **pss = NULL, **attr_tables = NULL;
int i, ret;
- glite_jp_db_stmt_t stmt;
+ glite_jp_db_stmt_t stmt = NULL;
glite_jp_attr_orig_t orig;
trio_asprintf(&qb, "");
/* select given records in attr_ table */
- trio_asprintf(&qa,"%s%s jobs.jobid = attr_%|Ss.jobid",
- (i ? "AND" : ""), qb, attr_md5);
+ trio_asprintf(&qa,"%s%sjobs.jobid = attr_%|Ss.jobid",
+ (i ? "AND " : ""), qb, attr_md5);
free(qb);
}
}
free(qor);
- trio_asprintf(&qb,"%s %s", qwhere, qa);
+ trio_asprintf(&qb,"%s%s%s", qwhere, qa[0] ? " " : "", qa);
free(qa); qwhere = qb; qb = NULL; qa = NULL;
free(attr_md5);
}
trio_asprintf(&query, "SELECT DISTINCT dg_jobid,ps FROM jobs%s WHERE%s", qa, qwhere);
}
else {
- trio_asprintf(&query, "SELECT DISTINCT dg_jobid,ps FROM jobs,users%s WHERE (jobs.ownerid = users.userid AND users.cert_subj='%s') AND %s", qa, ctx->jpctx->peer, qwhere);
+ trio_asprintf(&query, "SELECT DISTINCT dg_jobid,ps FROM jobs,users%s WHERE (jobs.ownerid = users.userid AND users.cert_subj='%s') AND%s", qa, ctx->jpctx->peer, qwhere);
}
printf("Incomming QUERY:\n %s\n", query);
free(qwhere);