Exemple #1
0
 def test_update_new_dids(self):
     """ DATA IDENTIFIERS (API): List new identifiers and update the flag new """
     tmp_scope = scope_name_generator()
     tmp_dsn = 'dsn_%s' % generate_uuid()
     scope.add_scope(tmp_scope, 'jdoe', 'jdoe')
     dids = []
     for i in xrange(0, 5):
         d = {
             'scope': tmp_scope,
             'name': '%s-%i' % (tmp_dsn, i),
             'did_type': DIDType.DATASET
         }
         did.add_did(scope=tmp_scope,
                     name='%s-%i' % (tmp_dsn, i),
                     type='DATASET',
                     issuer='root')
         dids.append(d)
     st = did.set_new_dids(dids, None)
     assert_true(st)
     with assert_raises(DataIdentifierNotFound):
         did.set_new_dids([{
             'scope': 'dummyscope',
             'name': 'dummyname',
             'did_type': DIDType.DATASET
         }], None)
Exemple #2
0
    def test_api_did(self):
        """ DID (API): Test external representation of DIDs """
        # add some dids
        add_did(self.scope_name, 'ext_parent', 'container', issuer='root', account=self.account_name, **self.vo)
        add_did(self.scope_name, 'ext_child', 'dataset', issuer='root', account=self.account_name, **self.vo)
        attachment = {'scope': self.scope_name, 'name': 'ext_parent',
                      'dids': [{'scope': self.scope_name, 'name': 'ext_child', 'type': 'DATASET'}]}
        attach_dids_to_dids([attachment], issuer='root', **self.vo)

        # test scope_list
        out = scope_list(self.scope_name, recursive=True, **self.vo)
        out = list(out)
        assert_not_equal(0, len(out))
        parent_found = False
        for did in out:
            assert_equal(did['scope'], self.scope_name)
            if did['parent'] is not None:
                parent_found = True
                assert_equal(did['parent']['scope'], self.scope_name)
        assert_true(parent_found)

        # test get_did
        add_did_to_followed(self.scope_name, 'ext_parent', self.account_name, **self.vo)
        out = get_users_following_did('ext_parent', self.scope_name, **self.vo)
        out = list(out)
        assert_not_equal(0, len(out))
        for user in out:
            assert_equal(user['user'], self.account_name)
Exemple #3
0
    def register_container(self):
        self.container_exists = False
        if self.is_at_pnn and self.dry_run:
            logging.info('Dry Run: Create container %s in scope %s.',
                         self.container, self.scope)
            self.container_exists = True
            return self.container_exists

        try:
            get_did(scope=self.scope, name=self.container)
            monitor.record_counter('cms_sync.container_exists')
            self.container_exists = True
            logging.info('Found container %s', self.container)
        except DataIdentifierNotFound:
            if self.is_at_pnn:
                try:
                    logging.info('Create container %s in scope %s.',
                                 self.container, self.scope)
                    add_did(scope=self.scope,
                            name=self.container,
                            type='CONTAINER',
                            issuer=self.account,
                            lifetime=self.lifetime)
                    monitor.record_counter('cms_sync.container_created')
                    self.container_exists = True
                    logging.info('Created container %s in scope %s.',
                                 self.container, self.scope)
                except DataIdentifierAlreadyExists:
                    logging.warning('Container was created in the meanwhile')
                    monitor.record_counter('cms_sync.container_collision')
                    self.container_exists = True
            else:
                logging.warning('Container was not at PNN')

        return self.container_exists
Exemple #4
0
    def register_block(self):
        """
        Register the dataset (if there is a replica at the pnn) and attach to container
        :dry: Dry run. Default false.
        """

        # FIXME: The logic here could use some improvement as we try to create a block even if it exists already

        try:
            get_did(scope=self.scope, name=self.block_name)
            self.block_exists = True
            monitor.record_counter('cms_sync.dataset_exists')
        except DataIdentifierNotFound:
            self.block_exists = False

        if self.is_at_pnn and self.dry_run:
            logging.info('Dry Run: Create dataset %s in scope %s.',
                         self.block_name, self.scope)
            self.block_exists = True
        elif self.is_at_pnn:
            logging.info('Create block %s in scope %s.', self.block_name,
                         self.scope)
            try:
                if not self.block_exists:
                    add_did(scope=self.scope,
                            name=self.block_name,
                            type='DATASET',
                            issuer=self.account,
                            lifetime=self.lifetime)
                    monitor.record_counter('cms_sync.dataset_created')
            except DataIdentifierAlreadyExists:
                logging.warning('Attempt to add %s:%s failed, already exists.',
                                self.scope, self.block_name)
                monitor.record_counter('cms_sync.dataset_collision')

            try:
                attach_dids(scope=self.scope,
                            name=self.container,
                            attachment={
                                'dids': [{
                                    'scope': self.scope,
                                    'name': self.block_name
                                }]
                            },
                            issuer=self.account)
            except DuplicateContent:
                logging.warning(
                    'Attempt to add %s:%s to %s failed, already exists.',
                    self.scope, self.block_name, self.container)
            except DataIdentifierNotFound:
                logging.error(
                    'Attempt to add %s:%s to %s failed. Container does not exist.',
                    self.scope, self.block_name, self.container)
                return False
            self.block_exists = True
        else:
            logging.warning('Block %s was not at PNN', self.block_name)

        return self.block_exists
Exemple #5
0
    def POST(self, scope, name):
        """
        Create a new data identifier.

        HTTP Success:
            200 OK

        HTTP Error:
            401 Unauthorized
            500 InternalError

        :param scope: Create the data identifier within this scope.
        :param name: Create the data identifier with this name.
        """
        statuses, meta, rules, lifetime, dids, rse = {}, {}, [], None, [], None
        try:
            json_data = loads(data())
            type = json_data['type']
            if 'statuses' in json_data:
                statuses = json_data['statuses']
            if 'meta' in json_data:
                meta = json_data['meta']
            if 'rules' in json_data:
                rules = json_data['rules']
            if 'lifetime' in json_data:
                lifetime = json_data['lifetime']
            if 'dids' in json_data:
                dids = json_data['dids']
            if 'rse' in json_data:
                rse = json_data['rse']
        except ValueError:
            raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter list')
        except KeyError as error:
            raise generate_http_error(400, 'ValueError', str(error))

        try:
            add_did(scope=scope, name=name, type=type, statuses=statuses, meta=meta, rules=rules, lifetime=lifetime, dids=dids, rse=rse, issuer=ctx.env.get('issuer'))
        except DataIdentifierNotFound as error:
            raise generate_http_error(404, 'DataIdentifierNotFound', error.args[0])
        except DuplicateContent as error:
            raise generate_http_error(409, 'DuplicateContent', error.args[0])
        except DataIdentifierAlreadyExists as error:
            raise generate_http_error(409, 'DataIdentifierAlreadyExists', error.args[0])
        except AccessDenied as error:
            raise generate_http_error(401, 'AccessDenied', error.args[0])
        except UnsupportedOperation as error:
            raise generate_http_error(409, 'UnsupportedOperation', error.args[0])
        except DatabaseException as error:
            raise generate_http_error(500, 'DatabaseException', error.args[0])
        except RucioException as error:
            raise generate_http_error(500, error.__class__.__name__, error.args[0])
        except Exception as error:
            print(format_exc())
            raise InternalError(error)
        raise Created()
    def register_and_attach_did(self, scope='cms', name=None, did_type=None, parent_did=None):

        existed = False
        created = False
        attached = False
        already_attached = False

        try:
            get_did(scope=scope, name=name)
            existed = True
            logging.info('DID existed: %s %s:%s', did_type, scope, name)
        except DataIdentifierNotFound:
            try:
                add_did(scope=scope, name=name, type=did_type,
                        issuer=self.account, lifetime=self.lifetime)
                created = True
                logging.info('Created DID: %s %s:%s', did_type, scope, name)
            except:
                logging.critical('Attempt to add %s:%s failed. Unknown', scope, name)
                logging.critical('Reg and attach exiting. Existed %s, created %s, attached %s', existed, created,
                                 attached)
        except:
            logging.critical('Attempt to get %s:%s failed. Unknown', scope, name)
            logging.critical('Reg and attach exiting. Existed %s, created %s, attached %s', existed, created,
                             attached)

        if parent_did:
            try:
                attach_dids(scope=scope, name=parent_did,
                            attachment={'dids': [{'scope': scope, 'name': name}]}, issuer=self.account)
                logging.info('Attached %s to %s', name, parent_did)
                attached = True
            except DuplicateContent:
                logging.warning('Attempt to add %s:%s to %s failed, already exists.',
                                self.scope, self.block_name, self.container)
                attached = True
                already_attached = True
            except DataIdentifierNotFound:
                logging.critical('Attempt to add %s to %s failed. Parent does not exist.',
                                 self.block_name, self.container)
                logging.critical('Reg and attach failed to attach. Existed %s, created %s, attached %s', existed,
                                 created,
                                 attached)
            except:
                logging.critical('Attempt to attach %s to %s failed. Unknown', name, parent_did)
                logging.critical('Reg and attach failed to attach. Existed %s, created %s, attached %s', existed,
                                 created,
                                 attached)
                self.block_exists = True

        return existed, created, attached, already_attached
Exemple #7
0
    def test_api_subscription(self):
        """ SUBSCRIPTION (API): Test external representation of subscriptions """

        sub = 'ext_' + generate_uuid()
        did = 'ext_' + generate_uuid()
        new_acc_name = ''.join(random.choice(string.ascii_lowercase) for x in range(10))
        new_scope_name = ''.join(random.choice(string.ascii_lowercase) for x in range(10))
        add_account(new_acc_name, 'USER', '*****@*****.**', 'root', **self.new_vo)
        add_scope(new_scope_name, new_acc_name, 'root', **self.new_vo)
        api_acc_lim.set_local_account_limit(new_acc_name, self.rse3_name, 10, 'root', **self.new_vo)
        api_acc_lim.set_local_account_limit(new_acc_name, self.rse4_name, 10, 'root', **self.new_vo)
        add_did(new_scope_name, did, 'DATASET', 'root', account=new_acc_name, rse=self.rse3_name, **self.new_vo)

        sub_id = add_subscription(sub, new_acc_name, {'account': [new_acc_name], 'scope': [new_scope_name]},
                                  [{'copies': 1, 'rse_expression': self.rse3_name, 'weight': 0, 'activity': 'User Subscriptions',
                                    'source_replica_expression': self.rse4_name}],
                                  '', False, 0, 0, 3, 'root', **self.new_vo)
        add_replication_rule(dids=[{'scope': new_scope_name, 'name': did}], copies=1, rse_expression=self.rse3_name, weight=None,
                             lifetime=180, grouping='DATASET', account=new_acc_name, locked=False, subscription_id=sub_id,
                             source_replica_expression=self.rse4_name, activity='User Subscriptions', notify=None,
                             purge_replicas=False, ignore_availability=False, comment='', ask_approval=False, asynchronous=False,
                             priority=0, split_container=False, meta='', issuer='root', **self.new_vo)

        out = list_subscriptions(sub, **self.new_vo)
        out = list(out)
        assert_not_equal(0, len(out))
        assert_in(sub_id, [o['id'] for o in out])
        for o in out:
            if o['id'] == sub_id:
                assert_equal(o['account'], new_acc_name)
                rules = loads(o['replication_rules'])[0]
                assert_equal(rules['rse_expression'], self.rse3_name)
                assert_equal(rules['source_replica_expression'], self.rse4_name)
                fil = loads(o['filter'])
                assert_equal(fil['account'], [new_acc_name])
                assert_equal(fil['scope'], [new_scope_name])

        out = list_subscription_rule_states(sub, **self.new_vo)
        out = list(out)
        assert_not_equal(0, len(out))
        for o in out:
            assert_equal(o.account, new_acc_name)

        out = get_subscription_by_id(sub_id, **self.new_vo)
        assert_equal(out['account'], new_acc_name)
        rules = loads(out['replication_rules'])[0]
        assert_equal(rules['rse_expression'], self.rse3_name)
        assert_equal(rules['source_replica_expression'], self.rse4_name)
        fil = loads(out['filter'])
        assert_equal(fil['account'], [new_acc_name])
        assert_equal(fil['scope'], [new_scope_name])
Exemple #8
0
    def test_api_request(self):
        """ REQUEST (API): Test external representation of requests """

        did = generate_uuid()
        add_did(self.scope_name, did, 'dataset', issuer='root', account=self.account_name, rse=self.rse_name, **self.vo)

        requests = [{
            'dest_rse_id': self.rse2_id,
            'source_rse_id': self.rse_id,
            'request_type': constants.RequestType.TRANSFER,
            'request_id': generate_uuid(),
            'name': did,
            'scope': self.scope_name,
            'account': self.account_name,
            'rule_id': generate_uuid(),
            'retry_count': 1,
            'requested_at': datetime.now(),
            'attributes': {
                'activity': 'User Subscription',
                'bytes': 10,
                'md5': '',
                'adler32': ''
            }
        }]

        reqs = queue_requests(requests, issuer='root', **self.vo)  # this does not pass in the source rse
        reqs = list(reqs)
        assert_not_equal(0, len(reqs))
        for r in reqs:
            assert_equal(r['scope'], self.scope_name)
            assert_equal(r['account'], self.account_name)
            assert_equal(r['source_rse'], self.rse_name)
            assert_equal(r['dest_rse'], self.rse2_name)

        out = get_request_by_did(self.scope_name, did, self.rse2_name, issuer='root', **self.vo)
        assert_equal(out['scope'], self.scope_name)
        assert_equal(out['account'], self.account_name)
        assert_equal(out['dest_rse'], self.rse2_name)
        assert_equal(out['source_rse'], self.rse_name)

        out = list_requests([self.rse_name], [self.rse2_name], [constants.RequestState.QUEUED], issuer='root', **self.vo)
        out = list(out)
        assert_not_equal(0, len(out))
        assert_in(self.scope_name, [req['scope'] for req in out])
        for req in out:
            if req['scope'] == self.scope_name:
                assert_equal(req['scope'], self.scope_name)
                assert_equal(req['account'], self.account_name)
                assert_equal(req['dest_rse'], self.rse2_name)
                assert_equal(req['source_rse'], self.rse_name)
Exemple #9
0
 def test_list_new_dids(self):
     """ DATA IDENTIFIERS (API): List new identifiers """
     tmp_scope = scope_name_generator()
     tmp_dsn = 'dsn_%s' % generate_uuid()
     scope.add_scope(tmp_scope, 'jdoe', 'jdoe')
     for i in xrange(0, 5):
         did.add_did(scope=tmp_scope, name='%s-%i' % (tmp_dsn, i), type='DATASET', issuer='root')
     for i in did.list_new_dids('DATASET'):
         assert_not_equal(i, {})
         assert_equal(str(i['did_type']), 'DATASET')
         break
     for i in did.list_new_dids():
         assert_not_equal(i, {})
         break
Exemple #10
0
 def test_update_new_dids(self):
     """ DATA IDENTIFIERS (API): List new identifiers and update the flag new """
     tmp_scope = scope_name_generator()
     tmp_dsn = 'dsn_%s' % generate_uuid()
     scope.add_scope(tmp_scope, 'jdoe', 'jdoe')
     dids = []
     for i in xrange(0, 5):
         d = {'scope': tmp_scope, 'name': '%s-%i' % (tmp_dsn, i), 'did_type': DIDType.DATASET}
         did.add_did(scope=tmp_scope, name='%s-%i' % (tmp_dsn, i), type='DATASET', issuer='root')
         dids.append(d)
     st = did.set_new_dids(dids, None)
     assert_true(st)
     with assert_raises(DataIdentifierNotFound):
         did.set_new_dids([{'scope': 'dummyscope', 'name': 'dummyname', 'did_type': DIDType.DATASET}], None)
Exemple #11
0
 def test_list_new_dids(self):
     """ DATA IDENTIFIERS (API): List new identifiers """
     tmp_scope = scope_name_generator()
     tmp_dsn = 'dsn_%s' % generate_uuid()
     scope.add_scope(tmp_scope, 'jdoe', 'jdoe', **self.vo)
     for i in range(0, 5):
         did.add_did(scope=tmp_scope, name='%s-%i' % (tmp_dsn, i), type='DATASET', issuer='root', **self.vo)
     for i in did.list_new_dids('DATASET', **self.vo):
         assert i != {}
         assert str(i['did_type']) == 'DATASET'
         break
     for i in did.list_new_dids(**self.vo):
         assert i != {}
         break
Exemple #12
0
    def test_api_did(self):
        """ DID (API): Test external representation of DIDs """
        # add some dids
        ext_parent = did_name_generator('container')
        ext_child = did_name_generator('dataset')
        add_did(self.scope_name,
                ext_parent,
                'container',
                issuer='root',
                account=self.account_name,
                **self.vo)
        add_did(self.scope_name,
                ext_child,
                'dataset',
                issuer='root',
                account=self.account_name,
                **self.vo)
        attachment = {
            'scope':
            self.scope_name,
            'name':
            ext_parent,
            'dids': [{
                'scope': self.scope_name,
                'name': ext_child,
                'type': 'DATASET'
            }]
        }
        attach_dids_to_dids([attachment], issuer='root', **self.vo)

        # test scope_list
        out = scope_list(self.scope_name, recursive=True, **self.vo)
        out = list(out)
        assert 0 != len(out)
        parent_found = False
        for did in out:
            assert did['scope'] == self.scope_name
            if did['parent'] is not None:
                parent_found = True
                assert did['parent']['scope'] == self.scope_name
        assert parent_found

        # test get_did
        add_did_to_followed(self.scope_name, ext_parent, self.account_name,
                            **self.vo)
        out = get_users_following_did(ext_parent, self.scope_name, **self.vo)
        out = list(out)
        assert 0 != len(out)
        for user in out:
            assert user['user'] == self.account_name
Exemple #13
0
 def test_list_new_dids(self):
     """ DATA IDENTIFIERS (API): List new identifiers """
     tmp_scope = scope_name_generator()
     tmp_dsn = 'dsn_%s' % generate_uuid()
     scope.add_scope(tmp_scope, 'jdoe', 'jdoe')
     for i in range(0, 5):
         did.add_did(scope=tmp_scope, name='%s-%i' % (tmp_dsn, i), type='DATASET', issuer='root')
     for i in did.list_new_dids('DATASET'):
         assert_not_equal(i, {})
         assert_equal(str(i['did_type']), 'DATASET')
         break
     for i in did.list_new_dids():
         assert_not_equal(i, {})
         break
Exemple #14
0
 def test_dids_at_different_vos(self):
     """ MULTI VO (CLIENT): Test that dids from 2nd vo don't interfere """
     scope_uuid = str(generate_uuid()).lower()[:16]
     scope = 'shr_%s' % scope_uuid
     add_scope(scope, 'root', 'root', **self.vo)
     add_scope(scope, 'root', 'root', **self.new_vo)
     did_client = DIDClient()
     did_uuid = str(generate_uuid()).lower()[:16]
     tst = 'tstset_%s' % did_uuid
     new = 'newset_%s' % did_uuid
     shr = 'shrset_%s' % did_uuid
     did_client.add_did(scope, tst, 'DATASET')
     did_client.add_did(scope, shr, 'DATASET')
     add_did(scope, new, 'DATASET', 'root', **self.new_vo)
     add_did(scope, shr, 'DATASET', 'root', **self.new_vo)
     did_list_tst = list(did_client.list_dids(scope, {}))
     did_list_new = list(list_dids(scope, {}, **self.new_vo))
     assert_true(tst in did_list_tst)
     assert_false(new in did_list_tst)
     assert_true(shr in did_list_tst)
     assert_false(tst in did_list_new)
     assert_true(new in did_list_new)
     assert_true(shr in did_list_new)
Exemple #15
0
    def test_api_replica(self):
        """ REPLICA (API): Test external representation of replicas """

        did = 'ext_' + str(generate_uuid())
        pfn = 'srm://mock2.com:8443/srm/managerv2?SFN=/rucio/tmpdisk/rucio_tests/%s/%s' % (self.scope_name, generate_uuid())
        add_replicas(self.rse2_name, files=[{'scope': self.scope_name, 'name': did, 'bytes': 100, 'pfn': pfn}], issuer='root', **self.vo)

        add_did(self.scope_name, 'ext_parent_2', 'dataset', issuer='root', account=self.account_name, **self.vo)
        attachment = {'scope': self.scope_name, 'name': 'ext_parent_2',
                      'dids': [{'scope': self.scope_name, 'name': did}]}
        attach_dids_to_dids([attachment], issuer='root', **self.vo)

        out = get_did_from_pfns([pfn], self.rse2_name, **self.vo)
        out = list(out)
        assert_not_equal(0, len(out))
        did_found = False
        for p in out:
            for key in p:
                if p[key]['name'] == did:
                    did_found = True
                    assert_equal(self.scope_name, p[key]['scope'])
        assert_true(did_found)

        out = list_replicas(dids=[{'scope': self.scope_name, 'name': did}], resolve_parents=True, **self.vo)
        out = list(out)
        assert_not_equal(0, len(out))
        parents_found = False
        for rep in out:
            assert_equal(rep['scope'], self.scope_name)
            if 'parents' in rep:
                parents_found = True
                for parent in rep['parents']:
                    assert_in(self.scope_name, parent)
                    if self.multi_vo:
                        assert_not_in(self.scope.internal, parent)
        assert_true(parents_found)
Exemple #16
0
    def post(self, scope_name):
        """
        Create a new data identifier.

        .. :quickref: DIDs; Create a new DID.

        .. sourcecode:: http

            POST /dids/scope1/container1 HTTP/1.1
            Host: rucio.cern.ch

            {"type": "CONTAINER", "lifetime": 86400},

        **Example response**:

        .. sourcecode:: http

            HTTP/1.1 201 Created
            Vary: Accept

        :reqheader Accept: application/json
        :param scope_name: data identifier (scope)/(name).
        :<json string type: the new DID type
        :<json dict statuses: Dictionary with statuses, e.g. {'monotonic':True}
        :<json dict meta: Dictionary with metadata, e.g. {'length':1234}
        :<json dict rules: Replication rules associated with the did. e.g., [{'copies': 2, 'rse_expression': 'TIERS1'}, ]
        :<json int lifetime: DID's liftime in seconds.
        :<json list dids: The content.
        :<json string rse: The RSE name when registering replicas.
        :status 201: new DIDs created
        :status 401: Invalid Auth Token
        :status 409: DID already exists
        """
        try:
            scope, name = parse_scope_name(scope_name, request.environ.get('vo'))
        except ValueError as error:
            return generate_http_error_flask(400, error)

        parameters = json_parameters()
        type_param = param_get(parameters, 'type')

        try:
            add_did(
                scope=scope,
                name=name,
                type=type_param,
                statuses=param_get(parameters, 'statuses', default={}),
                meta=param_get(parameters, 'meta', default={}),
                rules=param_get(parameters, 'rules', default=[]),
                lifetime=param_get(parameters, 'lifetime', default=None),
                dids=param_get(parameters, 'dids', default=[]),
                rse=param_get(parameters, 'rse', default=None),
                issuer=request.environ.get('issuer'),
                vo=request.environ.get('vo'),
            )
        except (InvalidObject, InvalidPath) as error:
            return generate_http_error_flask(400, error)
        except (DataIdentifierNotFound, ScopeNotFound) as error:
            return generate_http_error_flask(404, error)
        except (DuplicateContent, DataIdentifierAlreadyExists, UnsupportedOperation) as error:
            return generate_http_error_flask(409, error)
        except AccessDenied as error:
            return generate_http_error_flask(401, error)

        return 'Created', 201
Exemple #17
0
            if 'dids' in json_data:
                dids = json_data['dids']
            if 'rse' in json_data:
                rse = json_data['rse']
        except ValueError:
            return generate_http_error_flask(
                400, 'ValueError', 'Cannot decode json parameter list')
        except KeyError, error:
            return generate_http_error_flask(400, 'ValueError', str(error))

        try:
            add_did(scope=scope,
                    name=name,
                    type=type,
                    statuses=statuses,
                    meta=meta,
                    rules=rules,
                    lifetime=lifetime,
                    dids=dids,
                    rse=rse,
                    issuer=request.environ.get('issuer'))
        except DataIdentifierNotFound, error:
            return generate_http_error_flask(404, 'DataIdentifierNotFound',
                                             error.args[0][0])
        except DuplicateContent, error:
            return generate_http_error_flask(409, 'DuplicateContent',
                                             error.args[0][0])
        except DataIdentifierAlreadyExists, error:
            return generate_http_error_flask(409,
                                             'DataIdentifierAlreadyExists',
                                             error.args[0][0])
        except AccessDenied, error:
Exemple #18
0
    create_root_account()
    add_account_identity('/CN=docker client',
                         'x509',
                         'root',
                         '*****@*****.**',
                         issuer="root")

    # Create a user called jdoe
    add_account('jdoe', 'USER', 'test', 'root')

    # Add 2 scopes
    add_scope('user.jdoe', 'jdoe', 'root')
    add_scope('tests', 'root', 'root')

    # Create a test dataset for jdoe
    add_did('user.jdoe', 'test1', 'DATASET', 'root', account='jdoe')

    # Create 2 sites into the /tmp partition
    os.mkdir('/tmp/SITE2_DISK')
    os.mkdir('/tmp/SITE1_DISK')

    params = {
        'scheme': 'file',
        'prefix': '/tmp/SITE1_DISK/',
        'impl': 'rucio.rse.protocols.posix.Default',
        'domains': {
            "lan": {
                "read": 1,
                "write": 1,
                "delete": 1
            },
Exemple #19
0
    def test_api_replica(self):
        """ REPLICA (API): Test external representation of replicas """

        did = did_name_generator('file')
        did_parent = did_name_generator('dataset')
        pfn = 'srm://mock2.com:8443/srm/managerv2?SFN=/rucio/tmpdisk/rucio_tests/%s/%s' % (
            self.scope_name, generate_uuid())
        add_replicas(self.rse2_name,
                     files=[{
                         'scope': self.scope_name,
                         'name': did,
                         'bytes': 100,
                         'pfn': pfn
                     }],
                     issuer='root',
                     **self.vo)

        add_did(self.scope_name,
                did_parent,
                'dataset',
                issuer='root',
                account=self.account_name,
                **self.vo)
        attachment = {
            'scope': self.scope_name,
            'name': did_parent,
            'dids': [{
                'scope': self.scope_name,
                'name': did
            }]
        }
        attach_dids_to_dids([attachment], issuer='root', **self.vo)

        out = get_did_from_pfns([pfn], self.rse2_name, **self.vo)
        out = list(out)
        assert 0 != len(out)
        did_found = False
        for p in out:
            for key in p:
                if p[key]['name'] == did:
                    did_found = True
                    assert self.scope_name == p[key]['scope']
        assert did_found

        out = list_replicas(dids=[{
            'scope': self.scope_name,
            'name': did
        }],
                            resolve_parents=True,
                            **self.vo)
        out = list(out)
        assert 0 != len(out)
        parents_found = False
        for rep in out:
            assert rep['scope'] == self.scope_name
            if 'parents' in rep:
                parents_found = True
                for parent in rep['parents']:
                    assert self.scope_name in parent
                    if self.multi_vo:
                        assert self.scope.internal not in parent
        assert parents_found
Exemple #20
0
def make_block(mock_request, did_metadata, rse, n_files):
    # Open a new block
    blockname = mock_request["outputdataset"] + "#" + str(uuid.uuid1())
    # client.add_dataset(scope="cms", name=blockname, meta=did_metadata)
    add_did(scope="cms",
            name=blockname,
            type="DATASET",
            issuer="wma_prod",
            account="wma_prod",
            meta=did_metadata)

    # Here we place a rule with a lifetime so that the block will be deleted.
    # The file source replicas will not go away until a rule is placed on them
    # and subsequently expired: the transition lock count 1 -> 0 sets a "tombstone"
    # which marks the replica as candidate for deletion.
    # The container rule will still collect the output before these files are removed
    client.add_replication_rule(
        dids=[{
            "scope": "cms",
            "name": blockname
        }],
        copies=1,
        rse_expression=rse,
        comment="Production block protection",
        meta=json.dumps({
            # Here it may be useful to save some metadata that ties the block to the workflow
            "workflow": "workflow_name",
            "agent": "agent_name",
        }),
        # Activity is probably optional as the rule should not cause any transfer requests
        activity="Production Output",
        # The lifetime is somewhat arbitrary, as even if the rule expires, any replicas that
        # are needed for transfer (to satsify the container rule) will not be removed until
        # the transfers complete, so there is no race condition.
        # *update* since TaskChains may force these blocks to stay at a site for indefinite period,
        # we let WMAgent hold onto the rule and release it when they deem appropriate
        # lifetime=datetime.timedelta(days=7).total_seconds(),
    )

    # For the container rule to be updated, we have to attach the block to the container
    client.add_datasets_to_container(
        scope="cms",
        name=mock_request["outputdataset"],
        dsns=[{
            "scope": "cms",
            "name": blockname
        }],
    )

    # Inject some file DIDs and source replicas into an RSE
    lfns = []
    for _ in range(n_files):
        lfn = "/store/mc/{campaign}/{pd}/AODSIM/{ps}/{uuid}.root".format(
            campaign=mock_request["campaign"],
            pd=mock_request["primarydataset"],
            ps=mock_request["processingstring"],
            uuid=uuid.uuid1(),
        )
        # This creates a DID and adds replica in one call
        client.add_replica(
            rse=rse,
            scope="cms",
            name=lfn,
            bytes=int(random.gauss(3e9, 2e8)),
            adler32="12341234",
        )
        lfns.append({"scope": "cms", "name": lfn})

    # Add the files to the block
    client.attach_dids(scope="cms", name=blockname, dids=lfns)

    # Here we close the block, saying no more files will be added
    client.close(scope="cms", name=blockname)
Exemple #21
0
    def post(self, scope, name):
        """
        Create a new data identifier.

        .. :quickref: DIDs; Create a new DID.

        .. sourcecode:: http

            POST /dids/scope1/container1 HTTP/1.1
            Host: rucio.cern.ch

            {"type": "CONTAINER", "lifetime": 86400},

        **Example response**:

        .. sourcecode:: http

            HTTP/1.1 201 Created
            Vary: Accept

        :reqheader Accept: application/json
        :param scope: data identifier scope.
        :param name: data identifier name.
        :<json string type: the new DID type
        :<json dict statuses: Dictionary with statuses, e.g. {'monotonic':True}
        :<json dict meta: Dictionary with metadata, e.g. {'length':1234}
        :<json dict rules: Replication rules associated with the did. e.g., [{'copies': 2, 'rse_expression': 'TIERS1'}, ]
        :<json int lifetime: DID's liftime in seconds.
        :<json list dids: The content.
        :<json string rse: The RSE name when registering replicas.
        :status 201: new DIDs created
        :status 401: Invalid Auth Token
        :status 409: DID already exists
        :status 500: Database Exception
        """
        statuses, meta, rules, lifetime, dids, rse = {}, {}, [], None, [], None
        try:
            json_data = loads(request.data)
            type = json_data['type']
            if 'statuses' in json_data:
                statuses = json_data['statuses']
            if 'meta' in json_data:
                meta = json_data['meta']
            if 'rules' in json_data:
                rules = json_data['rules']
            if 'lifetime' in json_data:
                lifetime = json_data['lifetime']
            if 'dids' in json_data:
                dids = json_data['dids']
            if 'rse' in json_data:
                rse = json_data['rse']
        except ValueError:
            return generate_http_error_flask(
                400, 'ValueError', 'Cannot decode json parameter list')
        except KeyError as error:
            return generate_http_error_flask(400, 'ValueError', str(error))

        try:
            add_did(scope=scope,
                    name=name,
                    type=type,
                    statuses=statuses,
                    meta=meta,
                    rules=rules,
                    lifetime=lifetime,
                    dids=dids,
                    rse=rse,
                    issuer=request.environ.get('issuer'))
        except DataIdentifierNotFound as error:
            return generate_http_error_flask(404, 'DataIdentifierNotFound',
                                             error.args[0])
        except DuplicateContent as error:
            return generate_http_error_flask(409, 'DuplicateContent',
                                             error.args[0])
        except DataIdentifierAlreadyExists as error:
            return generate_http_error_flask(409,
                                             'DataIdentifierAlreadyExists',
                                             error.args[0])
        except AccessDenied as error:
            return generate_http_error_flask(401, 'AccessDenied',
                                             error.args[0])
        except UnsupportedOperation as error:
            return generate_http_error_flask(409, 'UnsupportedOperation',
                                             error.args[0])
        except DatabaseException as error:
            return generate_http_error_flask(500, 'DatabaseException',
                                             error.args[0])
        except RucioException as error:
            return generate_http_error_flask(500, error.__class__.__name__,
                                             error.args[0])
        except Exception as error:
            print format_exc()
            return error, 500
        return "Created", 201
Exemple #22
0
    def test_subscriptions_at_different_vos(self):
        """ MULTI VO (CLIENT): Test that subscriptions from 2nd vo don't interfere """

        account_client = AccountClient()
        usr_uuid = str(generate_uuid()).lower()[:16]
        shr_acc = 'shr-%s' % usr_uuid
        account_client.add_account(shr_acc, 'USER', '*****@*****.**')
        add_account(shr_acc, 'USER', '*****@*****.**', 'root', **self.new_vo)

        scope_client = ScopeClient()
        scope_uuid = str(generate_uuid()).lower()[:16]
        tst_scope = 'tst_%s' % scope_uuid
        new_scope = 'new_%s' % scope_uuid
        scope_client.add_scope('root', tst_scope)
        add_scope(new_scope, 'root', 'root', **self.new_vo)

        did_client = DIDClient()
        did_uuid = str(generate_uuid()).lower()[:16]
        tst_did = 'tstset_%s' % did_uuid
        new_did = 'newset_%s' % did_uuid

        rse_client = RSEClient()
        rse_str = ''.join(choice(ascii_uppercase) for x in range(10))
        tst_rse1 = 'TST1_%s' % rse_str
        tst_rse2 = 'TST2_%s' % rse_str
        new_rse1 = 'NEW1_%s' % rse_str
        new_rse2 = 'NEW2_%s' % rse_str
        rse_client.add_rse(tst_rse1)
        rse_client.add_rse(tst_rse2)
        add_rse(new_rse1, 'root', **self.new_vo)
        add_rse(new_rse2, 'root', **self.new_vo)

        acc_lim_client = AccountLimitClient()
        acc_lim_client.set_local_account_limit(shr_acc, tst_rse1, 10)
        acc_lim_client.set_local_account_limit(shr_acc, tst_rse2, 10)
        set_local_account_limit(shr_acc, new_rse1, 10, 'root', **self.new_vo)
        set_local_account_limit(shr_acc, new_rse2, 10, 'root', **self.new_vo)

        did_client.add_did(tst_scope, tst_did, 'DATASET', rse=tst_rse1)
        add_did(new_scope, new_did, 'DATASET', 'root', rse=new_rse1, **self.new_vo)

        sub_client = SubscriptionClient()
        sub_str = generate_uuid()
        tst_sub = 'tstsub_' + sub_str
        new_sub = 'newsub_' + sub_str
        shr_sub = 'shrsub_' + sub_str

        tst_sub_id = sub_client.add_subscription(tst_sub, shr_acc, {'scope': [tst_scope]},
                                                 [{'copies': 1, 'rse_expression': tst_rse2, 'weight': 0,
                                                   'activity': 'User Subscriptions'}],
                                                 '', None, 0, 0)
        shr_tst_sub_id = sub_client.add_subscription(shr_sub, shr_acc, {'scope': [tst_scope]},
                                                     [{'copies': 1, 'rse_expression': tst_rse2, 'weight': 0,
                                                       'activity': 'User Subscriptions'}],
                                                     '', None, 0, 0)

        new_sub_id = add_subscription(new_sub, shr_acc, {'scope': [new_scope]},
                                      [{'copies': 1, 'rse_expression': new_rse2, 'weight': 0, 'activity': 'User Subscriptions'}],
                                      '', False, 0, 0, 3, 'root', **self.new_vo)
        shr_new_sub_id = add_subscription(shr_sub, shr_acc, {'scope': [new_scope]},
                                          [{'copies': 1, 'rse_expression': new_rse2, 'weight': 0, 'activity': 'User Subscriptions'}],
                                          '', False, 0, 0, 3, 'root', **self.new_vo)

        tst_subs = [s['id'] for s in sub_client.list_subscriptions()]
        assert_in(tst_sub_id, tst_subs)
        assert_in(shr_tst_sub_id, tst_subs)
        assert_not_in(new_sub_id, tst_subs)
        assert_not_in(shr_new_sub_id, tst_subs)

        new_subs = [s['id'] for s in list_subscriptions(**self.new_vo)]
        assert_in(new_sub_id, new_subs)
        assert_in(shr_new_sub_id, new_subs)
        assert_not_in(tst_sub_id, new_subs)
        assert_not_in(shr_tst_sub_id, new_subs)

        shr_tst_subs = [s['id'] for s in sub_client.list_subscriptions(name=shr_sub)]
        assert_in(shr_tst_sub_id, shr_tst_subs)
        assert_not_in(shr_new_sub_id, shr_tst_subs)

        shr_new_subs = [s['id'] for s in list_subscriptions(name=shr_sub, **self.new_vo)]
        assert_in(shr_new_sub_id, shr_new_subs)
        assert_not_in(shr_tst_sub_id, shr_new_subs)

        acc_tst_subs = [s['id'] for s in sub_client.list_subscriptions(account=shr_acc)]
        assert_in(tst_sub_id, acc_tst_subs)
        assert_in(shr_tst_sub_id, acc_tst_subs)
        assert_not_in(new_sub_id, acc_tst_subs)
        assert_not_in(shr_new_sub_id, acc_tst_subs)

        acc_new_subs = [s['id'] for s in list_subscriptions(account=shr_acc, **self.new_vo)]
        assert_in(new_sub_id, acc_new_subs)
        assert_in(shr_new_sub_id, acc_new_subs)
        assert_not_in(tst_sub_id, acc_new_subs)
        assert_not_in(shr_tst_sub_id, acc_new_subs)
Exemple #23
0
    def test_api_rse(self):
        """ RSE (API): Test external representation of RSEs """

        out = api_rse.get_rse(self.rse_name, **self.vo)
        assert out['rse'] == self.rse_name
        assert out['id'] == self.rse_id

        out = api_rse.list_rses(**self.new_vo)
        out = list(out)
        assert 0 != len(out)
        rse_ids = [rse['id'] for rse in out]
        assert self.rse3_id in rse_ids
        assert self.rse4_id in rse_ids
        for rse in out:
            assert 'rse' in rse
            if rse['id'] == self.rse3_id:
                assert rse['rse'] == self.rse3_name
            elif rse['id'] == self.rse4_id:
                assert rse['rse'] == self.rse4_name

        key = "KEY_" + generate_uuid()
        api_rse.add_rse_attribute(self.rse_name,
                                  key,
                                  1,
                                  issuer='root',
                                  **self.vo)
        out = api_rse.get_rses_with_attribute(key)
        out = list(out)
        assert 0 != len(out)
        for rse in out:
            assert rse['rse'] == self.rse_name

        out = api_rse.get_rse_protocols(self.rse_name,
                                        issuer='root',
                                        **self.vo)
        assert out['rse'] == self.rse_name

        # add some account and RSE counters
        rse_mock = 'MOCK4'
        rse_mock_id = get_rse_id(rse_mock, **self.vo)
        account_counter.del_counter(rse_id=rse_mock_id, account=self.account)
        account_counter.add_counter(rse_id=rse_mock_id, account=self.account)
        account_counter.increase(rse_id=rse_mock_id,
                                 account=self.account,
                                 files=1,
                                 bytes=10)
        account_counter.update_account_counter(self.account, rse_mock_id)
        did = 'file_' + generate_uuid()
        add_did(self.scope_name,
                did,
                'DATASET',
                'root',
                account=self.account_name,
                rse=rse_mock,
                **self.vo)
        abacus_rse.run(once=True)

        out = api_rse.get_rse_usage(rse_mock,
                                    per_account=True,
                                    issuer='root',
                                    **self.vo)
        assert rse_mock_id in [o['rse_id'] for o in out]
        for usage in out:
            if usage['rse_id'] == rse_mock_id:
                assert usage['rse'] == rse_mock
                accounts = [u['account'] for u in usage['account_usages']]
                assert self.account_name in accounts
                if self.multi_vo:
                    assert self.account.internal not in accounts

        # clean up files
        cleaner.run(once=True)
        if self.multi_vo:
            reaper.run(once=True,
                       include_rses='vo=%s&(%s)' % (self.vo['vo'], rse_mock),
                       greedy=True)
        else:
            reaper.run(once=True, include_rses=rse_mock, greedy=True)
        abacus_rse.run(once=True)

        out = api_rse.parse_rse_expression(
            '%s|%s' % (self.rse_name, self.rse2_name), **self.vo)
        assert self.rse_name in out
        assert self.rse2_name in out
        assert self.rse_id not in out
        assert self.rse2_id not in out