Skip to content

Commit 2c9a407

Browse files
Reinoud SleemanReinoud Sleeman
Reinoud Sleeman
authored and
Reinoud Sleeman
committed
from-javier
1 parent 470464e commit 2c9a407

25 files changed

+8044
-0
lines changed

COPYING

+674
Large diffs are not rendered by default.

README.rst

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
Routing Service v1.2
2+
--------------------
3+
4+
Why a Routing Service?
5+
======================
6+
7+
One of the aims of the
8+
`European Integrated Data Archive <http://www.orfeus-eu.org/eida/eida.html>`_
9+
(EIDA) is to provide transparent access and services to high quality, seismic
10+
data across different data archives in Europe. In the context of the design
11+
of the `EIDA New Generation` (EIDA-NG) software we envision a future in which
12+
many different data centers offer data products using compatible types of
13+
services, but pertaining to different seismic objects, such as waveforms,
14+
inventory, or event data. EIDA provides one example, in which data centers
15+
(the EIDA “nodes”) have long offered Arclink and Seedlink services, and now
16+
offer FDSN web services, for accessing their holdings. In keeping with the
17+
distributed nature of EIDA, these services could run at different nodes.
18+
Depending on the type of service, these may only provide information about a
19+
reduced subset of all the available waveforms.
20+
21+
To assist users to locate data, we have designed a Routing Service, which
22+
could run at EIDA nodes or elsewhere, including on a user's personal computer.
23+
This (meta)service is supposed to be queried by clients (or other services) in
24+
order to localize the address(es) where the desired information is provided.
25+
26+
The Routing Service must serve this information in order to help the
27+
development of smart clients and/or services of higher level, which can offer
28+
the user an integrated view of the whole EIDA, hiding the complexity of its
29+
internal structure. However, the Routing Service need not be aware of the
30+
extent of the content offered by each service, avoiding the need for a large
31+
synchronised database at any place.
32+
33+
The service is intended to be open and able to be queried by anyone without
34+
the need of credentials or authentication.
35+
36+
License
37+
=======
38+
39+
This program is free software: you can redistribute it and/or modify
40+
it under the terms of the GNU General Public License as published by
41+
the Free Software Foundation, either version 3 of the License, or
42+
any later version.
43+
44+
This program is distributed in the hope that it will be useful,
45+
but WITHOUT ANY WARRANTY; without even the implied warranty of
46+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47+
GNU General Public License for more details.
48+
49+
You should have received a copy of the GNU General Public License
50+
along with this program. If not, see <http://www.gnu.org/licenses/>.
51+
52+
Installation
53+
============
54+
55+
The installation instructions are included in the package, but need first to be
56+
generated. Follow the instructions in the next section to do it.
57+
58+
Documentation
59+
=============
60+
61+
To get the documentation of the current version of the Routing Service you
62+
please follow these steps:
63+
64+
1. Go to the "doc" subdirectory located where the package was decompressed.
65+
Let's suppose it is "/var/www/eidaws/routing/1". ::
66+
67+
$ cd /var/www/eidaws/routing/1/doc
68+
69+
2. Build the
70+
documentation. ::
71+
72+
$ make latexpdf
73+
74+
3. Open the generated PDF file with an appropriate application (e.g. acroread,
75+
evince, etc). The file will be located under the .build/latex directory. ::
76+
77+
$ acroread .build/latex/Routing-WS.pdf
78+
79+
Copy this file to the location most suitable to you for future use.

application.wadl

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<application xmlns="http://wadl.dev.java.net/2009/02"
2+
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
3+
<resources base="%s">
4+
<resource path="query">
5+
<method href="#queryGET"/>
6+
<method href="#queryPOST"/>
7+
</resource>
8+
<resource path="localconfig">
9+
<method name="GET">
10+
<response>
11+
<representation mediaType="text/xml"/>
12+
</response>
13+
</method>
14+
</resource>
15+
<resource path="version">
16+
<method name="GET">
17+
<response>
18+
<representation mediaType="text/plain"/>
19+
</response>
20+
</method>
21+
</resource>
22+
<resource path="application.wadl">
23+
<method name="GET">
24+
<response>
25+
<representation mediaType="application/xml"/>
26+
</response>
27+
</method>
28+
</resource>
29+
</resources>
30+
<method name="GET" id="queryGET">
31+
<request>
32+
<param name="service" style="query" type="xsd:string" default="dataselect">
33+
<option value="xml"/>
34+
<option value="json"/>
35+
<option value="get"/>
36+
<option value="post"/>
37+
</param>
38+
<param name="starttime" style="query" type="xsd:dateTime" default="1980-01-01T00:00:00"/>
39+
<param name="endtime" style="query" type="xsd:dateTime" default="%s"/>
40+
<param name="network" style="query" type="xsd:string" default="*"/>
41+
<param name="station" style="query" type="xsd:string" default="*"/>
42+
<param name="location" style="query" type="xsd:string" default="*"/>
43+
<param name="channel" style="query" type="xsd:string" default="*"/>
44+
<param name="format" style="query" type="xsd:string" default="xml">
45+
<option value="xml"/>
46+
<option value="json"/>
47+
<option value="get"/>
48+
<option value="post"/>
49+
</param>
50+
</request>
51+
<response status="200">
52+
<representation mediaType="text/plain"/>
53+
</response>
54+
<response status="204 400 401 403 404 413 414 500 503">
55+
<representation mediaType="text/plain"/>
56+
</response>
57+
</method>
58+
<method name="POST" id="queryPOST">
59+
<response status="200">
60+
<representation mediaType="text/plain"/>
61+
</response>
62+
<response status="204 400 401 403 404 413 414 500 503">
63+
<representation mediaType="text/plain"/>
64+
</response>
65+
</method>
66+
</application>

