mirror of https://github.com/apache/nifi.git
NIFI-8528 Migrate NiFi Registry into NiFi codebase (#5065)
NIFI-8528 Migrate NiFi Registry fully codebase into NiFi as a module. No changes except certain dependency scopes to preserve the NiFi Registry original by overriding the new parent (nifi). - Version adjustments. Removed distinct checkstye rules form nifi-registry. (Using nifi's instead.) - Made some tests Windows-compatible. - Consolidated LICENSE, NOTICE and README.md. - Fixed CryptoKeyLoaderGroovyTest.groovy. - Disable frontend-maven-plugin on Windows. - Skipping all goals of the frontend-maven-plugin on Windows. - Registry integration tests not to run in github jobs (same as the original settings). Skip all registry tests (build and run) on Windows. - Removed Husky from registry.
This commit is contained in:
parent
103aae64cb
commit
dfa683af0e
|
@ -93,7 +93,7 @@ jobs:
|
|||
env:
|
||||
MAVEN_OPTS: -Xmx2g -XX:ReservedCodeCacheSize=1g -XX:+UseG1GC -Dorg.slf4j.simpleLogger.defaultLogLevel=WARN -Duser.language=en -Duser.country=AU -Duser.region=AU -Duser.timezone=Australia/Melbourne -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false
|
||||
run: |
|
||||
mvn -V -T 0.7C package verify -B -Pcontrib-check,include-grpc -Ddir-only -ntp -ff -pl -nifi-assembly,-nifi-toolkit/nifi-toolkit-assembly,-nifi-system-tests -nsu
|
||||
mvn -V -T 0.7C package verify -B -Pcontrib-check,include-grpc,nifi-registry-no-integration-tests -Ddir-only -ntp -ff -pl -nifi-assembly,-nifi-toolkit/nifi-toolkit-assembly,-nifi-system-tests -nsu
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
|
@ -176,7 +176,7 @@ jobs:
|
|||
env:
|
||||
MAVEN_OPTS: -Xmx2g -XX:ReservedCodeCacheSize=1g -XX:+UseG1GC -Dorg.slf4j.simpleLogger.defaultLogLevel=WARN -Duser.language=ja -Duser.country=JP -Duser.region=JP -Duser.timezone=Asia/Tokyo -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false
|
||||
run: |
|
||||
mvn -V -T 0.7C package verify -B -Pcontrib-check,include-grpc -Ddir-only -ntp -ff -pl -nifi-assembly,-nifi-toolkit/nifi-toolkit-assembly,-nifi-system-tests -nsu
|
||||
mvn -V -T 0.7C package verify -B -Pcontrib-check,include-grpc,nifi-registry-no-integration-tests -Ddir-only -ntp -ff -pl -nifi-assembly,-nifi-toolkit/nifi-toolkit-assembly,-nifi-system-tests -nsu
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
|
@ -250,7 +250,7 @@ jobs:
|
|||
env:
|
||||
MAVEN_OPTS: -Xmx2g -Dorg.slf4j.simpleLogger.defaultLogLevel=WARN -Duser.language=fr -Duser.country=FR -Duser.region=FR -Duser.timezone=Europe/Paris -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false
|
||||
run: |
|
||||
mvn -V -T 0.7C package -B -Ddir-only -ntp -ff -pl -nifi-assembly -pl -nifi-system-tests -nsu
|
||||
mvn -V -T 0.7C package -B -Pnifi-registry-no-integration-tests -Ddir-only -ntp -ff -pl -nifi-assembly -pl -nifi-system-tests -nsu
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
if: ${{ false }}
|
||||
|
|
22
LICENSE
22
LICENSE
|
@ -364,3 +364,25 @@ This product bundles source from 'AbstractingTheJavaConsole'. The source is avai
|
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
This product bundles karma-test-shim.js and systemjs-angular-loader.js from 'Angular Quickstart' which is available under an MIT license.
|
||||
|
||||
Copyright (c) 2010-2016 Google, Inc. https://angularjs.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
79
README.md
79
README.md
|
@ -28,6 +28,7 @@ reliable system to process and distribute data.
|
|||
- [Requirements](#requirements)
|
||||
- [Getting Started](#getting-started)
|
||||
- [MiNiFi subproject](#minifi-subproject)
|
||||
- [Registry subproject](#registry-subproject)
|
||||
- [Getting Help](#getting-help)
|
||||
- [Documentation](#documentation)
|
||||
- [License](#license)
|
||||
|
@ -183,6 +184,84 @@ To build:
|
|||
docker run -d -v YOUR_CONFIG.YML:/opt/minifi/minifi-${minifi.version}/conf/config.yml apacheminifi:${minifi.version}
|
||||
```
|
||||
|
||||
## Registry subproject
|
||||
|
||||
Registry—a subproject of Apache NiFi—is a complementary application that provides a central location for storage and management of shared resources across one or more instances of NiFi and/or MiNiFi.
|
||||
|
||||
### Getting Registry Started
|
||||
|
||||
1) Build nifi
|
||||
See [Gettin Started](#getting-started) for NiFi
|
||||
|
||||
or
|
||||
|
||||
Build only the Registry subproject:
|
||||
|
||||
cd nifi/nifi-registry
|
||||
mvn clean install
|
||||
|
||||
If you wish to enable style and license checks, specify the contrib-check profile:
|
||||
|
||||
mvn clean install -Pcontrib-check
|
||||
|
||||
3) Start Registry
|
||||
|
||||
cd nifi-registry/nifi-registry-assembly/target/nifi-registry-<VERSION>-bin/nifi-registry-<VERSION>/
|
||||
./bin/nifi-registry.sh start
|
||||
|
||||
Note that the application web server can take a while to load before it is accessible.
|
||||
|
||||
4) Accessing the application web UI
|
||||
|
||||
With the default settings, the application UI will be available at [http://localhost:18080/nifi-registry](http://localhost:18080/nifi-registry)
|
||||
|
||||
5) Accessing the application REST API
|
||||
|
||||
If you wish to test against the application REST API, you can access the REST API directly. With the default settings, the base URL of the REST API will be at `http://localhost:18080/nifi-registry-api`. A UI for testing the REST API will be available at [http://localhost:18080/nifi-registry-api/swagger/ui.html](http://localhost:18080/nifi-registry-api/swagger/ui.html)
|
||||
|
||||
6) Accessing the application logs
|
||||
|
||||
Logs will be available in `logs/nifi-registry-app.log`
|
||||
|
||||
### Database Testing
|
||||
|
||||
In order to ensure that NiFi Registry works correctly against different relational databases,
|
||||
the existing integration tests can be run against different databases by leveraging the [Testcontainers framework](https://www.testcontainers.org/).
|
||||
|
||||
Spring profiles are used to control the DataSource factory that will be made available to the Spring application context.
|
||||
DataSource factories are provided that use the Testcontainers framework to start a Docker container for a given database and create a corresponding DataSource.
|
||||
If no profile is specified then an H2 DataSource will be used by default and no Docker containers are required.
|
||||
|
||||
Assuming Docker is running on the system where the build is running, then the following commands can be run:
|
||||
|
||||
| Target Database | Build Command |
|
||||
| --------------- | ------------- |
|
||||
| All supported | `mvn verify -Ptest-all-dbs` |
|
||||
| H2 (default) | `mvn verify` |
|
||||
| PostgreSQL 9.x | `mvn verify -Dspring.profiles.active=postgres` |
|
||||
| PostgreSQL 10.x | `mvn verify -Dspring.profiles.active=postgres-10` |
|
||||
| MySQL 5.6 | `mvn verify -Pcontrib-check -Dspring.profiles.active=mysql-56` |
|
||||
| MySQL 5.7 | `mvn verify -Pcontrib-check -Dspring.profiles.active=mysql-57` |
|
||||
| MySQL 8 | `mvn verify -Pcontrib-check -Dspring.profiles.active=mysql-8` |
|
||||
|
||||
When one of the Testcontainer profiles is activated, the test output should show logs that indicate a container has been started, such as the following:
|
||||
|
||||
2019-05-15 16:14:45.078 INFO 66091 --- [ main] 🐳 [mysql:5.7] : Creating container for image: mysql:5.7
|
||||
2019-05-15 16:14:45.145 INFO 66091 --- [ main] o.t.utility.RegistryAuthLocator : Credentials not found for host (index.docker.io) when using credential helper/store (docker-credential-osxkeychain)
|
||||
2019-05-15 16:14:45.646 INFO 66091 --- [ main] 🐳 [mysql:5.7] : Starting container with ID: ca85c8c5a1990d2a898fad04c5897ddcdb3a9405e695cc11259f50f2ebe67c5f
|
||||
2019-05-15 16:14:46.437 INFO 66091 --- [ main] 🐳 [mysql:5.7] : Container mysql:5.7 is starting: ca85c8c5a1990d2a898fad04c5897ddcdb3a9405e695cc11259f50f2ebe67c5f
|
||||
2019-05-15 16:14:46.479 INFO 66091 --- [ main] 🐳 [mysql:5.7] : Waiting for database connection to become available at jdbc:mysql://localhost:33051/test?useSSL=false&allowPublicKeyRetrieval=true using query 'SELECT 1'
|
||||
|
||||
The Flyway connection should also indicate the given database:
|
||||
|
||||
2019-05-15 16:15:02.114 INFO 66091 --- [ main] o.a.n.r.db.CustomFlywayConfiguration : Determined database type is MYSQL
|
||||
2019-05-15 16:15:02.115 INFO 66091 --- [ main] o.a.n.r.db.CustomFlywayConfiguration : Setting migration locations to [classpath:db/migration/common, classpath:db/migration/mysql]
|
||||
2019-05-15 16:15:02.373 INFO 66091 --- [ main] o.a.n.r.d.CustomFlywayMigrationStrategy : First time initializing database...
|
||||
2019-05-15 16:15:02.380 INFO 66091 --- [ main] o.f.c.internal.license.VersionPrinter : Flyway Community Edition 5.2.1 by Boxfuse
|
||||
2019-05-15 16:15:02.403 INFO 66091 --- [ main] o.f.c.internal.database.DatabaseFactory : Database: jdbc:mysql://localhost:33051/test (MySQL 5.7)
|
||||
|
||||
For a full list of the available DataSource factories, consult the `nifi-registry-test` module.
|
||||
|
||||
## Getting Help
|
||||
If you have questions, you can reach out to our mailing list: dev@nifi.apache.org
|
||||
([archive](http://mail-archives.apache.org/mod_mbox/nifi-dev)). For more interactive discussions, community members can often be found in the following locations:
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-data-model</artifactId>
|
||||
<version>${nifi.registry.version}</version>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<profiles>
|
||||
|
|
|
@ -75,17 +75,17 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-data-model</artifactId>
|
||||
<version>${nifi.registry.version}</version>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-flow-diff</artifactId>
|
||||
<version>${nifi.registry.version}</version>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-client</artifactId>
|
||||
<version>${nifi.registry.version}</version>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
|
|
@ -68,12 +68,12 @@ language governing permissions and limitations under the License. -->
|
|||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-data-model</artifactId>
|
||||
<version>${nifi.registry.version}</version>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-client</artifactId>
|
||||
<version>${nifi.registry.version}</version>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<profiles>
|
||||
|
|
|
@ -185,17 +185,17 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-data-model</artifactId>
|
||||
<version>${nifi.registry.version}</version>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-flow-diff</artifactId>
|
||||
<version>${nifi.registry.version}</version>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-client</artifactId>
|
||||
<version>${nifi.registry.version}</version>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
REGISTRY_SCRIPT=`find nifi-registry-assembly/target/ -name nifi-registry.sh | head -1`
|
||||
REGISTRY_BIN_DIR=$(dirname "${REGISTRY_SCRIPT}")
|
||||
REGISTRY_DIR=$REGISTRY_BIN_DIR/..
|
||||
SKIP_UI=$1
|
||||
|
||||
./${REGISTRY_SCRIPT} stop
|
||||
|
||||
if [ "$SKIP_UI" == "skipUi" ]; then
|
||||
mvn clean install -Pcontrib-check --projects \!nifi-registry-web-ui
|
||||
else
|
||||
mvn clean install -Pcontrib-check
|
||||
fi
|
||||
|
||||
./${REGISTRY_SCRIPT} start
|
||||
|
||||
tail -n 500 -f ${REGISTRY_DIR}/logs/nifi-registry-app.log
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,319 @@
|
|||
Apache NiFi Registry
|
||||
Copyright 2017-2020 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (https://www.apache.org/).
|
||||
|
||||
This includes derived works from the Apache NiFi (ASLv2 licensed) project (https://git-wip-us.apache.org/repos/asf?p=nifi.git):
|
||||
Copyright 2015-2020 The Apache Software Foundation
|
||||
This includes sources for bootstrapping, runtime, component API, security/authorization API
|
||||
===========================================
|
||||
Apache Software License v2
|
||||
===========================================
|
||||
|
||||
The following binary components are provided under the Apache Software License v2
|
||||
|
||||
(ASLv2) Jetty
|
||||
The following NOTICE information applies:
|
||||
Jetty Web Container
|
||||
Copyright 1995-2019 Mort Bay Consulting Pty Ltd.
|
||||
|
||||
(ASLv2) Apache Commons Codec
|
||||
The following NOTICE information applies:
|
||||
Apache Commons Codec
|
||||
Copyright 2002-2014 The Apache Software Foundation
|
||||
|
||||
src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
|
||||
contains test data from https://aspell.net/test/orig/batch0.tab.
|
||||
Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
|
||||
|
||||
===============================================================================
|
||||
|
||||
The content of package org.apache.commons.codec.language.bm has been translated
|
||||
from the original php source code available at https://stevemorse.org/phoneticinfo.htm
|
||||
with permission from the original authors.
|
||||
Original source copyright:
|
||||
Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
|
||||
|
||||
(ASLv2) Apache Commons Lang
|
||||
The following NOTICE information applies:
|
||||
Apache Commons Lang
|
||||
Copyright 2001-2017 The Apache Software Foundation
|
||||
|
||||
This product includes software from the Spring Framework,
|
||||
under the Apache License 2.0 (see: StringUtils.containsWhitespace())
|
||||
|
||||
(ASLv2) Jackson JSON processor
|
||||
The following NOTICE information applies:
|
||||
# Jackson JSON processor
|
||||
|
||||
Jackson is a high-performance, Free/Open Source JSON processing library.
|
||||
It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has
|
||||
been in development since 2007.
|
||||
It is currently developed by a community of developers, as well as supported
|
||||
commercially by FasterXML.com.
|
||||
|
||||
## Licensing
|
||||
|
||||
Jackson core and extension components may licensed under different licenses.
|
||||
To find the details that apply to this artifact see the accompanying LICENSE file.
|
||||
For more information, including possible other licensing options, contact
|
||||
FasterXML.com (https://fasterxml.com).
|
||||
|
||||
## Credits
|
||||
|
||||
A list of contributors may be found from CREDITS file, which is included
|
||||
in some artifacts (usually source distributions); but is always available
|
||||
from the source code management (SCM) system project uses.
|
||||
|
||||
(ASLv2) Java Native Access Platform
|
||||
The following NOTICE information applies:
|
||||
Java Native Access Platform
|
||||
Copyright 2013 Timothy Wall, Matthias Bläsing
|
||||
|
||||
This product includes software developed by
|
||||
The Apache Software Foundation (https://www.apache.org/).
|
||||
|
||||
===============================================================================
|
||||
|
||||
The BracketFinder (package org.apache.commons.math3.optimization.univariate)
|
||||
and PowellOptimizer (package org.apache.commons.math3.optimization.general)
|
||||
classes are based on the Python code in module "optimize.py" (version 0.5)
|
||||
developed by Travis E. Oliphant for the SciPy library (https://www.scipy.org/)
|
||||
Copyright © 2003-2009 SciPy Developers.
|
||||
===============================================================================
|
||||
|
||||
The LinearConstraint, LinearObjectiveFunction, LinearOptimizer,
|
||||
RelationShip, SimplexSolver and SimplexTableau classes in package
|
||||
org.apache.commons.math3.optimization.linear include software developed by
|
||||
Benjamin McCann (https://www.benmccann.com) and distributed with
|
||||
the following copyright: Copyright 2009 Google Inc.
|
||||
===============================================================================
|
||||
|
||||
This product includes software developed by the
|
||||
University of Chicago, as Operator of Argonne National
|
||||
Laboratory.
|
||||
The LevenbergMarquardtOptimizer class in package
|
||||
org.apache.commons.math3.optimization.general includes software
|
||||
translated from the lmder, lmpar and qrsolv Fortran routines
|
||||
from the Minpack package
|
||||
Minpack Copyright Notice (1999) University of Chicago. All rights reserved
|
||||
===============================================================================
|
||||
|
||||
The GraggBulirschStoerIntegrator class in package
|
||||
org.apache.commons.math3.ode.nonstiff includes software translated
|
||||
from the odex Fortran routine developed by E. Hairer and G. Wanner.
|
||||
Original source copyright:
|
||||
Copyright (c) 2004, Ernst Hairer
|
||||
===============================================================================
|
||||
|
||||
The EigenDecompositionImpl class in package
|
||||
org.apache.commons.math3.linear includes software translated
|
||||
from some LAPACK Fortran routines. Original source copyright:
|
||||
Copyright (c) 1992-2008 The University of Tennessee. All rights reserved.
|
||||
===============================================================================
|
||||
|
||||
The MersenneTwister class in package org.apache.commons.math3.random
|
||||
includes software translated from the 2002-01-26 version of
|
||||
the Mersenne-Twister generator written in C by Makoto Matsumoto and Takuji
|
||||
Nishimura. Original source copyright:
|
||||
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||
All rights reserved
|
||||
===============================================================================
|
||||
|
||||
The LocalizedFormatsTest class in the unit tests is an adapted version of
|
||||
the OrekitMessagesTest class from the orekit library distributed under the
|
||||
terms of the Apache 2 licence. Original source copyright:
|
||||
Copyright 2010 CS Systèmes d'Information
|
||||
===============================================================================
|
||||
|
||||
The HermiteInterpolator class and its corresponding test have been imported from
|
||||
the orekit library distributed under the terms of the Apache 2 licence. Original
|
||||
source copyright:
|
||||
Copyright 2010-2012 CS Systèmes d'Information
|
||||
===============================================================================
|
||||
|
||||
The creation of the package "o.a.c.m.analysis.integration.gauss" was inspired
|
||||
by an original code donated by Sébastien Brisard.
|
||||
===============================================================================
|
||||
|
||||
(ASLv2) JSON-SMART
|
||||
The following NOTICE information applies:
|
||||
Copyright 2011 JSON-SMART authors
|
||||
|
||||
(ASLv2) JsonPath
|
||||
The following NOTICE information applies:
|
||||
Copyright 2011 JsonPath authors
|
||||
|
||||
(ASLv2) Classmate
|
||||
The following NOTICE information applies
|
||||
Java ClassMate library was originally written by Tatu Saloranta (tatu.saloranta@iki.fi)
|
||||
|
||||
Other developers who have contributed code are:
|
||||
|
||||
* Brian Langel
|
||||
|
||||
(ASLv2) Apache Commons IO
|
||||
The following NOTICE information applies:
|
||||
Apache Commons IO
|
||||
Copyright 2002-2016 The Apache Software Foundation
|
||||
|
||||
(ASLv2) Apache log4j
|
||||
The following NOTICE information applies:
|
||||
Apache log4j
|
||||
Copyright 2010 The Apache Software Foundation
|
||||
|
||||
(ASLv2) Spring Framework
|
||||
The following NOTICE information applies:
|
||||
Spring Framework 5.1.8.RELEASE
|
||||
Copyright (c) 2002-2019 Pivotal, Inc.
|
||||
|
||||
(ASLv2) Spring Security
|
||||
The following NOTICE information applies:
|
||||
Spring Framework 5.1.5.RELEASE
|
||||
Copyright (c) 2002-2019 Pivotal, Inc.
|
||||
|
||||
This product includes software developed by Spring Security
|
||||
Project (https://www.springframework.org/security).
|
||||
|
||||
(ASLv2) Spring LDAP
|
||||
The following NOTICE information applies:
|
||||
Spring LDAP 2.3.2.RELEASE
|
||||
Copyright (c) 2002-2017 Pivotal, Inc.
|
||||
|
||||
This product includes software developed by the Spring LDAP
|
||||
Project (https://www.springframework.org/ldap).
|
||||
|
||||
(ASLv2) Apache Tomcat Embed EL
|
||||
The following NOTICE information applies:
|
||||
Apache Tomcat
|
||||
Copyright 1999-2017 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (https://www.apache.org/).
|
||||
|
||||
This software contains code derived from netty-native
|
||||
developed by the Netty project
|
||||
(https://netty.io, https://github.com/netty/netty-tcnative/)
|
||||
and from finagle-native developed at Twitter
|
||||
(https://github.com/twitter/finagle).
|
||||
|
||||
The Windows Installer is built with the Nullsoft
|
||||
Scriptable Install System (NSIS), which is
|
||||
open source software. The original software and
|
||||
related information is available at
|
||||
https://nsis.sourceforge.net.
|
||||
|
||||
Java compilation software for JSP pages is provided by the Eclipse
|
||||
JDT Core Batch Compiler component, which is open source software.
|
||||
The original software and related information is available at
|
||||
https://www.eclipse.org/jdt/core/.
|
||||
|
||||
For portions of the Tomcat JNI OpenSSL API and the OpenSSL JSSE integration
|
||||
The org.apache.tomcat.jni and the org.apache.tomcat.net.openssl packages
|
||||
are derivative work originating from the Netty project and the finagle-native
|
||||
project developed at Twitter
|
||||
* Copyright 2014 The Netty Project
|
||||
* Copyright 2014 Twitter
|
||||
|
||||
The original XML Schemas for Java EE Deployment Descriptors:
|
||||
- javaee_5.xsd
|
||||
- javaee_web_services_1_2.xsd
|
||||
- javaee_web_services_client_1_2.xsd
|
||||
- javaee_6.xsd
|
||||
- javaee_web_services_1_3.xsd
|
||||
- javaee_web_services_client_1_3.xsd
|
||||
- jsp_2_2.xsd
|
||||
- web-app_3_0.xsd
|
||||
- web-common_3_0.xsd
|
||||
- web-fragment_3_0.xsd
|
||||
- javaee_7.xsd
|
||||
- javaee_web_services_1_4.xsd
|
||||
- javaee_web_services_client_1_4.xsd
|
||||
- jsp_2_3.xsd
|
||||
- web-app_3_1.xsd
|
||||
- web-common_3_1.xsd
|
||||
- web-fragment_3_1.xsd
|
||||
- javaee_8.xsd
|
||||
- web-app_4_0.xsd
|
||||
- web-common_4_0.xsd
|
||||
- web-fragment_4_0.xsd
|
||||
|
||||
may be obtained from:
|
||||
https://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/index.html
|
||||
|
||||
(ASLv2) SnakeYAML
|
||||
The following NOTICE information applies:
|
||||
Copyright (c) 2008, https://www.snakeyaml.org
|
||||
|
||||
(ASLv2) Swagger UI
|
||||
The following NOTICE information applies:
|
||||
Copyright 2017 SmartBear Software
|
||||
|
||||
(ASLv2) Nimbus OAuth 2.0 SDK with OpenID Connect extensions
|
||||
The following NOTICE information applies:
|
||||
Nimbus OAuth 2.0 SDK with OpenID Connect extensions
|
||||
Copyright 2012-2020, Connect2id Ltd and contributors.
|
||||
|
||||
(ASLv2) Guava
|
||||
The following NOTICE information applies:
|
||||
Guava
|
||||
Copyright 2015 The Guava Authors
|
||||
|
||||
************************
|
||||
Common Development and Distribution License 1.1
|
||||
************************
|
||||
|
||||
The following binary components are provided under the Common Development and Distribution License 1.1. See project link for details.
|
||||
|
||||
(CDDL 1.1) (GPL2 w/ CPE) JavaMail API (compat) (javax.mail:mail:jar:1.4.7 - https://kenai.com/projects/javamail/mail)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) Java Servlet API (javax.servlet:javax.servlet-api:jar:3.1.0 - https://servlet-spec.java.net)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) JavaServer Pages Standard Tag Library (javax.servlet.jsp.jstl:jstl:jar:1.2 - https://javaee.github.io/jstl-api/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) javax.annotation API (javax.annotation:javax.annotation-api:jar:1.2 - https://jcp.org/en/jsr/detail?id=250)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) aopalliance-repackaged (org.glassfish.hk2.external:aopalliance-repackaged:jar:2.5.0-b42 - https://javaee.github.io/glassfish/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) asm-all-repackaged (org.glassfish.hk2.external:asm-all-repackaged:jar:2.5.0-b42 - https://javaee.github.io/glassfish/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) class-model (org.glassfish.hk2:class-model:jar:2.5.0-b42 - https://javaee.github.io/glassfish/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) config-types (org.glassfish.hk2:config-types:jar:2.5.0-b42 - https://javaee.github.io/glassfish/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) hk2 (org.glassfish.hk2:hk2:jar:2.5.0-b42 - https://javaee.github.io/glassfish/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) hk2-api (org.glassfish.hk2:hk2-api:jar:2.5.0-b42 - https://javaee.github.io/glassfish/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) hk2-utils (org.glassfish.hk2:hk2-utils:jar:2.5.0-b42 - https://javaee.github.io/glassfish/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) hk2-locator (org.glassfish.hk2:hk2-locator:jar:2.5.0-b42 - https://javaee.github.io/glassfish/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) hk2-config (org.glassfish.hk2:hk2-config:jar:2.5.0-b42 - https://javaee.github.io/glassfish/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) hk2-core (org.glassfish.hk2:hk2-core:jar:2.5.0-b42 - https://javaee.github.io/glassfish/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) hk2-runlevel (org.glassfish.hk2:hk2-runlevel:jar:2.5.0-b42 - https://javaee.github.io/glassfish/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) spring-bridge (org.glassfish.hk2:spring-bridge:jar:2.5.0-b42 - https://javaee.github.io/glassfish/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) javax.inject:1 as OSGi bundle (org.glassfish.hk2.external:javax.inject:jar:2.4.0-b25 - https://hk2.java.net/external/javax.inject)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) javax.ws.rs-api (javax.ws.rs:javax.ws.rs-api:jar:2.1 - https://jax-rs-spec.java.net)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) javax.el (org.glassfish:javax.el:jar:3.0.1-b08 - https://github.com/javaee/el-spec)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) jersey-bean-validation (org.glassfish.jersey.ext:jersey-bean-validation:jar:2.27 - https://jersey.github.io/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) jersey-client (org.glassfish.jersey.core:jersey-client:jar:2.27 - https://jersey.github.io/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) jersey-common (org.glassfish.jersey.core:jersey-common:jar:2.27 - https://jersey.github.io/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) jersey-container-servlet-core (org.glassfish.jersey.containers:jersey-container-servlet-core:jar:2.27 - https://jersey.github.io/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) jersey-entity-filtering (org.glassfish.jersey.ext:jersey-entity-filtering:jar:2.27 - https://jersey.github.io/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) jersey-hk2 (org.glassfish.jersey.inject:jersey-hk2:jar:2.27 - https://jersey.github.io/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) jersey-media-jaxb (org.glassfish.jersey.media:jersey-media-jaxb:jar:2.27 - https://jersey.github.io/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) jersey-media-json-jackson (org.glassfish.jersey.media:jersey-media-json-jackson:jar:2.27 - https://jersey.github.io/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) jersey-server (org.glassfish.jersey.core:jersey-server:jar:2.27 - https://jersey.github.io/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) jersey-spring4 (org.glassfish.jersey.ext:jersey-spring4:jar:2.27 - https://jersey.github.io/)
|
||||
(CDDL 1.1) (GPL2 w/ CPE) OSGi resource locator bundle (org.glassfish.hk2:osgi-resource-locator:jar:1.0.1 - https://glassfish.org/osgi-resource-locator)
|
||||
|
||||
|
||||
************************
|
||||
Common Development and Distribution License 1.0
|
||||
************************
|
||||
|
||||
The following binary components are provided under the Common Development and Distribution License 1.0. See project link for details.
|
||||
|
||||
(CDDL 1.0) JavaBeans Activation Framework (JAF) (javax.activation:activation:jar:1.1 - https://java.sun.com/products/javabeans/jaf/index.jsp)
|
||||
|
||||
|
||||
************************
|
||||
Eclipse Public License 1.0
|
||||
************************
|
||||
|
||||
The following binary components are provided under the Eclipse Public License 1.0. See project link for details.
|
||||
|
||||
(EPL 1.0)(MPL 2.0) H2 Database (com.h2database:h2:jar:h2-1.4.199 - https://www.h2database.com/html/license.html)
|
||||
(EPL 1.0)(LGPL 2.1) Logback Classic (ch.qos.logback:logback-classic:jar:1.2.3 - https://logback.qos.ch/)
|
||||
(EPL 1.0)(LGPL 2.1) Logback Core (ch.qos.logback:logback-core:jar:1.2.3 - https://logback.qos.ch/)
|
||||
(EPL 1.0) AspectJ Weaver (org.aspectj:aspectjweaver:jar:1.8.13 - https://www.eclipse.org/aspectj/)
|
|
@ -0,0 +1,63 @@
|
|||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
# Apache NiFi Registry
|
||||
|
||||
Registry—a subproject of Apache NiFi—is a complementary application that provides a central location for storage and management of shared resources across one or more instances of NiFi and/or MiNiFi.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Requirements](#requirements)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Getting Help](#getting-help)
|
||||
- [License](#license)
|
||||
|
||||
## Requirements
|
||||
|
||||
* Java 1.8 (above 1.8.0_45)
|
||||
|
||||
## Getting Started
|
||||
|
||||
To start NiFi Registry:
|
||||
- [linux/osx] execute bin/nifi-registry.sh start
|
||||
- [windows] execute bin/run-nifi-registry.bat
|
||||
- Direct your browser to http://localhost:18080/nifi-registry/
|
||||
|
||||
## Getting Help
|
||||
|
||||
If you have questions, you can reach out to our mailing list: dev@nifi.apache.org
|
||||
([archive](http://mail-archives.apache.org/mod_mbox/nifi-dev)). For more interactive discussions, community members can often be found in the following locations:
|
||||
|
||||
- Apache NiFi Slack Workspace: https://apachenifi.slack.com/
|
||||
|
||||
New users can join the workspace using the following [invite link](https://s.apache.org/nifi-community-slack).
|
||||
|
||||
- IRC: #nifi on [irc.freenode.net](http://webchat.freenode.net/?channels=#nifi)
|
||||
|
||||
## License
|
||||
|
||||
Except as otherwise noted this software is licensed under the
|
||||
[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,493 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nifi-registry-assembly</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<description>This is the assembly for nifi-registry.</description>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<finalName>nifi-registry-${project.version}</finalName>
|
||||
<attach>false</attach>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make shared resource</id>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<phase>package</phase>
|
||||
<configuration>
|
||||
<archiverConfig>
|
||||
<defaultDirectoryMode>0775</defaultDirectoryMode>
|
||||
<directoryMode>0775</directoryMode>
|
||||
<fileMode>0664</fileMode>
|
||||
</archiverConfig>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/dependencies.xml</descriptor>
|
||||
</descriptors>
|
||||
<tarLongFileMode>posix</tarLongFileMode>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jul-to-slf4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>log4j-over-slf4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-utils</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-bootstrap</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-runtime</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-security-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-provider-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-web-ui</artifactId>
|
||||
<type>war</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-web-api</artifactId>
|
||||
<type>war</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-web-docs</artifactId>
|
||||
<type>war</type>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-resources</artifactId>
|
||||
<classifier>resources</classifier>
|
||||
<scope>runtime</scope>
|
||||
<type>zip</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-docs</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
<classifier>resources</classifier>
|
||||
<scope>runtime</scope>
|
||||
<type>zip</type>
|
||||
</dependency>
|
||||
<!-- Dependencies required for running on Java 11 that will be placed in the lib/java11 dir -->
|
||||
<!-- TODO: remove these once minimum Java version is 11 and these can be bundle directly into the application -->
|
||||
<dependency>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
<artifactId>jaxb-runtime</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<!-- nifi-registry.properties: web properties -->
|
||||
<nifi.registry.web.war.directory>./lib</nifi.registry.web.war.directory>
|
||||
<nifi.registry.web.http.host />
|
||||
<nifi.registry.web.http.port>18080</nifi.registry.web.http.port>
|
||||
<nifi.registry.web.https.host />
|
||||
<nifi.registry.web.https.port />
|
||||
<nifi.registry.jetty.work.dir>./work/jetty</nifi.registry.jetty.work.dir>
|
||||
<nifi.registry.web.jetty.threads>200</nifi.registry.web.jetty.threads>
|
||||
<nifi.registry.web.should.send.server.version>true</nifi.registry.web.should.send.server.version>
|
||||
|
||||
<!-- nifi-registry.properties: security properties -->
|
||||
<nifi.registry.security.keystore />
|
||||
<nifi.registry.security.keystoreType />
|
||||
<nifi.registry.security.keystorePasswd />
|
||||
<nifi.registry.security.keyPasswd />
|
||||
<nifi.registry.security.truststore />
|
||||
<nifi.registry.security.truststoreType />
|
||||
<nifi.registry.security.truststorePasswd />
|
||||
<nifi.registry.security.needClientAuth />
|
||||
<nifi.registry.security.authorizers.configuration.file>./conf/authorizers.xml</nifi.registry.security.authorizers.configuration.file>
|
||||
<nifi.registry.security.authorizer>managed-authorizer</nifi.registry.security.authorizer>
|
||||
<nifi.registry.security.identity.providers.configuration.file>./conf/identity-providers.xml</nifi.registry.security.identity.providers.configuration.file>
|
||||
<nifi.registry.security.identity.provider />
|
||||
|
||||
<!-- nifi-registry.properties: provider properties -->
|
||||
<nifi.registry.providers.configuration.file>./conf/providers.xml</nifi.registry.providers.configuration.file>
|
||||
|
||||
<!-- nifi-registry.properties: registry alias properties -->
|
||||
<nifi.registry.registry.alias.configuration.file>./conf/registry-aliases.xml</nifi.registry.registry.alias.configuration.file>
|
||||
|
||||
<!-- nifi-registry.properties: extension properties -->
|
||||
<nifi.registry.extensions.working.directory>./work/extensions</nifi.registry.extensions.working.directory>
|
||||
<nifi.registry.extension.dir.aws />
|
||||
|
||||
<!-- nifi-registry.properties: legacy database properties, used to migrate data from old DB to the new DB below -->
|
||||
<nifi.registry.db.directory />
|
||||
<nifi.registry.db.url.append />
|
||||
|
||||
<!-- nifi-registry.properties: database properties -->
|
||||
<nifi.registry.db.url>jdbc:h2:./database/nifi-registry-primary;AUTOCOMMIT=OFF;DB_CLOSE_ON_EXIT=FALSE;LOCK_MODE=3;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE</nifi.registry.db.url>
|
||||
<nifi.registry.db.driver.class>org.h2.Driver</nifi.registry.db.driver.class>
|
||||
<nifi.registry.db.driver.directory />
|
||||
<nifi.registry.db.username>nifireg</nifi.registry.db.username>
|
||||
<nifi.registry.db.password>nifireg</nifi.registry.db.password>
|
||||
<nifi.registry.db.maxConnections>5</nifi.registry.db.maxConnections>
|
||||
<nifi.registry.db.sql.debug>false</nifi.registry.db.sql.debug>
|
||||
|
||||
<!-- nifi-registry.properties: kerberos properties -->
|
||||
<nifi.registry.kerberos.krb5.file />
|
||||
<nifi.registry.kerberos.spnego.principal />
|
||||
<nifi.registry.kerberos.spnego.keytab.location />
|
||||
<nifi.registry.kerberos.spnego.authentication.expiration>12 hours</nifi.registry.kerberos.spnego.authentication.expiration>
|
||||
|
||||
<!-- nifi-registry.properties: OIDC properties -->
|
||||
<nifi.registry.security.user.oidc.discovery.url />
|
||||
<nifi.registry.security.user.oidc.connect.timeout />
|
||||
<nifi.registry.security.user.oidc.read.timeout />
|
||||
<nifi.registry.security.user.oidc.client.id />
|
||||
<nifi.registry.security.user.oidc.client.secret />
|
||||
<nifi.registry.security.user.oidc.preferred.jwsalgorithm />
|
||||
|
||||
<!-- nifi.registry.properties: revision management properties -->
|
||||
<nifi.registry.revisions.enabled>false</nifi.registry.revisions.enabled>
|
||||
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>rpm</id>
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<nifi.registry.run.as>nifi</nifi.registry.run.as>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>unpack-shared-resources</id>
|
||||
<goals>
|
||||
<goal>unpack-dependencies</goal>
|
||||
</goals>
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
|
||||
<includeArtifactIds>nifi-registry-resources</includeArtifactIds>
|
||||
<includeGroupIds>org.apache.nifi.registry</includeGroupIds>
|
||||
<excludeTransitive>false</excludeTransitive>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>unpack-docs</id>
|
||||
<goals>
|
||||
<goal>unpack-dependencies</goal>
|
||||
</goals>
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/generated-docs</outputDirectory>
|
||||
<includeArtifactIds>nifi-registry-docs</includeArtifactIds>
|
||||
<includeGroupIds>org.apache.nifi.registry</includeGroupIds>
|
||||
<excludeTransitive>false</excludeTransitive>
|
||||
<excludes>LICENSE,NOTICE</excludes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>rpm-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<name>nifi-registry</name>
|
||||
<summary>Apache NiFi Registry</summary>
|
||||
<description>A sub-project of Apache NiFi that provides a central location for storage and management of shared resources across one or more instances of NiFi and/or MiNiFi.</description>
|
||||
<license>Apache License, Version 2.0 and others (see included LICENSE file)</license>
|
||||
<url>https://nifi.apache.org/registry.html</url>
|
||||
<group>Utilities</group>
|
||||
<prefix>/opt/nifi-registry</prefix>
|
||||
<defineStatements>
|
||||
<defineStatement>_use_internal_dependency_generator 0</defineStatement>
|
||||
</defineStatements>
|
||||
<defaultDirmode>750</defaultDirmode>
|
||||
<defaultFilemode>640</defaultFilemode>
|
||||
<defaultUsername>nifi</defaultUsername>
|
||||
<defaultGroupname>nifi</defaultGroupname>
|
||||
<!-- This allows the stanza to produce bootstrap.conf that is pre-configured with run.as=nifi
|
||||
given the uid is created by the preinstallScriptlet below. Meanwhile, normal zip and tar.gz
|
||||
ship without this particular property set -->
|
||||
<installScriptlet>
|
||||
<!-- It is important to note because of the way the plugin calls the command, the sed backup
|
||||
parameter -i and the sed command do not beed to be wrapped by single or double quotes.
|
||||
Also note maven properties are processed before RPM variables and before sed commands -->
|
||||
<script>sed -i s/^run\.as=$/run\.as=${nifi.registry.run.as}/ $RPM_BUILD_ROOT/opt/nifi-registry/nifi-registry-${project.version}/conf/bootstrap.conf</script>
|
||||
</installScriptlet>
|
||||
<preinstallScriptlet>
|
||||
<script>/usr/bin/getent group nifi >/dev/null || /usr/sbin/groupadd -r nifi; /usr/bin/getent passwd nifi >/dev/null || /usr/sbin/useradd -r -g nifi -d /opt/nifi-registry -s /sbin/nologin -c "NiFi System User" nifi</script>
|
||||
</preinstallScriptlet>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>build-bin-rpm</id>
|
||||
<goals>
|
||||
<goal>attached-rpm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<group>Apache NiFI</group>
|
||||
<classifier>bin</classifier>
|
||||
<provides>
|
||||
<provide>nifi-registry</provide>
|
||||
</provides>
|
||||
<mappings>
|
||||
<mapping>
|
||||
<directory>/opt/nifi-registry/nifi-registry-${project.version}</directory>
|
||||
</mapping>
|
||||
<mapping>
|
||||
<directory>/opt/nifi-registry/nifi-registry-${project.version}</directory>
|
||||
<sources>
|
||||
<source>
|
||||
<location>./LICENSE</location>
|
||||
</source>
|
||||
<source>
|
||||
<location>./NOTICE</location>
|
||||
</source>
|
||||
<source>
|
||||
<location>./README.md</location>
|
||||
<destination>README</destination>
|
||||
</source>
|
||||
</sources>
|
||||
</mapping>
|
||||
<mapping>
|
||||
<directory>/opt/nifi-registry</directory>
|
||||
</mapping>
|
||||
<mapping>
|
||||
<directory>/opt/nifi-registry/nifi-registry-${project.version}/bin</directory>
|
||||
<filemode>750</filemode>
|
||||
<sources>
|
||||
<source>
|
||||
<location>${project.build.directory}/generated-resources/bin/nifi-registry.sh</location>
|
||||
<destination>nifi-registry.sh</destination>
|
||||
<filter>true</filter>
|
||||
</source>
|
||||
<source>
|
||||
<location>${project.build.directory}/generated-resources/bin/nifi-registry-env.sh</location>
|
||||
<destination>nifi-registry-env.sh</destination>
|
||||
<filter>true</filter>
|
||||
</source>
|
||||
</sources>
|
||||
</mapping>
|
||||
<mapping>
|
||||
<directory>/opt/nifi-registry/nifi-registry-${project.version}/conf</directory>
|
||||
<configuration>true</configuration>
|
||||
<sources>
|
||||
<source>
|
||||
<location>${project.build.directory}/generated-resources/conf</location>
|
||||
<filter>true</filter>
|
||||
</source>
|
||||
</sources>
|
||||
</mapping>
|
||||
<mapping>
|
||||
<directory>/opt/nifi-registry/nifi-registry-${project.version}/lib</directory>
|
||||
</mapping>
|
||||
<!--
|
||||
The lib/shared mapping includes the common dependencies between the registry
|
||||
application (lib) and registry bootstrap (lib/bootstrap).
|
||||
|
||||
The lib/bootstrap mapping then excludes what was in lib/shared and includes
|
||||
the other dependencies needed for the registry bootstrap.
|
||||
|
||||
The lib mapping excludes what was in lib/shared and excluded the bootstrap module,
|
||||
and would bring in everything else from the lib directory of a non RPM build.
|
||||
-->
|
||||
<mapping>
|
||||
<directory>/opt/nifi-registry/nifi-registry-${project.version}/lib</directory>
|
||||
<dependency>
|
||||
<excludes>
|
||||
<exclude>org.apache.commons:commons-lang3</exclude>
|
||||
<exclude>org.apache.nifi.registry:nifi-registry-utils</exclude>
|
||||
<exclude>org.apache.nifi.registry:nifi-registry-bootstrap</exclude>
|
||||
<exclude>org.apache.nifi.registry:nifi-registry-docs</exclude>
|
||||
</excludes>
|
||||
</dependency>
|
||||
</mapping>
|
||||
<mapping>
|
||||
<directory>/opt/nifi-registry/nifi-registry-${project.version}/lib/bootstrap</directory>
|
||||
<dependency>
|
||||
<includes>
|
||||
<include>org.slf4j:slf4j-api</include>
|
||||
<include>ch.qos.logback:logback-classic</include>
|
||||
<include>ch.qos.logback:logback-core</include>
|
||||
<include>org.apache.nifi.registry:nifi-registry-bootstrap</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>org.apache.commons:commons-lang3</exclude>
|
||||
<exclude>org.apache.nifi.registry:nifi-registry-utils</exclude>
|
||||
</excludes>
|
||||
</dependency>
|
||||
</mapping>
|
||||
<mapping>
|
||||
<directory>/opt/nifi-registry/nifi-registry-${project.version}/lib/shared</directory>
|
||||
<dependency>
|
||||
<includes>
|
||||
<include>org.apache.commons:commons-lang3</include>
|
||||
<include>org.apache.nifi.registry:nifi-registry-utils</include>
|
||||
</includes>
|
||||
</dependency>
|
||||
</mapping>
|
||||
<mapping>
|
||||
<directory>/opt/nifi-registry/nifi-registry-${project.version}/docs</directory>
|
||||
<sources>
|
||||
<source>
|
||||
<location>${project.build.directory}/generated-docs</location>
|
||||
</source>
|
||||
</sources>
|
||||
</mapping>
|
||||
</mappings>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>include-ranger</id>
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-ranger-assembly</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
<classifier>bin</classifier>
|
||||
<scope>runtime</scope>
|
||||
<type>zip</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>unpack-ranger-extensions</id>
|
||||
<goals>
|
||||
<goal>unpack-dependencies</goal>
|
||||
</goals>
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/ext/ranger</outputDirectory>
|
||||
<includeGroupIds>org.apache.nifi.registry</includeGroupIds>
|
||||
<includeArtifactIds>nifi-registry-ranger-assembly</includeArtifactIds>
|
||||
<excludeTransitive>false</excludeTransitive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>include-aws</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!skipAws</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<nifi.registry.extension.dir.aws>./ext/aws/lib</nifi.registry.extension.dir.aws>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-aws-assembly</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
<classifier>bin</classifier>
|
||||
<scope>runtime</scope>
|
||||
<type>zip</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>unpack-aws-extensions</id>
|
||||
<goals>
|
||||
<goal>unpack-dependencies</goal>
|
||||
</goals>
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/ext/aws</outputDirectory>
|
||||
<includeGroupIds>org.apache.nifi.registry</includeGroupIds>
|
||||
<includeArtifactIds>nifi-registry-aws-assembly</includeArtifactIds>
|
||||
<excludeTransitive>false</excludeTransitive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -0,0 +1,187 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<assembly>
|
||||
<id>bin</id>
|
||||
<formats>
|
||||
<format>dir</format>
|
||||
<format>zip</format>
|
||||
<format>tar.gz</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>true</includeBaseDirectory>
|
||||
<baseDirectory>nifi-registry-${project.version}</baseDirectory>
|
||||
|
||||
<dependencySets>
|
||||
<!-- Write out the dependencies shared between bootstrap and the main app to lib/shared -->
|
||||
<dependencySet>
|
||||
<scope>runtime</scope>
|
||||
<useProjectArtifact>false</useProjectArtifact>
|
||||
<outputDirectory>lib/shared</outputDirectory>
|
||||
<directoryMode>0770</directoryMode>
|
||||
<fileMode>0664</fileMode>
|
||||
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||
<includes>
|
||||
<include>nifi-registry-utils</include>
|
||||
<include>commons-lang3</include>
|
||||
</includes>
|
||||
</dependencySet>
|
||||
|
||||
<!-- Write out the bootstrap lib component to its own dir -->
|
||||
<dependencySet>
|
||||
<scope>runtime</scope>
|
||||
<useProjectArtifact>false</useProjectArtifact>
|
||||
<outputDirectory>lib/bootstrap</outputDirectory>
|
||||
<directoryMode>0770</directoryMode>
|
||||
<fileMode>0664</fileMode>
|
||||
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||
<includes>
|
||||
<include>nifi-registry-bootstrap</include>
|
||||
<include>slf4j-api</include>
|
||||
<include>logback-classic</include>
|
||||
</includes>
|
||||
</dependencySet>
|
||||
|
||||
<!-- Write out the libs for java11 to its own dir -->
|
||||
<!-- TODO: remove these once minimum Java version is 11 and these can be bundle directly into the application -->
|
||||
<dependencySet>
|
||||
<scope>runtime</scope>
|
||||
<useProjectArtifact>false</useProjectArtifact>
|
||||
<outputDirectory>lib/java11</outputDirectory>
|
||||
<directoryMode>0770</directoryMode>
|
||||
<fileMode>0664</fileMode>
|
||||
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||
<includes>
|
||||
<include>jakarta.xml.bind:jakarta.xml.bind-api</include>
|
||||
<include>org.glassfish.jaxb:jaxb-runtime</include>
|
||||
</includes>
|
||||
</dependencySet>
|
||||
|
||||
<!-- Write out all dependency artifacts to lib directory -->
|
||||
<dependencySet>
|
||||
<scope>runtime</scope>
|
||||
<useProjectArtifact>false</useProjectArtifact>
|
||||
<outputDirectory>lib</outputDirectory>
|
||||
<directoryMode>0770</directoryMode>
|
||||
<fileMode>0664</fileMode>
|
||||
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||
<excludes>
|
||||
<exclude>nifi-registry-resources</exclude>
|
||||
<exclude>nifi-registry-bootstrap</exclude>
|
||||
<exclude>nifi-registry-utils</exclude>
|
||||
<exclude>nifi-registry-docs</exclude>
|
||||
<exclude>nifi-registry-ranger-assembly</exclude>
|
||||
<exclude>nifi-registry-aws-assembly</exclude>
|
||||
|
||||
<!-- Exclude any jaxb dependencies because they will be in lib/java11 -->
|
||||
<!-- TODO: remove these once minimum Java version is 11 and these can be bundle directly into the application -->
|
||||
<exclude>jakarta.xml.bind:jakarta.xml.bind-api</exclude>
|
||||
<exclude>org.glassfish.jaxb:jaxb-runtime</exclude>
|
||||
</excludes>
|
||||
</dependencySet>
|
||||
|
||||
<!-- Write out the conf directory contents -->
|
||||
<dependencySet>
|
||||
<scope>runtime</scope>
|
||||
<useProjectArtifact>false</useProjectArtifact>
|
||||
<outputDirectory>./</outputDirectory>
|
||||
<directoryMode>0770</directoryMode>
|
||||
<fileMode>0664</fileMode>
|
||||
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||
<includes>
|
||||
<include>nifi-registry-resources</include>
|
||||
</includes>
|
||||
<unpack>true</unpack>
|
||||
<unpackOptions>
|
||||
<filtered>true</filtered>
|
||||
<includes>
|
||||
<include>conf/*</include>
|
||||
</includes>
|
||||
</unpackOptions>
|
||||
</dependencySet>
|
||||
|
||||
<!-- Write out the bin directory contents -->
|
||||
<dependencySet>
|
||||
<scope>runtime</scope>
|
||||
<useProjectArtifact>false</useProjectArtifact>
|
||||
<outputDirectory>./</outputDirectory>
|
||||
<directoryMode>0770</directoryMode>
|
||||
<fileMode>0770</fileMode>
|
||||
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||
<includes>
|
||||
<include>nifi-registry-resources</include>
|
||||
</includes>
|
||||
<unpack>true</unpack>
|
||||
<unpackOptions>
|
||||
<filtered>true</filtered>
|
||||
<includes>
|
||||
<include>bin/*</include>
|
||||
</includes>
|
||||
</unpackOptions>
|
||||
</dependencySet>
|
||||
|
||||
<!-- Writes out the docs directory contents -->
|
||||
<dependencySet>
|
||||
<scope>runtime</scope>
|
||||
<useProjectArtifact>false</useProjectArtifact>
|
||||
<outputDirectory>docs/</outputDirectory>
|
||||
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||
<includes>
|
||||
<include>nifi-registry-docs</include>
|
||||
</includes>
|
||||
<unpack>true</unpack>
|
||||
<unpackOptions>
|
||||
<filtered>false</filtered>
|
||||
<excludes>
|
||||
<!-- LICENSE and NOTICE both covered by top-level -->
|
||||
<exclude>LICENSE</exclude>
|
||||
<exclude>NOTICE</exclude>
|
||||
</excludes>
|
||||
</unpackOptions>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
|
||||
<files>
|
||||
<file>
|
||||
<source>./README.md</source>
|
||||
<outputDirectory>./</outputDirectory>
|
||||
<destName>README</destName>
|
||||
<fileMode>0644</fileMode>
|
||||
<filtered>true</filtered>
|
||||
</file>
|
||||
<file>
|
||||
<source>./LICENSE</source>
|
||||
<outputDirectory>./</outputDirectory>
|
||||
<destName>LICENSE</destName>
|
||||
<fileMode>0644</fileMode>
|
||||
<filtered>true</filtered>
|
||||
</file>
|
||||
<file>
|
||||
<source>./NOTICE</source>
|
||||
<outputDirectory>./</outputDirectory>
|
||||
<destName>NOTICE</destName>
|
||||
<fileMode>0644</fileMode>
|
||||
<filtered>true</filtered>
|
||||
</file>
|
||||
</files>
|
||||
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<!-- Extensions are extracted by maven-dependency-plugin defined in pom.xml -->
|
||||
<directory>${project.build.directory}/ext</directory>
|
||||
<outputDirectory>ext</outputDirectory>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
</assembly>
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
|
||||
license agreements. See the NOTICE file distributed with this work for additional
|
||||
information regarding copyright ownership. The ASF licenses this file to
|
||||
You under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
|
||||
by applicable law or agreed to in writing, software distributed under the
|
||||
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
|
||||
OF ANY KIND, either express or implied. See the License for the specific
|
||||
language governing permissions and limitations under the License. -->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-core</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>nifi-registry-bootstrap</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-utils</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna-platform</artifactId>
|
||||
<version>4.4.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bootstrap;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.nifi.registry.bootstrap.exception.InvalidCommandException;
|
||||
|
||||
public class BootstrapCodec {
|
||||
|
||||
private final RunNiFiRegistry runner;
|
||||
private final BufferedReader reader;
|
||||
private final BufferedWriter writer;
|
||||
|
||||
public BootstrapCodec(final RunNiFiRegistry runner, final InputStream in, final OutputStream out) {
|
||||
this.runner = runner;
|
||||
this.reader = new BufferedReader(new InputStreamReader(in));
|
||||
this.writer = new BufferedWriter(new OutputStreamWriter(out));
|
||||
}
|
||||
|
||||
public void communicate() throws IOException {
|
||||
final String line = reader.readLine();
|
||||
final String[] splits = line.split(" ");
|
||||
if (splits.length < 0) {
|
||||
throw new IOException("Received invalid command from NiFi Registry: " + line);
|
||||
}
|
||||
|
||||
final String cmd = splits[0];
|
||||
final String[] args;
|
||||
if (splits.length == 1) {
|
||||
args = new String[0];
|
||||
} else {
|
||||
args = Arrays.copyOfRange(splits, 1, splits.length);
|
||||
}
|
||||
|
||||
try {
|
||||
processRequest(cmd, args);
|
||||
} catch (final InvalidCommandException ice) {
|
||||
throw new IOException("Received invalid command from NiFi Registry: " + line + (ice.getMessage() == null ? "" : " - Details: " + ice.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
private void processRequest(final String cmd, final String[] args) throws InvalidCommandException, IOException {
|
||||
switch (cmd) {
|
||||
case "PORT": {
|
||||
if (args.length != 2) {
|
||||
throw new InvalidCommandException();
|
||||
}
|
||||
|
||||
final int port;
|
||||
try {
|
||||
port = Integer.parseInt(args[0]);
|
||||
} catch (final NumberFormatException nfe) {
|
||||
throw new InvalidCommandException("Invalid Port number; should be integer between 1 and 65535");
|
||||
}
|
||||
|
||||
if (port < 1 || port > 65535) {
|
||||
throw new InvalidCommandException("Invalid Port number; should be integer between 1 and 65535");
|
||||
}
|
||||
|
||||
final String secretKey = args[1];
|
||||
|
||||
runner.setNiFiRegistryCommandControlPort(port, secretKey);
|
||||
writer.write("OK");
|
||||
writer.newLine();
|
||||
writer.flush();
|
||||
}
|
||||
break;
|
||||
case "STARTED": {
|
||||
if (args.length != 1) {
|
||||
throw new InvalidCommandException("STARTED command must contain a status argument");
|
||||
}
|
||||
|
||||
if (!"true".equals(args[0]) && !"false".equals(args[0])) {
|
||||
throw new InvalidCommandException("Invalid status for STARTED command; should be true or false, but was '" + args[0] + "'");
|
||||
}
|
||||
|
||||
final boolean started = Boolean.parseBoolean(args[0]);
|
||||
runner.setNiFiRegistryStarted(started);
|
||||
writer.write("OK");
|
||||
writer.newLine();
|
||||
writer.flush();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bootstrap;
|
||||
|
||||
import org.apache.nifi.registry.bootstrap.util.LimitingInputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class NiFiRegistryListener {
|
||||
|
||||
private ServerSocket serverSocket;
|
||||
private volatile Listener listener;
|
||||
|
||||
int start(final RunNiFiRegistry runner) throws IOException {
|
||||
serverSocket = new ServerSocket();
|
||||
serverSocket.bind(new InetSocketAddress("localhost", 0));
|
||||
|
||||
final int localPort = serverSocket.getLocalPort();
|
||||
listener = new Listener(serverSocket, runner);
|
||||
final Thread listenThread = new Thread(listener);
|
||||
listenThread.setName("Listen to NiFi Registry");
|
||||
listenThread.setDaemon(true);
|
||||
listenThread.start();
|
||||
return localPort;
|
||||
}
|
||||
|
||||
public void stop() throws IOException {
|
||||
final Listener listener = this.listener;
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
listener.stop();
|
||||
}
|
||||
|
||||
private class Listener implements Runnable {
|
||||
|
||||
private final ServerSocket serverSocket;
|
||||
private final ExecutorService executor;
|
||||
private final RunNiFiRegistry runner;
|
||||
private volatile boolean stopped = false;
|
||||
|
||||
public Listener(final ServerSocket serverSocket, final RunNiFiRegistry runner) {
|
||||
this.serverSocket = serverSocket;
|
||||
this.executor = Executors.newFixedThreadPool(2, new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(final Runnable runnable) {
|
||||
final Thread t = Executors.defaultThreadFactory().newThread(runnable);
|
||||
t.setDaemon(true);
|
||||
t.setName("NiFi Registry Bootstrap Command Listener");
|
||||
return t;
|
||||
}
|
||||
});
|
||||
|
||||
this.runner = runner;
|
||||
}
|
||||
|
||||
public void stop() throws IOException {
|
||||
stopped = true;
|
||||
|
||||
executor.shutdown();
|
||||
try {
|
||||
executor.awaitTermination(3, TimeUnit.SECONDS);
|
||||
} catch (final InterruptedException ie) {
|
||||
}
|
||||
|
||||
serverSocket.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!serverSocket.isClosed()) {
|
||||
try {
|
||||
if (stopped) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Socket socket;
|
||||
try {
|
||||
socket = serverSocket.accept();
|
||||
} catch (final IOException ioe) {
|
||||
if (stopped) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw ioe;
|
||||
}
|
||||
|
||||
executor.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// we want to ensure that we don't try to read data from an InputStream directly
|
||||
// by a BufferedReader because any user on the system could open a socket and send
|
||||
// a multi-gigabyte file without any new lines in order to crash the Bootstrap,
|
||||
// which in turn may cause the Shutdown Hook to shutdown NiFi.
|
||||
// So we will limit the amount of data to read to 4 KB
|
||||
final InputStream limitingIn = new LimitingInputStream(socket.getInputStream(), 4096);
|
||||
final BootstrapCodec codec = new BootstrapCodec(runner, limitingIn, socket.getOutputStream());
|
||||
codec.communicate();
|
||||
} catch (final Throwable t) {
|
||||
System.out.println("Failed to communicate with NiFi Registry due to " + t);
|
||||
t.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (final IOException ioe) {
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (final Throwable t) {
|
||||
System.err.println("Failed to receive information from NiFi Registry due to " + t);
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bootstrap;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ShutdownHook extends Thread {
|
||||
|
||||
private final Process nifiRegistryProcess;
|
||||
private final RunNiFiRegistry runner;
|
||||
private final int gracefulShutdownSeconds;
|
||||
private final ExecutorService executor;
|
||||
|
||||
private volatile String secretKey;
|
||||
|
||||
public ShutdownHook(final Process nifiRegistryProcess, final RunNiFiRegistry runner, final String secretKey, final int gracefulShutdownSeconds, final ExecutorService executor) {
|
||||
this.nifiRegistryProcess = nifiRegistryProcess;
|
||||
this.runner = runner;
|
||||
this.secretKey = secretKey;
|
||||
this.gracefulShutdownSeconds = gracefulShutdownSeconds;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
void setSecretKey(final String secretKey) {
|
||||
this.secretKey = secretKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
executor.shutdown();
|
||||
runner.setAutoRestartNiFiRegistry(false);
|
||||
final int ccPort = runner.getNiFiRegistryCommandControlPort();
|
||||
if (ccPort > 0) {
|
||||
System.out.println("Initiating Shutdown of NiFi Registry...");
|
||||
|
||||
try {
|
||||
final Socket socket = new Socket("localhost", ccPort);
|
||||
final OutputStream out = socket.getOutputStream();
|
||||
out.write(("SHUTDOWN " + secretKey + "\n").getBytes(StandardCharsets.UTF_8));
|
||||
out.flush();
|
||||
|
||||
socket.close();
|
||||
} catch (final IOException ioe) {
|
||||
System.out.println("Failed to Shutdown NiFi Registry due to " + ioe);
|
||||
}
|
||||
}
|
||||
|
||||
runner.notifyStop();
|
||||
System.out.println("Waiting for Apache NiFi Registry to finish shutting down...");
|
||||
final long startWait = System.nanoTime();
|
||||
while (RunNiFiRegistry.isAlive(nifiRegistryProcess)) {
|
||||
final long waitNanos = System.nanoTime() - startWait;
|
||||
final long waitSeconds = TimeUnit.NANOSECONDS.toSeconds(waitNanos);
|
||||
if (waitSeconds >= gracefulShutdownSeconds && gracefulShutdownSeconds > 0) {
|
||||
if (RunNiFiRegistry.isAlive(nifiRegistryProcess)) {
|
||||
System.out.println("NiFi Registry has not finished shutting down after " + gracefulShutdownSeconds + " seconds. Killing process.");
|
||||
nifiRegistryProcess.destroy();
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
try {
|
||||
Thread.sleep(1000L);
|
||||
} catch (final InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
final File statusFile = runner.getStatusFile();
|
||||
if (!statusFile.delete()) {
|
||||
System.err.println("Failed to delete status file " + statusFile.getAbsolutePath() + "; this file should be cleaned up manually");
|
||||
}
|
||||
}catch (IOException ex){
|
||||
System.err.println("Failed to retrieve status file " + ex);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bootstrap.exception;
|
||||
|
||||
public class InvalidCommandException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidCommandException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public InvalidCommandException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public InvalidCommandException(final Throwable t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
public InvalidCommandException(final String message, final Throwable t) {
|
||||
super(message, t);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bootstrap.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class LimitingInputStream extends InputStream {
|
||||
|
||||
private final InputStream in;
|
||||
private final long limit;
|
||||
private long bytesRead = 0;
|
||||
|
||||
public LimitingInputStream(final InputStream in, final long limit) {
|
||||
this.in = in;
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (bytesRead >= limit) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
final int val = in.read();
|
||||
if (val > -1) {
|
||||
bytesRead++;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(final byte[] b) throws IOException {
|
||||
if (bytesRead >= limit) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
final int maxToRead = (int) Math.min(b.length, limit - bytesRead);
|
||||
|
||||
final int val = in.read(b, 0, maxToRead);
|
||||
if (val > 0) {
|
||||
bytesRead += val;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (bytesRead >= limit) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
final int maxToRead = (int) Math.min(len, limit - bytesRead);
|
||||
|
||||
final int val = in.read(b, off, maxToRead);
|
||||
if (val > 0) {
|
||||
bytesRead += val;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(final long n) throws IOException {
|
||||
final long skipped = in.skip(Math.min(n, limit - bytesRead));
|
||||
bytesRead += skipped;
|
||||
return skipped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return in.available();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark(int readlimit) {
|
||||
in.mark(readlimit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return in.markSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() throws IOException {
|
||||
in.reset();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.nifi.registry.bootstrap.util;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.Kernel32;
|
||||
import com.sun.jna.platform.win32.WinNT;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* OS specific utilities with generic method interfaces
|
||||
*/
|
||||
public final class OSUtils {
|
||||
/**
|
||||
* @param process NiFi Process Reference
|
||||
* @param logger Logger Reference for Debug
|
||||
* @return Returns pid or null in-case pid could not be determined
|
||||
* This method takes {@link Process} and {@link Logger} and returns
|
||||
* the platform specific ProcessId for Unix like systems, a.k.a <b>pid</b>
|
||||
* In-case it fails to determine the pid, it will return Null.
|
||||
* Purpose for the Logger is to log any interaction for debugging.
|
||||
*/
|
||||
private static Long getUnicesPid(final Process process, final Logger logger) {
|
||||
try {
|
||||
final Class<?> procClass = process.getClass();
|
||||
final Field pidField = procClass.getDeclaredField("pid");
|
||||
pidField.setAccessible(true);
|
||||
final Object pidObject = pidField.get(process);
|
||||
|
||||
logger.debug("PID Object = {}", pidObject);
|
||||
|
||||
if (pidObject instanceof Number) {
|
||||
return ((Number) pidObject).longValue();
|
||||
}
|
||||
return null;
|
||||
} catch (final IllegalAccessException | NoSuchFieldException nsfe) {
|
||||
logger.debug("Could not find PID for child process due to {}", nsfe);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param process NiFi Registry Process Reference
|
||||
* @param logger Logger Reference for Debug
|
||||
* @return Returns pid or null in-case pid could not be determined
|
||||
* This method takes {@link Process} and {@link Logger} and returns
|
||||
* the platform specific Handle for Win32 Systems, a.k.a <b>pid</b>
|
||||
* In-case it fails to determine the pid, it will return Null.
|
||||
* Purpose for the Logger is to log any interaction for debugging.
|
||||
*/
|
||||
private static Long getWindowsProcessId(final Process process, final Logger logger) {
|
||||
/* determine the pid on windows plattforms */
|
||||
try {
|
||||
Field f = process.getClass().getDeclaredField("handle");
|
||||
f.setAccessible(true);
|
||||
long handl = f.getLong(process);
|
||||
|
||||
Kernel32 kernel = Kernel32.INSTANCE;
|
||||
WinNT.HANDLE handle = new WinNT.HANDLE();
|
||||
handle.setPointer(Pointer.createConstant(handl));
|
||||
int ret = kernel.GetProcessId(handle);
|
||||
logger.debug("Detected pid: {}", ret);
|
||||
return Long.valueOf(ret);
|
||||
} catch (final IllegalAccessException | NoSuchFieldException nsfe) {
|
||||
logger.debug("Could not find PID for child process due to {}", nsfe);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param process NiFi Process Reference
|
||||
* @param logger Logger Reference for Debug
|
||||
* @return Returns pid or null in-case pid could not be determined
|
||||
* This method takes {@link Process} and {@link Logger} and returns
|
||||
* the platform specific ProcessId for Unix like systems or Handle for Win32 Systems, a.k.a <b>pid</b>
|
||||
* In-case it fails to determine the pid, it will return Null.
|
||||
* Purpose for the Logger is to log any interaction for debugging.
|
||||
*/
|
||||
public static Long getProcessId(final Process process, final Logger logger) {
|
||||
/*
|
||||
* NiFi Registry built with Java 1.8 and running on Java 9. Reflectively invoke Process.pid() on the given process
|
||||
* instance to get the PID of this Java process. Reflection is required in this scenario due to NiFi Registry being
|
||||
* compiled on Java 1.8, which does not have the Process API improvements available in Java 9.
|
||||
*
|
||||
* Otherwise, if NiFi is running on Java 1.8, attempt to get PID using capabilities available on Java 1.8.
|
||||
*
|
||||
* TODO: When minimum Java version updated to Java 9+, this class should be removed with the addition
|
||||
* of the pid method to the Process API.
|
||||
*/
|
||||
Long pid = null;
|
||||
if (!System.getProperty("java.version").startsWith("1.")) {
|
||||
try {
|
||||
Method pidMethod = process.getClass().getMethod("pid");
|
||||
pidMethod.setAccessible(true);
|
||||
Object pidMethodResult = pidMethod.invoke(process);
|
||||
if (Long.class.isAssignableFrom(pidMethodResult.getClass())) {
|
||||
pid = (Long) pidMethodResult;
|
||||
} else {
|
||||
logger.debug("Could not determine PID for child process because returned PID was not " +
|
||||
"assignable to type " + Long.class.getName());
|
||||
}
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||
logger.debug("Could not find PID for child process due to {}", e);
|
||||
}
|
||||
} else if (process.getClass().getName().equals("java.lang.UNIXProcess")) {
|
||||
pid = getUnicesPid(process, logger);
|
||||
} else if (process.getClass().getName().equals("java.lang.Win32Process")
|
||||
|| process.getClass().getName().equals("java.lang.ProcessImpl")) {
|
||||
pid = getWindowsProcessId(process, logger);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
|
||||
license agreements. See the NOTICE file distributed with this work for additional
|
||||
information regarding copyright ownership. The ASF licenses this file to
|
||||
You under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
|
||||
by applicable law or agreed to in writing, software distributed under the
|
||||
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
|
||||
OF ANY KIND, either express or implied. See the License for the specific
|
||||
language governing permissions and limitations under the License. -->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-core</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>nifi-registry-bundle-utils</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-data-model</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<!-- This profile provides configuration to allow NiFi Registry to be compiled on JDKs above 1.8. -->
|
||||
<id>jigsaw</id>
|
||||
<activation>
|
||||
<jdk>(1.8,)</jdk>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bundle.extract;
|
||||
|
||||
/**
|
||||
* Exception to be thrown from a BundleExtractor when an issue occurs during extraction.
|
||||
*/
|
||||
public class BundleException extends RuntimeException {
|
||||
|
||||
public BundleException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public BundleException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bundle.extract;
|
||||
|
||||
import org.apache.nifi.registry.bundle.model.BundleDetails;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Extracts the bundle metadata from the given InputStream.
|
||||
*/
|
||||
public interface BundleExtractor {
|
||||
|
||||
/**
|
||||
* @param inputStream the input stream of the binary bundle
|
||||
* @return the bundle metadata extracted from the input stream
|
||||
* @throws IOException if an error occurs reading from the InputStream
|
||||
*/
|
||||
BundleDetails extract(InputStream inputStream) throws IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bundle.extract.minificpp;
|
||||
|
||||
import org.apache.nifi.registry.bundle.model.BundleDetails;
|
||||
import org.apache.nifi.registry.bundle.extract.BundleExtractor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* ExtensionBundleExtractor for MiNiFi CPP extensions.
|
||||
*/
|
||||
public class MiNiFiCppBundleExtractor implements BundleExtractor {
|
||||
|
||||
@Override
|
||||
public BundleDetails extract(final InputStream inputStream) throws IOException {
|
||||
// TODO implement
|
||||
throw new UnsupportedOperationException("Minifi CPP extensions are not yet supported");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bundle.extract.nar;
|
||||
|
||||
import org.apache.nifi.registry.bundle.extract.BundleException;
|
||||
import org.apache.nifi.registry.bundle.extract.BundleExtractor;
|
||||
import org.apache.nifi.registry.bundle.extract.nar.docs.ExtensionManifestParser;
|
||||
import org.apache.nifi.registry.bundle.extract.nar.docs.JacksonExtensionManifestParser;
|
||||
import org.apache.nifi.registry.bundle.model.BundleIdentifier;
|
||||
import org.apache.nifi.registry.bundle.model.BundleDetails;
|
||||
import org.apache.nifi.registry.extension.bundle.BuildInfo;
|
||||
import org.apache.nifi.registry.extension.component.manifest.ExtensionManifest;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarInputStream;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Implementation of ExtensionBundleExtractor for NAR bundles.
|
||||
*/
|
||||
public class NarBundleExtractor implements BundleExtractor {
|
||||
|
||||
/**
|
||||
* The name of the JarEntry that contains the extension-docs.xml file.
|
||||
*/
|
||||
private static String EXTENSION_DESCRIPTOR_ENTRY = "META-INF/docs/extension-manifest.xml";
|
||||
|
||||
/**
|
||||
* The pattern of a JarEntry for additionalDetails.html entries.
|
||||
*/
|
||||
private static Pattern ADDITIONAL_DETAILS_ENTRY_PATTERN =
|
||||
Pattern.compile("META-INF\\/docs\\/additional-details\\/(.+)\\/additionalDetails.html");
|
||||
|
||||
/**
|
||||
* The format of the date string in the NAR MANIFEST for Built-Timestamp.
|
||||
*/
|
||||
private static String BUILT_TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
||||
|
||||
/**
|
||||
* Used in place of any build info that is not present.
|
||||
*/
|
||||
static String NA = "N/A";
|
||||
|
||||
|
||||
@Override
|
||||
public BundleDetails extract(final InputStream inputStream) throws IOException {
|
||||
try (final JarInputStream jarInputStream = new JarInputStream(inputStream)) {
|
||||
final Manifest manifest = jarInputStream.getManifest();
|
||||
if (manifest == null) {
|
||||
throw new BundleException("NAR bundles must contain a valid MANIFEST");
|
||||
}
|
||||
|
||||
final Attributes attributes = manifest.getMainAttributes();
|
||||
final BundleIdentifier bundleIdentifier = getBundleCoordinate(attributes);
|
||||
final BundleIdentifier dependencyCoordinate = getDependencyBundleCoordinate(attributes);
|
||||
final BuildInfo buildInfo = getBuildInfo(attributes);
|
||||
|
||||
final BundleDetails.Builder builder = new BundleDetails.Builder()
|
||||
.coordinate(bundleIdentifier)
|
||||
.addDependencyCoordinate(dependencyCoordinate)
|
||||
.buildInfo(buildInfo);
|
||||
|
||||
parseExtensionDocs(jarInputStream, builder);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
private BundleIdentifier getBundleCoordinate(final Attributes attributes) {
|
||||
try {
|
||||
final String groupId = attributes.getValue(NarManifestEntry.NAR_GROUP.getManifestName());
|
||||
final String artifactId = attributes.getValue(NarManifestEntry.NAR_ID.getManifestName());
|
||||
final String version = attributes.getValue(NarManifestEntry.NAR_VERSION.getManifestName());
|
||||
|
||||
return new BundleIdentifier(groupId, artifactId, version);
|
||||
} catch (Exception e) {
|
||||
throw new BundleException("Unable to obtain bundle coordinate due to: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private BundleIdentifier getDependencyBundleCoordinate(final Attributes attributes) {
|
||||
try {
|
||||
final String dependencyGroupId = attributes.getValue(NarManifestEntry.NAR_DEPENDENCY_GROUP.getManifestName());
|
||||
final String dependencyArtifactId = attributes.getValue(NarManifestEntry.NAR_DEPENDENCY_ID.getManifestName());
|
||||
final String dependencyVersion = attributes.getValue(NarManifestEntry.NAR_DEPENDENCY_VERSION.getManifestName());
|
||||
|
||||
final BundleIdentifier dependencyCoordinate;
|
||||
if (dependencyArtifactId != null) {
|
||||
dependencyCoordinate = new BundleIdentifier(dependencyGroupId, dependencyArtifactId, dependencyVersion);
|
||||
} else {
|
||||
dependencyCoordinate = null;
|
||||
}
|
||||
return dependencyCoordinate;
|
||||
} catch (Exception e) {
|
||||
throw new BundleException("Unable to obtain bundle coordinate for dependency due to: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private BuildInfo getBuildInfo(final Attributes attributes) {
|
||||
final String buildBranch = attributes.getValue(NarManifestEntry.BUILD_BRANCH.getManifestName());
|
||||
final String buildTag = attributes.getValue(NarManifestEntry.BUILD_TAG.getManifestName());
|
||||
final String buildRevision = attributes.getValue(NarManifestEntry.BUILD_REVISION.getManifestName());
|
||||
final String buildTimestamp = attributes.getValue(NarManifestEntry.BUILD_TIMESTAMP.getManifestName());
|
||||
final String buildJdk = attributes.getValue(NarManifestEntry.BUILD_JDK.getManifestName());
|
||||
final String builtBy = attributes.getValue(NarManifestEntry.BUILT_BY.getManifestName());
|
||||
|
||||
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(BUILT_TIMESTAMP_FORMAT);
|
||||
try {
|
||||
final Date buildDate = simpleDateFormat.parse(buildTimestamp);
|
||||
|
||||
final BuildInfo buildInfo = new BuildInfo();
|
||||
buildInfo.setBuildTool(isBlank(buildJdk) ? NA : buildJdk);
|
||||
buildInfo.setBuildBranch(isBlank(buildBranch) ? NA : buildBranch);
|
||||
buildInfo.setBuildTag(isBlank(buildTag) ? NA : buildTag);
|
||||
buildInfo.setBuildRevision(isBlank(buildRevision) ? NA : buildRevision);
|
||||
buildInfo.setBuilt(buildDate.getTime());
|
||||
buildInfo.setBuiltBy(isBlank(builtBy) ? NA : builtBy);
|
||||
buildInfo.setBuildFlags(NA);
|
||||
return buildInfo;
|
||||
|
||||
} catch (ParseException e) {
|
||||
throw new BundleException("Unable to parse " + NarManifestEntry.BUILD_TIMESTAMP.getManifestName(), e);
|
||||
} catch (Exception e) {
|
||||
throw new BundleException("Unable to create build info for bundle due to: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBlank(String value) {
|
||||
return (value == null || value.trim().isEmpty());
|
||||
}
|
||||
|
||||
private void parseExtensionDocs(final JarInputStream jarInputStream, final BundleDetails.Builder builder) throws IOException {
|
||||
JarEntry jarEntry;
|
||||
boolean foundExtensionDocs = false;
|
||||
while((jarEntry = jarInputStream.getNextJarEntry()) != null) {
|
||||
final String jarEntryName = jarEntry.getName();
|
||||
if (EXTENSION_DESCRIPTOR_ENTRY.equals(jarEntryName)) {
|
||||
try {
|
||||
final byte[] rawDocsContent = toByteArray(jarInputStream);
|
||||
final ExtensionManifestParser docsParser = new JacksonExtensionManifestParser();
|
||||
final InputStream inputStream = new NonCloseableInputStream(new ByteArrayInputStream(rawDocsContent));
|
||||
|
||||
final ExtensionManifest extensionManifest = docsParser.parse(inputStream);
|
||||
builder.addExtensions(extensionManifest.getExtensions());
|
||||
builder.systemApiVersion(extensionManifest.getSystemApiVersion());
|
||||
|
||||
foundExtensionDocs = true;
|
||||
} catch (Exception e) {
|
||||
throw new BundleException("Unable to obtain extension info for bundle due to: " + e.getMessage(), e);
|
||||
}
|
||||
} else {
|
||||
final Matcher matcher = ADDITIONAL_DETAILS_ENTRY_PATTERN.matcher(jarEntryName);
|
||||
if (matcher.matches()) {
|
||||
final String extensionName = matcher.group(1);
|
||||
final String additionalDetailsContent = new String(toByteArray(jarInputStream), StandardCharsets.UTF_8);
|
||||
builder.addAdditionalDetails(extensionName, additionalDetailsContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundExtensionDocs) {
|
||||
throw new BundleException("Unable to find descriptor at '" + EXTENSION_DESCRIPTOR_ENTRY + "'. " +
|
||||
"This NAR may need to be rebuilt with the latest version of the NiFi NAR Maven Plugin.");
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] toByteArray(final InputStream input) throws IOException {
|
||||
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
|
||||
int nRead;
|
||||
byte[] data = new byte[16384];
|
||||
while ((nRead = input.read(data, 0, data.length)) != -1) {
|
||||
buffer.write(data, 0, nRead);
|
||||
}
|
||||
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
private static class NonCloseableInputStream extends FilterInputStream {
|
||||
|
||||
private final InputStream toWrap;
|
||||
|
||||
public NonCloseableInputStream(final InputStream toWrap) {
|
||||
super(toWrap);
|
||||
this.toWrap = toWrap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return toWrap.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
return toWrap.read(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
return toWrap.read(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bundle.extract.nar;
|
||||
|
||||
/**
|
||||
* Enumeration of entries that will be in a NAR MANIFEST file.
|
||||
*/
|
||||
public enum NarManifestEntry {
|
||||
|
||||
NAR_GROUP("Nar-Group"),
|
||||
NAR_ID("Nar-Id"),
|
||||
NAR_VERSION("Nar-Version"),
|
||||
NAR_DEPENDENCY_GROUP("Nar-Dependency-Group"),
|
||||
NAR_DEPENDENCY_ID("Nar-Dependency-Id"),
|
||||
NAR_DEPENDENCY_VERSION("Nar-Dependency-Version"),
|
||||
BUILD_TAG("Build-Tag"),
|
||||
BUILD_REVISION("Build-Revision"),
|
||||
BUILD_BRANCH("Build-Branch"),
|
||||
BUILD_TIMESTAMP("Build-Timestamp"),
|
||||
BUILD_JDK("Build-Jdk"),
|
||||
BUILT_BY("Built-By"),
|
||||
;
|
||||
|
||||
final String manifestName;
|
||||
|
||||
NarManifestEntry(String manifestName) {
|
||||
this.manifestName = manifestName;
|
||||
}
|
||||
|
||||
public String getManifestName() {
|
||||
return manifestName;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bundle.extract.nar.docs;
|
||||
|
||||
import org.apache.nifi.registry.extension.component.manifest.ExtensionManifest;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Parses an InputStream that is expected to contain the content of META-INF/docs/extensions-manifest.xml from a NAR.
|
||||
*/
|
||||
public interface ExtensionManifestParser {
|
||||
|
||||
ExtensionManifest parse(InputStream inputStream);
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bundle.extract.nar.docs;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
|
||||
import org.apache.nifi.registry.bundle.extract.BundleException;
|
||||
import org.apache.nifi.registry.extension.component.manifest.ExtensionManifest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Implementation of {@link ExtensionManifestParser} that uses Jackson XML to unmarshall the extension-manifest.xml content.
|
||||
*/
|
||||
public class JacksonExtensionManifestParser implements ExtensionManifestParser {
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
|
||||
public JacksonExtensionManifestParser() {
|
||||
this.mapper = new XmlMapper();
|
||||
this.mapper.registerModule(new JaxbAnnotationModule());
|
||||
this.mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionManifest parse(InputStream inputStream) {
|
||||
try {
|
||||
return mapper.readValue(inputStream, ExtensionManifest.class);
|
||||
} catch (IOException e) {
|
||||
throw new BundleException("Unable to parse extension manifest due to: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bundle.model;
|
||||
|
||||
|
||||
import org.apache.nifi.registry.bundle.extract.BundleExtractor;
|
||||
import org.apache.nifi.registry.extension.bundle.BuildInfo;
|
||||
import org.apache.nifi.registry.extension.component.manifest.Extension;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.apache.nifi.registry.bundle.util.BundleUtils.validateNotNull;
|
||||
|
||||
/**
|
||||
* Details for a given bundle which are obtained from a given {@link BundleExtractor}.
|
||||
*/
|
||||
public class BundleDetails {
|
||||
|
||||
private final BundleIdentifier bundleIdentifier;
|
||||
private final Set<BundleIdentifier> dependencies;
|
||||
|
||||
private final String systemApiVersion;
|
||||
|
||||
private final Set<Extension> extensions;
|
||||
private final Map<String,String> additionalDetails;
|
||||
|
||||
private final BuildInfo buildInfo;
|
||||
|
||||
private BundleDetails(final Builder builder) {
|
||||
this.bundleIdentifier = builder.bundleIdentifier;
|
||||
this.dependencies = Collections.unmodifiableSet(new HashSet<>(builder.dependencies));
|
||||
this.extensions = Collections.unmodifiableSet(new HashSet<>(builder.extensions));
|
||||
this.additionalDetails = Collections.unmodifiableMap(new HashMap<>(builder.additionalDetails));
|
||||
this.systemApiVersion = builder.systemApiVersion;
|
||||
this.buildInfo = builder.buildInfo;
|
||||
|
||||
validateNotNull("Bundle Coordinate", this.bundleIdentifier);
|
||||
validateNotNull("Dependency Coordinates", this.dependencies);
|
||||
validateNotNull("Extension Details", this.extensions);
|
||||
validateNotNull("System API Version", this.systemApiVersion);
|
||||
validateNotNull("Build Details", this.buildInfo);
|
||||
}
|
||||
|
||||
public BundleIdentifier getBundleIdentifier() {
|
||||
return bundleIdentifier;
|
||||
}
|
||||
|
||||
public Set<BundleIdentifier> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
public String getSystemApiVersion() {
|
||||
return systemApiVersion;
|
||||
}
|
||||
|
||||
public Set<Extension> getExtensions() {
|
||||
return extensions;
|
||||
}
|
||||
|
||||
public Map<String, String> getAdditionalDetails() {
|
||||
return additionalDetails;
|
||||
}
|
||||
|
||||
public BuildInfo getBuildInfo() {
|
||||
return buildInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for creating instances of BundleDetails.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private BundleIdentifier bundleIdentifier;
|
||||
private Set<BundleIdentifier> dependencies = new HashSet<>();
|
||||
private Set<Extension> extensions = new HashSet<>();
|
||||
private Map<String,String> additionalDetails = new HashMap<>();
|
||||
private BuildInfo buildInfo;
|
||||
private String systemApiVersion;
|
||||
|
||||
public Builder coordinate(final BundleIdentifier bundleIdentifier) {
|
||||
this.bundleIdentifier = bundleIdentifier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addDependencyCoordinate(final BundleIdentifier dependencyCoordinate) {
|
||||
if (dependencyCoordinate != null) {
|
||||
this.dependencies.add(dependencyCoordinate);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder systemApiVersion(final String systemApiVersion) {
|
||||
this.systemApiVersion = systemApiVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addExtension(final Extension extension) {
|
||||
if (extension != null) {
|
||||
this.extensions.add(extension);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addExtensions(final List<Extension> extensions) {
|
||||
if (extensions != null) {
|
||||
this.extensions.addAll(extensions);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addAdditionalDetails(final String extensionName, final String additionalDetails) {
|
||||
this.additionalDetails.put(extensionName, additionalDetails);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder buildInfo(final BuildInfo buildInfo) {
|
||||
this.buildInfo = buildInfo;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BundleDetails build() {
|
||||
return new BundleDetails(this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bundle.model;
|
||||
|
||||
import static org.apache.nifi.registry.bundle.util.BundleUtils.validateNotBlank;
|
||||
|
||||
/**
|
||||
* The identifier of an extension bundle (i.e group + artifact + version).
|
||||
*/
|
||||
public class BundleIdentifier {
|
||||
|
||||
private final String groupId;
|
||||
private final String artifactId;
|
||||
private final String version;
|
||||
|
||||
private final String identifier;
|
||||
|
||||
public BundleIdentifier(final String groupId, final String artifactId, final String version) {
|
||||
this.groupId = groupId;
|
||||
this.artifactId = artifactId;
|
||||
this.version = version;
|
||||
validateNotBlank("Group Id", this.groupId);
|
||||
validateNotBlank("Artifact Id", this.artifactId);
|
||||
validateNotBlank("Version", this.version);
|
||||
|
||||
this.identifier = this.groupId + ":" + this.artifactId + ":" + this.version;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public String getArtifactId() {
|
||||
return artifactId;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public final String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(obj instanceof BundleIdentifier)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final BundleIdentifier other = (BundleIdentifier) obj;
|
||||
return getIdentifier().equals(other.getIdentifier());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 37 * this.identifier.hashCode();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bundle.util;
|
||||
|
||||
public class BundleUtils {
|
||||
|
||||
public static boolean isBlank(final String value) {
|
||||
return (value == null || value.trim().isEmpty());
|
||||
}
|
||||
|
||||
public static void validateNotNull(String fieldName, Object value) {
|
||||
if (value == null) {
|
||||
throw new IllegalArgumentException(fieldName + " is required");
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateNotBlank(String fieldName, String value) {
|
||||
if (isBlank(value)) {
|
||||
throw new IllegalArgumentException(fieldName + " is required");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bundle.extract.nar;
|
||||
|
||||
import org.apache.nifi.registry.bundle.extract.BundleException;
|
||||
import org.apache.nifi.registry.bundle.extract.BundleExtractor;
|
||||
import org.apache.nifi.registry.bundle.model.BundleIdentifier;
|
||||
import org.apache.nifi.registry.bundle.model.BundleDetails;
|
||||
import org.apache.nifi.registry.extension.bundle.BuildInfo;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class TestNarBundleExtractor {
|
||||
|
||||
private BundleExtractor extractor;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.extractor = new NarBundleExtractor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractFromGoodNarNoDependencies() throws IOException {
|
||||
try (final InputStream in = new FileInputStream("src/test/resources/nars/nifi-framework-nar.nar")) {
|
||||
final BundleDetails bundleDetails = extractor.extract(in);
|
||||
assertNotNull(bundleDetails);
|
||||
assertNotNull(bundleDetails.getBundleIdentifier());
|
||||
assertNotNull(bundleDetails.getDependencies());
|
||||
assertEquals(0, bundleDetails.getDependencies().size());
|
||||
|
||||
final BundleIdentifier bundleIdentifier = bundleDetails.getBundleIdentifier();
|
||||
assertEquals("org.apache.nifi", bundleIdentifier.getGroupId());
|
||||
assertEquals("nifi-framework-nar", bundleIdentifier.getArtifactId());
|
||||
assertEquals("1.8.0", bundleIdentifier.getVersion());
|
||||
|
||||
assertNotNull(bundleDetails.getExtensions());
|
||||
assertEquals(0, bundleDetails.getExtensions().size());
|
||||
assertEquals("1.8.0", bundleDetails.getSystemApiVersion());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractFromGoodNarWithDependencies() throws IOException {
|
||||
try (final InputStream in = new FileInputStream("src/test/resources/nars/nifi-foo-nar.nar")) {
|
||||
final BundleDetails bundleDetails = extractor.extract(in);
|
||||
assertNotNull(bundleDetails);
|
||||
assertNotNull(bundleDetails.getBundleIdentifier());
|
||||
assertNotNull(bundleDetails.getDependencies());
|
||||
assertEquals(1, bundleDetails.getDependencies().size());
|
||||
|
||||
final BundleIdentifier bundleIdentifier = bundleDetails.getBundleIdentifier();
|
||||
assertEquals("org.apache.nifi", bundleIdentifier.getGroupId());
|
||||
assertEquals("nifi-foo-nar", bundleIdentifier.getArtifactId());
|
||||
assertEquals("1.8.0", bundleIdentifier.getVersion());
|
||||
|
||||
final BundleIdentifier dependencyCoordinate = bundleDetails.getDependencies().stream().findFirst().get();
|
||||
assertEquals("org.apache.nifi", dependencyCoordinate.getGroupId());
|
||||
assertEquals("nifi-bar-nar", dependencyCoordinate.getArtifactId());
|
||||
assertEquals("2.0.0", dependencyCoordinate.getVersion());
|
||||
|
||||
final Map<String,String> additionalDetails = bundleDetails.getAdditionalDetails();
|
||||
assertNotNull(additionalDetails);
|
||||
assertEquals(0, additionalDetails.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = BundleException.class)
|
||||
public void testExtractFromNarMissingRequiredManifestEntries() throws IOException {
|
||||
try (final InputStream in = new FileInputStream("src/test/resources/nars/nifi-missing-manifest-entries.nar")) {
|
||||
extractor.extract(in);
|
||||
fail("Should have thrown exception");
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = BundleException.class)
|
||||
public void testExtractFromNarMissingManifest() throws IOException {
|
||||
try (final InputStream in = new FileInputStream("src/test/resources/nars/nifi-missing-manifest.nar")) {
|
||||
extractor.extract(in);
|
||||
fail("Should have thrown exception");
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = BundleException.class)
|
||||
public void testExtractFromNarMissingExtensionDescriptor() throws IOException {
|
||||
try (final InputStream in = new FileInputStream("src/test/resources/nars/nifi-foo-nar-missing-extension-descriptor.nar")) {
|
||||
extractor.extract(in);
|
||||
fail("Should have thrown exception");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractFromNarWithDescriptorAndAdditionalDetails() throws IOException {
|
||||
try (final InputStream in = new FileInputStream("src/test/resources/nars/nifi-hadoop-nar.nar")) {
|
||||
final BundleDetails bundleDetails = extractor.extract(in);
|
||||
assertNotNull(bundleDetails);
|
||||
assertNotNull(bundleDetails.getBundleIdentifier());
|
||||
assertNotNull(bundleDetails.getDependencies());
|
||||
assertEquals(1, bundleDetails.getDependencies().size());
|
||||
|
||||
final BundleIdentifier bundleIdentifier = bundleDetails.getBundleIdentifier();
|
||||
assertEquals("org.apache.nifi", bundleIdentifier.getGroupId());
|
||||
assertEquals("nifi-hadoop-nar", bundleIdentifier.getArtifactId());
|
||||
assertEquals("1.9.0-SNAPSHOT", bundleIdentifier.getVersion());
|
||||
|
||||
final BuildInfo buildDetails = bundleDetails.getBuildInfo();
|
||||
assertNotNull(buildDetails);
|
||||
assertEquals("1.8.0_162", buildDetails.getBuildTool());
|
||||
assertEquals(NarBundleExtractor.NA, buildDetails.getBuildFlags());
|
||||
assertEquals("master", buildDetails.getBuildBranch());
|
||||
assertEquals("HEAD", buildDetails.getBuildTag());
|
||||
assertEquals("1a937b6", buildDetails.getBuildRevision());
|
||||
assertEquals("jsmith", buildDetails.getBuiltBy());
|
||||
assertNotNull(buildDetails.getBuilt());
|
||||
|
||||
assertEquals("1.10.0-SNAPSHOT", bundleDetails.getSystemApiVersion());
|
||||
assertNotNull(bundleDetails.getExtensions());
|
||||
assertEquals(10, bundleDetails.getExtensions().size());
|
||||
|
||||
final Map<String,String> additionalDetails = bundleDetails.getAdditionalDetails();
|
||||
assertNotNull(additionalDetails);
|
||||
assertEquals(3, additionalDetails.size());
|
||||
|
||||
final String listHdfsKey = "org.apache.nifi.processors.hadoop.ListHDFS";
|
||||
assertTrue(additionalDetails.containsKey(listHdfsKey));
|
||||
assertTrue(additionalDetails.get(listHdfsKey).startsWith("<!DOCTYPE html>"));
|
||||
assertTrue(additionalDetails.get(listHdfsKey).trim().endsWith("</html>"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bundle.extract.nar.docs;
|
||||
|
||||
import org.apache.nifi.registry.extension.component.manifest.Extension;
|
||||
import org.apache.nifi.registry.extension.component.manifest.ExtensionManifest;
|
||||
import org.apache.nifi.registry.extension.component.manifest.ExtensionType;
|
||||
import org.apache.nifi.registry.extension.component.manifest.ProvidedServiceAPI;
|
||||
import org.apache.nifi.registry.extension.component.manifest.Restriction;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TestJacksonExtensionManifestParser {
|
||||
|
||||
private ExtensionManifestParser parser;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
parser = new JacksonExtensionManifestParser();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocsWithProcessors() throws IOException {
|
||||
final ExtensionManifest extensionManifest = parse("src/test/resources/descriptors/extension-manifest-hadoop-nar.xml");
|
||||
assertNotNull(extensionManifest);
|
||||
assertEquals("1.10.0-SNAPSHOT", extensionManifest.getSystemApiVersion());
|
||||
|
||||
final List<Extension> extensionDetails = extensionManifest.getExtensions();
|
||||
assertEquals(10, extensionDetails.size());
|
||||
|
||||
final Extension putHdfsExtension = extensionDetails.stream()
|
||||
.filter(e -> e.getName().equals("org.apache.nifi.processors.hadoop.PutHDFS"))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
assertNotNull(putHdfsExtension);
|
||||
assertEquals(ExtensionType.PROCESSOR, putHdfsExtension.getType());
|
||||
assertEquals("Write FlowFile data to Hadoop Distributed File System (HDFS)", putHdfsExtension.getDescription());
|
||||
assertEquals(5, putHdfsExtension.getTags().size());
|
||||
assertTrue(putHdfsExtension.getTags().contains("hadoop"));
|
||||
assertTrue(putHdfsExtension.getTags().contains("HDFS"));
|
||||
assertTrue(putHdfsExtension.getTags().contains("put"));
|
||||
assertTrue(putHdfsExtension.getTags().contains("copy"));
|
||||
assertTrue(putHdfsExtension.getTags().contains("filesystem"));
|
||||
assertNull(putHdfsExtension.getProvidedServiceAPIs());
|
||||
|
||||
assertNotNull(putHdfsExtension.getProperties());
|
||||
assertEquals(15, putHdfsExtension.getProperties().size());
|
||||
|
||||
assertNull(putHdfsExtension.getRestricted().getGeneralRestrictionExplanation());
|
||||
|
||||
final List<Restriction> restrictions = putHdfsExtension.getRestricted().getRestrictions();
|
||||
assertNotNull(restrictions);
|
||||
assertEquals(1, restrictions.size());
|
||||
|
||||
final Restriction restriction = restrictions.stream().findFirst().orElse(null);
|
||||
assertEquals("write filesystem", restriction.getRequiredPermission());
|
||||
assertEquals("Provides operator the ability to delete any file that NiFi has access to in HDFS or\n" +
|
||||
" the local filesystem.", restriction.getExplanation().trim());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocsWithControllerService() throws IOException {
|
||||
final ExtensionManifest extensionManifest = parse("src/test/resources/descriptors/extension-manifest-dbcp-service-nar.xml");
|
||||
assertNotNull(extensionManifest);
|
||||
assertEquals("1.10.0-SNAPSHOT", extensionManifest.getSystemApiVersion());
|
||||
|
||||
final List<Extension> extensions = extensionManifest.getExtensions();
|
||||
assertEquals(2, extensions.size());
|
||||
|
||||
final Extension dbcpPoolExtension = extensions.stream()
|
||||
.filter(e -> e.getName().equals("org.apache.nifi.dbcp.DBCPConnectionPool"))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
assertNotNull(dbcpPoolExtension);
|
||||
assertEquals(ExtensionType.CONTROLLER_SERVICE, dbcpPoolExtension.getType());
|
||||
assertEquals("Provides Database Connection Pooling Service. Connections can be asked from pool and returned\n" +
|
||||
" after usage.", dbcpPoolExtension.getDescription().trim());
|
||||
assertEquals(6, dbcpPoolExtension.getTags().size());
|
||||
assertEquals(1, dbcpPoolExtension.getProvidedServiceAPIs().size());
|
||||
|
||||
final ProvidedServiceAPI providedServiceApi = dbcpPoolExtension.getProvidedServiceAPIs().iterator().next();
|
||||
assertNotNull(providedServiceApi);
|
||||
assertEquals("org.apache.nifi.dbcp.DBCPService", providedServiceApi.getClassName());
|
||||
assertEquals("org.apache.nifi", providedServiceApi.getGroupId());
|
||||
assertEquals("nifi-standard-services-api-nar", providedServiceApi.getArtifactId());
|
||||
assertEquals("1.10.0-SNAPSHOT", providedServiceApi.getVersion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocsWithReportingTask() throws IOException {
|
||||
final ExtensionManifest extensionManifest = parse("src/test/resources/descriptors/extension-manifest-ambari-nar.xml");
|
||||
assertNotNull(extensionManifest);
|
||||
assertEquals("1.10.0-SNAPSHOT", extensionManifest.getSystemApiVersion());
|
||||
|
||||
final List<Extension> extensions = extensionManifest.getExtensions();
|
||||
assertEquals(1, extensions.size());
|
||||
|
||||
final Extension reportingTask = extensions.stream()
|
||||
.filter(e -> e.getName().equals("org.apache.nifi.reporting.ambari.AmbariReportingTask"))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
assertNotNull(reportingTask);
|
||||
assertEquals(ExtensionType.REPORTING_TASK, reportingTask.getType());
|
||||
assertNotNull(reportingTask.getDescription());
|
||||
assertEquals(3, reportingTask.getTags().size());
|
||||
assertTrue(reportingTask.getTags().contains("reporting"));
|
||||
assertTrue(reportingTask.getTags().contains("metrics"));
|
||||
assertTrue(reportingTask.getTags().contains("ambari"));
|
||||
assertNull(reportingTask.getProvidedServiceAPIs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocsForTestComponents() throws IOException {
|
||||
final ExtensionManifest extensionManifest = parse("src/test/resources/descriptors/extension-manifest-test-components.xml");
|
||||
assertNotNull(extensionManifest);
|
||||
assertEquals("1.8.0", extensionManifest.getSystemApiVersion());
|
||||
|
||||
final List<Extension> extensionDetails = extensionManifest.getExtensions();
|
||||
assertEquals(4, extensionDetails.size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocsForMissingSystemApi() throws IOException {
|
||||
final ExtensionManifest extensionManifest = parse("src/test/resources/descriptors/extension-manifest-missing-sys-api.xml");
|
||||
assertNotNull(extensionManifest);
|
||||
}
|
||||
|
||||
private ExtensionManifest parse(final String file) throws IOException {
|
||||
try (final InputStream inputStream = new FileInputStream(file)) {
|
||||
return parser.parse(inputStream);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
<extensionManifest>
|
||||
<systemApiVersion>1.10.0-SNAPSHOT</systemApiVersion>
|
||||
<extensions>
|
||||
<extension>
|
||||
<name>org.apache.nifi.reporting.ambari.AmbariReportingTask</name>
|
||||
<type>REPORTING_TASK</type>
|
||||
<deprecationNotice/>
|
||||
<description>Publishes metrics from NiFi to Ambari Metrics Service (AMS). Due to how the Ambari Metrics
|
||||
Service works, this reporting task should be scheduled to run every 60 seconds. Each iteration it will
|
||||
send the metrics from the previous iteration, and calculate the current metrics to be sent on next
|
||||
iteration. Scheduling this reporting task at a frequency other than 60 seconds may produce unexpected
|
||||
results.
|
||||
</description>
|
||||
<tags>
|
||||
<tag>reporting</tag>
|
||||
<tag>ambari</tag>
|
||||
<tag>metrics</tag>
|
||||
</tags>
|
||||
<properties>
|
||||
<property>
|
||||
<name>Metrics Collector URL</name>
|
||||
<displayName>Metrics Collector URL</displayName>
|
||||
<description>The URL of the Ambari Metrics Collector Service</description>
|
||||
<defaultValue>http://localhost:6188/ws/v1/timeline/metrics</defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>true</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>Application ID</name>
|
||||
<displayName>Application ID</displayName>
|
||||
<description>The Application ID to be included in the metrics sent to Ambari</description>
|
||||
<defaultValue>nifi</defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>true</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>Hostname</name>
|
||||
<displayName>Hostname</displayName>
|
||||
<description>The Hostname of this NiFi instance to be included in the metrics sent to Ambari
|
||||
</description>
|
||||
<defaultValue>${hostname(true)}</defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>true</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>Process Group ID</name>
|
||||
<displayName>Process Group ID</displayName>
|
||||
<description>If specified, the reporting task will send metrics about this process group only. If
|
||||
not, the root process group is used and global metrics are sent.
|
||||
</description>
|
||||
<defaultValue></defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>false</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
</properties>
|
||||
<dynamicProperties></dynamicProperties>
|
||||
<stateful></stateful>
|
||||
<restricted></restricted>
|
||||
<inputRequirement></inputRequirement>
|
||||
<systemResourceConsiderations></systemResourceConsiderations>
|
||||
<seeAlso/>
|
||||
</extension>
|
||||
</extensions>
|
||||
</extensionManifest>
|
|
@ -0,0 +1,325 @@
|
|||
<extensionManifest>
|
||||
<systemApiVersion>1.10.0-SNAPSHOT</systemApiVersion>
|
||||
<extensions>
|
||||
<extension>
|
||||
<name>org.apache.nifi.dbcp.DBCPConnectionPoolLookup</name>
|
||||
<type>CONTROLLER_SERVICE</type>
|
||||
<deprecationNotice/>
|
||||
<description>Provides a DBCPService that can be used to dynamically select another DBCPService. This service
|
||||
requires an attribute named 'database.name' to be passed in when asking for a connection, and will throw
|
||||
an exception if the attribute is missing. The value of 'database.name' will be used to select the
|
||||
DBCPService that has been registered with that name. This will allow multiple DBCPServices to be defined
|
||||
and registered, and then selected dynamically at runtime by tagging flow files with the appropriate
|
||||
'database.name' attribute.
|
||||
</description>
|
||||
<tags>
|
||||
<tag>dbcp</tag>
|
||||
<tag>jdbc</tag>
|
||||
<tag>database</tag>
|
||||
<tag>connection</tag>
|
||||
<tag>pooling</tag>
|
||||
<tag>store</tag>
|
||||
</tags>
|
||||
<properties></properties>
|
||||
<dynamicProperties>
|
||||
<dynamicProperty>
|
||||
<name>The</name>
|
||||
<value>JDBC property value</value>
|
||||
<description></description>
|
||||
<expressionLanguageSupported>false</expressionLanguageSupported>
|
||||
<expressionLanguageScope>NONE</expressionLanguageScope>
|
||||
</dynamicProperty>
|
||||
</dynamicProperties>
|
||||
<stateful></stateful>
|
||||
<restricted></restricted>
|
||||
<inputRequirement></inputRequirement>
|
||||
<systemResourceConsiderations></systemResourceConsiderations>
|
||||
<seeAlso/>
|
||||
<providedServiceAPIs>
|
||||
<providedServiceAPI>
|
||||
<className>org.apache.nifi.dbcp.DBCPService</className>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-standard-services-api-nar</artifactId>
|
||||
<version>1.10.0-SNAPSHOT</version>
|
||||
</providedServiceAPI>
|
||||
</providedServiceAPIs>
|
||||
</extension>
|
||||
<extension>
|
||||
<name>org.apache.nifi.dbcp.DBCPConnectionPool</name>
|
||||
<type>CONTROLLER_SERVICE</type>
|
||||
<deprecationNotice/>
|
||||
<description>Provides Database Connection Pooling Service. Connections can be asked from pool and returned
|
||||
after usage.
|
||||
</description>
|
||||
<tags>
|
||||
<tag>dbcp</tag>
|
||||
<tag>jdbc</tag>
|
||||
<tag>database</tag>
|
||||
<tag>connection</tag>
|
||||
<tag>pooling</tag>
|
||||
<tag>store</tag>
|
||||
</tags>
|
||||
<properties>
|
||||
<property>
|
||||
<name>Database Connection URL</name>
|
||||
<displayName>Database Connection URL</displayName>
|
||||
<description>A database connection URL used to connect to a database. May contain database system
|
||||
name, host, port, database name and some parameters. The exact syntax of a database connection
|
||||
URL is specified by your DBMS.
|
||||
</description>
|
||||
<defaultValue></defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>true</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>Database Driver Class Name</name>
|
||||
<displayName>Database Driver Class Name</displayName>
|
||||
<description>Database driver class name</description>
|
||||
<defaultValue></defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>true</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>database-driver-locations</name>
|
||||
<displayName>Database Driver Location(s)</displayName>
|
||||
<description>Comma-separated list of files/folders and/or URLs containing the driver JAR and its
|
||||
dependencies (if any). For example '/var/tmp/mariadb-java-client-1.1.7.jar'
|
||||
</description>
|
||||
<defaultValue></defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>false</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>kerberos-credentials-service</name>
|
||||
<displayName>Kerberos Credentials Service</displayName>
|
||||
<description>Specifies the Kerberos Credentials Controller Service that should be used for
|
||||
authenticating with Kerberos
|
||||
</description>
|
||||
<defaultValue></defaultValue>
|
||||
<controllerServiceDefinition>
|
||||
<className>org.apache.nifi.kerberos.KerberosCredentialsService</className>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>org.apache.nifi:nifi-standard-services-api-nar:nar:1.10.0-SNAPSHOT</artifactId>
|
||||
<version>1.10.0-SNAPSHOT</version>
|
||||
</controllerServiceDefinition>
|
||||
<allowableValues></allowableValues>
|
||||
<required>false</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>false</expressionLanguageSupported>
|
||||
<expressionLanguageScope>NONE</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>Database User</name>
|
||||
<displayName>Database User</displayName>
|
||||
<description>Database user name</description>
|
||||
<defaultValue></defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>false</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>Password</name>
|
||||
<displayName>Password</displayName>
|
||||
<description>The password for the database user</description>
|
||||
<defaultValue></defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>false</required>
|
||||
<sensitive>true</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>Max Wait Time</name>
|
||||
<displayName>Max Wait Time</displayName>
|
||||
<description>The maximum amount of time that the pool will wait (when there are no available
|
||||
connections) for a connection to be returned before failing, or -1 to wait indefinitely.
|
||||
</description>
|
||||
<defaultValue>500 millis</defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>true</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>false</expressionLanguageSupported>
|
||||
<expressionLanguageScope>NONE</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>Max Total Connections</name>
|
||||
<displayName>Max Total Connections</displayName>
|
||||
<description>The maximum number of active connections that can be allocated from this pool at the
|
||||
same time, or negative for no limit.
|
||||
</description>
|
||||
<defaultValue>8</defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>true</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>false</expressionLanguageSupported>
|
||||
<expressionLanguageScope>NONE</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>Validation-query</name>
|
||||
<displayName>Validation query</displayName>
|
||||
<description>Validation query used to validate connections before returning them. When connection is
|
||||
invalid, it get's dropped and new valid connection will be returned. Note!! Using validation
|
||||
might have some performance penalty.
|
||||
</description>
|
||||
<defaultValue></defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>false</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>dbcp-min-idle-conns</name>
|
||||
<displayName>Minimum Idle Connections</displayName>
|
||||
<description>The minimum number of connections that can remain idle in the pool, without extra ones
|
||||
being created, or zero to create none.
|
||||
</description>
|
||||
<defaultValue>0</defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>false</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>dbcp-max-idle-conns</name>
|
||||
<displayName>Max Idle Connections</displayName>
|
||||
<description>The maximum number of connections that can remain idle in the pool, without extra ones
|
||||
being released, or negative for no limit.
|
||||
</description>
|
||||
<defaultValue>8</defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>false</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>dbcp-max-conn-lifetime</name>
|
||||
<displayName>Max Connection Lifetime</displayName>
|
||||
<description>The maximum lifetime in milliseconds of a connection. After this time is exceeded the
|
||||
connection will fail the next activation, passivation or validation test. A value of zero or
|
||||
less means the connection has an infinite lifetime.
|
||||
</description>
|
||||
<defaultValue>-1</defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>false</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>dbcp-time-between-eviction-runs</name>
|
||||
<displayName>Time Between Eviction Runs</displayName>
|
||||
<description>The number of milliseconds to sleep between runs of the idle connection evictor thread.
|
||||
When non-positive, no idle connection evictor thread will be run.
|
||||
</description>
|
||||
<defaultValue>-1</defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>false</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>dbcp-min-evictable-idle-time</name>
|
||||
<displayName>Minimum Evictable Idle Time</displayName>
|
||||
<description>The minimum amount of time a connection may sit idle in the pool before it is eligible
|
||||
for eviction.
|
||||
</description>
|
||||
<defaultValue>30 mins</defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>false</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
<property>
|
||||
<name>dbcp-soft-min-evictable-idle-time</name>
|
||||
<displayName>Soft Minimum Evictable Idle Time</displayName>
|
||||
<description>The minimum amount of time a connection may sit idle in the pool before it is eligible
|
||||
for eviction by the idle connection evictor, with the extra condition that at least a minimum
|
||||
number of idle connections remain in the pool. When the not-soft version of this option is set
|
||||
to a positive value, it is examined first by the idle connection evictor: when idle connections
|
||||
are visited by the evictor, idle time is first compared against it (without considering the
|
||||
number of idle connections in the pool) and then against this soft option, including the minimum
|
||||
idle connections constraint.
|
||||
</description>
|
||||
<defaultValue>-1</defaultValue>
|
||||
<allowableValues></allowableValues>
|
||||
<required>false</required>
|
||||
<sensitive>false</sensitive>
|
||||
<expressionLanguageSupported>true</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
<dynamicallyModifiesClasspath>false</dynamicallyModifiesClasspath>
|
||||
<dynamic>false</dynamic>
|
||||
</property>
|
||||
</properties>
|
||||
<dynamicProperties>
|
||||
<dynamicProperty>
|
||||
<name>JDBC property name</name>
|
||||
<value>JDBC property value</value>
|
||||
<description>Specifies a property name and value to be set on the JDBC connection(s). If Expression
|
||||
Language is used, evaluation will be performed upon the controller service being enabled. Note
|
||||
that no flow file input (attributes, e.g.) is available for use in Expression Language
|
||||
constructs for these properties.
|
||||
</description>
|
||||
<expressionLanguageSupported>false</expressionLanguageSupported>
|
||||
<expressionLanguageScope>VARIABLE_REGISTRY</expressionLanguageScope>
|
||||
</dynamicProperty>
|
||||
</dynamicProperties>
|
||||
<stateful></stateful>
|
||||
<restricted></restricted>
|
||||
<inputRequirement></inputRequirement>
|
||||
<systemResourceConsiderations></systemResourceConsiderations>
|
||||
<seeAlso/>
|
||||
<providedServiceAPIs>
|
||||
<providedServiceAPI>
|
||||
<className>org.apache.nifi.dbcp.DBCPService</className>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-standard-services-api-nar</artifactId>
|
||||
<version>1.10.0-SNAPSHOT</version>
|
||||
</providedServiceAPI>
|
||||
</providedServiceAPIs>
|
||||
</extension>
|
||||
</extensions>
|
||||
</extensionManifest>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,4 @@
|
|||
<extensionManifest>
|
||||
<systemApiVersion></systemApiVersion>
|
||||
<extensions></extensions>
|
||||
</extensionManifest>
|
|
@ -0,0 +1,56 @@
|
|||
<extensionManifest>
|
||||
<systemApiVersion>1.8.0</systemApiVersion>
|
||||
<extensions>
|
||||
<extension>
|
||||
<name>org.apache.nifi.processors.TestProcessor1</name>
|
||||
<type>PROCESSOR</type>
|
||||
<description>Test processor 1.</description>
|
||||
<tags>
|
||||
<tag>test</tag>
|
||||
<tag>processor</tag>
|
||||
</tags>
|
||||
</extension>
|
||||
<extension>
|
||||
<name>org.apache.nifi.processors.TestProcessor2</name>
|
||||
<type>PROCESSOR</type>
|
||||
<description>Test processor 2.</description>
|
||||
<tags>
|
||||
<tag>test</tag>
|
||||
<tag>processor</tag>
|
||||
</tags>
|
||||
<restricted>
|
||||
<restrictions>
|
||||
<restriction>
|
||||
<requiredPermission>write filesystem</requiredPermission>
|
||||
<explanation>Test explanation.</explanation>
|
||||
</restriction>
|
||||
</restrictions>
|
||||
</restricted>
|
||||
</extension>
|
||||
<extension>
|
||||
<name>org.apache.nifi.processors.TestProcessor3</name>
|
||||
<type>PROCESSOR</type>
|
||||
<description/>
|
||||
<tags>
|
||||
</tags>
|
||||
</extension>
|
||||
<extension>
|
||||
<name>org.apache.nifi.service.TestServiceImpl</name>
|
||||
<type>CONTROLLER_SERVICE</type>
|
||||
<deprecationNotice/>
|
||||
<description>Test service.</description>
|
||||
<tags>
|
||||
<tag>test</tag>
|
||||
<tag>service</tag>
|
||||
</tags>
|
||||
<providedServiceAPIs>
|
||||
<providedServiceAPI>
|
||||
<className>org.apache.nifi.service.TestService</className>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-test-service-api-nar</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</providedServiceAPI>
|
||||
</providedServiceAPIs>
|
||||
</extension>
|
||||
</extensions>
|
||||
</extensionManifest>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,66 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
|
||||
license agreements. See the NOTICE file distributed with this work for additional
|
||||
information regarding copyright ownership. The ASF licenses this file to
|
||||
You under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
|
||||
by applicable law or agreed to in writing, software distributed under the
|
||||
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
|
||||
OF ANY KIND, either express or implied. See the License for the specific
|
||||
language governing permissions and limitations under the License. -->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-core</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>nifi-registry-client</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-data-model</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-security-utils</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.core</groupId>
|
||||
<artifactId>jersey-client</artifactId>
|
||||
<version>${jersey.client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.media</groupId>
|
||||
<artifactId>jersey-media-json-jackson</artifactId>
|
||||
<version>${jersey.client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.inject</groupId>
|
||||
<artifactId>jersey-hk2</artifactId>
|
||||
<version>${jersey.client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.core</groupId>
|
||||
<artifactId>jersey-common</artifactId>
|
||||
<version>${jersey.client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.media</groupId>
|
||||
<artifactId>jersey-media-multipart</artifactId>
|
||||
<version>${jersey.client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Client for interacting with the AccessResource.
|
||||
*/
|
||||
public interface AccessClient {
|
||||
|
||||
/**
|
||||
* Get an access token by authenticating with a username and password aginst the configured identity provider.
|
||||
*
|
||||
* @param username the username
|
||||
* @param password the password
|
||||
* @return the access token
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
String getToken(String username, String password) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets an access token via spnego. It is expected that the caller of this method has wrapped the call
|
||||
* in a {@code doAs()} using a {@link javax.security.auth.Subject}.
|
||||
*
|
||||
* @return the token
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
String getTokenFromKerberosTicket() throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Performs a logout for the user represented by the given token.
|
||||
*
|
||||
* @param token the toke to authenticate with
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
void logout(String token) throws NiFiRegistryException, IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import org.apache.nifi.registry.bucket.Bucket;
|
||||
import org.apache.nifi.registry.field.Fields;
|
||||
import org.apache.nifi.registry.revision.entity.RevisionInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Client for interacting with buckets.
|
||||
*/
|
||||
public interface BucketClient {
|
||||
|
||||
/**
|
||||
* Creates the given bucket.
|
||||
*
|
||||
* @param bucket the bucket to create
|
||||
* @return the created bucket with containing identifier that was generated
|
||||
*/
|
||||
Bucket create(Bucket bucket) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets the bucket with the given id.
|
||||
*
|
||||
* @param bucketId the id of the bucket to retrieve
|
||||
* @return the bucket with the given id
|
||||
*/
|
||||
Bucket get(String bucketId) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Updates the given bucket. Only the name and description can be updated.
|
||||
*
|
||||
* @param bucket the bucket with updates, must contain the id
|
||||
* @return the updated bucket
|
||||
*/
|
||||
Bucket update(Bucket bucket) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Deletes the bucket with the given id.
|
||||
*
|
||||
* @param bucketId the id of the bucket to delete
|
||||
* @return the deleted bucket
|
||||
*/
|
||||
Bucket delete(String bucketId) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Deletes the bucket with the given id and revision
|
||||
*
|
||||
* @param bucketId the id of the bucket to delete
|
||||
* @param revision the revision info for the bucket being deleted
|
||||
* @return the deleted bucket
|
||||
*/
|
||||
Bucket delete(String bucketId, RevisionInfo revision) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets the fields that can be used to sort/search buckets.
|
||||
*
|
||||
* @return the bucket fields
|
||||
*/
|
||||
Fields getFields() throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets all buckets.
|
||||
*
|
||||
* @return the list of all buckets
|
||||
*/
|
||||
List<Bucket> getAll() throws NiFiRegistryException, IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import org.apache.nifi.registry.extension.bundle.Bundle;
|
||||
import org.apache.nifi.registry.extension.bundle.BundleFilterParams;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Client for interacting with extension bundles.
|
||||
*/
|
||||
public interface BundleClient {
|
||||
|
||||
/**
|
||||
* Retrieves all extension bundles located in buckets the current user is authorized for.
|
||||
*
|
||||
* @return the list of extension bundles
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
List<Bundle> getAll() throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Retrieves all extension bundles matching the specified filters, located in buckets the current user is authorized for.
|
||||
*
|
||||
* @param filterParams the filter params
|
||||
* @return the list of extension bundles
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
List<Bundle> getAll(BundleFilterParams filterParams) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Retrieves the extension bundles located in the given bucket.
|
||||
*
|
||||
* @param bucketId the bucket id
|
||||
* @return the list of bundles in the bucket
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
List<Bundle> getByBucket(String bucketId) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Retrieves the extension bundle with the given id.
|
||||
*
|
||||
* @param bundleId the id of the bundle
|
||||
* @return the bundle with the given id
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
Bundle get(String bundleId) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Deletes the extension bundle with the given id, and all of its versions.
|
||||
*
|
||||
* @param bundleId the bundle id
|
||||
* @return the deleted bundle
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
Bundle delete(String bundleId) throws IOException, NiFiRegistryException;
|
||||
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import org.apache.nifi.registry.extension.bundle.BundleType;
|
||||
import org.apache.nifi.registry.extension.bundle.BundleVersion;
|
||||
import org.apache.nifi.registry.extension.bundle.BundleVersionFilterParams;
|
||||
import org.apache.nifi.registry.extension.bundle.BundleVersionMetadata;
|
||||
import org.apache.nifi.registry.extension.component.manifest.Extension;
|
||||
import org.apache.nifi.registry.extension.component.ExtensionMetadata;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Client for interacting with extension bundle versions.
|
||||
*/
|
||||
public interface BundleVersionClient {
|
||||
|
||||
/**
|
||||
* Uploads a version of an extension bundle to NiFi Registry where the bundle content comes from an InputStream.
|
||||
*
|
||||
* @param bucketId the bucket where the extension bundle will leave
|
||||
* @param bundleType the type of bundle being uploaded
|
||||
* @param bundleContentStream the input stream with the binary content of the bundle
|
||||
* @return the BundleVersion entity
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
BundleVersion create(String bucketId, BundleType bundleType, InputStream bundleContentStream)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Uploads a version of an extension bundle to NiFi Registry where the bundle content comes from an InputStream.
|
||||
*
|
||||
* @param bucketId the bucket where the extension bundle will leave
|
||||
* @param bundleType the type of bundle being uploaded
|
||||
* @param bundleContentStream the input stream with the binary content of the bundle
|
||||
* @param sha256 the optional SHA-256 in hex form
|
||||
* @return the BundleVersion entity
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
BundleVersion create(String bucketId, BundleType bundleType, InputStream bundleContentStream, String sha256)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Uploads a version of an extension bundle to NiFi Registry where the bundle content comes from a File.
|
||||
*
|
||||
* @param bucketId the bucket where the extension bundle will leave
|
||||
* @param bundleType the type of bundle being uploaded
|
||||
* @param bundleFile the file with the binary content of the bundle
|
||||
* @return the BundleVersion entity
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
BundleVersion create(String bucketId, BundleType bundleType, File bundleFile)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Uploads a version of an extension bundle to NiFi Registry where the bundle content comes from a File.
|
||||
*
|
||||
* @param bucketId the bucket where the extension bundle will leave
|
||||
* @param bundleType the type of bundle being uploaded
|
||||
* @param bundleFile the file with the binary content of the bundle
|
||||
* @param sha256 the optional SHA-256 in hex form
|
||||
* @return the BundleVersion entity
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
BundleVersion create(String bucketId, BundleType bundleType, File bundleFile, String sha256)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Retrieves all the extension bundle versions located in buckets the current user is authorized for, and
|
||||
* matching any of the provided filter params.
|
||||
*
|
||||
* @param filterParams the filter params
|
||||
* @return the list of bundle version metadata
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
List<BundleVersionMetadata> getBundleVersions(BundleVersionFilterParams filterParams)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Retrieves the metadata about the versions of the given bundle.
|
||||
*
|
||||
* @param bundleId the bundle id
|
||||
* @return the list of version metadata
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
List<BundleVersionMetadata> getBundleVersions(String bundleId) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Retrieves bundle version entity for the given bundle id and version string.
|
||||
*
|
||||
* The entity contains all of the information about the version, such as the bucket, bundle, and version metadata.
|
||||
*
|
||||
* The binary content of the bundle can be obtained by calling {@method getBundleVersionContent}.
|
||||
*
|
||||
* @param bundleId the bundle id
|
||||
* @param version the bundle version
|
||||
* @return the BundleVersion entity
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
BundleVersion getBundleVersion(String bundleId, String version) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Retrieves the metadata about the extensions in the given bundle version.
|
||||
*
|
||||
* @param bundleId the bundle id
|
||||
* @param version the bundle version
|
||||
* @return the list of metadata about the extensions
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
List<ExtensionMetadata> getExtensions(String bundleId, String version) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Retrieves the full extension info for the extension with the given name in the given bundle version.
|
||||
*
|
||||
* @param bundleId the bundle id
|
||||
* @param version the version of the bundle
|
||||
* @param name the name of the extension
|
||||
* @return the extension info
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
Extension getExtension(String bundleId, String version, String name) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Obtains an InputStream for the html docs of the given extension.
|
||||
*
|
||||
* @param bundleId the bundle id
|
||||
* @param version the version of the bundle
|
||||
* @param name the name of the extensions
|
||||
* @return the InputStream for the extension docs
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
InputStream getExtensionDocs(String bundleId, String version, String name) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Obtains an InputStream for the binary content for the version of the given bundle.
|
||||
*
|
||||
* @param bundleId the bundle id
|
||||
* @param version the version
|
||||
* @return the InputStream for the bundle version content
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
InputStream getBundleVersionContent(String bundleId, String version) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Writes the binary content for the version of the given the bundle to the specified directory.
|
||||
*
|
||||
* @param bundleId the bundle id
|
||||
* @param version the bundle version
|
||||
* @param directory the directory to write to
|
||||
* @return the File object for the bundle that was written
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
File writeBundleVersionContent(String bundleId, String version, File directory) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Deletes the given extension bundle version.
|
||||
*
|
||||
* @param bundleId the bundle id
|
||||
* @param version the bundle version
|
||||
* @return the deleted bundle versions
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
BundleVersion delete(String bundleId, String version) throws IOException, NiFiRegistryException;
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import org.apache.nifi.registry.extension.component.ExtensionFilterParams;
|
||||
import org.apache.nifi.registry.extension.component.ExtensionMetadataContainer;
|
||||
import org.apache.nifi.registry.extension.component.TagCount;
|
||||
import org.apache.nifi.registry.extension.component.manifest.ProvidedServiceAPI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Client for obtaining information about extensions.
|
||||
*/
|
||||
public interface ExtensionClient {
|
||||
|
||||
/**
|
||||
* Retrieves extensions according to the given filter params.
|
||||
*
|
||||
* @param filterParams the filter params
|
||||
* @return the metadata for the extensions matching the filter params
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
ExtensionMetadataContainer findExtensions(ExtensionFilterParams filterParams) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Retrieves extensions that provide the given service API.
|
||||
*
|
||||
* @param providedServiceAPI the service API
|
||||
* @return the metadata for extensions that provided the service API
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
ExtensionMetadataContainer findExtensions(ProvidedServiceAPI providedServiceAPI) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* @return all of the tags known the registry with their corresponding counts
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
List<TagCount> getTagCounts() throws IOException, NiFiRegistryException;
|
||||
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import org.apache.nifi.registry.extension.component.manifest.Extension;
|
||||
import org.apache.nifi.registry.extension.repo.ExtensionRepoArtifact;
|
||||
import org.apache.nifi.registry.extension.repo.ExtensionRepoBucket;
|
||||
import org.apache.nifi.registry.extension.repo.ExtensionRepoExtensionMetadata;
|
||||
import org.apache.nifi.registry.extension.repo.ExtensionRepoGroup;
|
||||
import org.apache.nifi.registry.extension.repo.ExtensionRepoVersion;
|
||||
import org.apache.nifi.registry.extension.repo.ExtensionRepoVersionSummary;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Client for interacting with the extension repository.
|
||||
*/
|
||||
public interface ExtensionRepoClient {
|
||||
|
||||
/**
|
||||
* Gets the buckets in the extension repo.
|
||||
*
|
||||
* @return the list of extension repo buckets.
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
List<ExtensionRepoBucket> getBuckets() throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Gets the extension repo groups in the specified bucket.
|
||||
*
|
||||
* @param bucketName the bucket name
|
||||
* @return the list of groups
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
List<ExtensionRepoGroup> getGroups(String bucketName) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Gets the extension repo artifacts in the given bucket and group.
|
||||
*
|
||||
* @param bucketName the bucket name
|
||||
* @param groupId the group id
|
||||
* @return the list of artifacts
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
List<ExtensionRepoArtifact> getArtifacts(String bucketName, String groupId) throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Gets the extension repo versions for the given bucket, group, artifact.
|
||||
*
|
||||
* @param bucketName the bucket name
|
||||
* @param groupId the group id
|
||||
* @param artifactId the artifact id
|
||||
* @return the list of version summaries
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
List<ExtensionRepoVersionSummary> getVersions(String bucketName, String groupId, String artifactId)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Gets the extension repo version for the given bucket, group, artifact, and version.
|
||||
*
|
||||
* @param bucketName the bucket name
|
||||
* @param groupId the group id
|
||||
* @param artifactId the artifact id
|
||||
* @param version the version
|
||||
* @return the extension repo version
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
ExtensionRepoVersion getVersion(String bucketName, String groupId, String artifactId, String version)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Gets the metadata about the extensions for the given bucket, group, artifact, and version.
|
||||
*
|
||||
* @param bucketName the bucket name
|
||||
* @param groupId the group id
|
||||
* @param artifactId the artifact id
|
||||
* @param version the version
|
||||
* @return the list of extension metadata
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
List<ExtensionRepoExtensionMetadata> getVersionExtensions(String bucketName, String groupId, String artifactId, String version)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Gets the metadata about the extension with the given name in the given bucket, group, artifact, and version.
|
||||
*
|
||||
* @param bucketName the bucket name
|
||||
* @param groupId the group id
|
||||
* @param artifactId the artifact id
|
||||
* @param version the version
|
||||
* @param extensionName the extension name
|
||||
* @return the extension info
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
Extension getVersionExtension(String bucketName, String groupId, String artifactId, String version, String extensionName)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Gets an InputStream for the html docs of the extension with the given name in the given bucket, group, artifact, and version.
|
||||
*
|
||||
* @param bucketName the bucket name
|
||||
* @param groupId the group id
|
||||
* @param artifactId the artifact id
|
||||
* @param version the version
|
||||
* @param extensionName the extension name
|
||||
* @return the InputStream for the html docs
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
InputStream getVersionExtensionDocs(String bucketName, String groupId, String artifactId, String version, String extensionName)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Gets an InputStream for the binary content of the specified version.
|
||||
*
|
||||
* @param bucketName the bucket name
|
||||
* @param groupId the group id
|
||||
* @param artifactId the artifact id
|
||||
* @param version the version
|
||||
* @return the input stream
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
InputStream getVersionContent(String bucketName, String groupId, String artifactId, String version)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Writes the binary content for the version of the given the bundle to the specified directory.
|
||||
*
|
||||
* @param bucketName the bucket name
|
||||
* @param groupId the group id
|
||||
* @param artifactId the artifact id
|
||||
* @param version the version
|
||||
* @param directory the directory to write to
|
||||
* @return the File object for the bundle that was written
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
File writeBundleVersionContent(String bucketName, String groupId, String artifactId, String version, File directory)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Gets the hex representation of the SHA-256 hash of the binary content for the given version.
|
||||
*
|
||||
* @param bucketName the bucket name
|
||||
* @param groupId the group id
|
||||
* @param artifactId the artifact id
|
||||
* @param version the version
|
||||
* @return the SHA-256 hex string
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
String getVersionSha256(String bucketName, String groupId, String artifactId, String version)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
/**
|
||||
* Gets the hex representation of the SHA-256 hash of the binary content for the given version.
|
||||
*
|
||||
* If the version is a SNAPSHOT version, there may be more than one instance of the SNAPSHOT version in different
|
||||
* buckets. In this case the instance with the latest created timestamp will be used to obtain the checksum.
|
||||
*
|
||||
* @param groupId the group id
|
||||
* @param artifactId the artifact id
|
||||
* @param version the version
|
||||
* @return the SHA-256 hex string
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NiFiRegistryException if an non I/O error occurs
|
||||
*/
|
||||
Optional<String> getVersionSha256(String groupId, String artifactId, String version)
|
||||
throws IOException, NiFiRegistryException;
|
||||
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import org.apache.nifi.registry.diff.VersionedFlowDifference;
|
||||
import org.apache.nifi.registry.field.Fields;
|
||||
import org.apache.nifi.registry.flow.VersionedFlow;
|
||||
import org.apache.nifi.registry.revision.entity.RevisionInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Client for interacting with flows.
|
||||
*/
|
||||
public interface FlowClient {
|
||||
|
||||
/**
|
||||
* Create the given flow in the given bucket.
|
||||
*
|
||||
* @param flow the flow to create
|
||||
* @return the created flow with the identifier populated
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlow create(VersionedFlow flow) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets the flow with the given id in the given bucket.
|
||||
*
|
||||
* The list of snapshot metadata will NOT be populated.
|
||||
*
|
||||
* @param bucketId a bucket id
|
||||
* @param flowId a flow id
|
||||
* @return the flow with the given id in the given bucket
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlow get(String bucketId, String flowId) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets the flow with the given id.
|
||||
*
|
||||
* @param flowId a flow id
|
||||
* @return the flow with the given id
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlow get(String flowId) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Updates the given flow with in the given bucket.
|
||||
*
|
||||
* The identifier of the flow must be populated in the flow object, and only the name and description can be updated.
|
||||
*
|
||||
* @param bucketId a bucket id
|
||||
* @param flow the flow with updates
|
||||
* @return the updated flow
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlow update(String bucketId, VersionedFlow flow) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Deletes the flow with the given id in the given bucket.
|
||||
*
|
||||
* @param bucketId a bucket id
|
||||
* @param flowId the id of the flow to delete
|
||||
* @return the deleted flow
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlow delete(String bucketId, String flowId) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Deletes the flow with the given id in the given bucket.
|
||||
*
|
||||
* @param bucketId a bucket id
|
||||
* @param flowId the id of the flow to delete
|
||||
* @param revision the revision information for the entity being deleted
|
||||
* @return the deleted flow
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlow delete(String bucketId, String flowId, RevisionInfo revision) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets the field info for flows.
|
||||
*
|
||||
* @return field info for flows
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
Fields getFields() throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets the flows for a given bucket.
|
||||
*
|
||||
* @param bucketId a bucket id
|
||||
* @return the flows in the given bucket
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
List<VersionedFlow> getByBucket(String bucketId) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bucketId a bucket id
|
||||
* @param flowId the flow that is under inspection
|
||||
* @param versionA the first version to use in the comparison
|
||||
* @param versionB the second flow to use in the comparison
|
||||
* @return the list of differences between the 2 flow versions grouped by component
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlowDifference diff(final String bucketId, final String flowId,
|
||||
final Integer versionA, final Integer versionB) throws NiFiRegistryException, IOException;
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
|
||||
import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Client for interacting with snapshots.
|
||||
*/
|
||||
public interface FlowSnapshotClient {
|
||||
|
||||
/**
|
||||
* Creates a new snapshot/version for the given flow.
|
||||
*
|
||||
* The snapshot object must have the version populated, and will receive an error if the submitted version is
|
||||
* not the next one-up version.
|
||||
*
|
||||
* @param snapshot the new snapshot
|
||||
* @return the created snapshot
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlowSnapshot create(VersionedFlowSnapshot snapshot) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets the snapshot for the given bucket, flow, and version.
|
||||
*
|
||||
* @param bucketId the bucket id
|
||||
* @param flowId the flow id
|
||||
* @param version the version
|
||||
* @return the snapshot with the given version of the given flow in the given bucket
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlowSnapshot get(String bucketId, String flowId, int version) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets the snapshot for the given flow and version.
|
||||
*
|
||||
* @param flowId the flow id
|
||||
* @param version the version
|
||||
* @return the snapshot with the given version of the given flow
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlowSnapshot get(String flowId, int version) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets the latest snapshot for the given flow.
|
||||
*
|
||||
* @param bucketId the bucket id
|
||||
* @param flowId the flow id
|
||||
* @return the snapshot with the latest version for the given flow
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlowSnapshot getLatest(String bucketId, String flowId) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets the latest snapshot for the given flow.
|
||||
*
|
||||
* @param flowId the flow id
|
||||
* @return the snapshot with the latest version for the given flow
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlowSnapshot getLatest(String flowId) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets the latest snapshot metadata for the given flow.
|
||||
*
|
||||
* @param bucketId the bucket id
|
||||
* @param flowId the flow id
|
||||
* @return the snapshot metadata for the latest version of the given flow
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlowSnapshotMetadata getLatestMetadata(String bucketId, String flowId) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets the latest snapshot metadata for the given flow.
|
||||
*
|
||||
* @param flowId the flow id
|
||||
* @return the snapshot metadata for the latest version of the given flow
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
VersionedFlowSnapshotMetadata getLatestMetadata(String flowId) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets a list of the metadata for all snapshots of a given flow.
|
||||
*
|
||||
* The contents of each snapshot are not part of the response.
|
||||
*
|
||||
* @param bucketId the bucket id
|
||||
* @param flowId the flow id
|
||||
* @return the list of snapshot metadata
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
List<VersionedFlowSnapshotMetadata> getSnapshotMetadata(String bucketId, String flowId) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets a list of the metadata for all snapshots of a given flow.
|
||||
*
|
||||
* The contents of each snapshot are not part of the response.
|
||||
*
|
||||
* @param flowId the flow id
|
||||
* @return the list of snapshot metadata
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
List<VersionedFlowSnapshotMetadata> getSnapshotMetadata(String flowId) throws NiFiRegistryException, IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import org.apache.nifi.registry.bucket.BucketItem;
|
||||
import org.apache.nifi.registry.field.Fields;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Client for interacting with bucket items.
|
||||
*
|
||||
* Bucket items contain the common fields across anything stored in the registry.
|
||||
*
|
||||
* Each item contains a type field and a link to the URI of the specific item.
|
||||
*
|
||||
* i.e. The link field of a flow item would contain the URI to the specific flow.
|
||||
*/
|
||||
public interface ItemsClient {
|
||||
|
||||
/**
|
||||
* Gets all bucket items in the registry.
|
||||
*
|
||||
* @return the list of all bucket items
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
List<BucketItem> getAll() throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets all bucket items for the given bucket.
|
||||
*
|
||||
* @param bucketId the bucket id
|
||||
* @return the list of items in the given bucket
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
List<BucketItem> getByBucket(String bucketId) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Gets the field info for bucket items.
|
||||
*
|
||||
* @return the list of field info
|
||||
* @throws NiFiRegistryException if an error is encountered other than IOException
|
||||
* @throws IOException if an I/O error is encountered
|
||||
*/
|
||||
Fields getFields() throws NiFiRegistryException, IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
/**
|
||||
* A client for interacting with the REST API of a NiFi registry instance.
|
||||
*/
|
||||
public interface NiFiRegistryClient extends Closeable {
|
||||
|
||||
/**
|
||||
* @return the client for interacting with buckets
|
||||
*/
|
||||
BucketClient getBucketClient();
|
||||
|
||||
/**
|
||||
* @deprecated use getBucketClient(RequestConfig requestConfig)
|
||||
*
|
||||
* @return the client for interacting with buckets on behalf of the given proxied entities
|
||||
*/
|
||||
BucketClient getBucketClient(String ... proxiedEntity);
|
||||
|
||||
/**
|
||||
* @return the client for interacting with buckets using the given request config
|
||||
*/
|
||||
BucketClient getBucketClient(RequestConfig requestConfig);
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return the client for interacting with flows
|
||||
*/
|
||||
FlowClient getFlowClient();
|
||||
|
||||
/**
|
||||
* @deprecated use getFlowClient(RequestConfig requestConfig)
|
||||
*
|
||||
* @return the client for interacting with flows on behalf of the given proxied entities
|
||||
*/
|
||||
FlowClient getFlowClient(String ... proxiedEntity);
|
||||
|
||||
/**
|
||||
* @return the client for interacting with flows using the given request config
|
||||
*/
|
||||
FlowClient getFlowClient(RequestConfig requestConfig);
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return the client for interacting with flows/snapshots
|
||||
*/
|
||||
FlowSnapshotClient getFlowSnapshotClient();
|
||||
|
||||
/**
|
||||
* @deprecated use getFlowSnapshotClient(RequestConfig requestConfig)
|
||||
*
|
||||
* @return the client for interacting with flows/snapshots on behalf of the given proxied entities
|
||||
*/
|
||||
FlowSnapshotClient getFlowSnapshotClient(String ... proxiedEntity);
|
||||
|
||||
/**
|
||||
* @return the client for interacting with flows/snapshots using the given request config
|
||||
*/
|
||||
FlowSnapshotClient getFlowSnapshotClient(RequestConfig requestConfig);
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return the client for interacting with bucket items
|
||||
*/
|
||||
ItemsClient getItemsClient();
|
||||
|
||||
/**
|
||||
* @deprecated use getItemsClient(RequestConfig requestConfig)
|
||||
*
|
||||
* @return the client for interacting with bucket items on behalf of the given proxied entities
|
||||
*/
|
||||
ItemsClient getItemsClient(String ... proxiedEntity);
|
||||
|
||||
/**
|
||||
* @return the client for interacting with bucket items using the given request config
|
||||
*/
|
||||
ItemsClient getItemsClient(RequestConfig requestConfig);
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return the client for obtaining information about the current user
|
||||
*/
|
||||
UserClient getUserClient();
|
||||
|
||||
/**
|
||||
* @deprecated use getUserClient(RequestConfig requestConfig)
|
||||
*
|
||||
* @return the client for obtaining information about the current user based on the given proxied entities
|
||||
*/
|
||||
UserClient getUserClient(String ... proxiedEntity);
|
||||
|
||||
/**
|
||||
* @return the client for obtaining information about the current user based on the request config
|
||||
*/
|
||||
UserClient getUserClient(RequestConfig requestConfig);
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return the client for interacting with extension bundles
|
||||
*/
|
||||
BundleClient getBundleClient();
|
||||
|
||||
/**
|
||||
* @deprecated use getBundleClient(RequestConfig requestConfig)
|
||||
*
|
||||
* @return the client for interacting with extension bundles on behalf of the given proxied entities
|
||||
*/
|
||||
BundleClient getBundleClient(String ... proxiedEntity);
|
||||
|
||||
/**
|
||||
* @return the client for interacting with extension bundles using the given request config
|
||||
*/
|
||||
BundleClient getBundleClient(RequestConfig requestConfig);
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return the client for interacting with extension bundle versions
|
||||
*/
|
||||
BundleVersionClient getBundleVersionClient();
|
||||
|
||||
/**
|
||||
* @deprecated use getBundleVersionClient(RequestConfig requestConfig)
|
||||
*
|
||||
* @return the client for interacting with extension bundle versions on behalf of the given proxied entities
|
||||
*/
|
||||
BundleVersionClient getBundleVersionClient(String ... proxiedEntity);
|
||||
|
||||
/**
|
||||
* @return the client for interacting with extension bundle versions using the given request config
|
||||
*/
|
||||
BundleVersionClient getBundleVersionClient(RequestConfig requestConfig);
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return the client for interacting with the extension repository
|
||||
*/
|
||||
ExtensionRepoClient getExtensionRepoClient();
|
||||
|
||||
/**
|
||||
* @deprecated use getExtensionRepoClient(RequestConfig requestConfig)
|
||||
*
|
||||
* @return the client for interacting with the extension repository on behalf of the given proxied entities
|
||||
*/
|
||||
ExtensionRepoClient getExtensionRepoClient(String ... proxiedEntity);
|
||||
|
||||
/**
|
||||
* @return the client for interacting with the extension repository using the given request config
|
||||
*/
|
||||
ExtensionRepoClient getExtensionRepoClient(RequestConfig requestConfig);
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return the client for interacting with extensions
|
||||
*/
|
||||
ExtensionClient getExtensionClient();
|
||||
|
||||
/**
|
||||
* @deprecated use getExtensionClient(RequestConfig requestConfig)
|
||||
*
|
||||
* @return the client for interacting with extensions on behalf of the given proxied entities
|
||||
*/
|
||||
ExtensionClient getExtensionClient(String ... proxiedEntity);
|
||||
|
||||
/**
|
||||
* @return the client for interacting with extensions using the given request config
|
||||
*/
|
||||
ExtensionClient getExtensionClient(RequestConfig requestConfig);
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns client for interacting with tenants.
|
||||
*
|
||||
* @return the client for interacting with tenants
|
||||
*/
|
||||
TenantsClient getTenantsClient();
|
||||
|
||||
/**
|
||||
* Returns client for interacting with tenants.
|
||||
*
|
||||
* @deprecated use getTenantsClient(RequestConfig requestConfig)
|
||||
*
|
||||
* @param proxiedEntity The given proxied entities.
|
||||
*
|
||||
* @return the client for interacting with tenants on behalf of the given proxied entities.
|
||||
*/
|
||||
TenantsClient getTenantsClient(String ... proxiedEntity);
|
||||
|
||||
/**
|
||||
* @return the client for interacting with tenants using the given request config
|
||||
*/
|
||||
TenantsClient getTenantsClient(RequestConfig requestConfig);
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns client for interacting with access policies.
|
||||
*
|
||||
* @return the client for interacting with access policies
|
||||
*/
|
||||
PoliciesClient getPoliciesClient();
|
||||
|
||||
/**
|
||||
* Returns client for interacting with access policies.
|
||||
*
|
||||
* @deprecated use getPoliciesClient(RequestConfig requestConfig)
|
||||
*
|
||||
* @param proxiedEntity The given proxied entities.
|
||||
*
|
||||
* @return the client for interacting with access policies on behalf of the given proxied entities.
|
||||
*/
|
||||
PoliciesClient getPoliciesClient(String ... proxiedEntity);
|
||||
|
||||
/**
|
||||
* @return the client for interacting with access policies using the given request config
|
||||
*/
|
||||
PoliciesClient getPoliciesClient(RequestConfig requestConfig);
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return the client for obtaining access tokens
|
||||
*/
|
||||
AccessClient getAccessClient();
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The builder interface that implementations should provide for obtaining the client.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
Builder config(NiFiRegistryClientConfig clientConfig);
|
||||
|
||||
NiFiRegistryClientConfig getConfig();
|
||||
|
||||
NiFiRegistryClient build();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import org.apache.nifi.registry.security.util.CertificateUtils;
|
||||
import org.apache.nifi.registry.security.util.KeyStoreUtils;
|
||||
import org.apache.nifi.registry.security.util.KeystoreType;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* Configuration for a NiFiRegistryClient.
|
||||
*/
|
||||
public class NiFiRegistryClientConfig {
|
||||
|
||||
public static final String DEFAULT_PROTOCOL = CertificateUtils.getHighestCurrentSupportedTlsProtocolVersion();
|
||||
|
||||
private final String baseUrl;
|
||||
private final SSLContext sslContext;
|
||||
private final String keystoreFilename;
|
||||
private final String keystorePass;
|
||||
private final String keyPass;
|
||||
private final KeystoreType keystoreType;
|
||||
private final String truststoreFilename;
|
||||
private final String truststorePass;
|
||||
private final KeystoreType truststoreType;
|
||||
private final String protocol;
|
||||
private final HostnameVerifier hostnameVerifier;
|
||||
private final Integer readTimeout;
|
||||
private final Integer connectTimeout;
|
||||
|
||||
|
||||
private NiFiRegistryClientConfig(final Builder builder) {
|
||||
this.baseUrl = builder.baseUrl;
|
||||
this.sslContext = builder.sslContext;
|
||||
this.keystoreFilename = builder.keystoreFilename;
|
||||
this.keystorePass = builder.keystorePass;
|
||||
this.keyPass = builder.keyPass;
|
||||
this.keystoreType = builder.keystoreType;
|
||||
this.truststoreFilename = builder.truststoreFilename;
|
||||
this.truststorePass = builder.truststorePass;
|
||||
this.truststoreType = builder.truststoreType;
|
||||
this.protocol = builder.protocol == null ? DEFAULT_PROTOCOL : builder.protocol;
|
||||
this.hostnameVerifier = builder.hostnameVerifier;
|
||||
this.readTimeout = builder.readTimeout;
|
||||
this.connectTimeout = builder.connectTimeout;
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
public SSLContext getSslContext() {
|
||||
if (sslContext != null) {
|
||||
return sslContext;
|
||||
}
|
||||
|
||||
final KeyManagerFactory keyManagerFactory;
|
||||
if (keystoreFilename != null && keystorePass != null && keystoreType != null) {
|
||||
try {
|
||||
// prepare the keystore
|
||||
final KeyStore keyStore = KeyStoreUtils.getKeyStore(keystoreType.name());
|
||||
try (final InputStream keyStoreStream = new FileInputStream(new File(keystoreFilename))) {
|
||||
keyStore.load(keyStoreStream, keystorePass.toCharArray());
|
||||
}
|
||||
keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||
|
||||
if (keyPass == null) {
|
||||
keyManagerFactory.init(keyStore, keystorePass.toCharArray());
|
||||
} else {
|
||||
keyManagerFactory.init(keyStore, keyPass.toCharArray());
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
throw new IllegalStateException("Failed to load Keystore", e);
|
||||
}
|
||||
} else {
|
||||
keyManagerFactory = null;
|
||||
}
|
||||
|
||||
final TrustManagerFactory trustManagerFactory;
|
||||
if (truststoreFilename != null && truststorePass != null && truststoreType != null) {
|
||||
try {
|
||||
// prepare the truststore
|
||||
final KeyStore trustStore = KeyStoreUtils.getKeyStore(truststoreType.name());
|
||||
try (final InputStream trustStoreStream = new FileInputStream(new File(truststoreFilename))) {
|
||||
trustStore.load(trustStoreStream, truststorePass.toCharArray());
|
||||
}
|
||||
trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
trustManagerFactory.init(trustStore);
|
||||
} catch (final Exception e) {
|
||||
throw new IllegalStateException("Failed to load Truststore", e);
|
||||
}
|
||||
} else {
|
||||
trustManagerFactory = null;
|
||||
}
|
||||
|
||||
if (keyManagerFactory != null || trustManagerFactory != null) {
|
||||
try {
|
||||
// initialize the ssl context
|
||||
KeyManager[] keyManagers = keyManagerFactory != null ? keyManagerFactory.getKeyManagers() : null;
|
||||
TrustManager[] trustManagers = trustManagerFactory != null ? trustManagerFactory.getTrustManagers() : null;
|
||||
final SSLContext sslContext = SSLContext.getInstance(getProtocol());
|
||||
sslContext.init(keyManagers, trustManagers, new SecureRandom());
|
||||
sslContext.getDefaultSSLParameters().setNeedClientAuth(true);
|
||||
|
||||
return sslContext;
|
||||
} catch (final Exception e) {
|
||||
throw new IllegalStateException("Created keystore and truststore but failed to initialize SSLContext", e);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getKeystoreFilename() {
|
||||
return keystoreFilename;
|
||||
}
|
||||
|
||||
public String getKeystorePass() {
|
||||
return keystorePass;
|
||||
}
|
||||
|
||||
public String getKeyPass() {
|
||||
return keyPass;
|
||||
}
|
||||
|
||||
public KeystoreType getKeystoreType() {
|
||||
return keystoreType;
|
||||
}
|
||||
|
||||
public String getTruststoreFilename() {
|
||||
return truststoreFilename;
|
||||
}
|
||||
|
||||
public String getTruststorePass() {
|
||||
return truststorePass;
|
||||
}
|
||||
|
||||
public KeystoreType getTruststoreType() {
|
||||
return truststoreType;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public HostnameVerifier getHostnameVerifier() {
|
||||
return hostnameVerifier;
|
||||
}
|
||||
|
||||
public Integer getReadTimeout() {
|
||||
return readTimeout;
|
||||
}
|
||||
|
||||
public Integer getConnectTimeout() {
|
||||
return connectTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for client configuration.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private String baseUrl;
|
||||
private SSLContext sslContext;
|
||||
private String keystoreFilename;
|
||||
private String keystorePass;
|
||||
private String keyPass;
|
||||
private KeystoreType keystoreType;
|
||||
private String truststoreFilename;
|
||||
private String truststorePass;
|
||||
private KeystoreType truststoreType;
|
||||
private String protocol;
|
||||
private HostnameVerifier hostnameVerifier;
|
||||
private Integer readTimeout;
|
||||
private Integer connectTimeout;
|
||||
|
||||
public Builder baseUrl(final String baseUrl) {
|
||||
this.baseUrl = baseUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder sslContext(final SSLContext sslContext) {
|
||||
this.sslContext = sslContext;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder keystoreFilename(final String keystoreFilename) {
|
||||
this.keystoreFilename = keystoreFilename;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder keystorePassword(final String keystorePass) {
|
||||
this.keystorePass = keystorePass;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder keyPassword(final String keyPass) {
|
||||
this.keyPass = keyPass;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder keystoreType(final KeystoreType keystoreType) {
|
||||
this.keystoreType = keystoreType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder truststoreFilename(final String truststoreFilename) {
|
||||
this.truststoreFilename = truststoreFilename;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder truststorePassword(final String truststorePass) {
|
||||
this.truststorePass = truststorePass;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder truststoreType(final KeystoreType truststoreType) {
|
||||
this.truststoreType = truststoreType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder protocol(final String protocol) {
|
||||
this.protocol = protocol;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder hostnameVerifier(final HostnameVerifier hostnameVerifier) {
|
||||
this.hostnameVerifier = hostnameVerifier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder readTimeout(final Integer readTimeout) {
|
||||
this.readTimeout = readTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder connectTimeout(final Integer connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public NiFiRegistryClientConfig build() {
|
||||
return new NiFiRegistryClientConfig(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
/**
|
||||
* Indicates an error interacting with the NiFi registry for a reason other than IOException.
|
||||
*/
|
||||
public class NiFiRegistryException extends Exception {
|
||||
|
||||
public NiFiRegistryException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NiFiRegistryException(final String message, final Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import org.apache.nifi.registry.authorization.AccessPolicy;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface PoliciesClient {
|
||||
|
||||
/**
|
||||
* Returns a given access policy.
|
||||
*
|
||||
* @param resource The action allowed by the access policy.
|
||||
* @param action The resource managed by the access policy.
|
||||
*
|
||||
* @return The access policy.
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
AccessPolicy getAccessPolicy(String action, String resource) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Creates a new access policy.
|
||||
*
|
||||
* @param policy The access policy to be created. Note: identifier will be ignored and assigned by NiFi Registry.
|
||||
*
|
||||
* @return The created access with an assigned identifier.
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
AccessPolicy createAccessPolicy(AccessPolicy policy) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Updates an existing access policy.
|
||||
*
|
||||
* @param policy The access policy with new attributes.
|
||||
*
|
||||
* @return The updated access policy.
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
AccessPolicy updateAccessPolicy(AccessPolicy policy) throws NiFiRegistryException, IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Configuration applied to each client request.
|
||||
*/
|
||||
public interface RequestConfig {
|
||||
|
||||
/**
|
||||
* @return the headers to apply to each request
|
||||
*/
|
||||
Map<String,String> getHeaders();
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import org.apache.nifi.registry.authorization.User;
|
||||
import org.apache.nifi.registry.authorization.UserGroup;
|
||||
import org.apache.nifi.registry.revision.entity.RevisionInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public interface TenantsClient {
|
||||
|
||||
/**
|
||||
* Returns all users.
|
||||
*
|
||||
* @return The list of users.
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
List<User> getUsers() throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Returns a user with a given identifier.
|
||||
*
|
||||
* @param id Identifier of the user.
|
||||
*
|
||||
* @return The user.
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
User getUser(String id) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Creates a new user in NiFi Registry.
|
||||
*
|
||||
* @param user The new user. Note: identifier will be ignored and assigned be NiFi Registry.
|
||||
*
|
||||
* @return The created user with an assigned identifier.
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
User createUser(User user) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Updates an existing user.
|
||||
*
|
||||
* @param user The user with the new attributes.
|
||||
*
|
||||
* @return The updated user.
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
User updateUser(User user) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Deletes an existing user.
|
||||
*
|
||||
* @param id identifier of the user
|
||||
* @return the deleted user
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
User deleteUser(String id) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Deletes an existing user.
|
||||
*
|
||||
* @param id identifier of the user
|
||||
* @param revisionInfo the revision info for the user to delete
|
||||
* @return the deleted user
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
User deleteUser(String id, RevisionInfo revisionInfo) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Returns all user groups.
|
||||
*
|
||||
* @return The list of user groups.
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
List<UserGroup> getUserGroups() throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Returns a user group with a given identifier.
|
||||
*
|
||||
* @param id Identifier of the user group.
|
||||
*
|
||||
* @return The user group.
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
UserGroup getUserGroup(String id) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Creates a new user group.
|
||||
*
|
||||
* @param group The user group to be created. Note: identifier will be ignored and assigned by NiFi Registry.
|
||||
*
|
||||
* @return The created user group with an assigned identifier.
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
UserGroup createUserGroup(UserGroup group) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Updates an existing user group.
|
||||
*
|
||||
* @param group The user group with new attributes.
|
||||
*
|
||||
* @return The user group after store.
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
UserGroup updateUserGroup(UserGroup group) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Deletes an existing group.
|
||||
*
|
||||
* @param id identifier of the group
|
||||
* @return the deleted group
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
UserGroup deleteUserGroup(String id) throws NiFiRegistryException, IOException;
|
||||
|
||||
/**
|
||||
* Deletes an existing group.
|
||||
*
|
||||
* @param id identifier of the group
|
||||
* @param revisionInfo the revision info for the group to delete
|
||||
* @return the deleted group
|
||||
*
|
||||
* @throws NiFiRegistryException Thrown in case of unsuccessful execution.
|
||||
* @throws IOException Thrown when there is an issue while communicating with NiFi Registry.
|
||||
*/
|
||||
UserGroup deleteUserGroup(String id, RevisionInfo revisionInfo) throws NiFiRegistryException, IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client;
|
||||
|
||||
import org.apache.nifi.registry.authorization.CurrentUser;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface UserClient {
|
||||
|
||||
/**
|
||||
* Obtains the access status of the current user.
|
||||
*
|
||||
* If the UserClient was obtained with proxied entities, then the access status should represent the status
|
||||
* of the last identity in the chain.
|
||||
*
|
||||
* If the UserClient was obtained without proxied entities, then it would represent the identity of the certificate
|
||||
* in the keystore used by the client.
|
||||
*
|
||||
* If the registry is not in secure mode, the anonymous identity is expected to be returned along with a flag indicating
|
||||
* the user is anonymous.
|
||||
*
|
||||
* @return the access status of the current user
|
||||
* @throws NiFiRegistryException if the proxying user is not a valid proxy or identity claim is otherwise invalid
|
||||
*/
|
||||
CurrentUser getAccessStatus() throws NiFiRegistryException, IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.revision.entity.RevisionInfo;
|
||||
|
||||
import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.io.IOException;
|
||||
|
||||
public class AbstractCRUDJerseyClient extends AbstractJerseyClient {
|
||||
|
||||
protected final WebTarget baseTarget;
|
||||
|
||||
public AbstractCRUDJerseyClient(final WebTarget baseTarget, final RequestConfig requestConfig) {
|
||||
super(requestConfig);
|
||||
this.baseTarget = baseTarget;
|
||||
}
|
||||
|
||||
protected <T> T get(
|
||||
String id,
|
||||
Class<T> entityType,
|
||||
String entityTypeName,
|
||||
String entityPath
|
||||
) throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(id)) {
|
||||
throw new IllegalArgumentException(entityTypeName + " id cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving " + entityTypeName.toLowerCase(), () -> {
|
||||
final WebTarget target = baseTarget.path(entityPath).path(id);
|
||||
return getRequestBuilder(target).get(entityType);
|
||||
});
|
||||
}
|
||||
|
||||
protected <T> T create(
|
||||
T entity,
|
||||
Class<T> entityType,
|
||||
String entityTypeName,
|
||||
String entityPath
|
||||
) throws NiFiRegistryException, IOException {
|
||||
if (entity == null) {
|
||||
throw new IllegalArgumentException(entityTypeName + " cannot be null");
|
||||
}
|
||||
|
||||
return executeAction("Error creating " + entityTypeName.toLowerCase(), () -> {
|
||||
final WebTarget target = baseTarget.path(entityPath);
|
||||
|
||||
return getRequestBuilder(target).post(
|
||||
Entity.entity(entity, MediaType.APPLICATION_JSON_TYPE), entityType
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
protected <T> T update(
|
||||
T entity,
|
||||
String id,
|
||||
Class<T> entityType,
|
||||
String entityTypeName,
|
||||
String entityPath
|
||||
) throws NiFiRegistryException, IOException {
|
||||
if (entity == null) {
|
||||
throw new IllegalArgumentException(entityTypeName + " cannot be null");
|
||||
}
|
||||
|
||||
return executeAction("Error updating " + entityTypeName.toLowerCase(), () -> {
|
||||
final WebTarget target = baseTarget.path(entityPath).path(id);
|
||||
|
||||
return getRequestBuilder(target).put(
|
||||
Entity.entity(entity, MediaType.APPLICATION_JSON_TYPE), entityType
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
protected <T> T delete(
|
||||
String id,
|
||||
RevisionInfo revisionInfo,
|
||||
Class<T> entityType,
|
||||
String entityTypeName,
|
||||
String entityPath
|
||||
) throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(id)) {
|
||||
throw new IllegalArgumentException(entityTypeName + " id cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error deleting " + entityTypeName.toLowerCase(), () -> {
|
||||
WebTarget target = baseTarget.path(entityPath).path(id);
|
||||
target = addRevisionQueryParams(target, revisionInfo);
|
||||
|
||||
return getRequestBuilder(target).delete(entityType);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.revision.entity.RevisionInfo;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.client.Invocation;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Base class for the client operations to share exception handling.
|
||||
*
|
||||
* Sub-classes should always execute a request from getRequestBuilder(target) to ensure proper headers are sent.
|
||||
*/
|
||||
public class AbstractJerseyClient {
|
||||
|
||||
private static final RequestConfig EMPTY_REQUEST_CONFIG = () -> Collections.emptyMap();
|
||||
|
||||
private final RequestConfig requestConfig;
|
||||
|
||||
public AbstractJerseyClient(final RequestConfig requestConfig) {
|
||||
this.requestConfig = (requestConfig == null ? EMPTY_REQUEST_CONFIG : requestConfig);
|
||||
}
|
||||
|
||||
protected RequestConfig getRequestConfig() {
|
||||
return this.requestConfig;
|
||||
}
|
||||
/**
|
||||
* Adds query parameters for the given RevisionInfo if populated.
|
||||
*
|
||||
* @param target the WebTarget
|
||||
* @param revision the RevisionInfo
|
||||
* @return the target with query params added
|
||||
*/
|
||||
protected WebTarget addRevisionQueryParams(WebTarget target, RevisionInfo revision) {
|
||||
if (revision == null) {
|
||||
return target;
|
||||
}
|
||||
|
||||
WebTarget localTarget = target;
|
||||
|
||||
final Long version = revision.getVersion();
|
||||
if (version != null) {
|
||||
localTarget = localTarget.queryParam("version", version.longValue());
|
||||
}
|
||||
|
||||
final String clientId = revision.getClientId();
|
||||
if (!StringUtils.isBlank(clientId)) {
|
||||
localTarget = localTarget.queryParam("clientId", clientId);
|
||||
}
|
||||
return localTarget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Invocation.Builder for the given WebTarget with the headers added to the builder.
|
||||
*
|
||||
* @param webTarget the target for the request
|
||||
* @return the builder for the target with the headers added
|
||||
*/
|
||||
protected Invocation.Builder getRequestBuilder(final WebTarget webTarget) {
|
||||
final Invocation.Builder requestBuilder = webTarget.request();
|
||||
|
||||
final Map<String,String> headers = requestConfig.getHeaders();
|
||||
headers.entrySet().stream().forEach(e -> requestBuilder.header(e.getKey(), e.getValue()));
|
||||
|
||||
return requestBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given action and returns the result.
|
||||
*
|
||||
* @param action the action to execute
|
||||
* @param errorMessage the message to use if a NiFiRegistryException is thrown
|
||||
* @param <T> the return type of the action
|
||||
* @return the result of the action
|
||||
* @throws NiFiRegistryException if any exception other than IOException is encountered
|
||||
* @throws IOException if an I/O error occurs communicating with the registry
|
||||
*/
|
||||
protected <T> T executeAction(final String errorMessage, final NiFiRegistryAction<T> action) throws NiFiRegistryException, IOException {
|
||||
try {
|
||||
return action.execute();
|
||||
} catch (final Exception e) {
|
||||
final Throwable ioeCause = getIOExceptionCause(e);
|
||||
|
||||
if (ioeCause == null) {
|
||||
final StringBuilder errorMessageBuilder = new StringBuilder(errorMessage);
|
||||
|
||||
// see if we have a WebApplicationException, and if so add the response body to the error message
|
||||
if (e instanceof WebApplicationException) {
|
||||
final Response response = ((WebApplicationException) e).getResponse();
|
||||
final String responseBody = response.readEntity(String.class);
|
||||
errorMessageBuilder.append(": ").append(responseBody);
|
||||
}
|
||||
|
||||
throw new NiFiRegistryException(errorMessageBuilder.toString(), e);
|
||||
} else {
|
||||
throw (IOException) ioeCause;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An action to execute with the given return type.
|
||||
*
|
||||
* @param <T> the return type of the action
|
||||
*/
|
||||
protected interface NiFiRegistryAction<T> {
|
||||
|
||||
T execute();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param e an exception that was encountered interacting with the registry
|
||||
* @return the IOException that caused this exception, or null if the an IOException did not cause this exception
|
||||
*/
|
||||
protected Throwable getIOExceptionCause(final Throwable e) {
|
||||
if (e == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (e instanceof IOException) {
|
||||
return e;
|
||||
}
|
||||
|
||||
return getIOExceptionCause(e.getCause());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.bucket.BucketItem;
|
||||
import org.apache.nifi.registry.bucket.BucketItemType;
|
||||
import org.apache.nifi.registry.extension.bundle.Bundle;
|
||||
import org.apache.nifi.registry.flow.VersionedFlow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class BucketItemDeserializer extends StdDeserializer<BucketItem[]> {
|
||||
|
||||
public BucketItemDeserializer() {
|
||||
super(BucketItem[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BucketItem[] deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
|
||||
final JsonNode arrayNode = jsonParser.getCodec().readTree(jsonParser);
|
||||
|
||||
final List<BucketItem> bucketItems = new ArrayList<>();
|
||||
|
||||
final Iterator<JsonNode> nodeIter = arrayNode.elements();
|
||||
while (nodeIter.hasNext()) {
|
||||
final JsonNode node = nodeIter.next();
|
||||
|
||||
final String type = node.get("type").asText();
|
||||
if (StringUtils.isBlank(type)) {
|
||||
throw new IllegalStateException("BucketItem type cannot be null or blank");
|
||||
}
|
||||
|
||||
final BucketItemType bucketItemType;
|
||||
try {
|
||||
bucketItemType = BucketItemType.valueOf(type);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Unknown type for BucketItem: " + type, e);
|
||||
}
|
||||
|
||||
|
||||
switch (bucketItemType) {
|
||||
case Flow:
|
||||
final VersionedFlow versionedFlow = jsonParser.getCodec().treeToValue(node, VersionedFlow.class);
|
||||
bucketItems.add(versionedFlow);
|
||||
break;
|
||||
case Bundle:
|
||||
final Bundle bundle = jsonParser.getCodec().treeToValue(node, Bundle.class);
|
||||
bucketItems.add(bundle);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown type for BucketItem: " + bucketItemType);
|
||||
}
|
||||
}
|
||||
|
||||
return bucketItems.toArray(new BucketItem[bucketItems.size()]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
|
||||
public class ClientUtils {
|
||||
|
||||
public static File getExtensionBundleVersionContent(final Response response, final File outputDirectory) {
|
||||
final String contentDispositionHeader = response.getHeaderString("Content-Disposition");
|
||||
if (StringUtils.isBlank(contentDispositionHeader)) {
|
||||
throw new IllegalStateException("Content-Disposition header was blank or missing");
|
||||
}
|
||||
|
||||
final int equalsIndex = contentDispositionHeader.lastIndexOf("=");
|
||||
final String filename = contentDispositionHeader.substring(equalsIndex + 1).trim();
|
||||
final File bundleFile = new File(outputDirectory, filename);
|
||||
|
||||
try (final InputStream responseInputStream = response.readEntity(InputStream.class)) {
|
||||
Files.copy(responseInputStream, bundleFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
return bundleFile;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Unable to write bundle content due to: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.client.AccessClient;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.client.impl.request.BasicAuthRequestConfig;
|
||||
import org.apache.nifi.registry.client.impl.request.BearerTokenRequestConfig;
|
||||
|
||||
import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.client.Invocation;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Jersey implementation of AccessClient.
|
||||
*/
|
||||
public class JerseyAccessClient extends AbstractJerseyClient implements AccessClient {
|
||||
|
||||
private final WebTarget accessTarget;
|
||||
|
||||
public JerseyAccessClient(final WebTarget baseTarget) {
|
||||
super(null);
|
||||
this.accessTarget = baseTarget.path("/access");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToken(final String username, final String password) throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(username)) {
|
||||
throw new IllegalArgumentException("Username is required");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(password)) {
|
||||
throw new IllegalArgumentException("Password is required");
|
||||
}
|
||||
|
||||
return executeAction("Error performing login", () -> {
|
||||
final WebTarget target = accessTarget.path("token/login");
|
||||
final Invocation.Builder requestBuilder = getRequestBuilder(target);
|
||||
|
||||
final RequestConfig basicCredsConfig = new BasicAuthRequestConfig(username, password);
|
||||
final Map<String,String> basicAuthHeaders = basicCredsConfig.getHeaders();
|
||||
basicAuthHeaders.entrySet().stream().forEach(e -> requestBuilder.header(e.getKey(), e.getValue()));
|
||||
|
||||
return requestBuilder.post(Entity.json(null), String.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTokenFromKerberosTicket() throws NiFiRegistryException, IOException {
|
||||
return executeAction("Error performing kerberos login", () -> {
|
||||
final WebTarget target = accessTarget.path("token/kerberos");
|
||||
return getRequestBuilder(target).post(Entity.json(null), String.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout(final String token) throws IOException, NiFiRegistryException {
|
||||
if (StringUtils.isBlank(token)) {
|
||||
throw new IllegalArgumentException("Token is required");
|
||||
}
|
||||
|
||||
executeAction("Error performing logout", () -> {
|
||||
final WebTarget target = accessTarget.path("logout");
|
||||
final Invocation.Builder requestBuilder = getRequestBuilder(target);
|
||||
|
||||
final RequestConfig tokenConfig = new BearerTokenRequestConfig(token);
|
||||
final Map<String,String> bearerHeaders = tokenConfig.getHeaders();
|
||||
bearerHeaders.entrySet().stream().forEach(e -> requestBuilder.header(e.getKey(), e.getValue()));
|
||||
|
||||
requestBuilder.delete();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.bucket.Bucket;
|
||||
import org.apache.nifi.registry.client.BucketClient;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.field.Fields;
|
||||
import org.apache.nifi.registry.revision.entity.RevisionInfo;
|
||||
|
||||
import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Jersey implementation of BucketClient.
|
||||
*/
|
||||
public class JerseyBucketClient extends AbstractJerseyClient implements BucketClient {
|
||||
|
||||
private final WebTarget bucketsTarget;
|
||||
|
||||
|
||||
public JerseyBucketClient(final WebTarget baseTarget) {
|
||||
this(baseTarget, null);
|
||||
}
|
||||
|
||||
public JerseyBucketClient(final WebTarget baseTarget, final RequestConfig requestConfig) {
|
||||
super(requestConfig);
|
||||
this.bucketsTarget = baseTarget.path("/buckets");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bucket create(final Bucket bucket) throws NiFiRegistryException, IOException {
|
||||
if (bucket == null) {
|
||||
throw new IllegalArgumentException("Bucket cannot be null");
|
||||
}
|
||||
|
||||
return executeAction("Error creating bucket", () -> {
|
||||
return getRequestBuilder(bucketsTarget)
|
||||
.post(
|
||||
Entity.entity(bucket, MediaType.APPLICATION_JSON),
|
||||
Bucket.class
|
||||
);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bucket get(final String bucketId) throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket ID cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving bucket", () -> {
|
||||
final WebTarget target = bucketsTarget
|
||||
.path("/{bucketId}")
|
||||
.resolveTemplate("bucketId", bucketId);
|
||||
|
||||
return getRequestBuilder(target).get(Bucket.class);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bucket update(final Bucket bucket) throws NiFiRegistryException, IOException {
|
||||
if (bucket == null) {
|
||||
throw new IllegalArgumentException("Bucket cannot be null");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(bucket.getIdentifier())) {
|
||||
throw new IllegalArgumentException("Bucket Identifier must be provided");
|
||||
}
|
||||
|
||||
return executeAction("Error updating bucket", () -> {
|
||||
final WebTarget target = bucketsTarget
|
||||
.path("/{bucketId}")
|
||||
.resolveTemplate("bucketId", bucket.getIdentifier());
|
||||
|
||||
return getRequestBuilder(target)
|
||||
.put(
|
||||
Entity.entity(bucket, MediaType.APPLICATION_JSON),
|
||||
Bucket.class
|
||||
);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bucket delete(final String bucketId) throws NiFiRegistryException, IOException {
|
||||
return delete(bucketId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bucket delete(final String bucketId, final RevisionInfo revision) throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket ID cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error deleting bucket", () -> {
|
||||
WebTarget target = bucketsTarget
|
||||
.path("/{bucketId}")
|
||||
.resolveTemplate("bucketId", bucketId);
|
||||
|
||||
target = addRevisionQueryParams(target, revision);
|
||||
|
||||
return getRequestBuilder(target).delete(Bucket.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fields getFields() throws NiFiRegistryException, IOException {
|
||||
return executeAction("Error retrieving bucket field info", () -> {
|
||||
final WebTarget target = bucketsTarget
|
||||
.path("/fields");
|
||||
|
||||
return getRequestBuilder(target).get(Fields.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Bucket> getAll() throws NiFiRegistryException, IOException {
|
||||
return executeAction("Error retrieving all buckets", () -> {
|
||||
final Bucket[] buckets = getRequestBuilder(bucketsTarget).get(Bucket[].class);
|
||||
return buckets == null ? Collections.emptyList() : Arrays.asList(buckets);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.client.BundleClient;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.extension.bundle.Bundle;
|
||||
import org.apache.nifi.registry.extension.bundle.BundleFilterParams;
|
||||
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Jersey implementation of BundleClient.
|
||||
*/
|
||||
public class JerseyBundleClient extends AbstractJerseyClient implements BundleClient {
|
||||
|
||||
private final WebTarget bucketExtensionBundlesTarget;
|
||||
private final WebTarget extensionBundlesTarget;
|
||||
|
||||
public JerseyBundleClient(final WebTarget baseTarget) {
|
||||
this(baseTarget, null);
|
||||
}
|
||||
|
||||
public JerseyBundleClient(final WebTarget baseTarget, final RequestConfig requestConfig) {
|
||||
super(requestConfig);
|
||||
this.bucketExtensionBundlesTarget = baseTarget.path("buckets/{bucketId}/bundles");
|
||||
this.extensionBundlesTarget = baseTarget.path("bundles");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Bundle> getAll() throws IOException, NiFiRegistryException {
|
||||
return getAll(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Bundle> getAll(final BundleFilterParams filterParams) throws IOException, NiFiRegistryException {
|
||||
return executeAction("Error getting extension bundles", () -> {
|
||||
WebTarget target = extensionBundlesTarget;
|
||||
|
||||
if (filterParams != null) {
|
||||
if (!StringUtils.isBlank(filterParams.getBucketName())) {
|
||||
target = target.queryParam("bucketName", filterParams.getBucketName());
|
||||
}
|
||||
if (!StringUtils.isBlank(filterParams.getGroupId())) {
|
||||
target = target.queryParam("groupId", filterParams.getGroupId());
|
||||
}
|
||||
if (!StringUtils.isBlank(filterParams.getArtifactId())) {
|
||||
target = target.queryParam("artifactId", filterParams.getArtifactId());
|
||||
}
|
||||
}
|
||||
|
||||
final Bundle[] bundles = getRequestBuilder(target).get(Bundle[].class);
|
||||
return bundles == null ? Collections.emptyList() : Arrays.asList(bundles);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Bundle> getByBucket(final String bucketId) throws IOException, NiFiRegistryException {
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket id cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error getting extension bundles for bucket", () -> {
|
||||
WebTarget target = bucketExtensionBundlesTarget.resolveTemplate("bucketId", bucketId);
|
||||
|
||||
final Bundle[] bundles = getRequestBuilder(target).get(Bundle[].class);
|
||||
return bundles == null ? Collections.emptyList() : Arrays.asList(bundles);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle get(final String bundleId) throws IOException, NiFiRegistryException {
|
||||
if (StringUtils.isBlank(bundleId)) {
|
||||
throw new IllegalArgumentException("Bundle id cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error getting extension bundle", () -> {
|
||||
WebTarget target = extensionBundlesTarget
|
||||
.path("{bundleId}")
|
||||
.resolveTemplate("bundleId", bundleId);
|
||||
|
||||
return getRequestBuilder(target).get(Bundle.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle delete(final String bundleId) throws IOException, NiFiRegistryException {
|
||||
if (StringUtils.isBlank(bundleId)) {
|
||||
throw new IllegalArgumentException("Bundle id cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error deleting extension bundle", () -> {
|
||||
WebTarget target = extensionBundlesTarget
|
||||
.path("{bundleId}")
|
||||
.resolveTemplate("bundleId", bundleId);
|
||||
|
||||
return getRequestBuilder(target).delete(Bundle.class);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,370 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.client.BundleVersionClient;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.extension.bundle.BundleType;
|
||||
import org.apache.nifi.registry.extension.bundle.BundleVersion;
|
||||
import org.apache.nifi.registry.extension.bundle.BundleVersionFilterParams;
|
||||
import org.apache.nifi.registry.extension.bundle.BundleVersionMetadata;
|
||||
import org.apache.nifi.registry.extension.component.ExtensionMetadata;
|
||||
import org.apache.nifi.registry.extension.component.manifest.Extension;
|
||||
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
|
||||
import org.glassfish.jersey.media.multipart.file.FileDataBodyPart;
|
||||
import org.glassfish.jersey.media.multipart.file.StreamDataBodyPart;
|
||||
|
||||
import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Jersey implementation of BundleVersionClient.
|
||||
*/
|
||||
public class JerseyBundleVersionClient extends AbstractJerseyClient implements BundleVersionClient {
|
||||
|
||||
private final WebTarget bucketExtensionBundlesTarget;
|
||||
private final WebTarget extensionBundlesTarget;
|
||||
|
||||
public JerseyBundleVersionClient(final WebTarget baseTarget) {
|
||||
this(baseTarget, null);
|
||||
}
|
||||
|
||||
public JerseyBundleVersionClient(final WebTarget baseTarget, final RequestConfig requestConfig) {
|
||||
super(requestConfig);
|
||||
this.bucketExtensionBundlesTarget = baseTarget.path("buckets/{bucketId}/bundles");
|
||||
this.extensionBundlesTarget = baseTarget.path("bundles");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BundleVersion create(final String bucketId, final BundleType bundleType, final InputStream bundleContentStream)
|
||||
throws IOException, NiFiRegistryException {
|
||||
return create(bucketId, bundleType, bundleContentStream, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BundleVersion create(final String bucketId, final BundleType bundleType, final InputStream bundleContentStream, final String sha256)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (bundleType == null) {
|
||||
throw new IllegalArgumentException("Bundle type cannot be null");
|
||||
}
|
||||
|
||||
if (bundleContentStream == null) {
|
||||
throw new IllegalArgumentException("Bundle content cannot be null");
|
||||
}
|
||||
|
||||
return executeAction("Error creating extension bundle version", () -> {
|
||||
final WebTarget target = bucketExtensionBundlesTarget
|
||||
.path("{bundleType}")
|
||||
.resolveTemplate("bucketId", bucketId)
|
||||
.resolveTemplate("bundleType", bundleType.toString());
|
||||
|
||||
final StreamDataBodyPart streamBodyPart = new StreamDataBodyPart("file", bundleContentStream);
|
||||
|
||||
final FormDataMultiPart multipart = new FormDataMultiPart();
|
||||
multipart.bodyPart(streamBodyPart);
|
||||
|
||||
if (!StringUtils.isBlank(sha256)) {
|
||||
multipart.field("sha256", sha256);
|
||||
}
|
||||
|
||||
return getRequestBuilder(target)
|
||||
.post(
|
||||
Entity.entity(multipart, multipart.getMediaType()),
|
||||
BundleVersion.class
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public BundleVersion create(final String bucketId, final BundleType bundleType, final File bundleFile)
|
||||
throws IOException, NiFiRegistryException {
|
||||
return create(bucketId, bundleType, bundleFile, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BundleVersion create(final String bucketId, final BundleType bundleType, final File bundleFile, final String sha256)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (bundleType == null) {
|
||||
throw new IllegalArgumentException("Bundle type cannot be null");
|
||||
}
|
||||
|
||||
if (bundleFile == null) {
|
||||
throw new IllegalArgumentException("Bundle file cannot be null");
|
||||
}
|
||||
|
||||
return executeAction("Error creating extension bundle version", () -> {
|
||||
final WebTarget target = bucketExtensionBundlesTarget
|
||||
.path("{bundleType}")
|
||||
.resolveTemplate("bucketId", bucketId)
|
||||
.resolveTemplate("bundleType", bundleType.toString());
|
||||
|
||||
final FileDataBodyPart fileBodyPart = new FileDataBodyPart("file", bundleFile, MediaType.APPLICATION_OCTET_STREAM_TYPE);
|
||||
|
||||
final FormDataMultiPart multipart = new FormDataMultiPart();
|
||||
multipart.bodyPart(fileBodyPart);
|
||||
|
||||
if (!StringUtils.isBlank(sha256)) {
|
||||
multipart.field("sha256", sha256);
|
||||
}
|
||||
|
||||
return getRequestBuilder(target)
|
||||
.post(
|
||||
Entity.entity(multipart, multipart.getMediaType()),
|
||||
BundleVersion.class
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BundleVersionMetadata> getBundleVersions(final BundleVersionFilterParams filterParams)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
return executeAction("Error getting extension bundle versions", () -> {
|
||||
WebTarget target = extensionBundlesTarget.path("/versions");
|
||||
|
||||
if (filterParams != null) {
|
||||
if (!StringUtils.isBlank(filterParams.getGroupId())) {
|
||||
target = target.queryParam("groupId", filterParams.getGroupId());
|
||||
}
|
||||
|
||||
if (!StringUtils.isBlank(filterParams.getArtifactId())) {
|
||||
target = target.queryParam("artifactId", filterParams.getArtifactId());
|
||||
}
|
||||
|
||||
if (!StringUtils.isBlank(filterParams.getVersion())) {
|
||||
target = target.queryParam("version", filterParams.getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
final BundleVersionMetadata[] bundleVersions = getRequestBuilder(target).get(BundleVersionMetadata[].class);
|
||||
return bundleVersions == null ? Collections.emptyList() : Arrays.asList(bundleVersions);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BundleVersionMetadata> getBundleVersions(final String bundleId)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
if (StringUtils.isBlank(bundleId)) {
|
||||
throw new IllegalArgumentException("Bundle id cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error getting extension bundle versions", () -> {
|
||||
final WebTarget target = extensionBundlesTarget
|
||||
.path("{bundleId}/versions")
|
||||
.resolveTemplate("bundleId", bundleId);
|
||||
|
||||
final BundleVersionMetadata[] bundleVersions = getRequestBuilder(target).get(BundleVersionMetadata[].class);
|
||||
return bundleVersions == null ? Collections.emptyList() : Arrays.asList(bundleVersions);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public BundleVersion getBundleVersion(final String bundleId, final String version)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
if (StringUtils.isBlank(bundleId)) {
|
||||
throw new IllegalArgumentException("Bundle id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(version)) {
|
||||
throw new IllegalArgumentException("Version cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error getting extension bundle version", () -> {
|
||||
final WebTarget target = extensionBundlesTarget
|
||||
.path("{bundleId}/versions/{version}")
|
||||
.resolveTemplate("bundleId", bundleId)
|
||||
.resolveTemplate("version", version);
|
||||
|
||||
return getRequestBuilder(target).get(BundleVersion.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtensionMetadata> getExtensions(final String bundleId, final String version)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
if (StringUtils.isBlank(bundleId)) {
|
||||
throw new IllegalArgumentException("Bundle id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(version)) {
|
||||
throw new IllegalArgumentException("Version cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error getting extension bundle metadata", () -> {
|
||||
final WebTarget target = extensionBundlesTarget
|
||||
.path("{bundleId}/versions/{version}/extensions")
|
||||
.resolveTemplate("bundleId", bundleId)
|
||||
.resolveTemplate("version", version);
|
||||
|
||||
final ExtensionMetadata[] extensions = getRequestBuilder(target).get(ExtensionMetadata[].class);
|
||||
return extensions == null ? Collections.emptyList() : Arrays.asList(extensions);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Extension getExtension(final String bundleId, final String version, final String name) throws IOException, NiFiRegistryException {
|
||||
if (StringUtils.isBlank(bundleId)) {
|
||||
throw new IllegalArgumentException("Bundle id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(version)) {
|
||||
throw new IllegalArgumentException("Version cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(name)) {
|
||||
throw new IllegalArgumentException("Extension name cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error getting extension", () -> {
|
||||
final WebTarget target = extensionBundlesTarget
|
||||
.path("{bundleId}/versions/{version}/extensions/{name}")
|
||||
.resolveTemplate("bundleId", bundleId)
|
||||
.resolveTemplate("version", version)
|
||||
.resolveTemplate("name", name);
|
||||
|
||||
final Extension extension = getRequestBuilder(target).get(Extension.class);
|
||||
return extension;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getExtensionDocs(final String bundleId, final String version, final String name) throws IOException, NiFiRegistryException {
|
||||
if (StringUtils.isBlank(bundleId)) {
|
||||
throw new IllegalArgumentException("Bundle id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(version)) {
|
||||
throw new IllegalArgumentException("Version cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(name)) {
|
||||
throw new IllegalArgumentException("Extension name cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error getting extension", () -> {
|
||||
final WebTarget target = extensionBundlesTarget
|
||||
.path("{bundleId}/versions/{version}/extensions/{name}/docs")
|
||||
.resolveTemplate("bundleId", bundleId)
|
||||
.resolveTemplate("version", version)
|
||||
.resolveTemplate("name", name);
|
||||
|
||||
return getRequestBuilder(target)
|
||||
.accept(MediaType.TEXT_HTML)
|
||||
.get()
|
||||
.readEntity(InputStream.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBundleVersionContent(final String bundleId, final String version)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
if (StringUtils.isBlank(bundleId)) {
|
||||
throw new IllegalArgumentException("Bundle id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(version)) {
|
||||
throw new IllegalArgumentException("Version cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error getting extension bundle version", () -> {
|
||||
final WebTarget target = extensionBundlesTarget
|
||||
.path("{bundleId}/versions/{version}/content")
|
||||
.resolveTemplate("bundleId", bundleId)
|
||||
.resolveTemplate("version", version);
|
||||
|
||||
return getRequestBuilder(target)
|
||||
.accept(MediaType.APPLICATION_OCTET_STREAM_TYPE)
|
||||
.get()
|
||||
.readEntity(InputStream.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public File writeBundleVersionContent(final String bundleId, final String version, final File directory)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
if (StringUtils.isBlank(bundleId)) {
|
||||
throw new IllegalArgumentException("Bundle id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(version)) {
|
||||
throw new IllegalArgumentException("Version cannot be null or blank");
|
||||
}
|
||||
|
||||
if (directory == null || !directory.exists() || !directory.isDirectory()) {
|
||||
throw new IllegalArgumentException("Directory must exist and be a valid directory");
|
||||
}
|
||||
|
||||
return executeAction("Error getting extension bundle version", () -> {
|
||||
final WebTarget target = extensionBundlesTarget
|
||||
.path("{bundleId}/versions/{version}/content")
|
||||
.resolveTemplate("bundleId", bundleId)
|
||||
.resolveTemplate("version", version);
|
||||
|
||||
final Response response = getRequestBuilder(target)
|
||||
.accept(MediaType.APPLICATION_OCTET_STREAM_TYPE)
|
||||
.get();
|
||||
|
||||
return ClientUtils.getExtensionBundleVersionContent(response, directory);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public BundleVersion delete(final String bundleId, final String version) throws IOException, NiFiRegistryException {
|
||||
if (StringUtils.isBlank(bundleId)) {
|
||||
throw new IllegalArgumentException("Bundle id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(version)) {
|
||||
throw new IllegalArgumentException("Version cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error deleting extension bundle version", () -> {
|
||||
final WebTarget target = extensionBundlesTarget
|
||||
.path("{bundleId}/versions/{version}")
|
||||
.resolveTemplate("bundleId", bundleId)
|
||||
.resolveTemplate("version", version);
|
||||
|
||||
return getRequestBuilder(target).delete(BundleVersion.class);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.client.ExtensionClient;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.extension.bundle.BundleType;
|
||||
import org.apache.nifi.registry.extension.component.ExtensionFilterParams;
|
||||
import org.apache.nifi.registry.extension.component.ExtensionMetadataContainer;
|
||||
import org.apache.nifi.registry.extension.component.TagCount;
|
||||
import org.apache.nifi.registry.extension.component.manifest.ExtensionType;
|
||||
import org.apache.nifi.registry.extension.component.manifest.ProvidedServiceAPI;
|
||||
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class JerseyExtensionClient extends AbstractJerseyClient implements ExtensionClient {
|
||||
|
||||
private final WebTarget extensionsTarget;
|
||||
|
||||
public JerseyExtensionClient(final WebTarget baseTarget) {
|
||||
this(baseTarget, null);
|
||||
}
|
||||
|
||||
public JerseyExtensionClient(final WebTarget baseTarget, final RequestConfig requestConfig) {
|
||||
super(requestConfig);
|
||||
this.extensionsTarget = baseTarget.path("extensions");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionMetadataContainer findExtensions(final ExtensionFilterParams filterParams)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
return executeAction("Error retrieving extensions", () -> {
|
||||
WebTarget target = extensionsTarget;
|
||||
|
||||
if (filterParams != null) {
|
||||
final BundleType bundleType = filterParams.getBundleType();
|
||||
if (bundleType != null) {
|
||||
target = target.queryParam("bundleType", bundleType.toString());
|
||||
}
|
||||
|
||||
final ExtensionType extensionType = filterParams.getExtensionType();
|
||||
if (extensionType != null) {
|
||||
target = target.queryParam("extensionType", extensionType.toString());
|
||||
}
|
||||
|
||||
final Set<String> tags = filterParams.getTags();
|
||||
if (tags != null) {
|
||||
for (final String tag : tags) {
|
||||
target = target.queryParam("tag", tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return getRequestBuilder(target).get(ExtensionMetadataContainer.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionMetadataContainer findExtensions(final ProvidedServiceAPI serviceAPI) throws IOException, NiFiRegistryException {
|
||||
if (serviceAPI == null
|
||||
|| StringUtils.isBlank(serviceAPI.getClassName())
|
||||
|| StringUtils.isBlank(serviceAPI.getGroupId())
|
||||
|| StringUtils.isBlank(serviceAPI.getArtifactId())
|
||||
|| StringUtils.isBlank(serviceAPI.getVersion())) {
|
||||
throw new IllegalArgumentException("Provided service API must be specified with a class, group, artifact, and version");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving extensions", () -> {
|
||||
WebTarget target = extensionsTarget.path("provided-service-api");
|
||||
target = target.queryParam("className", serviceAPI.getClassName());
|
||||
target = target.queryParam("groupId", serviceAPI.getGroupId());
|
||||
target = target.queryParam("artifactId", serviceAPI.getArtifactId());
|
||||
target = target.queryParam("version", serviceAPI.getVersion());
|
||||
|
||||
return getRequestBuilder(target).get(ExtensionMetadataContainer.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TagCount> getTagCounts() throws IOException, NiFiRegistryException {
|
||||
return executeAction("Error retrieving tag counts", () -> {
|
||||
final WebTarget target = extensionsTarget.path("tags");
|
||||
|
||||
final TagCount[] tagCounts = getRequestBuilder(target).get(TagCount[].class);
|
||||
return tagCounts == null ? Collections.emptyList() : Arrays.asList(tagCounts);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,335 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.client.ExtensionRepoClient;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.extension.component.manifest.Extension;
|
||||
import org.apache.nifi.registry.extension.repo.ExtensionRepoArtifact;
|
||||
import org.apache.nifi.registry.extension.repo.ExtensionRepoBucket;
|
||||
import org.apache.nifi.registry.extension.repo.ExtensionRepoExtensionMetadata;
|
||||
import org.apache.nifi.registry.extension.repo.ExtensionRepoGroup;
|
||||
import org.apache.nifi.registry.extension.repo.ExtensionRepoVersion;
|
||||
import org.apache.nifi.registry.extension.repo.ExtensionRepoVersionSummary;
|
||||
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class JerseyExtensionRepoClient extends AbstractJerseyClient implements ExtensionRepoClient {
|
||||
|
||||
private WebTarget extensionRepoTarget;
|
||||
|
||||
public JerseyExtensionRepoClient(final WebTarget baseTarget) {
|
||||
this(baseTarget, null);
|
||||
}
|
||||
|
||||
public JerseyExtensionRepoClient(final WebTarget baseTarget, final RequestConfig requestConfig) {
|
||||
super(requestConfig);
|
||||
this.extensionRepoTarget = baseTarget.path("extension-repository");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtensionRepoBucket> getBuckets() throws IOException, NiFiRegistryException {
|
||||
return executeAction("Error retrieving buckets for extension repo", () -> {
|
||||
final ExtensionRepoBucket[] repoBuckets = getRequestBuilder(extensionRepoTarget).get(ExtensionRepoBucket[].class);
|
||||
return repoBuckets == null ? Collections.emptyList() : Arrays.asList(repoBuckets);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtensionRepoGroup> getGroups(final String bucketName) throws IOException, NiFiRegistryException {
|
||||
if (StringUtils.isBlank(bucketName)) {
|
||||
throw new IllegalArgumentException("Bucket name cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving groups for extension repo", () -> {
|
||||
final WebTarget target = extensionRepoTarget
|
||||
.path("{bucketName}")
|
||||
.resolveTemplate("bucketName", bucketName);
|
||||
|
||||
final ExtensionRepoGroup[] repoGroups = getRequestBuilder(target).get(ExtensionRepoGroup[].class);
|
||||
return repoGroups == null ? Collections.emptyList() : Arrays.asList(repoGroups);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtensionRepoArtifact> getArtifacts(final String bucketName, final String groupId)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
if (StringUtils.isBlank(bucketName)) {
|
||||
throw new IllegalArgumentException("Bucket name cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(groupId)) {
|
||||
throw new IllegalArgumentException("Group id cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving artifacts for extension repo", () -> {
|
||||
final WebTarget target = extensionRepoTarget
|
||||
.path("{bucketName}/{groupId}")
|
||||
.resolveTemplate("bucketName", bucketName)
|
||||
.resolveTemplate("groupId", groupId);
|
||||
|
||||
final ExtensionRepoArtifact[] repoArtifacts = getRequestBuilder(target).get(ExtensionRepoArtifact[].class);
|
||||
return repoArtifacts == null ? Collections.emptyList() : Arrays.asList(repoArtifacts);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtensionRepoVersionSummary> getVersions(final String bucketName, final String groupId, final String artifactId)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
if (StringUtils.isBlank(bucketName)) {
|
||||
throw new IllegalArgumentException("Bucket name cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(groupId)) {
|
||||
throw new IllegalArgumentException("Group id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(artifactId)) {
|
||||
throw new IllegalArgumentException("Artifact id cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving versions for extension repo", () -> {
|
||||
final WebTarget target = extensionRepoTarget
|
||||
.path("{bucketName}/{groupId}/{artifactId}")
|
||||
.resolveTemplate("bucketName", bucketName)
|
||||
.resolveTemplate("groupId", groupId)
|
||||
.resolveTemplate("artifactId", artifactId);
|
||||
|
||||
final ExtensionRepoVersionSummary[] repoVersions = getRequestBuilder(target).get(ExtensionRepoVersionSummary[].class);
|
||||
return repoVersions == null ? Collections.emptyList() : Arrays.asList(repoVersions);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionRepoVersion getVersion(final String bucketName, final String groupId, final String artifactId, final String version)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
validate(bucketName, groupId, artifactId, version);
|
||||
|
||||
return executeAction("Error retrieving versions for extension repo", () -> {
|
||||
final WebTarget target = extensionRepoTarget
|
||||
.path("{bucketName}/{groupId}/{artifactId}/{version}")
|
||||
.resolveTemplate("bucketName", bucketName)
|
||||
.resolveTemplate("groupId", groupId)
|
||||
.resolveTemplate("artifactId", artifactId)
|
||||
.resolveTemplate("version", version);
|
||||
|
||||
return getRequestBuilder(target).get(ExtensionRepoVersion.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtensionRepoExtensionMetadata> getVersionExtensions(final String bucketName, final String groupId, final String artifactId, final String version)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
validate(bucketName, groupId, artifactId, version);
|
||||
|
||||
return executeAction("Error retrieving versions for extension repo", () -> {
|
||||
final WebTarget target = extensionRepoTarget
|
||||
.path("{bucketName}/{groupId}/{artifactId}/{version}/extensions")
|
||||
.resolveTemplate("bucketName", bucketName)
|
||||
.resolveTemplate("groupId", groupId)
|
||||
.resolveTemplate("artifactId", artifactId)
|
||||
.resolveTemplate("version", version);
|
||||
|
||||
final ExtensionRepoExtensionMetadata[] extensions = getRequestBuilder(target).get(ExtensionRepoExtensionMetadata[].class);
|
||||
return extensions == null ? Collections.emptyList() : Arrays.asList(extensions);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Extension getVersionExtension(final String bucketName, final String groupId, final String artifactId,
|
||||
final String version, final String extensionName)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
validate(bucketName, groupId, artifactId, version);
|
||||
|
||||
if (StringUtils.isBlank(extensionName)) {
|
||||
throw new IllegalArgumentException("Extension name is required");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving versions for extension repo", () -> {
|
||||
final WebTarget target = extensionRepoTarget
|
||||
.path("{bucketName}/{groupId}/{artifactId}/{version}/extensions/{extensionName}")
|
||||
.resolveTemplate("bucketName", bucketName)
|
||||
.resolveTemplate("groupId", groupId)
|
||||
.resolveTemplate("artifactId", artifactId)
|
||||
.resolveTemplate("version", version)
|
||||
.resolveTemplate("extensionName", extensionName);
|
||||
|
||||
final Extension extension = getRequestBuilder(target).get(Extension.class);
|
||||
return extension;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getVersionExtensionDocs(final String bucketName, final String groupId, final String artifactId,
|
||||
final String version, final String extensionName)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
validate(bucketName, groupId, artifactId, version);
|
||||
|
||||
if (StringUtils.isBlank(extensionName)) {
|
||||
throw new IllegalArgumentException("Extension name is required");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving versions for extension repo", () -> {
|
||||
final WebTarget target = extensionRepoTarget
|
||||
.path("{bucketName}/{groupId}/{artifactId}/{version}/extensions/{extensionName}/docs")
|
||||
.resolveTemplate("bucketName", bucketName)
|
||||
.resolveTemplate("groupId", groupId)
|
||||
.resolveTemplate("artifactId", artifactId)
|
||||
.resolveTemplate("version", version)
|
||||
.resolveTemplate("extensionName", extensionName);
|
||||
|
||||
return getRequestBuilder(target)
|
||||
.accept(MediaType.TEXT_HTML)
|
||||
.get()
|
||||
.readEntity(InputStream.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getVersionContent(final String bucketName, final String groupId, final String artifactId, final String version)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
validate(bucketName, groupId, artifactId, version);
|
||||
|
||||
return executeAction("Error retrieving version content for extension repo", () -> {
|
||||
final WebTarget target = extensionRepoTarget
|
||||
.path("{bucketName}/{groupId}/{artifactId}/{version}/content")
|
||||
.resolveTemplate("bucketName", bucketName)
|
||||
.resolveTemplate("groupId", groupId)
|
||||
.resolveTemplate("artifactId", artifactId)
|
||||
.resolveTemplate("version", version);
|
||||
|
||||
return getRequestBuilder(target)
|
||||
.accept(MediaType.APPLICATION_OCTET_STREAM_TYPE)
|
||||
.get()
|
||||
.readEntity(InputStream.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public File writeBundleVersionContent(final String bucketName, final String groupId, final String artifactId, final String version, final File directory)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
validate(bucketName, groupId, artifactId, version);
|
||||
|
||||
if (directory == null) {
|
||||
throw new IllegalArgumentException("Directory cannot be null");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving version content for extension repo", () -> {
|
||||
final WebTarget target = extensionRepoTarget
|
||||
.path("{bucketName}/{groupId}/{artifactId}/{version}/content")
|
||||
.resolveTemplate("bucketName", bucketName)
|
||||
.resolveTemplate("groupId", groupId)
|
||||
.resolveTemplate("artifactId", artifactId)
|
||||
.resolveTemplate("version", version);
|
||||
|
||||
final Response response = getRequestBuilder(target)
|
||||
.accept(MediaType.APPLICATION_OCTET_STREAM_TYPE)
|
||||
.get();
|
||||
|
||||
return ClientUtils.getExtensionBundleVersionContent(response, directory);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionSha256(final String bucketName, final String groupId, final String artifactId, final String version)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
validate(bucketName, groupId, artifactId, version);
|
||||
|
||||
return executeAction("Error retrieving version content for extension repo", () -> {
|
||||
final WebTarget target = extensionRepoTarget
|
||||
.path("{bucketName}/{groupId}/{artifactId}/{version}/sha256")
|
||||
.resolveTemplate("bucketName", bucketName)
|
||||
.resolveTemplate("groupId", groupId)
|
||||
.resolveTemplate("artifactId", artifactId)
|
||||
.resolveTemplate("version", version);
|
||||
|
||||
return getRequestBuilder(target).accept(MediaType.TEXT_PLAIN_TYPE).get(String.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getVersionSha256(final String groupId, final String artifactId, final String version)
|
||||
throws IOException, NiFiRegistryException {
|
||||
|
||||
if (StringUtils.isBlank(groupId)) {
|
||||
throw new IllegalArgumentException("Group id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(artifactId)) {
|
||||
throw new IllegalArgumentException("Artifact id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(version)) {
|
||||
throw new IllegalArgumentException("Version cannot be null or blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving version content for extension repo", () -> {
|
||||
final WebTarget target = extensionRepoTarget
|
||||
.path("{groupId}/{artifactId}/{version}/sha256")
|
||||
.resolveTemplate("groupId", groupId)
|
||||
.resolveTemplate("artifactId", artifactId)
|
||||
.resolveTemplate("version", version);
|
||||
|
||||
try {
|
||||
final String sha256 = getRequestBuilder(target).accept(MediaType.TEXT_PLAIN_TYPE).get(String.class);
|
||||
return Optional.of(sha256);
|
||||
} catch (NotFoundException nfe) {
|
||||
return Optional.empty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void validate(String bucketName, String groupId, String artifactId, String version) {
|
||||
if (StringUtils.isBlank(bucketName)) {
|
||||
throw new IllegalArgumentException("Bucket name cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(groupId)) {
|
||||
throw new IllegalArgumentException("Group id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(artifactId)) {
|
||||
throw new IllegalArgumentException("Artifact id cannot be null or blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(version)) {
|
||||
throw new IllegalArgumentException("Version cannot be null or blank");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.client.FlowClient;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.diff.VersionedFlowDifference;
|
||||
import org.apache.nifi.registry.field.Fields;
|
||||
import org.apache.nifi.registry.flow.VersionedFlow;
|
||||
import org.apache.nifi.registry.revision.entity.RevisionInfo;
|
||||
|
||||
import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Jersey implementation of FlowClient.
|
||||
*/
|
||||
public class JerseyFlowClient extends AbstractJerseyClient implements FlowClient {
|
||||
|
||||
private final WebTarget flowsTarget;
|
||||
private final WebTarget bucketFlowsTarget;
|
||||
|
||||
public JerseyFlowClient(final WebTarget baseTarget) {
|
||||
this(baseTarget, null);
|
||||
}
|
||||
|
||||
public JerseyFlowClient(final WebTarget baseTarget, final RequestConfig requestConfig) {
|
||||
super(requestConfig);
|
||||
this.flowsTarget = baseTarget.path("/flows");
|
||||
this.bucketFlowsTarget = baseTarget.path("/buckets/{bucketId}/flows");
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlow create(final VersionedFlow flow) throws NiFiRegistryException, IOException {
|
||||
if (flow == null) {
|
||||
throw new IllegalArgumentException("VersionedFlow cannot be null");
|
||||
}
|
||||
|
||||
final String bucketId = flow.getBucketIdentifier();
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket Identifier cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error creating flow", () -> {
|
||||
final WebTarget target = bucketFlowsTarget
|
||||
.resolveTemplate("bucketId", bucketId);
|
||||
|
||||
return getRequestBuilder(target)
|
||||
.post(
|
||||
Entity.entity(flow, MediaType.APPLICATION_JSON),
|
||||
VersionedFlow.class
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlow get(final String bucketId, final String flowId) throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket Identifier cannot be blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(flowId)) {
|
||||
throw new IllegalArgumentException("Flow Identifier cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving flow", () -> {
|
||||
final WebTarget target = bucketFlowsTarget
|
||||
.path("/{flowId}")
|
||||
.resolveTemplate("bucketId", bucketId)
|
||||
.resolveTemplate("flowId", flowId);
|
||||
|
||||
return getRequestBuilder(target).get(VersionedFlow.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlow get(final String flowId) throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(flowId)) {
|
||||
throw new IllegalArgumentException("Flow Identifier cannot be blank");
|
||||
}
|
||||
|
||||
// this uses the flowsTarget because its calling /flows/{flowId} without knowing a bucketId
|
||||
return executeAction("Error retrieving flow", () -> {
|
||||
final WebTarget target = flowsTarget
|
||||
.path("/{flowId}")
|
||||
.resolveTemplate("flowId", flowId);
|
||||
|
||||
return getRequestBuilder(target).get(VersionedFlow.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlow update(final String bucketId, final VersionedFlow flow) throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket Identifier cannot be blank");
|
||||
}
|
||||
|
||||
if (flow == null) {
|
||||
throw new IllegalArgumentException("VersionedFlow cannot be null");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(flow.getIdentifier())) {
|
||||
throw new IllegalArgumentException("VersionedFlow identifier must be provided");
|
||||
}
|
||||
|
||||
return executeAction("Error updating flow", () -> {
|
||||
final WebTarget target = bucketFlowsTarget
|
||||
.path("/{flowId}")
|
||||
.resolveTemplate("bucketId", bucketId)
|
||||
.resolveTemplate("flowId", flow.getIdentifier());
|
||||
|
||||
return getRequestBuilder(target)
|
||||
.put(
|
||||
Entity.entity(flow, MediaType.APPLICATION_JSON),
|
||||
VersionedFlow.class
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlow delete(final String bucketId, final String flowId) throws NiFiRegistryException, IOException {
|
||||
return delete(bucketId, flowId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlow delete(final String bucketId, final String flowId, final RevisionInfo revision)
|
||||
throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket Identifier cannot be blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(flowId)) {
|
||||
throw new IllegalArgumentException("Flow Identifier cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error deleting flow", () -> {
|
||||
WebTarget target = bucketFlowsTarget
|
||||
.path("/{flowId}")
|
||||
.resolveTemplate("bucketId", bucketId)
|
||||
.resolveTemplate("flowId", flowId);
|
||||
|
||||
target = addRevisionQueryParams(target, revision);
|
||||
|
||||
return getRequestBuilder(target).delete(VersionedFlow.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fields getFields() throws NiFiRegistryException, IOException {
|
||||
return executeAction("Error retrieving fields info for flows", () -> {
|
||||
final WebTarget target = flowsTarget.path("/fields");
|
||||
return getRequestBuilder(target).get(Fields.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VersionedFlow> getByBucket(final String bucketId) throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket Identifier cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error getting flows for bucket", () -> {
|
||||
WebTarget target = bucketFlowsTarget;
|
||||
target = target.resolveTemplate("bucketId", bucketId);
|
||||
|
||||
final VersionedFlow[] versionedFlows = getRequestBuilder(target).get(VersionedFlow[].class);
|
||||
return versionedFlows == null ? Collections.emptyList() : Arrays.asList(versionedFlows);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlowDifference diff(final String bucketId, final String flowId,
|
||||
final Integer versionA, final Integer versionB) throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket Identifier cannot be blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(flowId)) {
|
||||
throw new IllegalArgumentException("Flow Identifier cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving flow", () -> {
|
||||
final WebTarget target = bucketFlowsTarget
|
||||
.path("/{flowId}/diff/{versionA}/{versionB}")
|
||||
.resolveTemplate("bucketId", bucketId)
|
||||
.resolveTemplate("flowId", flowId)
|
||||
.resolveTemplate("versionA", versionA)
|
||||
.resolveTemplate("versionB", versionB);
|
||||
|
||||
return getRequestBuilder(target).get(VersionedFlowDifference.class);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.client.FlowSnapshotClient;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
|
||||
import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
|
||||
|
||||
import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Jersey implementation of FlowSnapshotClient.
|
||||
*/
|
||||
public class JerseyFlowSnapshotClient extends AbstractJerseyClient implements FlowSnapshotClient {
|
||||
|
||||
final WebTarget bucketFlowSnapshotTarget;
|
||||
final WebTarget flowsFlowSnapshotTarget;
|
||||
|
||||
public JerseyFlowSnapshotClient(final WebTarget baseTarget) {
|
||||
this(baseTarget, null);
|
||||
}
|
||||
|
||||
public JerseyFlowSnapshotClient(final WebTarget baseTarget, final RequestConfig requestConfig) {
|
||||
super(requestConfig);
|
||||
this.bucketFlowSnapshotTarget = baseTarget.path("/buckets/{bucketId}/flows/{flowId}/versions");
|
||||
this.flowsFlowSnapshotTarget = baseTarget.path("/flows/{flowId}/versions");
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlowSnapshot create(final VersionedFlowSnapshot snapshot)
|
||||
throws NiFiRegistryException, IOException {
|
||||
if (snapshot.getSnapshotMetadata() == null) {
|
||||
throw new IllegalArgumentException("Snapshot Metadata cannot be null");
|
||||
}
|
||||
|
||||
final String bucketId = snapshot.getSnapshotMetadata().getBucketIdentifier();
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket Identifier cannot be blank");
|
||||
}
|
||||
|
||||
final String flowId = snapshot.getSnapshotMetadata().getFlowIdentifier();
|
||||
if (StringUtils.isBlank(flowId)) {
|
||||
throw new IllegalArgumentException("Flow Identifier cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error creating snapshot", () -> {
|
||||
final WebTarget target = bucketFlowSnapshotTarget
|
||||
.resolveTemplate("bucketId", bucketId)
|
||||
.resolveTemplate("flowId", flowId);
|
||||
|
||||
return getRequestBuilder(target)
|
||||
.post(
|
||||
Entity.entity(snapshot, MediaType.APPLICATION_JSON),
|
||||
VersionedFlowSnapshot.class
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlowSnapshot get(final String bucketId, final String flowId, final int version)
|
||||
throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket Identifier cannot be blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(flowId)) {
|
||||
throw new IllegalArgumentException("Flow Identifier cannot be blank");
|
||||
}
|
||||
|
||||
if (version < 1) {
|
||||
throw new IllegalArgumentException("Version must be greater than 1");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving flow snapshot", () -> {
|
||||
final WebTarget target = bucketFlowSnapshotTarget
|
||||
.path("/{version}")
|
||||
.resolveTemplate("bucketId", bucketId)
|
||||
.resolveTemplate("flowId", flowId)
|
||||
.resolveTemplate("version", version);
|
||||
|
||||
return getRequestBuilder(target).get(VersionedFlowSnapshot.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlowSnapshot get(final String flowId, final int version)
|
||||
throws NiFiRegistryException, IOException {
|
||||
|
||||
if (StringUtils.isBlank(flowId)) {
|
||||
throw new IllegalArgumentException("Flow Identifier cannot be blank");
|
||||
}
|
||||
|
||||
if (version < 1) {
|
||||
throw new IllegalArgumentException("Version must be greater than 1");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving flow snapshot", () -> {
|
||||
final WebTarget target = flowsFlowSnapshotTarget
|
||||
.path("/{version}")
|
||||
.resolveTemplate("flowId", flowId)
|
||||
.resolveTemplate("version", version);
|
||||
|
||||
return getRequestBuilder(target).get(VersionedFlowSnapshot.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlowSnapshot getLatest(final String bucketId, final String flowId)
|
||||
throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket Identifier cannot be blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(flowId)) {
|
||||
throw new IllegalArgumentException("Flow Identifier cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving latest snapshot", () -> {
|
||||
final WebTarget target = bucketFlowSnapshotTarget
|
||||
.path("/latest")
|
||||
.resolveTemplate("bucketId", bucketId)
|
||||
.resolveTemplate("flowId", flowId);
|
||||
|
||||
return getRequestBuilder(target).get(VersionedFlowSnapshot.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlowSnapshot getLatest(final String flowId)
|
||||
throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(flowId)) {
|
||||
throw new IllegalArgumentException("Flow Identifier cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving latest snapshot", () -> {
|
||||
final WebTarget target = flowsFlowSnapshotTarget
|
||||
.path("/latest")
|
||||
.resolveTemplate("flowId", flowId);
|
||||
|
||||
return getRequestBuilder(target).get(VersionedFlowSnapshot.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlowSnapshotMetadata getLatestMetadata(final String bucketId, final String flowId) throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket Identifier cannot be blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(flowId)) {
|
||||
throw new IllegalArgumentException("Flow Identifier cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving latest snapshot metadata", () -> {
|
||||
final WebTarget target = bucketFlowSnapshotTarget
|
||||
.path("/latest/metadata")
|
||||
.resolveTemplate("bucketId", bucketId)
|
||||
.resolveTemplate("flowId", flowId);
|
||||
|
||||
return getRequestBuilder(target).get(VersionedFlowSnapshotMetadata.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionedFlowSnapshotMetadata getLatestMetadata(final String flowId) throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(flowId)) {
|
||||
throw new IllegalArgumentException("Flow Identifier cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving latest snapshot metadata", () -> {
|
||||
final WebTarget target = flowsFlowSnapshotTarget
|
||||
.path("/latest/metadata")
|
||||
.resolveTemplate("flowId", flowId);
|
||||
|
||||
return getRequestBuilder(target).get(VersionedFlowSnapshotMetadata.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<VersionedFlowSnapshotMetadata> getSnapshotMetadata(final String bucketId, final String flowId)
|
||||
throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket Identifier cannot be blank");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(flowId)) {
|
||||
throw new IllegalArgumentException("Flow Identifier cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving snapshot metadata", () -> {
|
||||
final WebTarget target = bucketFlowSnapshotTarget
|
||||
.resolveTemplate("bucketId", bucketId)
|
||||
.resolveTemplate("flowId", flowId);
|
||||
|
||||
final VersionedFlowSnapshotMetadata[] snapshots = getRequestBuilder(target)
|
||||
.get(VersionedFlowSnapshotMetadata[].class);
|
||||
|
||||
return snapshots == null ? Collections.emptyList() : Arrays.asList(snapshots);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<VersionedFlowSnapshotMetadata> getSnapshotMetadata(final String flowId)
|
||||
throws NiFiRegistryException, IOException {
|
||||
|
||||
if (StringUtils.isBlank(flowId)) {
|
||||
throw new IllegalArgumentException("Flow Identifier cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving snapshot metadata", () -> {
|
||||
final WebTarget target = flowsFlowSnapshotTarget
|
||||
.resolveTemplate("flowId", flowId);
|
||||
|
||||
final VersionedFlowSnapshotMetadata[] snapshots = getRequestBuilder(target)
|
||||
.get(VersionedFlowSnapshotMetadata[].class);
|
||||
|
||||
return snapshots == null ? Collections.emptyList() : Arrays.asList(snapshots);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.bucket.BucketItem;
|
||||
import org.apache.nifi.registry.client.ItemsClient;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.field.Fields;
|
||||
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Jersey implementation of ItemsClient.
|
||||
*/
|
||||
public class JerseyItemsClient extends AbstractJerseyClient implements ItemsClient {
|
||||
|
||||
private final WebTarget itemsTarget;
|
||||
|
||||
public JerseyItemsClient(final WebTarget baseTarget) {
|
||||
this(baseTarget, null);
|
||||
}
|
||||
|
||||
public JerseyItemsClient(final WebTarget baseTarget, final RequestConfig requestConfig) {
|
||||
super(requestConfig);
|
||||
this.itemsTarget = baseTarget.path("/items");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public List<BucketItem> getAll() throws NiFiRegistryException, IOException {
|
||||
return executeAction("", () -> {
|
||||
WebTarget target = itemsTarget;
|
||||
final BucketItem[] bucketItems = getRequestBuilder(target).get(BucketItem[].class);
|
||||
return bucketItems == null ? Collections.emptyList() : Arrays.asList(bucketItems);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BucketItem> getByBucket(final String bucketId)
|
||||
throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(bucketId)) {
|
||||
throw new IllegalArgumentException("Bucket Identifier cannot be blank");
|
||||
}
|
||||
|
||||
return executeAction("", () -> {
|
||||
WebTarget target = itemsTarget
|
||||
.path("/{bucketId}")
|
||||
.resolveTemplate("bucketId", bucketId);
|
||||
|
||||
final BucketItem[] bucketItems = getRequestBuilder(target).get(BucketItem[].class);
|
||||
return bucketItems == null ? Collections.emptyList() : Arrays.asList(bucketItems);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fields getFields() throws NiFiRegistryException, IOException {
|
||||
return executeAction("", () -> {
|
||||
final WebTarget target = itemsTarget.path("/fields");
|
||||
return getRequestBuilder(target).get(Fields.class);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,363 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.bucket.BucketItem;
|
||||
import org.apache.nifi.registry.client.AccessClient;
|
||||
import org.apache.nifi.registry.client.BucketClient;
|
||||
import org.apache.nifi.registry.client.BundleClient;
|
||||
import org.apache.nifi.registry.client.BundleVersionClient;
|
||||
import org.apache.nifi.registry.client.ExtensionClient;
|
||||
import org.apache.nifi.registry.client.ExtensionRepoClient;
|
||||
import org.apache.nifi.registry.client.FlowClient;
|
||||
import org.apache.nifi.registry.client.FlowSnapshotClient;
|
||||
import org.apache.nifi.registry.client.ItemsClient;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryClient;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryClientConfig;
|
||||
import org.apache.nifi.registry.client.PoliciesClient;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.client.TenantsClient;
|
||||
import org.apache.nifi.registry.client.UserClient;
|
||||
import org.apache.nifi.registry.client.impl.request.ProxiedEntityRequestConfig;
|
||||
import org.glassfish.jersey.client.ClientConfig;
|
||||
import org.glassfish.jersey.client.ClientProperties;
|
||||
import org.glassfish.jersey.client.RequestEntityProcessing;
|
||||
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider;
|
||||
import org.glassfish.jersey.media.multipart.MultiPartFeature;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.ws.rs.client.Client;
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* A NiFiRegistryClient that uses Jersey Client.
|
||||
*/
|
||||
public class JerseyNiFiRegistryClient implements NiFiRegistryClient {
|
||||
|
||||
static final String NIFI_REGISTRY_CONTEXT = "nifi-registry-api";
|
||||
static final int DEFAULT_CONNECT_TIMEOUT = 10000;
|
||||
static final int DEFAULT_READ_TIMEOUT = 10000;
|
||||
|
||||
private final Client client;
|
||||
private final WebTarget baseTarget;
|
||||
|
||||
private final BucketClient bucketClient;
|
||||
private final FlowClient flowClient;
|
||||
private final FlowSnapshotClient flowSnapshotClient;
|
||||
private final ItemsClient itemsClient;
|
||||
|
||||
private JerseyNiFiRegistryClient(final NiFiRegistryClient.Builder builder) {
|
||||
final NiFiRegistryClientConfig registryClientConfig = builder.getConfig();
|
||||
if (registryClientConfig == null) {
|
||||
throw new IllegalArgumentException("NiFiRegistryClientConfig cannot be null");
|
||||
}
|
||||
|
||||
String baseUrl = registryClientConfig.getBaseUrl();
|
||||
if (StringUtils.isBlank(baseUrl)) {
|
||||
throw new IllegalArgumentException("Base URL cannot be blank");
|
||||
}
|
||||
|
||||
if (baseUrl.endsWith("/")) {
|
||||
baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
|
||||
}
|
||||
|
||||
if (!baseUrl.endsWith(NIFI_REGISTRY_CONTEXT)) {
|
||||
baseUrl = baseUrl + "/" + NIFI_REGISTRY_CONTEXT;
|
||||
}
|
||||
|
||||
try {
|
||||
new URI(baseUrl);
|
||||
} catch (final Exception e) {
|
||||
throw new IllegalArgumentException("Invalid base URL: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
final SSLContext sslContext = registryClientConfig.getSslContext();
|
||||
final HostnameVerifier hostnameVerifier = registryClientConfig.getHostnameVerifier();
|
||||
|
||||
final ClientBuilder clientBuilder = ClientBuilder.newBuilder();
|
||||
if (sslContext != null) {
|
||||
clientBuilder.sslContext(sslContext);
|
||||
}
|
||||
if (hostnameVerifier != null) {
|
||||
clientBuilder.hostnameVerifier(hostnameVerifier);
|
||||
}
|
||||
|
||||
final int connectTimeout = registryClientConfig.getConnectTimeout() == null ? DEFAULT_CONNECT_TIMEOUT : registryClientConfig.getConnectTimeout();
|
||||
final int readTimeout = registryClientConfig.getReadTimeout() == null ? DEFAULT_READ_TIMEOUT : registryClientConfig.getReadTimeout();
|
||||
|
||||
final ClientConfig clientConfig = new ClientConfig();
|
||||
clientConfig.property(ClientProperties.CONNECT_TIMEOUT, connectTimeout);
|
||||
clientConfig.property(ClientProperties.READ_TIMEOUT, readTimeout);
|
||||
clientConfig.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.CHUNKED);
|
||||
clientConfig.register(jacksonJaxbJsonProvider());
|
||||
clientBuilder.withConfig(clientConfig);
|
||||
|
||||
this.client = clientBuilder
|
||||
.register(MultiPartFeature.class)
|
||||
.build();
|
||||
|
||||
this.baseTarget = client.target(baseUrl);
|
||||
this.bucketClient = new JerseyBucketClient(baseTarget);
|
||||
this.flowClient = new JerseyFlowClient(baseTarget);
|
||||
this.flowSnapshotClient = new JerseyFlowSnapshotClient(baseTarget);
|
||||
this.itemsClient = new JerseyItemsClient(baseTarget);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BucketClient getBucketClient() {
|
||||
return this.bucketClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BucketClient getBucketClient(String... proxiedEntity) {
|
||||
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
|
||||
return new JerseyBucketClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BucketClient getBucketClient(RequestConfig requestConfig) {
|
||||
return new JerseyBucketClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlowClient getFlowClient() {
|
||||
return this.flowClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlowClient getFlowClient(String... proxiedEntity) {
|
||||
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
|
||||
return new JerseyFlowClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlowClient getFlowClient(RequestConfig requestConfig) {
|
||||
return new JerseyFlowClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlowSnapshotClient getFlowSnapshotClient() {
|
||||
return this.flowSnapshotClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlowSnapshotClient getFlowSnapshotClient(String... proxiedEntity) {
|
||||
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
|
||||
return new JerseyFlowSnapshotClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlowSnapshotClient getFlowSnapshotClient(RequestConfig requestConfig) {
|
||||
return new JerseyFlowSnapshotClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemsClient getItemsClient() {
|
||||
return this.itemsClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemsClient getItemsClient(String... proxiedEntity) {
|
||||
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
|
||||
return new JerseyItemsClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemsClient getItemsClient(RequestConfig requestConfig) {
|
||||
return new JerseyItemsClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserClient getUserClient() {
|
||||
return new JerseyUserClient(baseTarget);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserClient getUserClient(String... proxiedEntity) {
|
||||
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
|
||||
return new JerseyUserClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserClient getUserClient(RequestConfig requestConfig) {
|
||||
return new JerseyUserClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BundleClient getBundleClient() {
|
||||
return new JerseyBundleClient(baseTarget);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BundleClient getBundleClient(String... proxiedEntity) {
|
||||
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
|
||||
return new JerseyBundleClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BundleClient getBundleClient(RequestConfig requestConfig) {
|
||||
return new JerseyBundleClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BundleVersionClient getBundleVersionClient() {
|
||||
return new JerseyBundleVersionClient(baseTarget);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BundleVersionClient getBundleVersionClient(String... proxiedEntity) {
|
||||
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
|
||||
return new JerseyBundleVersionClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BundleVersionClient getBundleVersionClient(RequestConfig requestConfig) {
|
||||
return new JerseyBundleVersionClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionRepoClient getExtensionRepoClient() {
|
||||
return new JerseyExtensionRepoClient(baseTarget);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionRepoClient getExtensionRepoClient(String... proxiedEntity) {
|
||||
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
|
||||
return new JerseyExtensionRepoClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionRepoClient getExtensionRepoClient(RequestConfig requestConfig) {
|
||||
return new JerseyExtensionRepoClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionClient getExtensionClient() {
|
||||
return new JerseyExtensionClient(baseTarget);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionClient getExtensionClient(String... proxiedEntity) {
|
||||
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
|
||||
return new JerseyExtensionClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionClient getExtensionClient(RequestConfig requestConfig) {
|
||||
return new JerseyExtensionClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TenantsClient getTenantsClient() {
|
||||
return new JerseyTenantsClient(baseTarget);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TenantsClient getTenantsClient(String... proxiedEntity) {
|
||||
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
|
||||
return new JerseyTenantsClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TenantsClient getTenantsClient(RequestConfig requestConfig) {
|
||||
return new JerseyTenantsClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PoliciesClient getPoliciesClient() {
|
||||
return new JerseyPoliciesClient(baseTarget);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PoliciesClient getPoliciesClient(String... proxiedEntity) {
|
||||
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
|
||||
return new JerseyPoliciesClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PoliciesClient getPoliciesClient(RequestConfig requestConfig) {
|
||||
return new JerseyPoliciesClient(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessClient getAccessClient() {
|
||||
return new JerseyAccessClient(baseTarget);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (this.client != null) {
|
||||
try {
|
||||
this.client.close();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for creating a JerseyNiFiRegistryClient.
|
||||
*/
|
||||
public static class Builder implements NiFiRegistryClient.Builder {
|
||||
|
||||
private NiFiRegistryClientConfig clientConfig;
|
||||
|
||||
@Override
|
||||
public Builder config(final NiFiRegistryClientConfig clientConfig) {
|
||||
this.clientConfig = clientConfig;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NiFiRegistryClientConfig getConfig() {
|
||||
return clientConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NiFiRegistryClient build() {
|
||||
return new JerseyNiFiRegistryClient(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static JacksonJaxbJsonProvider jacksonJaxbJsonProvider() {
|
||||
JacksonJaxbJsonProvider jacksonJaxbJsonProvider = new JacksonJaxbJsonProvider();
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.setPropertyInclusion(JsonInclude.Value.construct(JsonInclude.Include.NON_NULL, JsonInclude.Include.NON_NULL));
|
||||
mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector(mapper.getTypeFactory()));
|
||||
// Ignore unknown properties so that deployed client remain compatible with future versions of NiFi Registry that add new fields
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.addDeserializer(BucketItem[].class, new BucketItemDeserializer());
|
||||
mapper.registerModule(module);
|
||||
|
||||
jacksonJaxbJsonProvider.setMapper(mapper);
|
||||
return jacksonJaxbJsonProvider;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.registry.authorization.AccessPolicy;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.PoliciesClient;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import java.io.IOException;
|
||||
|
||||
public class JerseyPoliciesClient extends AbstractCRUDJerseyClient implements PoliciesClient {
|
||||
|
||||
public static final String ACCESS_POLICY = "Access policy";
|
||||
public static final String POLICIES_PATH = "policies";
|
||||
|
||||
public JerseyPoliciesClient(final WebTarget baseTarget) {
|
||||
this(baseTarget, null);
|
||||
}
|
||||
|
||||
public JerseyPoliciesClient(final WebTarget baseTarget, final RequestConfig requestConfig) {
|
||||
super(baseTarget, requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy getAccessPolicy(String action, String resource) throws NiFiRegistryException, IOException {
|
||||
if (StringUtils.isBlank(resource) || StringUtils.isBlank(action)) {
|
||||
throw new IllegalArgumentException("Resource and action cannot be null");
|
||||
}
|
||||
|
||||
return executeAction("Error retrieving access policy", () -> {
|
||||
final WebTarget target = baseTarget.path(POLICIES_PATH).path(action).path(resource);
|
||||
return getRequestBuilder(target).get(AccessPolicy.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy createAccessPolicy(final AccessPolicy policy) throws NiFiRegistryException, IOException {
|
||||
return create(policy, AccessPolicy.class, ACCESS_POLICY, POLICIES_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessPolicy updateAccessPolicy(final AccessPolicy policy) throws NiFiRegistryException, IOException {
|
||||
return update(policy, policy.getIdentifier(), AccessPolicy.class, ACCESS_POLICY, POLICIES_PATH);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.nifi.registry.authorization.User;
|
||||
import org.apache.nifi.registry.authorization.UserGroup;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.client.TenantsClient;
|
||||
import org.apache.nifi.registry.revision.entity.RevisionInfo;
|
||||
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class JerseyTenantsClient extends AbstractCRUDJerseyClient implements TenantsClient {
|
||||
public static final String USER = "User";
|
||||
public static final String USERS_PATH = "users";
|
||||
|
||||
public static final String USER_GROUP = "User group";
|
||||
public static final String USER_GROUPS_PATH = "user-groups";
|
||||
|
||||
public JerseyTenantsClient(final WebTarget baseTarget) {
|
||||
this(baseTarget, null);
|
||||
}
|
||||
|
||||
public JerseyTenantsClient(final WebTarget baseTarget, final RequestConfig requestConfig) {
|
||||
super(baseTarget.path("/tenants"), requestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<User> getUsers() throws NiFiRegistryException, IOException {
|
||||
return executeAction("Error retrieving users", () -> {
|
||||
final WebTarget target = baseTarget.path(USERS_PATH);
|
||||
return Arrays.asList(getRequestBuilder(target).get(User[].class));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser(final String id) throws NiFiRegistryException, IOException {
|
||||
return get(id, User.class, USER, USERS_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User createUser(final User user) throws NiFiRegistryException, IOException {
|
||||
return create(user, User.class, USER, USERS_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User updateUser(final User user) throws NiFiRegistryException, IOException {
|
||||
return update(user, user.getIdentifier(), User.class, USER, USERS_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User deleteUser(final String id) throws NiFiRegistryException, IOException {
|
||||
return delete(id, null, User.class, USER, USERS_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User deleteUser(final String id, final RevisionInfo revisionInfo) throws NiFiRegistryException, IOException {
|
||||
return delete(id, revisionInfo, User.class, USER, USERS_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserGroup> getUserGroups() throws NiFiRegistryException, IOException {
|
||||
return executeAction("Error retrieving users", () -> {
|
||||
final WebTarget target = baseTarget.path(USER_GROUPS_PATH);
|
||||
return Arrays.asList(getRequestBuilder(target).get(UserGroup[].class));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserGroup getUserGroup(final String id) throws NiFiRegistryException, IOException {
|
||||
return get(id, UserGroup.class, USER_GROUP, USER_GROUPS_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserGroup createUserGroup(final UserGroup group) throws NiFiRegistryException, IOException {
|
||||
return create(group, UserGroup.class, USER_GROUP, USER_GROUPS_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserGroup updateUserGroup(final UserGroup group) throws NiFiRegistryException, IOException {
|
||||
return update(group, group.getIdentifier(), UserGroup.class, USER_GROUP, USER_GROUPS_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserGroup deleteUserGroup(final String id) throws NiFiRegistryException, IOException {
|
||||
return delete(id, null, UserGroup.class, USER_GROUP, USER_GROUPS_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserGroup deleteUserGroup(final String id, final RevisionInfo revisionInfo) throws NiFiRegistryException, IOException {
|
||||
return delete(id, revisionInfo, UserGroup.class, USER_GROUP, USER_GROUPS_PATH);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl;
|
||||
|
||||
import org.apache.nifi.registry.authorization.CurrentUser;
|
||||
import org.apache.nifi.registry.client.NiFiRegistryException;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.client.UserClient;
|
||||
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import java.io.IOException;
|
||||
|
||||
public class JerseyUserClient extends AbstractJerseyClient implements UserClient {
|
||||
|
||||
private final WebTarget accessTarget;
|
||||
|
||||
public JerseyUserClient(final WebTarget baseTarget) {
|
||||
this(baseTarget, null);
|
||||
}
|
||||
|
||||
public JerseyUserClient(final WebTarget baseTarget, final RequestConfig requestConfig) {
|
||||
super(requestConfig);
|
||||
this.accessTarget = baseTarget.path("/access");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CurrentUser getAccessStatus() throws NiFiRegistryException, IOException {
|
||||
return executeAction("Error retrieving access status for the current user", () -> {
|
||||
return getRequestBuilder(accessTarget).get(CurrentUser.class);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl.request;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Implementation of RequestConfig for a request with basic auth.
|
||||
*/
|
||||
public class BasicAuthRequestConfig implements RequestConfig {
|
||||
|
||||
public static final String AUTHORIZATION_HEADER = "Authorization";
|
||||
public static final String BASIC = "Basic";
|
||||
|
||||
private final String username;
|
||||
private final String password;
|
||||
|
||||
public BasicAuthRequestConfig(final String username, final String password) {
|
||||
this.username = Validate.notBlank(username);
|
||||
this.password = Validate.notBlank(password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getHeaders() {
|
||||
final String basicCreds = username + ":" + password;
|
||||
final byte[] basicCredsBytes = basicCreds.getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
final Base64.Encoder encoder = Base64.getEncoder();
|
||||
final String encodedBasicCreds = encoder.encodeToString(basicCredsBytes);
|
||||
|
||||
final Map<String,String> headers = new HashMap<>();
|
||||
headers.put(AUTHORIZATION_HEADER, BASIC + " " + encodedBasicCreds);
|
||||
return headers;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl.request;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Implementation of RequestConfig for a request with a bearer token.
|
||||
*/
|
||||
public class BearerTokenRequestConfig implements RequestConfig {
|
||||
|
||||
public static final String AUTHORIZATION_HEADER = "Authorization";
|
||||
public static final String BEARER = "Bearer";
|
||||
|
||||
private final String token;
|
||||
|
||||
public BearerTokenRequestConfig(final String token) {
|
||||
this.token = Validate.notBlank(token);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getHeaders() {
|
||||
final Map<String,String> headers = new HashMap<>();
|
||||
headers.put(AUTHORIZATION_HEADER, BEARER + " " + token);
|
||||
return headers;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl.request;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.security.util.ProxiedEntitiesUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Implementation of RequestConfig that produces headers for a request with proxied-entities.
|
||||
*/
|
||||
public class ProxiedEntityRequestConfig implements RequestConfig {
|
||||
|
||||
private final String proxiedEntitiesChain;
|
||||
|
||||
public ProxiedEntityRequestConfig(final String... proxiedEntities) {
|
||||
Validate.notNull(proxiedEntities);
|
||||
this.proxiedEntitiesChain = ProxiedEntitiesUtils.getProxiedEntitiesChain(proxiedEntities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getHeaders() {
|
||||
final Map<String,String> headers = new HashMap<>();
|
||||
if (proxiedEntitiesChain != null) {
|
||||
headers.put(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN, proxiedEntitiesChain);
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl.request;
|
||||
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TestBasicAuthRequestConfig {
|
||||
|
||||
@Test
|
||||
public void testBasicAuthRequestConfig() {
|
||||
final String username = "user1";
|
||||
final String password = "password";
|
||||
final String basicCreds = username + ":" + password;
|
||||
|
||||
final String expectedHeaderValue = "Basic " + Base64.getEncoder().encodeToString(basicCreds.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
final RequestConfig requestConfig = new BasicAuthRequestConfig(username, password);
|
||||
|
||||
final Map<String,String> headers = requestConfig.getHeaders();
|
||||
assertNotNull(headers);
|
||||
assertEquals(1, headers.size());
|
||||
|
||||
final String authorizationHeaderValue = headers.get("Authorization");
|
||||
assertEquals(expectedHeaderValue, authorizationHeaderValue);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl.request;
|
||||
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class TestBearerTokenRequestConfig {
|
||||
|
||||
@Test
|
||||
public void testBearerTokenRequestConfig() {
|
||||
final String token = "some-token";
|
||||
final String expectedHeaderValue = "Bearer " + token;
|
||||
|
||||
final RequestConfig requestConfig = new BearerTokenRequestConfig(token);
|
||||
|
||||
final Map<String,String> headers = requestConfig.getHeaders();
|
||||
assertNotNull(headers);
|
||||
assertEquals(1, headers.size());
|
||||
|
||||
final String authorizationHeaderValue = headers.get("Authorization");
|
||||
assertEquals(expectedHeaderValue, authorizationHeaderValue);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.client.impl.request;
|
||||
|
||||
import org.apache.nifi.registry.client.RequestConfig;
|
||||
import org.apache.nifi.registry.security.util.ProxiedEntitiesUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class TestProxiedEntityRequestConfig {
|
||||
|
||||
@Test
|
||||
public void testSingleProxiedEntity() {
|
||||
final String proxiedEntity = "user1";
|
||||
final String expectedProxiedEntitiesChain = "<user1>";
|
||||
|
||||
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
|
||||
|
||||
final Map<String,String> headers = requestConfig.getHeaders();
|
||||
assertNotNull(headers);
|
||||
assertEquals(1, headers.size());
|
||||
|
||||
final String proxiedEntitiesChainHeaderValue = headers.get(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN);
|
||||
assertEquals(expectedProxiedEntitiesChain, proxiedEntitiesChainHeaderValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleProxiedEntity() {
|
||||
final String proxiedEntity1 = "user1";
|
||||
final String proxiedEntity2 = "user2";
|
||||
final String proxiedEntity3 = "user3";
|
||||
final String expectedProxiedEntitiesChain = "<user1><user2><user3>";
|
||||
|
||||
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(
|
||||
proxiedEntity1, proxiedEntity2, proxiedEntity3);
|
||||
|
||||
final Map<String,String> headers = requestConfig.getHeaders();
|
||||
assertNotNull(headers);
|
||||
assertEquals(1, headers.size());
|
||||
|
||||
final String proxiedEntitiesChainHeaderValue = headers.get(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN);
|
||||
assertEquals(expectedProxiedEntitiesChain, proxiedEntitiesChainHeaderValue);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
|
||||
license agreements. See the NOTICE file distributed with this work for additional
|
||||
information regarding copyright ownership. The ASF licenses this file to
|
||||
You under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
|
||||
by applicable law or agreed to in writing, software distributed under the
|
||||
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
|
||||
OF ANY KIND, either express or implied. See the License for the specific
|
||||
language governing permissions and limitations under the License. -->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-core</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>nifi-registry-data-model</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-revision-entity-model</artifactId>
|
||||
<version>1.14.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<!-- This profile provides configuration to allow NiFi Registry to be compiled on JDKs above 1.8. -->
|
||||
<id>jigsaw</id>
|
||||
<activation>
|
||||
<jdk>(1.8,)</jdk>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
@XmlRootElement
|
||||
@ApiModel
|
||||
public class RegistryConfiguration {
|
||||
|
||||
private Boolean supportsManagedAuthorizer;
|
||||
private Boolean supportsConfigurableAuthorizer;
|
||||
private Boolean supportsConfigurableUsersAndGroups;
|
||||
|
||||
/**
|
||||
* @return whether this NiFi Registry supports a managed authorizer. Managed authorizers can visualize users, groups,
|
||||
* and policies in the UI. This value is read only
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "Whether this NiFi Registry supports a managed authorizer. Managed authorizers can visualize users, groups, and policies in the UI.",
|
||||
readOnly = true
|
||||
)
|
||||
public Boolean getSupportsManagedAuthorizer() {
|
||||
return supportsManagedAuthorizer;
|
||||
}
|
||||
|
||||
public void setSupportsManagedAuthorizer(Boolean supportsManagedAuthorizer) {
|
||||
this.supportsManagedAuthorizer = supportsManagedAuthorizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether this NiFi Registry supports configurable users and groups. This value is read only
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "Whether this NiFi Registry supports configurable users and groups.",
|
||||
readOnly = true
|
||||
)
|
||||
public Boolean getSupportsConfigurableUsersAndGroups() {
|
||||
return supportsConfigurableUsersAndGroups;
|
||||
}
|
||||
|
||||
public void setSupportsConfigurableUsersAndGroups(Boolean supportsConfigurableUsersAndGroups) {
|
||||
this.supportsConfigurableUsersAndGroups = supportsConfigurableUsersAndGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether this NiFi Registry supports a configurable authorizer. This value is read only
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "Whether this NiFi Registry supports a configurable authorizer.",
|
||||
readOnly = true
|
||||
)
|
||||
public Boolean getSupportsConfigurableAuthorizer() {
|
||||
return supportsConfigurableAuthorizer;
|
||||
}
|
||||
|
||||
public void setSupportsConfigurableAuthorizer(Boolean supportsConfigurableAuthorizer) {
|
||||
this.supportsConfigurableAuthorizer = supportsConfigurableAuthorizer;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.nifi.registry.authorization;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Access policy details, including the users and user groups to which the policy applies.
|
||||
*/
|
||||
@ApiModel
|
||||
public class AccessPolicy extends AccessPolicySummary {
|
||||
|
||||
private Set<Tenant> users;
|
||||
private Set<Tenant> userGroups;
|
||||
|
||||
@ApiModelProperty(value = "The set of user IDs associated with this access policy.")
|
||||
public Set<Tenant> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public void setUsers(Set<Tenant> users) {
|
||||
this.users = users;
|
||||
}
|
||||
|
||||
public void addUsers(Collection<? extends Tenant> users) {
|
||||
if (users != null) {
|
||||
if (this.users == null) {
|
||||
this.users = new HashSet<>();
|
||||
}
|
||||
this.users.addAll(users);
|
||||
}
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The set of user group IDs associated with this access policy.")
|
||||
public Set<Tenant> getUserGroups() {
|
||||
return userGroups;
|
||||
}
|
||||
|
||||
public void setUserGroups(Set<Tenant> userGroups) {
|
||||
this.userGroups = userGroups;
|
||||
}
|
||||
|
||||
public void addUserGroups(Collection<? extends Tenant> userGroups) {
|
||||
if (userGroups != null) {
|
||||
if (this.userGroups == null) {
|
||||
this.userGroups = new HashSet<>();
|
||||
}
|
||||
this.userGroups.addAll(userGroups);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.nifi.registry.authorization;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import org.apache.nifi.registry.revision.entity.RevisableEntity;
|
||||
import org.apache.nifi.registry.revision.entity.RevisionInfo;
|
||||
|
||||
/**
|
||||
* Access policy summary of which actions ("read', "write", "delete") are allowable for a specified web resource.
|
||||
*/
|
||||
@ApiModel
|
||||
public class AccessPolicySummary implements RevisableEntity {
|
||||
|
||||
private String identifier;
|
||||
private String resource;
|
||||
private String action;
|
||||
private Boolean configurable;
|
||||
private RevisionInfo revision;
|
||||
|
||||
@ApiModelProperty(value = "The id of the policy. Set by server at creation time.", readOnly = true)
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The resource for this access policy.", required = true
|
||||
)
|
||||
public String getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void setResource(String resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "The action associated with this access policy.",
|
||||
allowableValues = "read, write, delete",
|
||||
required = true
|
||||
)
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public void setAction(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "Indicates if this access policy is configurable, based on which Authorizer has been configured to manage it.", readOnly = true)
|
||||
public Boolean getConfigurable() {
|
||||
return configurable;
|
||||
}
|
||||
|
||||
public void setConfigurable(Boolean configurable) {
|
||||
this.configurable = configurable;
|
||||
}
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "The revision of this entity used for optimistic-locking during updates.",
|
||||
readOnly = true
|
||||
)
|
||||
@Override
|
||||
public RevisionInfo getRevision() {
|
||||
return revision;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRevision(RevisionInfo revision) {
|
||||
this.revision = revision;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.authorization;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
@ApiModel
|
||||
public class CurrentUser {
|
||||
|
||||
private String identity;
|
||||
private boolean anonymous;
|
||||
private boolean loginSupported;
|
||||
private boolean oidcLoginSupported;
|
||||
private ResourcePermissions resourcePermissions;
|
||||
|
||||
@ApiModelProperty(value = "The identity of the current user", readOnly = true)
|
||||
public String getIdentity() {
|
||||
return identity;
|
||||
}
|
||||
|
||||
public void setIdentity(String identity) {
|
||||
this.identity = identity;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "Indicates if the current user is anonymous", readOnly = true)
|
||||
public boolean isAnonymous() {
|
||||
return anonymous;
|
||||
}
|
||||
|
||||
public void setAnonymous(boolean anonymous) {
|
||||
this.anonymous = anonymous;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "Indicates if the NiFi Registry instance supports logging in")
|
||||
public boolean isLoginSupported() {
|
||||
return loginSupported;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "Indicates if the NiFi Registry instance supports logging in with an OIDC provider")
|
||||
public boolean isOIDCLoginSupported() {
|
||||
return oidcLoginSupported;
|
||||
}
|
||||
|
||||
public void setLoginSupported(boolean loginSupported) {
|
||||
this.loginSupported = loginSupported;
|
||||
}
|
||||
|
||||
public void setOIDCLoginSupported(boolean oidcLoginSupported) {
|
||||
this.oidcLoginSupported = oidcLoginSupported;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The access that the current user has to top level resources", readOnly = true)
|
||||
public ResourcePermissions getResourcePermissions() {
|
||||
return resourcePermissions;
|
||||
}
|
||||
|
||||
public void setResourcePermissions(ResourcePermissions resourcePermissions) {
|
||||
this.resourcePermissions = resourcePermissions;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.authorization;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
@ApiModel
|
||||
public class Permissions {
|
||||
|
||||
private boolean canRead = false;
|
||||
private boolean canWrite = false;
|
||||
private boolean canDelete = false;
|
||||
|
||||
public Permissions() {
|
||||
}
|
||||
|
||||
public Permissions(Permissions permissions) {
|
||||
if (permissions == null) {
|
||||
throw new IllegalArgumentException("Cannot call copy constructor with null argument");
|
||||
}
|
||||
|
||||
this.canRead = permissions.getCanRead();
|
||||
this.canWrite = permissions.getCanWrite();
|
||||
this.canDelete = permissions.getCanDelete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Indicates whether the user can read a given resource.
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "Indicates whether the user can read a given resource.",
|
||||
readOnly = true
|
||||
)
|
||||
public boolean getCanRead() {
|
||||
return canRead;
|
||||
}
|
||||
|
||||
public void setCanRead(boolean canRead) {
|
||||
this.canRead = canRead;
|
||||
}
|
||||
|
||||
public Permissions withCanRead(boolean canRead) {
|
||||
setCanRead(canRead);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Indicates whether the user can write a given resource.
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "Indicates whether the user can write a given resource.",
|
||||
readOnly = true
|
||||
)
|
||||
public boolean getCanWrite() {
|
||||
return canWrite;
|
||||
}
|
||||
|
||||
public void setCanWrite(boolean canWrite) {
|
||||
this.canWrite = canWrite;
|
||||
}
|
||||
|
||||
public Permissions withCanWrite(boolean canWrite) {
|
||||
setCanWrite(canWrite);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Indicates whether the user can delete a given resource.
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "Indicates whether the user can delete a given resource.",
|
||||
readOnly = true
|
||||
)
|
||||
public boolean getCanDelete() {
|
||||
return canDelete;
|
||||
}
|
||||
|
||||
public void setCanDelete(boolean canDelete) {
|
||||
this.canDelete = canDelete;
|
||||
}
|
||||
|
||||
public Permissions withCanDelete(boolean canDelete) {
|
||||
setCanDelete(canDelete);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Permissions that = (Permissions) o;
|
||||
|
||||
if (canRead != that.canRead) return false;
|
||||
if (canWrite != that.canWrite) return false;
|
||||
return canDelete == that.canDelete;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (canRead ? 1 : 0);
|
||||
result = 31 * result + (canWrite ? 1 : 0);
|
||||
result = 31 * result + (canDelete ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Permissions{" +
|
||||
"canRead=" + canRead +
|
||||
", canWrite=" + canWrite +
|
||||
", canDelete=" + canDelete +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.authorization;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
@ApiModel
|
||||
public class Resource {
|
||||
|
||||
private String identifier;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* The name of the resource.
|
||||
*
|
||||
* @return The name of the resource
|
||||
*/
|
||||
@ApiModelProperty(value = "The name of the resource.", readOnly = true)
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier of the resource.
|
||||
*
|
||||
* @return The identifier of the resource
|
||||
*/
|
||||
@ApiModelProperty(value = "The identifier of the resource.", readOnly = true)
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.authorization;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
@ApiModel
|
||||
public class ResourcePermissions {
|
||||
|
||||
private Permissions buckets = new Permissions();
|
||||
private Permissions tenants = new Permissions();
|
||||
private Permissions policies = new Permissions();
|
||||
private Permissions proxy = new Permissions();
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "The access that the current user has to any top level resources (a logical 'OR' of all other values)",
|
||||
readOnly = true)
|
||||
public Permissions getAnyTopLevelResource() {
|
||||
return new Permissions()
|
||||
.withCanRead(buckets.getCanRead()
|
||||
|| tenants.getCanRead()
|
||||
|| policies.getCanRead()
|
||||
|| proxy.getCanRead())
|
||||
.withCanWrite(buckets.getCanWrite()
|
||||
|| tenants.getCanWrite()
|
||||
|| policies.getCanWrite()
|
||||
|| proxy.getCanWrite())
|
||||
.withCanDelete(buckets.getCanDelete()
|
||||
|| tenants.getCanDelete()
|
||||
|| policies.getCanDelete()
|
||||
|| proxy.getCanDelete());
|
||||
}
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "The access that the current user has to the top level /buckets resource of this NiFi Registry (i.e., access to all buckets)",
|
||||
readOnly = true)
|
||||
public Permissions getBuckets() {
|
||||
return buckets;
|
||||
}
|
||||
|
||||
public void setBuckets(Permissions buckets) {
|
||||
this.buckets = buckets;
|
||||
}
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "The access that the current user has to the top level /tenants resource of this NiFi Registry",
|
||||
readOnly = true)
|
||||
public Permissions getTenants() {
|
||||
return tenants;
|
||||
}
|
||||
|
||||
public void setTenants(Permissions tenants) {
|
||||
this.tenants = tenants;
|
||||
}
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "The access that the current user has to the top level /policies resource of this NiFi Registry",
|
||||
readOnly = true)
|
||||
public Permissions getPolicies() {
|
||||
return policies;
|
||||
}
|
||||
|
||||
public void setPolicies(Permissions policies) {
|
||||
this.policies = policies;
|
||||
}
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "The access that the current user has to the top level /proxy resource of this NiFi Registry",
|
||||
readOnly = true)
|
||||
public Permissions getProxy() {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
public void setProxy(Permissions proxy) {
|
||||
this.proxy = proxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
ResourcePermissions that = (ResourcePermissions) o;
|
||||
|
||||
if (buckets != null ? !buckets.equals(that.buckets) : that.buckets != null)
|
||||
return false;
|
||||
if (tenants != null ? !tenants.equals(that.tenants) : that.tenants != null)
|
||||
return false;
|
||||
if (policies != null ? !policies.equals(that.policies) : that.policies != null)
|
||||
return false;
|
||||
return proxy != null ? proxy.equals(that.proxy) : that.proxy == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = buckets != null ? buckets.hashCode() : 0;
|
||||
result = 31 * result + (tenants != null ? tenants.hashCode() : 0);
|
||||
result = 31 * result + (policies != null ? policies.hashCode() : 0);
|
||||
result = 31 * result + (proxy != null ? proxy.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ResourcePermissions{" +
|
||||
"buckets=" + buckets +
|
||||
", tenants=" + tenants +
|
||||
", policies=" + policies +
|
||||
", proxy=" + proxy +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.authorization;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import org.apache.nifi.registry.revision.entity.RevisableEntity;
|
||||
import org.apache.nifi.registry.revision.entity.RevisionInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A tenant of this NiFi Registry
|
||||
*/
|
||||
@ApiModel
|
||||
public class Tenant implements RevisableEntity {
|
||||
|
||||
private String identifier;
|
||||
private String identity;
|
||||
private Boolean configurable;
|
||||
private ResourcePermissions resourcePermissions;
|
||||
private Set<AccessPolicySummary> accessPolicies;
|
||||
private RevisionInfo revision;
|
||||
|
||||
public Tenant() {}
|
||||
|
||||
public Tenant(String identifier, String identity) {
|
||||
this.identifier = identifier;
|
||||
this.identity = identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return tenant's unique identifier
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The computer-generated identifier of the tenant.",
|
||||
readOnly = true)
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return tenant's identity
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The human-facing identity of the tenant. This can only be changed if the tenant is configurable.",
|
||||
required = true)
|
||||
public String getIdentity() {
|
||||
return identity;
|
||||
}
|
||||
|
||||
public void setIdentity(String identity) {
|
||||
this.identity = identity;
|
||||
}
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "Indicates if this tenant is configurable, based on which UserGroupProvider has been configured to manage it.",
|
||||
readOnly = true)
|
||||
public Boolean getConfigurable() {
|
||||
return configurable;
|
||||
}
|
||||
|
||||
public void setConfigurable(Boolean configurable) {
|
||||
this.configurable = configurable;
|
||||
}
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "A summary top-level resource access policies granted to this tenant.",
|
||||
readOnly = true
|
||||
)
|
||||
public ResourcePermissions getResourcePermissions() {
|
||||
return resourcePermissions;
|
||||
}
|
||||
|
||||
public void setResourcePermissions(ResourcePermissions resourcePermissions) {
|
||||
this.resourcePermissions = resourcePermissions;
|
||||
}
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "The access policies granted to this tenant.",
|
||||
readOnly = true
|
||||
)
|
||||
public Set<AccessPolicySummary> getAccessPolicies() {
|
||||
return accessPolicies;
|
||||
}
|
||||
|
||||
public void setAccessPolicies(Set<AccessPolicySummary> accessPolicies) {
|
||||
this.accessPolicies = accessPolicies;
|
||||
}
|
||||
|
||||
public void addAccessPolicies(Collection<AccessPolicySummary> accessPolicies) {
|
||||
if (accessPolicies != null) {
|
||||
if (this.accessPolicies == null) {
|
||||
this.accessPolicies = new HashSet<>();
|
||||
}
|
||||
this.accessPolicies.addAll(accessPolicies);
|
||||
}
|
||||
}
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "The revision of this entity used for optimistic-locking during updates.",
|
||||
readOnly = true
|
||||
)
|
||||
@Override
|
||||
public RevisionInfo getRevision() {
|
||||
return revision;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRevision(RevisionInfo revision) {
|
||||
this.revision = revision;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.authorization;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@ApiModel
|
||||
public class User extends Tenant {
|
||||
|
||||
private Set<Tenant> userGroups;
|
||||
|
||||
public User() {}
|
||||
|
||||
public User(String identifier, String identity) {
|
||||
super(identifier, identity);
|
||||
}
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "The groups to which the user belongs.",
|
||||
readOnly = true
|
||||
)
|
||||
public Set<Tenant> getUserGroups() {
|
||||
return userGroups;
|
||||
}
|
||||
|
||||
public void setUserGroups(Set<Tenant> userGroups) {
|
||||
this.userGroups = userGroups;
|
||||
}
|
||||
|
||||
public void addUserGroups(Collection<? extends Tenant> userGroups) {
|
||||
if (userGroups != null) {
|
||||
if (this.userGroups == null) {
|
||||
this.userGroups = new HashSet<>();
|
||||
}
|
||||
this.userGroups.addAll(userGroups);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.authorization;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A user group, used to apply a single set of authorization policies to a group of users.
|
||||
*/
|
||||
@ApiModel
|
||||
public class UserGroup extends Tenant {
|
||||
|
||||
private Set<Tenant> users;
|
||||
|
||||
public UserGroup() {}
|
||||
|
||||
public UserGroup(String identifier, String identity) {
|
||||
super(identifier, identity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The users that belong to this user group.
|
||||
*/
|
||||
@ApiModelProperty(value = "The users that belong to this user group. This can only be changed if this group is configurable.")
|
||||
public Set<Tenant> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public void setUsers(Set<Tenant> users) {
|
||||
this.users = users;
|
||||
}
|
||||
|
||||
public void addUsers(Collection<? extends Tenant> users) {
|
||||
if (users != null) {
|
||||
if (this.users == null) {
|
||||
this.users = new HashSet<>();
|
||||
}
|
||||
this.users.addAll(users);
|
||||
}
|
||||
}
|
||||
|
||||
public void addUser(Tenant user) {
|
||||
if (user != null) {
|
||||
if (this.users == null) {
|
||||
this.users = new HashSet<>();
|
||||
}
|
||||
this.users.add(user);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bucket;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import org.apache.nifi.registry.authorization.Permissions;
|
||||
import org.apache.nifi.registry.link.LinkableEntity;
|
||||
import org.apache.nifi.registry.revision.entity.RevisableEntity;
|
||||
import org.apache.nifi.registry.revision.entity.RevisionInfo;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import java.util.Objects;
|
||||
|
||||
@XmlRootElement
|
||||
@ApiModel
|
||||
public class Bucket extends LinkableEntity implements RevisableEntity {
|
||||
|
||||
@NotBlank
|
||||
private String identifier;
|
||||
|
||||
@NotBlank
|
||||
private String name;
|
||||
|
||||
@Min(1)
|
||||
private long createdTimestamp;
|
||||
|
||||
private String description;
|
||||
|
||||
private Boolean allowBundleRedeploy;
|
||||
|
||||
private Boolean allowPublicRead;
|
||||
|
||||
private Permissions permissions;
|
||||
|
||||
private RevisionInfo revision;
|
||||
|
||||
@ApiModelProperty(value = "An ID to uniquely identify this object.", readOnly = true)
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The name of the bucket.", required = true)
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The timestamp of when the bucket was first created. This is set by the server at creation time.", readOnly = true)
|
||||
public long getCreatedTimestamp() {
|
||||
return createdTimestamp;
|
||||
}
|
||||
|
||||
public void setCreatedTimestamp(long createdTimestamp) {
|
||||
this.createdTimestamp = createdTimestamp;
|
||||
}
|
||||
|
||||
@ApiModelProperty("A description of the bucket.")
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@ApiModelProperty("Indicates if this bucket allows the same version of an extension bundle to be redeployed and thus overwrite the existing artifact. By default this is false.")
|
||||
public Boolean isAllowBundleRedeploy() {
|
||||
return allowBundleRedeploy;
|
||||
}
|
||||
|
||||
public void setAllowBundleRedeploy(final Boolean allowBundleRedeploy) {
|
||||
this.allowBundleRedeploy = allowBundleRedeploy;
|
||||
}
|
||||
|
||||
@ApiModelProperty("Indicates if this bucket allows read access to unauthenticated anonymous users")
|
||||
public Boolean isAllowPublicRead() {
|
||||
return allowPublicRead;
|
||||
}
|
||||
|
||||
public void setAllowPublicRead(final Boolean allowPublicRead) {
|
||||
this.allowPublicRead = allowPublicRead;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The access that the current user has to this bucket.", readOnly = true)
|
||||
public Permissions getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(Permissions permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "The revision of this entity used for optimistic-locking during updates.",
|
||||
readOnly = true
|
||||
)
|
||||
@Override
|
||||
public RevisionInfo getRevision() {
|
||||
return revision;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRevision(RevisionInfo revision) {
|
||||
this.revision = revision;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.getIdentifier());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Bucket other = (Bucket) obj;
|
||||
return Objects.equals(this.getIdentifier(), other.getIdentifier());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bucket;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import org.apache.nifi.registry.authorization.Permissions;
|
||||
import org.apache.nifi.registry.link.LinkableEntity;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Objects;
|
||||
|
||||
@ApiModel
|
||||
public abstract class BucketItem extends LinkableEntity {
|
||||
|
||||
@NotBlank
|
||||
private String identifier;
|
||||
|
||||
@NotBlank
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
@NotBlank
|
||||
private String bucketIdentifier;
|
||||
|
||||
// read-only
|
||||
private String bucketName;
|
||||
|
||||
@Min(1)
|
||||
private long createdTimestamp;
|
||||
|
||||
@Min(1)
|
||||
private long modifiedTimestamp;
|
||||
|
||||
@NotNull
|
||||
private final BucketItemType type;
|
||||
|
||||
private Permissions permissions;
|
||||
|
||||
|
||||
public BucketItem(final BucketItemType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "An ID to uniquely identify this object.", readOnly = true)
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The name of the item.", required = true)
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@ApiModelProperty("A description of the item.")
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The identifier of the bucket this items belongs to. This cannot be changed after the item is created.", required = true)
|
||||
public String getBucketIdentifier() {
|
||||
return bucketIdentifier;
|
||||
}
|
||||
|
||||
public void setBucketIdentifier(String bucketIdentifier) {
|
||||
this.bucketIdentifier = bucketIdentifier;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The name of the bucket this items belongs to.", readOnly = true)
|
||||
public String getBucketName() {
|
||||
return bucketName;
|
||||
}
|
||||
|
||||
public void setBucketName(String bucketName) {
|
||||
this.bucketName = bucketName;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The timestamp of when the item was created, as milliseconds since epoch.", readOnly = true)
|
||||
public long getCreatedTimestamp() {
|
||||
return createdTimestamp;
|
||||
}
|
||||
|
||||
public void setCreatedTimestamp(long createdTimestamp) {
|
||||
this.createdTimestamp = createdTimestamp;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The timestamp of when the item was last modified, as milliseconds since epoch.", readOnly = true)
|
||||
public long getModifiedTimestamp() {
|
||||
return modifiedTimestamp;
|
||||
}
|
||||
|
||||
public void setModifiedTimestamp(long modifiedTimestamp) {
|
||||
this.modifiedTimestamp = modifiedTimestamp;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The type of item.", required = true)
|
||||
public BucketItemType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The access that the current user has to the bucket containing this item.", readOnly = true)
|
||||
public Permissions getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(Permissions permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.getIdentifier());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final BucketItem other = (BucketItem) obj;
|
||||
return Objects.equals(this.getIdentifier(), other.getIdentifier());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.registry.bucket;
|
||||
|
||||
/**
|
||||
* Type of item in a bucket.
|
||||
*/
|
||||
public enum BucketItemType {
|
||||
|
||||
// The case of these enum names matches what we want to return in
|
||||
// the BucketItem.type field when serialized in an API response.
|
||||
|
||||
Flow,
|
||||
|
||||
Bundle;
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.nifi.registry.diff;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* Represents a specific, individual difference that has changed between 2 versions.
|
||||
* The change data and textual descriptions of the change are included for client consumption.
|
||||
*/
|
||||
public class ComponentDifference {
|
||||
private String valueA;
|
||||
private String valueB;
|
||||
private String changeDescription;
|
||||
private String differenceType;
|
||||
private String differenceTypeDescription;
|
||||
|
||||
@ApiModelProperty("The earlier value from the difference.")
|
||||
public String getValueA() {
|
||||
return valueA;
|
||||
}
|
||||
|
||||
public void setValueA(String valueA) {
|
||||
this.valueA = valueA;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The newer value from the difference.")
|
||||
public String getValueB() {
|
||||
return valueB;
|
||||
}
|
||||
|
||||
public void setValueB(String valueB) {
|
||||
this.valueB = valueB;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The description of the change.")
|
||||
public String getChangeDescription() {
|
||||
return changeDescription;
|
||||
}
|
||||
|
||||
public void setChangeDescription(String changeDescription) {
|
||||
this.changeDescription = changeDescription;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The key to the difference.")
|
||||
public String getDifferenceType() {
|
||||
return differenceType;
|
||||
}
|
||||
|
||||
public void setDifferenceType(String differenceType) {
|
||||
this.differenceType = differenceType;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The description of the change type.")
|
||||
public String getDifferenceTypeDescription() {
|
||||
return differenceTypeDescription;
|
||||
}
|
||||
|
||||
public void setDifferenceTypeDescription(String differenceTypeDescription) {
|
||||
this.differenceTypeDescription = differenceTypeDescription;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue