Repository: rucio/rucio
Issue: list_replicas with schemes=None and schemes=[...] gives conflicting results

Motivation
----------
In this case srm is the top priority protocol. If no schemes are given, the top-protocol is returned. If schemes are given, including srm, the sorting is done all wrong.

```
>>> print(c.list_replicas([did], metalink=True, rse_expression=rse, client_location=l, schemes=None))
...
   <url location="TRIUMF-LCG2_DATADISK" domain="wan" priority="1">srm://srm.triumf.ca:8443/srm/managerv2?SFN=/atlas/atlasdatadisk/rucio/mc15_13TeV/8e/0c/EVNT.04972714._000024.pool.root.1</url>
...

>>> print(c.list_replicas([did], metalink=True, rse_expression=rse, client_location=l, schemes=['davs', 'gsiftp', 'https', 'root', 'srm', 'file']))
...
   <url location="TRIUMF-LCG2_DATADISK" domain="wan" priority="1">root://xrootd.lcg.triumf.ca:1094//atlas/atlasdatadisk/rucio/mc15_13TeV/8e/0c/EVNT.04972714._000024.pool.root.1</url>
   <url location="TRIUMF-LCG2_DATADISK" domain="wan" priority="2">srm://srm.triumf.ca:8443/srm/managerv2?SFN=/atlas/atlasdatadisk/rucio/mc15_13TeV/8e/0c/EVNT.04972714._000024.pool.root.1</url>
   <url location="TRIUMF-LCG2_DATADISK" domain="wan" priority="3">davs://proxy.lcg.triumf.ca:2880/atlas/atlasdatadisk/rucio/mc15_13TeV/8e/0c/EVNT.04972714._000024.pool.root.1</url>
...
```


Changed files:
lib/rucio/core/replica.py, lib/rucio/tests/test_replica_sorting.py

diff --git a/lib/rucio/core/replica.py b/lib/rucio/core/replica.py
index 7a96b8bde..63791f69b 100644
--- a/lib/rucio/core/replica.py
+++ b/lib/rucio/core/replica.py
@@ -815,9 +815,10 @@ def _list_replicas(dataset_clause, file_clause, state_clause, show_pfns,
                 if rse not in rse_info:
                     rse_info[rse] = rsemgr.get_rse_info(rse, session=session)
 
-                # assign scheme priorities
-                rse_info[rse]['priority_wan'] = {p['scheme']: p['domains']['wan']['read'] for p in rse_info[rse]['protocols']}
-                rse_info[rse]['priority_lan'] = {p['scheme']: p['domains']['lan']['read'] for p in rse_info[rse]['protocols']}
+                # assign scheme priorities, and don't forget to exclude disabled protocols
+                # 0 in RSE protocol definition = disabled, 1 = highest priority
+                rse_info[rse]['priority_wan'] = {p['scheme']: p['domains']['wan']['read'] for p in rse_info[rse]['protocols'] if p['domains']['wan']['read'] > 0}
+                rse_info[rse]['priority_lan'] = {p['scheme']: p['domains']['lan']['read'] for p in rse_info[rse]['protocols'] if p['domains']['lan']['read'] > 0}
 
                 # select the lan door in autoselect mode, otherwise use the wan door
                 if domain is None:
diff --git a/lib/rucio/tests/test_replica_sorting.py b/lib/rucio/tests/test_replica_sorting.py
index 7c49d941a..6be7089de 100644
--- a/lib/rucio/tests/test_replica_sorting.py
+++ b/lib/rucio/tests/test_replica_sorting.py
@@ -190,6 +190,29 @@ class TestReplicaSorting(object):
         # assert_in('domain="wan" priority="6">root://root.blackmesa.com:1409//lambda/complex/mock/58/b5/element_0', ml)
         # assert_not_in('priority="7"', ml)
 
+        # ensure correct handling of disabled protocols
+        add_protocol(self.rse1, {'scheme': 'root',
+                                 'hostname': 'root2.aperture.com',
+                                 'port': 1409,
+                                 'prefix': '//test/chamber/',
+                                 'impl': 'rucio.rse.protocols.xrootd.Default',
+                                 'domains': {
+                                     'lan': {'read': 1, 'write': 1, 'delete': 1},
+                                     'wan': {'read': 0, 'write': 0, 'delete': 0}}})
+
+        ml = self.rc.list_replicas(dids=[{'scope': 'mock',
+                                          'name': f['name'],
+                                          'type': 'FILE'} for f in self.files],
+                                   schemes=['root', 'gsiftp', 'davs'],
+                                   metalink=True,
+                                   client_location={'site': 'BLACKMESA'})
+        assert_in('domain="lan" priority="1" client_extract="false">root://root.blackmesa.com:1409//lambda/complex/mock/58/b5/element_0', ml)
+        assert_in('domain="lan" priority="2" client_extract="false">gsiftp://gsiftp.blackmesa.com:8446/lambda/complex/mock/58/b5/element_0', ml)
+        assert_in('domain="wan" priority="3" client_extract="false">root://root.aperture.com:1409//test/chamber/mock/58/b5/element_0', ml)
+        assert_in('domain="wan" priority="4" client_extract="false">davs://davs.aperture.com:443/test/chamber/mock/58/b5/element_0', ml)
+        assert_in('domain="wan" priority="5" client_extract="false">gsiftp://gsiftp.aperture.com:8446/test/chamber/mock/58/b5/element_0', ml)
+        assert_not_in('priority="6"', ml)
+
         delete_replicas(rse=self.rse1, files=self.files)
         delete_replicas(rse=self.rse2, files=self.files)
         del_rse(self.rse1)