Embeddable settings (repeatable).
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 10 Sep 2009 13:02:18 +0000 (15:02 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 10 Sep 2009 13:02:18 +0000 (15:02 +0200)
The settings element may be be included verbatim in a service and it
is repeatable. This pretty makes settings with the src attribute
obsolete because of the include facility.

src/database.c
src/database.h
src/logic.c
src/pazpar2.c
src/pazpar2_config.c
src/pazpar2_config.h
src/settings.c
src/settings.h
test/test_http.cfg

index d7c3356..0dd359b 100644 (file)
@@ -98,13 +98,36 @@ static struct host *find_host(const char *hostport)
     return create_host(hostport);
 }
 
+int resolve_database(struct database *db)
+{
+    if (db->host == 0)
+    {
+        struct host *host;
+        char *p;
+        char hostport[256];
+        strcpy(hostport, db->url);
+        if ((p = strchr(hostport, '/')))
+            *p = '\0';
+        if (!(host = find_host(hostport)))
+            return -1;
+        db->host = host;
+    }
+    return 0;
+}
+
+void resolve_databases(struct conf_service *service)
+{
+    struct database *db = service->databases;
+    for (; db; db = db->next)
+        resolve_database(db);
+}
+
 static struct database *load_database(const char *id,
     struct conf_service *service)
 {
     xmlDoc *doc = 0;
     struct zr_explain *explain = 0;
     struct database *db;
-    struct host *host;
     char hostport[256];
     char *dbname;
     struct setting *idset;
@@ -126,11 +149,9 @@ static struct database *load_database(const char *id,
         *(dbname++) = '\0';
     else
         dbname = "";
-    if (!(host = find_host(hostport)))
-        return 0;
     db = nmem_malloc(service->nmem, sizeof(*db));
     memset(db, 0, sizeof(*db));
-    db->host = host;
+    db->host = 0;
     db->url = nmem_strdup(service->nmem, id);
     db->databases = xmalloc(2 * sizeof(char *));
     db->databases[0] = nmem_strdup(service->nmem, dbname);
index e7a51b2..7631b55 100644 (file)
@@ -28,5 +28,7 @@ int predef_grep_databases(void *context, struct conf_service *service,
                          struct database_criterion *cl,
                          void (*fun)(void *context, struct database *db));
 int match_zurl(const char *zurl, const char *pattern);
+int resolve_database(struct database *db);
+
 
 #endif
index c3aecbe..380806f 100644 (file)
@@ -606,6 +606,8 @@ static struct session_database *load_session_database(struct session *se,
 {
     struct database *db = find_database(id, 0, se->service);
 
+    resolve_database(db);
+
     session_init_databases_fun((void*) se, db);
     // New sdb is head of se->databases list
     return se->databases;
index e7d583a..5070a10 100644 (file)
@@ -39,7 +39,8 @@ static struct conf_config *sc_stop_config = 0;
 void child_handler(void *data)
 {
     struct conf_config *config = (struct conf_config *) data;
-    config_read_settings(config);
+
+    config_start_databases(config);
 
     pazpar2_event_loop();
 }
index b508eed..197b696 100644 (file)
@@ -247,7 +247,9 @@ static void service_destroy(struct conf_service *service)
 }
 
 static struct conf_service *service_create(struct conf_config *config,
-                                           xmlNode *node, const char *service_id)
+                                           xmlNode *node,
+                                           const char *service_id,
+                                           const char *server_settings)
 {
     xmlNode *n;
     int md_node = 0;
@@ -256,6 +258,7 @@ static struct conf_service *service_create(struct conf_config *config,
     struct conf_service *service = 0;
     int num_metadata = 0;
     int num_sortkeys = 0;
+    int got_settings = 0;
     
     // count num_metadata and num_sortkeys
     for (n = node->children; n; n = n->next)
@@ -277,16 +280,7 @@ static struct conf_service *service_create(struct conf_config *config,
         if (n->type != XML_ELEMENT_NODE)
             continue;
         if (!strcmp((const char *) n->name, "settings"))
-        {
-            if (service->settings)
-            {
-                yaz_log(YLOG_FATAL, "Can't repeat 'settings'");
-                return 0;
-            }
-            service->settings = parse_settings(config, service->nmem, n);
-            if (!service->settings)
-                return 0;
-        }
+            got_settings++;
         else if (!strcmp((const char *) n->name, (const char *) "targetprofiles"))
         {
             if (service->targetprofiles)
@@ -472,6 +466,44 @@ static struct conf_service *service_create(struct conf_config *config,
             return 0;
         }
     }
+    init_settings(service);
+    if (got_settings)
+    {
+        int pass;
+        /* metadata has been read.. Consider now settings */
+        for (pass = 1; pass <= 2; pass++)
+        {
+            for (n = node->children; n; n = n->next)
+            {
+                if (n->type != XML_ELEMENT_NODE)
+                    continue;
+                if (!strcmp((const char *) n->name, "settings"))
+                {
+                    xmlChar *src = xmlGetProp(n, (xmlChar *) "src");
+                    if (src)
+                    {
+                        WRBUF w = wrbuf_alloc();
+                        conf_dir_path(config, w, (const char *) src);
+                        settings_read_file(service, wrbuf_cstr(w), pass);
+                        wrbuf_destroy(w);
+                        xmlFree(src);
+                    }
+                    else
+                    {
+                        settings_read_node(service, n, pass);
+                    }
+                }
+            }
+        }
+    }
+    else
+    {
+        if (server_settings)
+        {
+            settings_read_file(service, server_settings, 1);
+            settings_read_file(service, server_settings, 2);
+        }
+    }
     return service;
 }
 
@@ -501,6 +533,7 @@ static struct conf_server *parse_server(struct conf_config *config,
                                         NMEM nmem, xmlNode *node)
 {
     xmlNode *n;
+    const char *server_settings = 0;
     struct conf_server *server = nmem_malloc(nmem, sizeof(struct conf_server));
 
     server->host = 0;
@@ -511,7 +544,6 @@ static struct conf_server *parse_server(struct conf_config *config,
     server->proxy_addr = 0;
     server->service = 0;
     server->next = 0;
-    server->server_settings = 0;
     server->relevance_pct = 0;
     server->sort_pct = 0;
     server->mergekey_pct = 0;
@@ -548,12 +580,12 @@ static struct conf_server *parse_server(struct conf_config *config,
         }
         else if (!strcmp((const char *) n->name, "settings"))
         {
-            if (server->server_settings)
+            if (server_settings)
             {
                 yaz_log(YLOG_FATAL, "Can't repeat 'settings'");
                 return 0;
             }
-            if (!(server->server_settings = parse_settings(config, nmem, n)))
+            if (!(server_settings = parse_settings(config, nmem, n)))
                 return 0;
         }
         else if (!strcmp((const char *) n->name, "relevance"))
@@ -597,7 +629,9 @@ static struct conf_server *parse_server(struct conf_config *config,
                 return 0;
             else
             {
-                struct conf_service *s = service_create(config, n, service_id);
+                struct conf_service *s = service_create(config, n,
+                                                        service_id,
+                                                        server_settings);
                 if (s)
                 {
                     if (server->relevance_pct)
@@ -610,7 +644,6 @@ static struct conf_server *parse_server(struct conf_config *config,
 
                     if (server->sort_pct)
                     {
-                        
                         s->sort_pct = server->sort_pct;
                         pp2_charset_incref(s->sort_pct);
                     }
@@ -747,7 +780,6 @@ static int config_include_one(struct conf_config *config, xmlNode **sib,
         if ((st.st_mode & S_IFMT) == S_IFREG)
         {
             xmlDoc *doc = xmlParseFile(path);
-            yaz_log(YLOG_LOG, "processing include path=%s", path);
             if (doc)
             {
                 xmlNodePtr t = xmlDocGetRootElement(doc);
@@ -926,26 +958,22 @@ void config_destroy(struct conf_config *config)
     }
 }
 
-void config_read_settings(struct conf_config *config)
+void config_stop_listeners(struct conf_config *conf)
 {
-    struct conf_service *s = config->servers->service;
-    for (;s ; s = s->next)
-    {
-        init_settings(s);
-        if (s->settings)
-            settings_read(s, s->settings);
-        else if (config->servers->server_settings)
-            settings_read(s, config->servers->server_settings);
-        else
-            yaz_log(YLOG_WARN, "No settings for service");
-    }
+    struct conf_server *ser;
+    for (ser = conf->servers; ser; ser = ser->next)
+        http_close_server(ser);
 }
 
-void config_stop_listeners(struct conf_config *conf)
+void config_start_databases(struct conf_config *conf)
 {
     struct conf_server *ser;
     for (ser = conf->servers; ser; ser = ser->next)
-        http_close_server(ser);
+    {
+        struct conf_service *s = ser->service;
+        for (;s ; s = s->next)
+            resolve_databases(s);
+    }
 }
 
 int config_start_listeners(struct conf_config *conf,
index 7400c9f..530794b 100644 (file)
@@ -152,8 +152,6 @@ struct conf_server
     struct sockaddr_in *proxy_addr;
     int listener_socket;
 
-    char *server_settings;
-
     pp2_charset_t relevance_pct;
     pp2_charset_t sort_pct;
     pp2_charset_t mergekey_pct;
@@ -174,7 +172,7 @@ void config_destroy(struct conf_config *config);
 xsltStylesheet *conf_load_stylesheet(struct conf_config *config,
                                      const char *fname);
 
-void config_read_settings(struct conf_config *config);
+void config_start_databases(struct conf_config *config);
 
 struct conf_service *locate_service(struct conf_server *server,
                                     const char *service_id);
index 5486c7c..2159628 100644 (file)
@@ -291,10 +291,6 @@ static void prepare_dictionary(struct conf_service *service,
     int i;
     char *p;
 
-    // If target address is not wildcard, add the database
-    if (*set->target && !zurl_wildcard(set->target))
-        find_database(set->target, 0, service);
-
     // Determine if we already have a dictionary entry
     if (!strncmp(set->name, "pz:", 3) && (p = strchr(set->name + 3, ':')))
         *(p + 1) = '\0';
@@ -447,21 +443,12 @@ static void prepare_target_dictionary(struct conf_service *service,
     yaz_log(YLOG_WARN, "Setting '%s' not configured as metadata", set->name);
 }
 
-// If we ever decide we need to be able to specify multiple settings directories,
-// the two calls to read_settings must be split -- so the dictionary is prepared
-// for the contents of every directory before the databases are updated.
-void settings_read(struct conf_service *service, const char *path)
-{
-    read_settings(path, service, prepare_target_dictionary);
-    read_settings(path, service, update_databases);
-}
-
 void init_settings(struct conf_service *service)
 {
     struct setting_dictionary *new;
-
+    
     assert(service->nmem);
-
+    
     new = nmem_malloc(service->nmem, sizeof(*new));
     memset(new, 0, sizeof(*new));
     service->dictionary = new;
@@ -469,6 +456,24 @@ void init_settings(struct conf_service *service)
     initialize_soft_settings(service);
 }
 
+void settings_read_file(struct conf_service *service, const char *path,
+                        int pass)
+{
+    if (pass == 1)
+        read_settings(path, service, prepare_target_dictionary);
+    else
+        read_settings(path, service, update_databases);
+}
+
+void settings_read_node(struct conf_service *service, xmlNode *n,
+                        int pass)
+{
+    if (pass == 1)
+        read_settings_node(n, service, prepare_target_dictionary);
+    else
+        read_settings_node(n, service, update_databases);
+}
+
 /*
  * Local variables:
  * c-basic-offset: 4
index d211cb6..cce76e6 100644 (file)
@@ -48,11 +48,15 @@ struct setting
     struct setting *next;
 };
 
+void settings_read_file(struct conf_service *service, const char *path,
+                        int pass);
+void settings_read_node(struct conf_service *service, xmlNode *n,
+                        int pass);
 int settings_num(struct conf_service *service);
-void settings_read(struct conf_service *service, const char *path);
 int settings_offset(struct conf_service *service, const char *name);
 int settings_offset_cprefix(struct conf_service *service, const char *name);
 void init_settings(struct conf_service *service);
+void resolve_databases(struct conf_service *service);
 
 #endif
 
index bc8be28..271efe9 100644 (file)
@@ -6,7 +6,7 @@
     <proxy host="localhost"/>
     
     <service>
-      <settings src="z3950_indexdata_com_marc.xml"/>
+      <include src="z3950_indexdata_com_marc.xml"/>
       <targetprofiles type="local" src="../zeerex/records/"/>
       <metadata name="url" merge="unique"/>
       <metadata name="title" brief="yes" sortkey="skiparticle" merge="longest" rank="6"/>