data/routing.xml.sample

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<ns0:routing xmlns:ns0="http://geofon.gfz-potsdam.de/ns/Routing/1.0/">
3+
<ns0:vnetwork networkCode="_GEALL">
4+
<ns0:stream networkCode="GE" stationCode="APE" locationCode="*" streamCode="*" start="2015-01-01T00:00:00" end="2015-12-31T00:00:00" />
5+
<ns0:stream networkCode="GE" stationCode="BNDI" locationCode="*" streamCode="*" start="2015-01-01T00:00:00" end="2015-12-31T00:00:00" />
6+
<ns0:stream networkCode="GE" stationCode="RUE" locationCode="*" streamCode="*" start="2015-01-01T00:00:00" end="2015-12-31T00:00:00" />
7+
</ns0:vnetwork>
8+
<ns0:route networkCode="RO" stationCode="*" locationCode="*" streamCode="*">
9+
<ns0:station address="http://eida-sc3.infp.ro/fdsnws/station/1/query" priority="1" start="1980-01-01T00:00:00" end="" />
10+
<ns0:wfcatalog address="http://eida-sc3.infp.ro/eidaws/wfcatalog/1/query" priority="1" start="1980-01-01T00:00:00" end="" />
11+
<ns0:dataselect address="http://eida-sc3.infp.ro/fdsnws/dataselect/1/query" priority="1" start="1980-01-01T00:00:00" end="" />
12+
<ns0:station address="http://geofon.gfz-potsdam.de/fdsnws/station/1/query" priority="2" start="1980-01-01T00:00:00" end="" />
13+
<ns0:wfcatalog address="http://geofon.gfz-potsdam.de/eidaws/wfcatalog/1/query" priority="2" start="1980-01-01T00:00:00" end="" />
14+
<ns0:dataselect address="http://geofon.gfz-potsdam.de/fdsnws/dataselect/1/query" priority="2" start="1980-01-01T00:00:00" end="" />
15+
</ns0:route>
16+
<ns0:route networkCode="4C" stationCode="KES27" locationCode="*" streamCode="HNZ">
17+
<ns0:station address="http://geofon.gfz-potsdam.de/fdsnws/station/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
18+
<ns0:wfcatalog address="http://geofon.gfz-potsdam.de/eidaws/wfcatalog/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
19+
<ns0:dataselect address="http://geofon.gfz-potsdam.de/fdsnws/dataselect/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
20+
</ns0:route>
21+
<ns0:route networkCode="GE" stationCode="*" locationCode="*" streamCode="*">
22+
<ns0:station address="http://geofon.gfz-potsdam.de/fdsnws/station/1/query" priority="1" start="1993-01-01T00:00:00" end="" />
23+
<ns0:wfcatalog address="http://geofon.gfz-potsdam.de/eidaws/wfcatalog/1/query" priority="1" start="1993-01-01T00:00:00" end="" />
24+
<ns0:dataselect address="http://geofon.gfz-potsdam.de/fdsnws/dataselect/1/query" priority="1" start="1993-01-01T00:00:00" end="" />
25+
</ns0:route>
26+
<ns0:route networkCode="CH" stationCode="*" locationCode="*" streamCode="*">
27+
<ns0:station address="http://eida.ethz.ch/fdsnws/station/1/query" priority="1" start="1980-01-01T00:00:00" end="" />
28+
<ns0:dataselect address="http://eida.ethz.ch/fdsnws/dataselect/1/query" priority="1" start="1980-01-01T00:00:00" end="" />
29+
</ns0:route>
30+
<ns0:route networkCode="4C" stationCode="KES20" locationCode="*" streamCode="HNE">
31+
<ns0:station address="http://geofon.gfz-potsdam.de/fdsnws/station/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
32+
<ns0:wfcatalog address="http://geofon.gfz-potsdam.de/eidaws/wfcatalog/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
33+
<ns0:dataselect address="http://geofon.gfz-potsdam.de/fdsnws/dataselect/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
34+
</ns0:route>
35+
<ns0:route networkCode="4C" stationCode="KES20" locationCode="*" streamCode="HNN">
36+
<ns0:station address="http://geofon.gfz-potsdam.de/fdsnws/station/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
37+
<ns0:wfcatalog address="http://geofon.gfz-potsdam.de/eidaws/wfcatalog/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
38+
<ns0:dataselect address="http://geofon.gfz-potsdam.de/fdsnws/dataselect/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
39+
</ns0:route>
40+
<ns0:route networkCode="4C" stationCode="KES27" locationCode="*" streamCode="HNE">
41+
<ns0:station address="http://geofon.gfz-potsdam.de/fdsnws/station/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
42+
<ns0:wfcatalog address="http://geofon.gfz-potsdam.de/eidaws/wfcatalog/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
43+
<ns0:dataselect address="http://geofon.gfz-potsdam.de/fdsnws/dataselect/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
44+
</ns0:route>
45+
<ns0:route networkCode="4C" stationCode="KES27" locationCode="*" streamCode="HNN">
46+
<ns0:station address="http://geofon.gfz-potsdam.de/fdsnws/station/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
47+
<ns0:wfcatalog address="http://geofon.gfz-potsdam.de/eidaws/wfcatalog/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
48+
<ns0:dataselect address="http://geofon.gfz-potsdam.de/fdsnws/dataselect/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
49+
</ns0:route>
50+
<ns0:route networkCode="4C" stationCode="KES20" locationCode="*" streamCode="HNZ">
51+
<ns0:station address="http://geofon.gfz-potsdam.de/fdsnws/station/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
52+
<ns0:wfcatalog address="http://geofon.gfz-potsdam.de/eidaws/wfcatalog/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
53+
<ns0:dataselect address="http://geofon.gfz-potsdam.de/fdsnws/dataselect/1/query" priority="1" start="2011-09-15T00:00:00" end="2012-04-20T23:59:00" />
54+
</ns0:route>
55+
<ns0:route networkCode="ZE" stationCode="*" locationCode="*" streamCode="*">
56+
<ns0:station address="http://geofon.gfz-potsdam.de/fdsnws/station/1/query" priority="1" start="2010-03-17T00:00:00" end="2011-10-22T00:00:00" />
57+
<ns0:dataselect address="http://geofon.gfz-potsdam.de/fdsnws/dataselect/1/query" priority="1" start="2010-03-17T00:00:00" end="2011-10-22T00:00:00" />
58+
<ns0:station address="http://geofon.gfz-potsdam.de/fdsnws/station/1/query" priority="1" start="1996-09-14T00:00:00" end="1997-12-31T00:00:00" />
59+
<ns0:dataselect address="http://geofon.gfz-potsdam.de/fdsnws/dataselect/1/query" priority="1" start="1996-09-14T00:00:00" end="1997-12-31T00:00:00" />
60+
<ns0:station address="http://geofon.gfz-potsdam.de/fdsnws/station/1/query" priority="1" start="2012-04-19T00:00:00" end="2014-12-31T00:00:00" />
61+
<ns0:dataselect address="http://geofon.gfz-potsdam.de/fdsnws/dataselect/1/query" priority="1" start="2012-04-19T00:00:00" end="2014-12-31T00:00:00" />
62+
<ns0:station address="http://geofon.gfz-potsdam.de/fdsnws/station/1/query" priority="1" start="1999-05-01T00:00:00" end="1999-11-01T00:00:00" />
63+
<ns0:dataselect address="http://geofon.gfz-potsdam.de/fdsnws/dataselect/1/query" priority="1" start="1999-05-01T00:00:00" end="1999-11-01T00:00:00" />
64+
</ns0:route>
65+
</ns0:routing>

data/updateAll.py

+173
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#!/usr/bin/python3
2+
3+
"""Retrieve data from a Routing WS (or Arclink server) to be used locally
4+
5+
This program is free software: you can redistribute it and/or modify
6+
it under the terms of the GNU General Public License as published by
7+
the Free Software Foundation, either version 3 of the License, or
8+
any later version.
9+
10+
:Copyright:
11+
2014-2020 Javier Quinteros, Deutsches GFZ Potsdam <[email protected]>
12+
:License:
13+
GPLv3
14+
:Platform:
15+
Linux
16+
17+
.. moduleauthor:: Javier Quinteros <[email protected]>, GEOFON, GFZ Potsdam
18+
"""
19+
20+
import os
21+
import sys
22+
import argparse
23+
import logging
24+
from urllib.parse import urlparse
25+
26+
try:
27+
import cPickle as pickle
28+
except ImportError:
29+
import pickle
30+
31+
try:
32+
import configparser
33+
except ImportError:
34+
import ConfigParser as configparser
35+
36+
sys.path.append('..')
37+
38+
try:
39+
from routeutils.utils import addRemote
40+
from routeutils.utils import addRoutes
41+
from routeutils.utils import addVirtualNets
42+
from routeutils.utils import cacheStations
43+
from routeutils.utils import Route
44+
from routeutils.utils import RoutingCache
45+
except:
46+
raise
47+
48+
49+
def mergeRoutes(fileRoutes, synchroList, allowOverlaps=False):
50+
"""Retrieve routes from different sources and merge them with the local
51+
ones in the routing tables. The configuration file is checked to see whether
52+
overlapping routes are allowed or not. A pickled version of the the routing
53+
table is saved under the same filename plus ``.bin`` (e.g. routing.xml.bin).
54+
55+
:param fileRoutes: File containing the local routing table
56+
:type fileRoutes: str
57+
:param synchroList: List of data centres where routes should be imported from
58+
:type synchroList: str
59+
:param allowOverlaps: Specify if overlapping streams should be allowed or not
60+
:type allowOverlaps: boolean
61+
62+
"""
63+
64+
logs = logging.getLogger('mergeRoutes')
65+
logs.info('Synchronizing with: %s' % synchroList)
66+
67+
ptRT = addRoutes(fileRoutes, allowOverlaps=allowOverlaps)
68+
ptVN = addVirtualNets(fileRoutes)
69+
70+
for line in synchroList.splitlines():
71+
if not len(line):
72+
break
73+
logs.debug(str(line.split(',')))
74+
dcid, url = line.split(',')
75+
url = url.strip()
76+
parts = urlparse(url)
77+
78+
if parts.scheme in ('file', ''):
79+
if parts.path != 'routing-%s.xml' % dcid:
80+
msg = 'Routes from %s must be in a file called "routing-%s.xml' \
81+
% (dcid, dcid)
82+
logs.error(msg)
83+
raise Exception('File must be called "routing-%s.xml"' % dcid)
84+
else:
85+
try:
86+
addRemote('./routing-%s.xml' % dcid.strip(), url.strip())
87+
except:
88+
msg = 'Failure updating routing information from %s (%s)' % \
89+
(dcid, url)
90+
logs.error(msg)
91+
92+
if os.path.exists('./routing-%s.xml' % dcid.strip()):
93+
# FIXME addRoutes should return no Exception ever and skip a
94+
# problematic file returning a coherent version of the routes
95+
print('Adding REMOTE %s' % dcid)
96+
ptRT = addRoutes('./routing-%s.xml' % dcid.strip(),
97+
routingTable=ptRT, allowOverlaps=allowOverlaps)
98+
ptVN = addVirtualNets('./routing-%s.xml' % dcid.strip(),
99+
vnTable=ptVN)
100+
101+
try:
102+
os.remove('./%s.bin' % fileRoutes)
103+
except:
104+
pass
105+
106+
stationTable = dict()
107+
cacheStations(ptRT, stationTable)
108+
109+
with open('./%s.bin' % fileRoutes, 'wb') as finalRoutes:
110+
pickle.dump((ptRT, stationTable, ptVN), finalRoutes)
111+
logs.info('Routes in main Routing Table: %s\n' % len(ptRT))
112+
logs.info('Stations cached: %s\n' %
113+
sum([len(stationTable[dc][st]) for dc in stationTable
114+
for st in stationTable[dc]]))
115+
logs.info('Virtual Networks defined: %s\n' % len(ptVN))
116+
117+
118+
def main():
119+
# FIXME logLevel must be used via argparser
120+
# Check verbosity in the output
121+
msg = 'Get EIDA routing configuration and export it to the FDSN-WS style.'
122+
parser = argparse.ArgumentParser(description=msg)
123+
parser.add_argument('-l', '--loglevel',
124+
help='Verbosity in the output.',
125+
choices=['CRITICAL', 'ERROR', 'WARNING', 'INFO',
126+
'DEBUG'])
127+
# TODO Add type=argparse.FileType
128+
parser.add_argument('-c', '--config',
129+
help='Config file to use.',
130+
default='../routing.cfg')
131+
args = parser.parse_args()
132+
133+
config = configparser.RawConfigParser()
134+
# Command line parameter has priority
135+
try:
136+
verbo = getattr(logging, args.loglevel)
137+
except:
138+
# If no command-line parameter then read from config file
139+
try:
140+
verbo = config.get('Service', 'verbosity')
141+
verbo = getattr(logging, verbo)
142+
except:
143+
# Otherwise, default value
144+
verbo = logging.INFO
145+
146+
# INFO is the default value
147+
logging.basicConfig(level=verbo)
148+
logs = logging.getLogger('getEIDAconfig')
149+
logs.setLevel(verbo)
150+
151+
if not len(config.read(args.config)):
152+
logs.error('Configuration file %s could not be read' % args.config)
153+
154+
print('Skipping routing information. Config file does not allow to '
155+
+ 'overwrite the information. (%s)' % args.config)
156+
157+
try:
158+
os.remove('routing-tmp.xml.bin')
159+
except:
160+
pass
161+
162+
try:
163+
if 'synchronize' in config.options('Service'):
164+
synchroList = config.get('Service', 'synchronize')
165+
except:
166+
# Otherwise, default value
167+
synchroList = ''
168+
169+
mergeRoutes('routing.xml', synchroList)
170+
171+
172+
if __name__ == '__main__':
173+
main()

doc/GFZ-logo.jpg

6.94 KB
Loading

0 commit comments

Comments
 (0)