Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
File Transfer Service
fts-rest
Commits
ea1ee4bc
Commit
ea1ee4bc
authored
Jul 24, 2017
by
Maria Arsuaga Rios
Browse files
FTS-793
: Provide an Optimizer API
parent
5bffdbec
Pipeline
#166426
passed with stage
in 19 seconds
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
docs/api-curl.md
View file @
ea1ee4bc
...
...
@@ -310,3 +310,22 @@ Unbanning:
`curl --capath /etc/grid-security/certificates -E ~/proxy.pem --cacert ~/proxy.pem "https://fts3-pilot.cern.ch:8446/ban/dn?user_dn=/DC=.../CN=..." -X DELETE`
Mind that unbanning returns nothing.
Get Current Optimizer values
------------------------
Return the current optimizer values for a given pair (source, destination).
`curl -E "${X509_USER_PROXY}" --cacert "${X509_USER_PROXY}" --capath "/etc/grid-security/certificates" "https://fts3-pilot.cern.ch:8446/optimizer/current?source_se="source-test"&dest_se="dest-test"" -H "Content-Type: application/json"`
Set Current Optimizer values
------------------------
Set the current optimizer values for given pair (source, destination).
` curl -E "${X509_USER_PROXY}" --cacert "${X509_USER_PROXY}" --capath "/etc/grid-security/certificates" https://fts3-pilot.cern.ch:8446/optimizer/current -H "Content-Type: application/json" -X POST -d '{"source_se": "source-test", "dest_se": "dest-test", "active": 4, "nostreams": 1, "ema": 3.4}'`
Get Current Optimizer Evolution
------------------------
Returns the evolution information for a given pair (source, destination).
`curl -E "${X509_USER_PROXY}" --cacert "${X509_USER_PROXY}" --capath "/etc/grid-security/certificates" "https://fts3-pilot.cern.ch:8446/optimizer/evolution?source_se="source-test"&dest_se="dest-test"" -H "Content-Type: application/json"`
src/fts3/model/optimizer.py
View file @
ea1ee4bc
...
...
@@ -44,7 +44,10 @@ class Optimizer(Base):
source_se
=
Column
(
String
(
150
),
nullable
=
True
,
primary_key
=
True
)
dest_se
=
Column
(
String
(
150
),
nullable
=
True
,
primary_key
=
True
)
ema
=
Column
(
Float
)
active
=
Column
(
Integer
)
datetime
=
Column
(
DateTime
)
nostreams
=
Column
(
Integer
)
def
__str__
(
self
):
return
"%s => %s"
%
(
self
.
source_se
,
self
.
dest_se
)
src/fts3rest/fts3rest/config/routing/base.py
View file @
ea1ee4bc
...
...
@@ -188,6 +188,11 @@ def do_connect(config, map):
map
.
connect
(
'/optimizer/evolution'
,
controller
=
'optimizer'
,
action
=
'evolution'
,
conditions
=
dict
(
method
=
[
'GET'
]))
map
.
connect
(
'/optimizer/current'
,
controller
=
'optimizer'
,
action
=
'get_optimizer_values'
,
conditions
=
dict
(
method
=
[
'GET'
]))
map
.
connect
(
'/optimizer/current'
,
controller
=
'optimizer'
,
action
=
'set_optimizer_values'
,
conditions
=
dict
(
method
=
[
'POST'
]))
# GFAL2 bindings
map
.
connect
(
'/dm/list'
,
controller
=
'datamanagement'
,
action
=
'list'
,
...
...
src/fts3rest/fts3rest/controllers/config/se.py
View file @
ea1ee4bc
...
...
@@ -52,7 +52,6 @@ class SeConfigurationController(BaseController):
Set the configuration parameters for a given SE
"""
input_dict
=
get_input_as_dict
(
request
)
try
:
for
storage
,
cfg
in
input_dict
.
iteritems
():
se_info_new
=
cfg
.
get
(
'se_info'
,
None
)
...
...
@@ -63,7 +62,7 @@ class SeConfigurationController(BaseController):
for
key
,
value
in
se_info_new
.
iteritems
():
#value = validate_type(Se, key, value)
setattr
(
se_info
,
key
,
value
)
audit_configuration
(
'set-se-config'
,
'Set config %s: %s'
%
(
storage
,
json
.
dumps
(
cfg
)))
Session
.
merge
(
se_info
)
...
...
@@ -91,7 +90,7 @@ class SeConfigurationController(BaseController):
except
:
Session
.
rollback
()
raise
return
None
return
(
se_info
,
operations
)
@
doc
.
query_arg
(
'se'
,
'Storage element'
,
required
=
False
)
@
doc
.
response
(
403
,
'The user is not allowed to query the configuration'
)
...
...
src/fts3rest/fts3rest/controllers/optimizer.py
View file @
ea1ee4bc
...
...
@@ -15,11 +15,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
try
:
import
simplejson
as
json
except
:
import
json
import
logging
from
pylons
import
config
,
request
from
fts3rest.lib.api
import
doc
from
fts3rest.lib.base
import
BaseController
,
Session
from
fts3rest.lib.helpers
import
jsonify
from
fts3rest.lib.helpers
import
jsonify
,
accept
,
get_input_as_dict
from
fts3.model
import
OptimizerEvolution
,
Optimizer
from
pylons
import
config
,
request
from
datetime
import
datetime
from
fts3rest.lib.http_exceptions
import
*
class
OptimizerController
(
BaseController
):
...
...
@@ -53,7 +62,7 @@ class OptimizerController(BaseController):
@
doc
.
return_type
(
array_of
=
Optimizer
)
@
jsonify
def
get_
current
_value
(
self
):
def
get_
optimizer
_value
s
(
self
):
"""
Returns the current number of actives and streams
"""
...
...
@@ -65,5 +74,63 @@ class OptimizerController(BaseController):
optimizer
=
optimizer
.
order_by
(
Optimizer
.
datetime
.
desc
())
return
optimizer
[:
0
]
return
optimizer
@
doc
.
response
(
400
,
'Invalid values passed in the request'
)
@
jsonify
def
set_optimizer_values
(
self
):
"""
Set the number of actives and streams
"""
input_dict
=
get_input_as_dict
(
request
)
source_se
=
input_dict
.
get
(
'source_se'
,
None
)
dest_se
=
input_dict
.
get
(
'dest_se'
,
None
)
current_time
=
datetime
.
utcnow
()
if
not
source_se
or
not
dest_se
:
raise
HTTPBadRequest
(
'Missing source and/or destination'
)
try
:
active
=
int
(
input_dict
.
get
(
'active'
,
2
))
except
Exception
,
e
:
raise
HTTPBadRequest
(
'Active must be an integer (%s)'
%
str
(
e
))
if
active
<
0
:
raise
HTTPBadRequest
(
'Active must be positive (%s)'
%
str
(
active
))
try
:
nostreams
=
int
(
input_dict
.
get
(
'nostreams'
,
1
))
except
Exception
,
e
:
raise
HTTPBadRequest
(
'Nostreams must be an integer (%s)'
%
str
(
e
))
if
nostreams
<
0
:
raise
HTTPBadRequest
(
'Nostreams must be positive (%s)'
%
str
(
nostreams
))
try
:
ema
=
float
(
input_dict
.
get
(
'ema'
,
0
))
except
Exception
,
e
:
raise
HTTPBadRequest
(
'Ema must be a float (%s)'
%
str
(
e
))
if
ema
<
0
:
raise
HTTPBadRequest
(
'Ema must be positive (%s)'
%
str
(
ema
))
optimizer
=
Optimizer
(
source_se
=
source_se
,
dest_se
=
dest_se
,
datetime
=
current_time
,
ema
=
ema
,
active
=
active
,
nostreams
=
nostreams
)
for
key
,
value
in
input_dict
.
iteritems
():
setattr
(
optimizer
,
key
,
value
)
Session
.
merge
(
optimizer
)
try
:
Session
.
commit
()
except
:
Session
.
rollback
()
raise
return
optimizer
src/fts3rest/fts3rest/tests/functional/test_options.py
View file @
ea1ee4bc
...
...
@@ -107,6 +107,9 @@ class TestOptions(TestController):
response
=
self
.
app
.
options
(
'/optimizer/evolution'
,
status
=
200
)
self
.
assertItemsEqual
([
'GET'
,
'OPTIONS'
],
response
.
allow
)
response
=
self
.
app
.
options
(
'/optimizer/current'
,
status
=
200
)
self
.
assertItemsEqual
([
'GET'
,
'POST'
,
'OPTIONS'
],
response
.
allow
)
def
test_options_404
(
self
):
"""
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment