Skip to content

Commit ebe3a0c

Browse files
committed
Merge branch 'master' of https://github.com/Chaffelson/nipyapi into next
� Conflicts: � nipyapi/canvas.py � nipyapi/versioning.py � resources/docker/tox-full/docker-compose.yml � tests/test_canvas.py
2 parents 12b77fe + b5297c2 commit ebe3a0c

File tree

14 files changed

+432
-26
lines changed

14 files changed

+432
-26
lines changed

docs/devnotes.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ Decision Points
1414
* We use Google style Docstrings to better enable Sphinx to produce nicely readable documentation
1515

1616

17+
Testing Notes
18+
-------------
19+
20+
When running tests on new code, you are advised to run 'test_default' first, then 'test_regression', then finally 'test_security'.
21+
Because of the way errors are propagated you may have code failures which cause a teardown which then fails because of security controls, which can then obscure the original error.
22+
23+
1724
Docker Test Environment
1825
-----------------------
1926

@@ -23,6 +30,30 @@ There is an Apache NiFi image available on Dockerhub::
2330

2431
There are a couple of configuration files for launching various Docker environment configurations in ./test_env_config for convenience.
2532

33+
Remote Testing on Centos7
34+
-------------------------
35+
36+
Deploy a 4x16 or better on EC2 running Centos 7.5 or better, ssh in as root::
37+
38+
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
39+
yum update -y
40+
yum install -y centos-release-scl yum-utils device-mapper-persistent-data lvm2
41+
yum install -y rh-python36 docker
42+
systemctl start docker
43+
scl enable rh-python36 bash
44+
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
45+
sudo chmod +x /usr/local/bin/docker-compose
46+
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
47+
48+
Set up remote execution environment to this server from your IDE, such as PyCharm.
49+
Python3 will be in a path like /opt/rh/rh-python36/root/usr/bin/python
50+
These commands are conveniently presented in /resources/test_setup/setup_centos7.sh
51+
52+
You will then want to open up /home/centos/tmp/<pycharmprojectname>/resources/docker/tox-full and run::
53+
54+
docker-compose pull
55+
docker-compose up -d
56+
2657
Testing on OSX
2758
--------------
2859

nipyapi/canvas.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,14 +1338,16 @@ def get_remote_process_group(rpg_id, summary=False):
13381338
return out
13391339

13401340

1341-
def create_remote_process_group(target_uris, transport='RAW', pg_id='root', position=None):
1341+
def create_remote_process_group(target_uris, transport='RAW', pg_id='root',
1342+
position=None):
13421343
"""
13431344
Creates a new Remote Process Group with given parameters
13441345
13451346
Args:
13461347
target_uris (str): Comma separated list of target URIs
13471348
transport (str): optional, RAW or HTTP
1348-
pg_id (str): optional, UUID of parent Process Group for remote process group
1349+
pg_id (str): optional, UUID of parent Process Group for remote
1350+
process group
13491351
position (tuple): optional, tuple of location ints
13501352
13511353
Returns:
@@ -1388,18 +1390,21 @@ def delete_remote_process_group(rpg, refresh=True):
13881390
assert isinstance(rpg, nipyapi.nifi.RemoteProcessGroupEntity)
13891391
if refresh:
13901392
rpg = get_remote_process_group(rpg.id)
1393+
handle = nipyapi.nifi.RemoteProcessGroupsApi()
13911394
with nipyapi.utils.rest_exceptions():
1392-
return nipyapi.nifi.RemoteProcessGroupsApi().remove_remote_process_group(
1395+
return handle.remove_remote_process_group(
13931396
id=rpg.id,
13941397
version=rpg.revision.version
13951398
)
13961399

13971400

13981401
def set_remote_process_group_transmission(rpg, enable=True, refresh=True):
13991402
"""
1403+
Enable or Disable Transmission for an RPG
14001404
14011405
Args:
1402-
rpg (RemoteProcessGroupEntity): The ID of the remote process group to modify
1406+
rpg (RemoteProcessGroupEntity): The ID of the remote process group
1407+
to modify
14031408
enable (bool): True to enable, False to disable
14041409
refresh (bool): Whether to refresh the object before action
14051410
@@ -1410,8 +1415,9 @@ def set_remote_process_group_transmission(rpg, enable=True, refresh=True):
14101415
assert isinstance(enable, bool)
14111416
if refresh:
14121417
rpg = get_remote_process_group(rpg.id)
1418+
handle = nipyapi.nifi.RemoteProcessGroupsApi()
14131419
with nipyapi.utils.rest_exceptions():
1414-
return nipyapi.nifi.RemoteProcessGroupsApi().update_remote_process_group_run_status(
1420+
return handle.update_remote_process_group_run_status(
14151421
id=rpg.id,
14161422
body=nipyapi.nifi.RemotePortRunStatusEntity(
14171423
state='TRANSMITTING' if enable else 'STOPPED',
@@ -1482,6 +1488,7 @@ def get_funnel(funnel_id):
14821488

14831489
def create_funnel(pg_id, position=None):
14841490
"""
1491+
Creates a Funnel Object
14851492
14861493
Args:
14871494
pg_id (str): ID of the parent Process Group
@@ -1510,6 +1517,7 @@ def create_funnel(pg_id, position=None):
15101517

15111518
def delete_funnel(funnel, refresh=True):
15121519
"""
1520+
Deletes a Funnel Object
15131521
15141522
Args:
15151523
funnel (FunnelEntity): The Funnel to delete

nipyapi/security.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def create_service_user_group(identity, service='nifi',
145145
Args:
146146
identity (str): Identity string for the user group
147147
service (str): 'nifi' or 'registry'
148-
users (list): A list of UserEntities belonging to the group
148+
users (list): A list of nifi.UserEntity or registry.User belonging to the group
149149
strict (bool): Whether to throw an error on already exists
150150
151151
Returns:
@@ -751,7 +751,9 @@ def bootstrap_security_policies(service, user_identity=None,
751751
None
752752
753753
"""
754-
assert service in _valid_services
754+
assert service in _valid_services, "service not in %s" % _valid_services
755+
if user_identity is not None:
756+
assert user_identity in [nipyapi.nifi.UserEntity, nipyapi.registry.User]
755757
if 'nifi' in service:
756758
rpg_id = nipyapi.canvas.get_root_pg_id()
757759
if user_identity is None and group_identity is None:

nipyapi/templates.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,15 @@ def get_template_by_name(name):
4646
return None
4747

4848

49-
def get_template(identifier, identifier_type='name'):
49+
def get_template(identifier, identifier_type='name', greedy=False):
5050
"""
5151
Filters the list of all Templates for a given string in a given field.
5252
Note that filters are configured in config.py
5353
5454
Args:
5555
identifier (str): The string to filter on
5656
identifier_type (str): The identifier of the field to filter on
57+
greedy (bool): True for greedy match, False for exact match
5758
5859
Returns:
5960
None for no matches, Single Object for unique match,
@@ -65,7 +66,8 @@ def get_template(identifier, identifier_type='name'):
6566
with nipyapi.utils.rest_exceptions():
6667
obj = nipyapi.templates.list_all_templates(native=False)
6768
if obj:
68-
return nipyapi.utils.filter_obj(obj, identifier, identifier_type)
69+
return nipyapi.utils.filter_obj(obj, identifier, identifier_type,
70+
greedy)
6971
return obj
7072

7173

nipyapi/utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,8 @@ def infer_object_label_from_class(obj):
476476
return 'FUNNEL'
477477
if isinstance(obj, nipyapi.nifi.PortEntity):
478478
return obj.port_type
479+
if isinstance(obj, nipyapi.nifi.RemoteProcessGroupDTO):
480+
return 'REMOTEPROCESSGROUP'
479481
if isinstance(obj, nipyapi.nifi.RemoteProcessGroupPortDTO):
480482
# get RPG summary, find id of obj in input or output list
481483
parent_rpg = nipyapi.canvas.get_remote_process_group(
@@ -513,6 +515,7 @@ def bypass_slash_encoding(service, bypass):
513515

514516
@contextmanager
515517
def rest_exceptions():
518+
"""Simple exception wrapper for Rest Exceptions"""
516519
try:
517520
yield
518521
except (nipyapi.nifi.rest.ApiException,

nipyapi/versioning.py

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ def get_flow_in_bucket(bucket_id, identifier, identifier_type='name'):
210210

211211

212212
def save_flow_ver(process_group, registry_client, bucket, flow_name=None,
213-
flow_id=None, comment='', desc='', refresh=True):
213+
flow_id=None, comment='', desc='', refresh=True,
214+
force=False):
214215
"""
215216
Adds a Process Group into NiFi Registry Version Control, or saves a new
216217
version to an existing VersionedFlow with a new version
@@ -228,7 +229,8 @@ def save_flow_ver(process_group, registry_client, bucket, flow_name=None,
228229
the bucket, if saving a new version to an existing flow
229230
comment (str): A comment for the version commit
230231
desc (str): A description of the VersionedFlow
231-
refresh (bool): whether to refresh the object revisions before action
232+
refresh (bool): Whether to refresh the object revisions before action
233+
force (bool): Whether to Force Commit, or just regular Commit
232234
233235
Returns:
234236
(VersionControlInformationEntity)
@@ -237,21 +239,36 @@ def save_flow_ver(process_group, registry_client, bucket, flow_name=None,
237239
target_pg = nipyapi.canvas.get_process_group(process_group.id, 'id')
238240
else:
239241
target_pg = process_group
242+
if nipyapi.utils.check_version('1.10.0') <= 0:
243+
body = nipyapi.nifi.StartVersionControlRequestEntity(
244+
process_group_revision=target_pg.revision,
245+
versioned_flow=nipyapi.nifi.VersionedFlowDTO(
246+
bucket_id=bucket.identifier,
247+
comments=comment,
248+
description=desc,
249+
flow_name=flow_name,
250+
flow_id=flow_id,
251+
registry_id=registry_client.id,
252+
action='FORCE_COMMIT' if force else 'COMMIT'
253+
)
254+
)
255+
else:
256+
# no 'action' property in versions < 1.10
257+
body = nipyapi.nifi.StartVersionControlRequestEntity(
258+
process_group_revision=target_pg.revision,
259+
versioned_flow={
260+
'bucketId': bucket.identifier,
261+
'comments': comment,
262+
'description': desc,
263+
'flowName': flow_name,
264+
'flowId': flow_id,
265+
'registryId': registry_client.id
266+
}
267+
)
240268
with nipyapi.utils.rest_exceptions():
241269
return nipyapi.nifi.VersionsApi().save_to_flow_registry(
242270
id=target_pg.id,
243-
body=nipyapi.nifi.StartVersionControlRequestEntity(
244-
process_group_revision=target_pg.revision,
245-
versioned_flow=nipyapi.nifi.VersionedFlowDTO(
246-
bucket_id=bucket.identifier,
247-
comments=comment,
248-
description=desc,
249-
flow_name=flow_name,
250-
flow_id=flow_id,
251-
registry_id=registry_client.id,
252-
action='COMMIT'
253-
)
254-
)
271+
body=body
255272
)
256273

257274

requirements_dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ bumpversion>=0.5.3
77
watchdog>=0.8.3
88
twine>=1.9.1,<2.0.0 # pyup: ignore
99
virtualenvwrapper>=4.8
10+
virtualenv>=16.0.0 # required for tox 3.14.2 but not forced
1011

1112
# Testing
1213
tox>=2.9.1
@@ -28,4 +29,3 @@ cryptography>=2.1.2
2829
py>=1.4.31
2930
randomize>=0.13
3031
certifi>=2017.7.27.1
31-
virtualenvwrapper>=4.8

resources/docker/tox-full/docker-compose.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ services:
1818
hostname: nifi-180
1919
ports:
2020
- "10180:8080"
21+
nifi-192:
22+
image: apache/nifi:1.9.2
23+
container_name: nifi-192
24+
hostname: nifi-192
25+
ports:
26+
- "10192:8080"
2127
nifi:
2228
image: apache/nifi:1.10.0
2329
container_name: nifi
@@ -32,6 +38,14 @@ services:
3238
- "18010:18010"
3339
environment:
3440
- NIFI_REGISTRY_WEB_HTTP_PORT=18010
41+
registry-030:
42+
image: apache/nifi-registry:0.3.0
43+
container_name: registry-030
44+
hostname: registry-030
45+
ports:
46+
- "18030:18030"
47+
environment:
48+
- NIFI_REGISTRY_WEB_HTTP_PORT=18030
3549
registry:
3650
image: apache/nifi-registry:0.5.0
3751
container_name: registry

resources/test_setup/setup_centos7.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
3+
set -x
4+
set -e
5+
set -u
6+
7+
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
8+
sudo yum update -y
9+
sudo yum install -y centos-release-scl yum-utils device-mapper-persistent-data lvm2
10+
sudo yum install -y rh-python36 docker
11+
sudo systemctl start docker
12+
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
13+
sudo chmod +x /usr/local/bin/docker-compose
14+
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
15+
source /opt/rh/python36/enable
16+
pip install --upgrade pip
17+
pip install -r ../../requirements.txt
18+
pip install -r ../../requirements_dev.txts
19+

tests/conftest.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
# Test template filenames should match the template PG name
4444
test_templates = {
4545
'basic': test_basename + 'Template_00',
46+
'greedy': test_basename + 'Template_00_greedy',
4647
'complex': test_basename + 'Template_01'
4748
}
4849

@@ -55,6 +56,7 @@
5556
'http://' + test_host + ':10112/nifi-api',
5657
'http://' + test_host + ':10120/nifi-api',
5758
'http://' + test_host + ':10180/nifi-api',
59+
'http://' + test_host + ':10192/nifi-api',
5860
]
5961
secure_nifi_endpoints = ['https://' + test_host + ':8443/nifi-api']
6062
default_registry_endpoints = [
@@ -67,6 +69,10 @@
6769
('http://' + test_host + ':18010/nifi-registry-api',
6870
'http://registry-010:18010',
6971
'http://' + test_host + ':8080/nifi-api'
72+
),
73+
('http://' + test_host + ':18030/nifi-registry-api',
74+
'http://registry-030:18030',
75+
'http://' + test_host + ':10192/nifi-api'
7076
)
7177
]
7278
secure_registry_endpoints = [
@@ -389,7 +395,7 @@ def fixture_templates(request, fix_pg):
389395
nipyapi.config.nifi_config.host)
390396
FixtureTemplates = namedtuple(
391397
'FixtureTemplates', ('pg', 'b_file', 'b_name', 'c_file',
392-
'c_name')
398+
'c_name', 'g_name', 'g_file')
393399
)
394400
f_pg = fix_pg
395401
f_b_file = path.join(
@@ -404,11 +410,19 @@ def fixture_templates(request, fix_pg):
404410
test_templates['complex'] + '.xml'
405411
)
406412
f_c_name = 'nipyapi_testTemplate_01'
413+
f_g_file = path.join(
414+
path.dirname(__file__),
415+
test_resource_dir,
416+
test_templates['greedy'] + '.xml'
417+
)
418+
f_g_name = 'nipyapi_testTemplate_00_greedy'
407419
out = FixtureTemplates(
408420
pg=f_pg,
409421
b_name=f_b_name,
410422
c_name=f_c_name,
423+
g_name=f_g_name,
411424
b_file=f_b_file,
425+
g_file=f_g_file,
412426
c_file=f_c_file
413427
)
414428
request.addfinalizer(remove_test_templates)

0 commit comments

Comments
 (0)