mirror of
https://github.com/apache/nifi.git
synced 2025-03-02 15:39:12 +00:00
NIFI-10380 Added ListDropbox and DropboxCredentialService
This closes #6331 Signed-off-by: David Handermann <exceptionfactory@apache.org>
This commit is contained in:
parent
eb68ffad70
commit
b1b3a7057c
@ -2257,6 +2257,11 @@ The following binary components are provided under the Apache Software License v
|
||||
atinject
|
||||
Copyright
|
||||
|
||||
(ASLv2) The Dropbox Project
|
||||
The following NOTICE information applies:
|
||||
The Dropbox Project
|
||||
Copyright 2013-2021 Dropbox Inc.
|
||||
|
||||
************************
|
||||
Common Development and Distribution License 1.1
|
||||
************************
|
||||
|
@ -862,6 +862,24 @@ language governing permissions and limitations under the License. -->
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
<type>nar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-processors-nar</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
<type>nar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-services-nar</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
<type>nar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-services-api-nar</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
<type>nar</type>
|
||||
</dependency>
|
||||
<!-- dependencies for jaxb/activation/annotation for running NiFi on Java 11 -->
|
||||
<!-- TODO: remove these once minimum Java version is 11 -->
|
||||
<dependency>
|
||||
|
@ -0,0 +1,45 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-bundle</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>nifi-dropbox-processors-nar</artifactId>
|
||||
<packaging>nar</packaging>
|
||||
<properties>
|
||||
<maven.javadoc.skip>true</maven.javadoc.skip>
|
||||
<source.skip>true</source.skip>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-services-api-nar</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
<type>nar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-processors</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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,38 @@
|
||||
nifi-dropbox-processors-nar
|
||||
Copyright 2015-2022 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
******************
|
||||
Apache Software License v2
|
||||
******************
|
||||
|
||||
The following binary components are provided under the Apache Software License v2
|
||||
(ASLv2) The Dropbox Project
|
||||
The following NOTICE information applies:
|
||||
The Dropbox Project
|
||||
Copyright 2013-2021 Dropbox Inc.
|
||||
|
||||
(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 (http://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.
|
@ -0,0 +1,91 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-bundle</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>nifi-dropbox-processors</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-utils</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-record</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-listed-entity</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-services-api</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dropbox.core</groupId>
|
||||
<artifactId>dropbox-core-sdk</artifactId>
|
||||
<version>${dropbox.client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-mock</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-record-serialization-services</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-record-serialization-service-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-distributed-cache-client-service-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-schema-registry-service-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-services</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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.processors.dropbox;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import org.apache.nifi.processor.util.list.ListableEntity;
|
||||
import org.apache.nifi.serialization.SimpleRecordSchema;
|
||||
import org.apache.nifi.serialization.record.MapRecord;
|
||||
import org.apache.nifi.serialization.record.Record;
|
||||
import org.apache.nifi.serialization.record.RecordField;
|
||||
import org.apache.nifi.serialization.record.RecordFieldType;
|
||||
import org.apache.nifi.serialization.record.RecordSchema;
|
||||
|
||||
public class DropboxFileInfo implements ListableEntity {
|
||||
|
||||
public static final String ID = "dropbox.id";
|
||||
public static final String PATH = "path";
|
||||
public static final String FILENAME = "filename";
|
||||
public static final String SIZE = "dropbox.size";
|
||||
public static final String TIMESTAMP = "dropbox.timestamp";
|
||||
public static final String REVISION = "dropbox.revision";
|
||||
|
||||
private static final RecordSchema SCHEMA;
|
||||
|
||||
static {
|
||||
final List<RecordField> recordFields = new ArrayList<>();
|
||||
recordFields.add(new RecordField(ID, RecordFieldType.STRING.getDataType(), false));
|
||||
recordFields.add(new RecordField(PATH, RecordFieldType.STRING.getDataType(), false));
|
||||
recordFields.add(new RecordField(FILENAME, RecordFieldType.STRING.getDataType(), false));
|
||||
recordFields.add(new RecordField(SIZE, RecordFieldType.LONG.getDataType(), false));
|
||||
recordFields.add(new RecordField(TIMESTAMP, RecordFieldType.LONG.getDataType(), false));
|
||||
recordFields.add(new RecordField(REVISION, RecordFieldType.STRING.getDataType(), false));
|
||||
|
||||
SCHEMA = new SimpleRecordSchema(recordFields);
|
||||
}
|
||||
|
||||
public static RecordSchema getRecordSchema() {
|
||||
return SCHEMA;
|
||||
}
|
||||
|
||||
private final String id;
|
||||
private final String path;
|
||||
private final String filename;
|
||||
private final long size;
|
||||
private final long timestamp;
|
||||
private final String revision;
|
||||
|
||||
private DropboxFileInfo(final Builder builder) {
|
||||
this.id = builder.id;
|
||||
this.path = builder.path;
|
||||
this.filename = builder.filename;
|
||||
this.size = builder.size;
|
||||
this.timestamp = builder.timestamp;
|
||||
this.revision = builder.revision;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getRevision() {
|
||||
return revision;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Record toRecord() {
|
||||
final Map<String, Object> values = new HashMap<>();
|
||||
|
||||
values.put(ID, getId());
|
||||
values.put(PATH, getPath());
|
||||
values.put(FILENAME, getFileName());
|
||||
values.put(SIZE, getSize());
|
||||
values.put(TIMESTAMP, getTimestamp());
|
||||
values.put(REVISION, getRevision());
|
||||
|
||||
return new MapRecord(SCHEMA, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return getFileName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
DropboxFileInfo that = (DropboxFileInfo) o;
|
||||
return id.equals(that.id) && size == that.size && timestamp == that.timestamp && path.equals(that.path) && filename.equals(that.filename)
|
||||
&& revision.equals(that.revision);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, path, filename, size, timestamp, revision);
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
private String id;
|
||||
private String path;
|
||||
private String filename;
|
||||
private long size;
|
||||
private long timestamp;
|
||||
private String revision;
|
||||
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder path(String path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder name(String filename) {
|
||||
this.filename = filename;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder size(long size) {
|
||||
this.size = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder timestamp(long createdTime) {
|
||||
this.timestamp = createdTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder revision(String revision) {
|
||||
this.revision = revision;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DropboxFileInfo build() {
|
||||
return new DropboxFileInfo(this);
|
||||
}
|
||||
}
|
||||
}
|
@ -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.processors.dropbox;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public enum DropboxFlowFileAttribute {
|
||||
ID(DropboxFileInfo.ID, DropboxFileInfo::getId),
|
||||
PATH(DropboxFileInfo.PATH, DropboxFileInfo::getPath),
|
||||
FILENAME(DropboxFileInfo.FILENAME, DropboxFileInfo::getName),
|
||||
SIZE(DropboxFileInfo.SIZE, fileInfo -> String.valueOf(fileInfo.getSize())),
|
||||
TIMESTAMP(DropboxFileInfo.TIMESTAMP, fileInfo -> String.valueOf(fileInfo.getTimestamp())),
|
||||
REVISION(DropboxFileInfo.REVISION, DropboxFileInfo::getRevision);
|
||||
|
||||
private final String name;
|
||||
private final Function<DropboxFileInfo, String> fromFileInfo;
|
||||
|
||||
DropboxFlowFileAttribute(String attributeName, Function<DropboxFileInfo, String> fromFileInfo) {
|
||||
this.name = attributeName;
|
||||
this.fromFileInfo = fromFileInfo;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getValue(DropboxFileInfo fileInfo) {
|
||||
return fromFileInfo.apply(fileInfo);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,293 @@
|
||||
/*
|
||||
* 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.processors.dropbox;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import com.dropbox.core.DbxException;
|
||||
import com.dropbox.core.DbxRequestConfig;
|
||||
import com.dropbox.core.oauth.DbxCredential;
|
||||
import com.dropbox.core.v2.DbxClientV2;
|
||||
import com.dropbox.core.v2.files.FileMetadata;
|
||||
import com.dropbox.core.v2.files.ListFolderBuilder;
|
||||
import com.dropbox.core.v2.files.ListFolderResult;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||
import org.apache.nifi.annotation.behavior.PrimaryNodeOnly;
|
||||
import org.apache.nifi.annotation.behavior.Stateful;
|
||||
import org.apache.nifi.annotation.behavior.TriggerSerially;
|
||||
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||
import org.apache.nifi.annotation.documentation.Tags;
|
||||
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
||||
import org.apache.nifi.components.PropertyDescriptor;
|
||||
import org.apache.nifi.components.state.Scope;
|
||||
import org.apache.nifi.context.PropertyContext;
|
||||
import org.apache.nifi.dropbox.credentials.service.DropboxCredentialDetails;
|
||||
import org.apache.nifi.dropbox.credentials.service.DropboxCredentialService;
|
||||
import org.apache.nifi.expression.ExpressionLanguageScope;
|
||||
import org.apache.nifi.processor.ProcessContext;
|
||||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
import org.apache.nifi.processor.util.list.AbstractListProcessor;
|
||||
import org.apache.nifi.processor.util.list.ListedEntityTracker;
|
||||
import org.apache.nifi.serialization.record.RecordSchema;
|
||||
|
||||
@PrimaryNodeOnly
|
||||
@TriggerSerially
|
||||
@Tags({"dropbox", "storage"})
|
||||
@CapabilityDescription("Retrieves a listing of files from Dropbox (shortcuts are ignored)." +
|
||||
" Each listed file may result in one FlowFile, the metadata being written as Flowfile attributes." +
|
||||
" When the 'Record Writer' property is set, the entire result is written as records to a single FlowFile." +
|
||||
" This Processor is designed to run on Primary Node only in a cluster. If the primary node changes, the new Primary Node will pick up where the" +
|
||||
" previous node left off without duplicating all of the data.")
|
||||
@InputRequirement(Requirement.INPUT_FORBIDDEN)
|
||||
@WritesAttributes({@WritesAttribute(attribute = DropboxFileInfo.ID, description = "The Dropbox identifier of the file"),
|
||||
@WritesAttribute(attribute = DropboxFileInfo.PATH, description = "The folder path where the file is located"),
|
||||
@WritesAttribute(attribute = DropboxFileInfo.FILENAME, description = "The name of the file"),
|
||||
@WritesAttribute(attribute = DropboxFileInfo.SIZE, description = "The size of the file"),
|
||||
@WritesAttribute(attribute = DropboxFileInfo.TIMESTAMP, description = "The server modified time, when the file was uploaded to Dropbox"),
|
||||
@WritesAttribute(attribute = DropboxFileInfo.REVISION, description = "Revision of the file")})
|
||||
@Stateful(scopes = {Scope.CLUSTER}, description = "The processor stores necessary data to be able to keep track what files have been listed already. " +
|
||||
"What exactly needs to be stored depends on the 'Listing Strategy'.")
|
||||
public class ListDropbox extends AbstractListProcessor<DropboxFileInfo> {
|
||||
|
||||
public static final PropertyDescriptor FOLDER = new PropertyDescriptor.Builder()
|
||||
.name("folder")
|
||||
.displayName("Folder")
|
||||
.description("The Dropbox identifier or path of the folder from which to pull list of files." +
|
||||
" 'Folder' should match the following regular expression pattern: /.*|id:.* ." +
|
||||
" Example for folder identifier: id:odTlUvbpIEAAAAAAAAAGGQ." +
|
||||
" Example for folder path: /Team1/Task1.")
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
|
||||
.required(true)
|
||||
.addValidator(StandardValidators.createRegexMatchingValidator(Pattern.compile("/.*|id:.*")))
|
||||
.defaultValue("/")
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor RECURSIVE_SEARCH = new PropertyDescriptor.Builder()
|
||||
.name("recursive-search")
|
||||
.displayName("Search Recursively")
|
||||
.description("Indicates whether to list files from subfolders of the Dropbox folder.")
|
||||
.required(true)
|
||||
.defaultValue("true")
|
||||
.allowableValues("true", "false")
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor MIN_AGE = new PropertyDescriptor.Builder()
|
||||
.name("min-age")
|
||||
.displayName("Minimum File Age")
|
||||
.description("The minimum age a file must be in order to be considered; any files newer than this will be ignored.")
|
||||
.required(true)
|
||||
.addValidator(StandardValidators.TIME_PERIOD_VALIDATOR)
|
||||
.defaultValue("0 sec")
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor CREDENTIAL_SERVICE = new PropertyDescriptor.Builder()
|
||||
.name("dropbox-credential-service")
|
||||
.displayName("Dropbox Credential Service")
|
||||
.description("Controller Service used to obtain Dropbox credentials (App Key, App Secret, Access Token, Refresh Token)." +
|
||||
" See controller service's Additional Details for more information.")
|
||||
.identifiesControllerService(DropboxCredentialService.class)
|
||||
.required(true)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor LISTING_STRATEGY = new PropertyDescriptor.Builder()
|
||||
.fromPropertyDescriptor(AbstractListProcessor.LISTING_STRATEGY)
|
||||
.allowableValues(BY_TIMESTAMPS, BY_ENTITIES, BY_TIME_WINDOW, NO_TRACKING)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor TRACKING_STATE_CACHE = new PropertyDescriptor.Builder()
|
||||
.fromPropertyDescriptor(ListedEntityTracker.TRACKING_STATE_CACHE)
|
||||
.dependsOn(LISTING_STRATEGY, BY_ENTITIES)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor TRACKING_TIME_WINDOW = new PropertyDescriptor.Builder()
|
||||
.fromPropertyDescriptor(ListedEntityTracker.TRACKING_TIME_WINDOW)
|
||||
.dependsOn(LISTING_STRATEGY, BY_ENTITIES)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor INITIAL_LISTING_TARGET = new PropertyDescriptor.Builder()
|
||||
.fromPropertyDescriptor(ListedEntityTracker.INITIAL_LISTING_TARGET)
|
||||
.dependsOn(LISTING_STRATEGY, BY_ENTITIES)
|
||||
.build();
|
||||
|
||||
private static final List<PropertyDescriptor> PROPERTIES = Collections.unmodifiableList(Arrays.asList(
|
||||
CREDENTIAL_SERVICE,
|
||||
FOLDER,
|
||||
RECURSIVE_SEARCH,
|
||||
MIN_AGE,
|
||||
LISTING_STRATEGY,
|
||||
TRACKING_STATE_CACHE,
|
||||
TRACKING_TIME_WINDOW,
|
||||
INITIAL_LISTING_TARGET,
|
||||
RECORD_WRITER
|
||||
));
|
||||
|
||||
private DbxClientV2 dropboxApiClient;
|
||||
|
||||
@OnScheduled
|
||||
public void onScheduled(final ProcessContext context) {
|
||||
dropboxApiClient = getDropboxApiClient(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
|
||||
return PROPERTIES;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, String> createAttributes(
|
||||
final DropboxFileInfo entity,
|
||||
final ProcessContext context) {
|
||||
final Map<String, String> attributes = new HashMap<>();
|
||||
|
||||
for (DropboxFlowFileAttribute attribute : DropboxFlowFileAttribute.values()) {
|
||||
Optional.ofNullable(attribute.getValue(entity))
|
||||
.ifPresent(value -> attributes.put(attribute.getName(), value));
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPath(final ProcessContext context) {
|
||||
return context.getProperty(FOLDER).evaluateAttributeExpressions().getValue();
|
||||
}
|
||||
|
||||
protected DbxClientV2 getDropboxApiClient(ProcessContext context) {
|
||||
final DropboxCredentialService credentialService = context.getProperty(CREDENTIAL_SERVICE)
|
||||
.asControllerService(DropboxCredentialService.class);
|
||||
DbxRequestConfig config = new DbxRequestConfig(format("%s-%s", getClass().getSimpleName(), getIdentifier()));
|
||||
DropboxCredentialDetails credential = credentialService.getDropboxCredential();
|
||||
return new DbxClientV2(config, new DbxCredential(credential.getAccessToken(), -1L,
|
||||
credential.getRefreshToken(), credential.getAppKey(), credential.getAppSecret()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<DropboxFileInfo> performListing(ProcessContext context, Long minTimestamp,
|
||||
ListingMode listingMode) throws IOException {
|
||||
final List<DropboxFileInfo> listing = new ArrayList<>();
|
||||
|
||||
final String folderName = getPath(context);
|
||||
final Boolean recursive = context.getProperty(RECURSIVE_SEARCH).asBoolean();
|
||||
final Long minAge = context.getProperty(MIN_AGE).asTimePeriod(TimeUnit.MILLISECONDS);
|
||||
|
||||
try {
|
||||
Predicate<FileMetadata> metadataFilter = createMetadataFilter(minTimestamp, minAge);
|
||||
|
||||
ListFolderBuilder listFolderBuilder = dropboxApiClient.files().listFolderBuilder(convertFolderName(folderName));
|
||||
ListFolderResult result = listFolderBuilder
|
||||
.withRecursive(recursive)
|
||||
.start();
|
||||
|
||||
List<FileMetadata> metadataList = new ArrayList<>(filterMetadata(result, metadataFilter));
|
||||
|
||||
while (result.getHasMore()) {
|
||||
result = dropboxApiClient.files().listFolderContinue(result.getCursor());
|
||||
metadataList.addAll(filterMetadata(result, metadataFilter));
|
||||
}
|
||||
|
||||
for (FileMetadata metadata : metadataList) {
|
||||
DropboxFileInfo.Builder builder = new DropboxFileInfo.Builder()
|
||||
.id(metadata.getId())
|
||||
.path(getParentPath(metadata.getPathDisplay()))
|
||||
.name(metadata.getName())
|
||||
.size(metadata.getSize())
|
||||
.timestamp(metadata.getServerModified().getTime())
|
||||
.revision(metadata.getRev());
|
||||
|
||||
listing.add(builder.build());
|
||||
}
|
||||
} catch (DbxException e) {
|
||||
throw new IOException("Failed to list Dropbox folder [" + folderName + "]", e);
|
||||
}
|
||||
|
||||
return listing;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isListingResetNecessary(final PropertyDescriptor property) {
|
||||
return LISTING_STRATEGY.equals(property)
|
||||
|| FOLDER.equals(property)
|
||||
|| RECURSIVE_SEARCH.equals(property);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Scope getStateScope(final PropertyContext context) {
|
||||
return Scope.CLUSTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RecordSchema getRecordSchema() {
|
||||
return DropboxFileInfo.getRecordSchema();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer countUnfilteredListing(final ProcessContext context) throws IOException {
|
||||
return performListing(context, null, ListingMode.CONFIGURATION_VERIFICATION).size();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getListingContainerName(final ProcessContext context) {
|
||||
return format("Dropbox Folder [%s]", getPath(context));
|
||||
}
|
||||
|
||||
private Predicate<FileMetadata> createMetadataFilter(Long minTimestamp, Long minAge) {
|
||||
Predicate<FileMetadata> metadataFilter = FileMetadata::getIsDownloadable;
|
||||
|
||||
if (minTimestamp != null && minTimestamp > 0) {
|
||||
metadataFilter = metadataFilter.and(metadata -> metadata.getServerModified().getTime() >= minTimestamp);
|
||||
}
|
||||
|
||||
if (minAge != null && minAge > 0) {
|
||||
long maxTimestamp = System.currentTimeMillis() - minAge;
|
||||
metadataFilter = metadataFilter.and(metadata -> metadata.getServerModified().getTime() < maxTimestamp);
|
||||
}
|
||||
return metadataFilter;
|
||||
}
|
||||
|
||||
private List<FileMetadata> filterMetadata(ListFolderResult result, Predicate<FileMetadata> metadataFilter) {
|
||||
return result.getEntries().stream()
|
||||
.filter(metadata -> metadata instanceof FileMetadata)
|
||||
.map(FileMetadata.class::cast)
|
||||
.filter(metadataFilter)
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
private String getParentPath(String fullPath) {
|
||||
int idx = fullPath.lastIndexOf("/");
|
||||
String parentPath = fullPath.substring(0, idx);
|
||||
return "".equals(parentPath) ? "/" : parentPath;
|
||||
}
|
||||
|
||||
private String convertFolderName(String folderName) {
|
||||
return "/".equals(folderName) ? "" : folderName;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
# 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.
|
||||
org.apache.nifi.processors.dropbox.ListDropbox
|
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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.processors.dropbox;
|
||||
|
||||
import com.dropbox.core.DbxRequestConfig;
|
||||
import com.dropbox.core.oauth.DbxCredential;
|
||||
import com.dropbox.core.v2.DbxClientV2;
|
||||
import com.dropbox.core.v2.files.FileMetadata;
|
||||
import com.dropbox.core.v2.files.GetMetadataErrorException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.apache.nifi.processor.Processor;
|
||||
import org.apache.nifi.services.dropbox.StandardDropboxCredentialService;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
/**
|
||||
* Set the following constants before running: <br/>
|
||||
* <br/> APPLICATION_KEY - App Key of your app
|
||||
* <br/> APPLICATION_SECRET - Your App Secret of your app
|
||||
* <br/> ACCESS_TOKEN - Access Token generated for your app
|
||||
* <br/> REFRESH_TOKEN - Refresh Token generated for your app
|
||||
* <br/><br/>
|
||||
* For App Key, App Secret, Access Token and Refresh Token generation please check controller service's Additional Details page.<br/><br/>
|
||||
* NOTE: Since the integration test creates the test files you need "files.content.write" permission besides the "files.content.read"
|
||||
* permission mentioned in controller service's Additional Details page.<br/>
|
||||
*
|
||||
* <br/> Created files and folders are cleaned up, but it's advisable to dedicate a folder for this test so that it can
|
||||
* be cleaned up easily should the test fail to do so. <br/>
|
||||
* <br/> WARNING: The creation of a file is not a synchronized operation, may need to adjust tests accordingly!
|
||||
*/
|
||||
public abstract class AbstractDropboxIT<T extends Processor> {
|
||||
|
||||
public static final String APP_KEY = "";
|
||||
public static final String APP_SECRET = "";
|
||||
public static final String ACCESS_TOKEN = "";
|
||||
public static final String REFRESH_TOKEN = "";
|
||||
|
||||
public static final String MAIN_FOLDER = "/testFolder";
|
||||
protected T testSubject;
|
||||
protected TestRunner testRunner;
|
||||
protected String mainFolderId;
|
||||
|
||||
private DbxClientV2 client;
|
||||
|
||||
@AfterEach
|
||||
public void teardown() throws Exception {
|
||||
deleteFolderIfExists(MAIN_FOLDER);
|
||||
}
|
||||
|
||||
protected abstract T createTestSubject();
|
||||
|
||||
@BeforeEach
|
||||
protected void init() throws Exception {
|
||||
testSubject = createTestSubject();
|
||||
testRunner = createTestRunner();
|
||||
DbxCredential credential =
|
||||
new DbxCredential(ACCESS_TOKEN, -1L, REFRESH_TOKEN, APP_KEY, APP_SECRET);
|
||||
DbxRequestConfig config = new DbxRequestConfig("nifi");
|
||||
client = new DbxClientV2(config, credential);
|
||||
mainFolderId = createFolder(MAIN_FOLDER);
|
||||
}
|
||||
|
||||
protected TestRunner createTestRunner() throws Exception {
|
||||
TestRunner testRunner = TestRunners.newTestRunner(testSubject);
|
||||
|
||||
StandardDropboxCredentialService controllerService = new StandardDropboxCredentialService();
|
||||
testRunner.addControllerService("dropbox_credential_provider_service", controllerService);
|
||||
testRunner.setProperty(controllerService, StandardDropboxCredentialService.APP_KEY, APP_KEY);
|
||||
testRunner.setProperty(controllerService, StandardDropboxCredentialService.APP_SECRET, APP_SECRET);
|
||||
testRunner.setProperty(controllerService, StandardDropboxCredentialService.ACCESS_TOKEN, ACCESS_TOKEN);
|
||||
testRunner.setProperty(controllerService, StandardDropboxCredentialService.REFRESH_TOKEN, REFRESH_TOKEN);
|
||||
testRunner.enableControllerService(controllerService);
|
||||
testRunner.setProperty(ListDropbox.CREDENTIAL_SERVICE, "dropbox_credential_provider_service");
|
||||
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
protected void deleteFolderIfExists(String path) throws Exception {
|
||||
if (folderExists(path)) {
|
||||
client.files().deleteV2(path);
|
||||
}
|
||||
}
|
||||
|
||||
protected FileMetadata createFile(String name, String fileContent, String folder) throws Exception {
|
||||
ByteArrayInputStream content = new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8));
|
||||
return client.files().upload(folder + "/" + name).uploadAndFinish(content);
|
||||
}
|
||||
|
||||
private String createFolder(String path) throws Exception {
|
||||
if (folderExists(path)) {
|
||||
deleteFolder(path);
|
||||
}
|
||||
return client.files().createFolderV2(path).getMetadata().getId();
|
||||
}
|
||||
|
||||
private void deleteFolder(String path) throws Exception {
|
||||
client.files().deleteV2(path);
|
||||
}
|
||||
|
||||
private boolean folderExists(String path) throws Exception {
|
||||
try {
|
||||
return client.files().getMetadata(path) != null;
|
||||
} catch (GetMetadataErrorException e) {
|
||||
if (e.errorValue.isPath() && e.errorValue.getPathValue().isNotFound()) {
|
||||
return false;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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.processors.dropbox;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class ListDropboxIT extends AbstractDropboxIT<ListDropbox> {
|
||||
|
||||
private static final String NOT_MAIN_FOLDER = "/notMainFolder";
|
||||
private static final String YOUNG_FILE_NAME = "just_created";
|
||||
|
||||
@BeforeEach
|
||||
public void init() throws Exception {
|
||||
super.init();
|
||||
testRunner.setProperty(ListDropbox.FOLDER, MAIN_FOLDER);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void teardown() throws Exception {
|
||||
super.teardown();
|
||||
deleteFolderIfExists(NOT_MAIN_FOLDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListDropbox createTestSubject() {
|
||||
return new ListDropbox();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmbeddedDirectoriesAreListed() throws Exception {
|
||||
createFile("test_file1", "test_file_content1", MAIN_FOLDER);
|
||||
createFile("test_file2", "test_file_content2", MAIN_FOLDER);
|
||||
createFile("test_file11", "test_file_content11", MAIN_FOLDER + "/testFolder1");
|
||||
createFile("test_file112", "test_file_content112", MAIN_FOLDER + "/testFolder2");
|
||||
|
||||
createFile("test_file_not_in_main_folder", "test_file_content31", NOT_MAIN_FOLDER);
|
||||
|
||||
List<String> expectedFileNames = Arrays.asList("test_file1", "test_file2", "test_file11", "test_file112");
|
||||
|
||||
waitForFileCreation();
|
||||
|
||||
testRunner.run();
|
||||
|
||||
List<MockFlowFile> successFlowFiles = testRunner.getFlowFilesForRelationship(ListDropbox.REL_SUCCESS);
|
||||
|
||||
List<String> actualFileNames = getFilenames(successFlowFiles);
|
||||
|
||||
assertEquals(expectedFileNames, actualFileNames);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFolderIsListedById() throws Exception {
|
||||
testRunner.setProperty(ListDropbox.FOLDER, mainFolderId);
|
||||
|
||||
createFile("test_file1", "test_file_content1", MAIN_FOLDER);
|
||||
createFile("test_file11", "test_file_content11", MAIN_FOLDER + "/testFolder1");
|
||||
|
||||
List<String> expectedFileNames = Arrays.asList("test_file1", "test_file11");
|
||||
|
||||
waitForFileCreation();
|
||||
|
||||
testRunner.run();
|
||||
|
||||
List<MockFlowFile> successFlowFiles = testRunner.getFlowFilesForRelationship(ListDropbox.REL_SUCCESS);
|
||||
|
||||
List<String> actualFileNames = getFilenames(successFlowFiles);
|
||||
|
||||
assertEquals(expectedFileNames, actualFileNames);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTooYoungFilesNotListedWhenMinAgeIsSet() throws Exception {
|
||||
testRunner.setProperty(ListDropbox.MIN_AGE, "15 s");
|
||||
|
||||
createFile(YOUNG_FILE_NAME, "test_file_content1", MAIN_FOLDER);
|
||||
|
||||
waitForFileCreation();
|
||||
|
||||
testRunner.run();
|
||||
|
||||
List<MockFlowFile> successFlowFiles = testRunner.getFlowFilesForRelationship(ListDropbox.REL_SUCCESS);
|
||||
|
||||
List<String> actualFileNames = getFilenames(successFlowFiles);
|
||||
|
||||
assertEquals(emptyList(), actualFileNames);
|
||||
|
||||
// Next, wait for another 10+ seconds for MIN_AGE to expire then list again.
|
||||
Thread.sleep(10000);
|
||||
|
||||
List<String> expectedFileNames = singletonList(YOUNG_FILE_NAME);
|
||||
|
||||
testRunner.run();
|
||||
|
||||
successFlowFiles = testRunner.getFlowFilesForRelationship(ListDropbox.REL_SUCCESS);
|
||||
|
||||
actualFileNames = getFilenames(successFlowFiles);
|
||||
|
||||
assertEquals(expectedFileNames, actualFileNames);
|
||||
}
|
||||
|
||||
private void waitForFileCreation() throws InterruptedException {
|
||||
// We need to wait since the creation of the files are not (completely) synchronized.
|
||||
Thread.sleep(5000);
|
||||
}
|
||||
|
||||
private List<String> getFilenames(List<MockFlowFile> flowFiles) {
|
||||
return flowFiles.stream()
|
||||
.map(flowFile -> flowFile.getAttribute("filename"))
|
||||
.collect(toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* 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.processors.dropbox;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Spliterators.spliteratorUnknownSize;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.apache.nifi.services.dropbox.StandardDropboxCredentialService.ACCESS_TOKEN;
|
||||
import static org.apache.nifi.services.dropbox.StandardDropboxCredentialService.APP_KEY;
|
||||
import static org.apache.nifi.services.dropbox.StandardDropboxCredentialService.APP_SECRET;
|
||||
import static org.apache.nifi.services.dropbox.StandardDropboxCredentialService.REFRESH_TOKEN;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.dropbox.core.DbxException;
|
||||
import com.dropbox.core.v2.DbxClientV2;
|
||||
import com.dropbox.core.v2.files.DbxUserFilesRequests;
|
||||
import com.dropbox.core.v2.files.FileMetadata;
|
||||
import com.dropbox.core.v2.files.FolderMetadata;
|
||||
import com.dropbox.core.v2.files.ListFolderBuilder;
|
||||
import com.dropbox.core.v2.files.ListFolderResult;
|
||||
import com.dropbox.core.v2.files.Metadata;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Spliterator;
|
||||
import java.util.stream.StreamSupport;
|
||||
import org.apache.nifi.json.JsonRecordSetWriter;
|
||||
import org.apache.nifi.processor.ProcessContext;
|
||||
import org.apache.nifi.reporting.InitializationException;
|
||||
import org.apache.nifi.serialization.RecordSetWriterFactory;
|
||||
import org.apache.nifi.services.dropbox.StandardDropboxCredentialService;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class ListDropboxTest {
|
||||
|
||||
public static final String ID_1 = "id:11111";
|
||||
public static final String ID_2 = "id:22222";
|
||||
public static final String TEST_FOLDER = "/testFolder";
|
||||
public static final String FILENAME_1 = "file_name_1";
|
||||
public static final String FILENAME_2 = "file_name_2";
|
||||
public static final long SIZE = 125;
|
||||
public static final long CREATED_TIME = 1659707000;
|
||||
public static final String REVISION = "5e4ddb1320676a5c29261";
|
||||
public static final boolean IS_RECURSIVE = true;
|
||||
public static final long MIN_TIMESTAMP = 1659707000;
|
||||
public static final long OLD_CREATED_TIME = 1657375066;
|
||||
private TestRunner testRunner;
|
||||
|
||||
@Mock
|
||||
private DbxClientV2 mockDropboxClient;
|
||||
|
||||
@Mock
|
||||
private StandardDropboxCredentialService credentialService;
|
||||
|
||||
@Mock
|
||||
private DbxUserFilesRequests mockDbxUserFilesRequest;
|
||||
|
||||
@Mock
|
||||
private ListFolderResult mockListFolderResult;
|
||||
|
||||
@Mock
|
||||
private ListFolderBuilder mockListFolderBuilder;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws Exception {
|
||||
ListDropbox testSubject = new ListDropbox() {
|
||||
@Override
|
||||
public DbxClientV2 getDropboxApiClient(ProcessContext context) {
|
||||
return mockDropboxClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<DropboxFileInfo> performListing(
|
||||
ProcessContext context, Long minTimestamp, ListingMode ignoredListingMode) throws IOException {
|
||||
return super.performListing(context, MIN_TIMESTAMP, ListingMode.EXECUTION);
|
||||
}
|
||||
};
|
||||
|
||||
testRunner = TestRunners.newTestRunner(testSubject);
|
||||
|
||||
mockStandardDropboxCredentialService();
|
||||
|
||||
testRunner.setProperty(ListDropbox.RECURSIVE_SEARCH, Boolean.toString(IS_RECURSIVE));
|
||||
testRunner.setProperty(ListDropbox.MIN_AGE, "0 sec");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFolderValidity() {
|
||||
testRunner.setProperty(ListDropbox.FOLDER, "id:odTlUvbpIEAAAAAAAAABmw");
|
||||
testRunner.assertValid();
|
||||
testRunner.setProperty(ListDropbox.FOLDER, "/");
|
||||
testRunner.assertValid();
|
||||
testRunner.setProperty(ListDropbox.FOLDER, "/tempFolder");
|
||||
testRunner.assertValid();
|
||||
testRunner.setProperty(ListDropbox.FOLDER, "/tempFolder/tempSubFolder");
|
||||
testRunner.assertValid();
|
||||
testRunner.setProperty(ListDropbox.FOLDER, "/tempFolder/tempSubFolder/");
|
||||
testRunner.assertValid();
|
||||
testRunner.setProperty(ListDropbox.FOLDER, "tempFolder");
|
||||
testRunner.assertNotValid();
|
||||
testRunner.setProperty(ListDropbox.FOLDER, "odTlUvbpIEAAAAAAAAABmw");
|
||||
testRunner.assertNotValid();
|
||||
testRunner.setProperty(ListDropbox.FOLDER, "");
|
||||
testRunner.assertNotValid();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRootIsListed() throws Exception {
|
||||
mockFileListing();
|
||||
|
||||
String folderName = "/";
|
||||
testRunner.setProperty(ListDropbox.FOLDER, folderName);
|
||||
|
||||
//root is listed when "" is used in Dropbox API
|
||||
when(mockDbxUserFilesRequest.listFolderBuilder("")).thenReturn(mockListFolderBuilder);
|
||||
when(mockListFolderResult.getEntries()).thenReturn(singletonList(
|
||||
createFileMetaData(FILENAME_1, folderName, ID_1, CREATED_TIME)
|
||||
));
|
||||
|
||||
testRunner.run();
|
||||
|
||||
testRunner.assertAllFlowFilesTransferred(ListDropbox.REL_SUCCESS, 1);
|
||||
List<MockFlowFile> flowFiles = testRunner.getFlowFilesForRelationship(ListDropbox.REL_SUCCESS);
|
||||
MockFlowFile ff0 = flowFiles.get(0);
|
||||
assertFlowFileAttributes(ff0, folderName);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOnlyFilesAreListedFolderIsFiltered() throws Exception {
|
||||
mockFileListing();
|
||||
|
||||
testRunner.setProperty(ListDropbox.FOLDER, TEST_FOLDER);
|
||||
|
||||
when(mockDbxUserFilesRequest.listFolderBuilder(TEST_FOLDER)).thenReturn(mockListFolderBuilder);
|
||||
when(mockListFolderResult.getEntries()).thenReturn(Arrays.asList(
|
||||
createFileMetaData(FILENAME_1, TEST_FOLDER, ID_1, CREATED_TIME),
|
||||
createFolderMetaData("testFolder1", TEST_FOLDER)
|
||||
));
|
||||
|
||||
testRunner.run();
|
||||
|
||||
testRunner.assertAllFlowFilesTransferred(ListDropbox.REL_SUCCESS, 1);
|
||||
List<MockFlowFile> flowFiles = testRunner.getFlowFilesForRelationship(ListDropbox.REL_SUCCESS);
|
||||
MockFlowFile ff0 = flowFiles.get(0);
|
||||
assertFlowFileAttributes(ff0, TEST_FOLDER);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOldItemIsFiltered() throws Exception {
|
||||
mockFileListing();
|
||||
|
||||
testRunner.setProperty(ListDropbox.FOLDER, TEST_FOLDER);
|
||||
|
||||
when(mockDbxUserFilesRequest.listFolderBuilder(TEST_FOLDER)).thenReturn(mockListFolderBuilder);
|
||||
when(mockListFolderResult.getEntries()).thenReturn(Arrays.asList(
|
||||
createFileMetaData(FILENAME_1, TEST_FOLDER, ID_1, CREATED_TIME),
|
||||
createFileMetaData(FILENAME_2, TEST_FOLDER, ID_2, OLD_CREATED_TIME)
|
||||
));
|
||||
|
||||
testRunner.run();
|
||||
|
||||
testRunner.assertAllFlowFilesTransferred(ListDropbox.REL_SUCCESS, 1);
|
||||
List<MockFlowFile> flowFiles = testRunner.getFlowFilesForRelationship(ListDropbox.REL_SUCCESS);
|
||||
MockFlowFile ff0 = flowFiles.get(0);
|
||||
assertFlowFileAttributes(ff0, TEST_FOLDER);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRecordWriter() throws Exception {
|
||||
mockFileListing();
|
||||
mockRecordWriter();
|
||||
|
||||
testRunner.setProperty(ListDropbox.FOLDER, TEST_FOLDER);
|
||||
|
||||
when(mockDbxUserFilesRequest.listFolderBuilder(TEST_FOLDER)).thenReturn(mockListFolderBuilder);
|
||||
when(mockListFolderResult.getEntries()).thenReturn(Arrays.asList(
|
||||
createFileMetaData(FILENAME_1, TEST_FOLDER, ID_1, CREATED_TIME),
|
||||
createFileMetaData(FILENAME_2, TEST_FOLDER, ID_2, CREATED_TIME)
|
||||
));
|
||||
|
||||
testRunner.run();
|
||||
|
||||
testRunner.assertAllFlowFilesTransferred(ListDropbox.REL_SUCCESS, 1);
|
||||
List<MockFlowFile> flowFiles = testRunner.getFlowFilesForRelationship(ListDropbox.REL_SUCCESS);
|
||||
MockFlowFile ff0 = flowFiles.get(0);
|
||||
List<String> expectedFileNames = Arrays.asList(FILENAME_1, FILENAME_2);
|
||||
List<String> actualFileNames = getFilenames(ff0.getContent());
|
||||
|
||||
assertEquals(expectedFileNames, actualFileNames);
|
||||
}
|
||||
|
||||
private void assertFlowFileAttributes(MockFlowFile flowFile, String folderName) {
|
||||
flowFile.assertAttributeEquals(DropboxFileInfo.ID, ID_1);
|
||||
flowFile.assertAttributeEquals(DropboxFileInfo.FILENAME, FILENAME_1);
|
||||
flowFile.assertAttributeEquals(DropboxFileInfo.PATH, folderName);
|
||||
flowFile.assertAttributeEquals(DropboxFileInfo.TIMESTAMP, Long.toString(CREATED_TIME));
|
||||
flowFile.assertAttributeEquals(DropboxFileInfo.SIZE, Long.toString(SIZE));
|
||||
flowFile.assertAttributeEquals(DropboxFileInfo.REVISION, REVISION);
|
||||
}
|
||||
|
||||
private FileMetadata createFileMetaData(
|
||||
String filename,
|
||||
String parent,
|
||||
String id,
|
||||
long createdTime) {
|
||||
return FileMetadata.newBuilder(filename, id,
|
||||
new Date(createdTime),
|
||||
new Date(createdTime),
|
||||
REVISION, SIZE)
|
||||
.withPathDisplay(parent + "/" + filename)
|
||||
.build();
|
||||
}
|
||||
|
||||
private Metadata createFolderMetaData(String folderName, String parent) {
|
||||
return FolderMetadata.newBuilder(folderName)
|
||||
.withPathDisplay(parent + "/" + folderName)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void mockStandardDropboxCredentialService() throws Exception {
|
||||
String credentialServiceId = "dropbox_credentials";
|
||||
when(credentialService.getIdentifier()).thenReturn(credentialServiceId);
|
||||
testRunner.addControllerService(credentialServiceId, credentialService);
|
||||
testRunner.setProperty(credentialService, APP_KEY, "appKey");
|
||||
testRunner.setProperty(credentialService, APP_SECRET, "appSecret");
|
||||
testRunner.setProperty(credentialService, ACCESS_TOKEN, "accessToken");
|
||||
testRunner.setProperty(credentialService, REFRESH_TOKEN, "refreshToken");
|
||||
testRunner.enableControllerService(credentialService);
|
||||
testRunner.setProperty(ListDropbox.CREDENTIAL_SERVICE, credentialServiceId);
|
||||
}
|
||||
|
||||
private void mockRecordWriter() throws InitializationException {
|
||||
RecordSetWriterFactory recordWriter = new JsonRecordSetWriter();
|
||||
testRunner.addControllerService("record_writer", recordWriter);
|
||||
testRunner.enableControllerService(recordWriter);
|
||||
testRunner.setProperty(ListDropbox.RECORD_WRITER, "record_writer");
|
||||
}
|
||||
|
||||
private void mockFileListing() throws DbxException {
|
||||
when(mockListFolderBuilder.withRecursive(IS_RECURSIVE)).thenReturn(mockListFolderBuilder);
|
||||
when(mockListFolderBuilder.start()).thenReturn(mockListFolderResult);
|
||||
when(mockDropboxClient.files()).thenReturn(mockDbxUserFilesRequest);
|
||||
when(mockListFolderResult.getHasMore()).thenReturn(false);
|
||||
}
|
||||
|
||||
private List<String> getFilenames(String flowFileContent) {
|
||||
try {
|
||||
JsonNode jsonNode = new ObjectMapper().readTree(flowFileContent);
|
||||
return StreamSupport.stream(spliteratorUnknownSize(jsonNode.iterator(), Spliterator.ORDERED), false)
|
||||
.map(node -> node.get("filename").asText())
|
||||
.collect(toList());
|
||||
} catch (JsonProcessingException e) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>nifi-dropbox-bundle</artifactId>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>nifi-dropbox-services-api-nar</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
<packaging>nar</packaging>
|
||||
<properties>
|
||||
<maven.javadoc.skip>true</maven.javadoc.skip>
|
||||
<source.skip>true</source.skip>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-services-api</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-standard-services-api-nar</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
<type>nar</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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,5 @@
|
||||
nifi-dropbox-services-api-nar
|
||||
Copyright 2015-2022 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
@ -0,0 +1,34 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>nifi-dropbox-bundle</artifactId>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>nifi-dropbox-services-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -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.dropbox.credentials.service;
|
||||
|
||||
public class DropboxCredentialDetails {
|
||||
private final String appKey;
|
||||
private final String appSecret;
|
||||
private final String accessToken;
|
||||
private final String refreshToken;
|
||||
|
||||
public DropboxCredentialDetails(String appKey, String appSecret, String accessToken, String refreshToken) {
|
||||
this.appKey = appKey;
|
||||
this.appSecret = appSecret;
|
||||
this.accessToken = accessToken;
|
||||
this.refreshToken = refreshToken;
|
||||
}
|
||||
|
||||
public String getAppKey() {
|
||||
return appKey;
|
||||
}
|
||||
|
||||
public String getAppSecret() {
|
||||
return appSecret;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.dropbox.credentials.service;
|
||||
|
||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||
import org.apache.nifi.annotation.documentation.Tags;
|
||||
import org.apache.nifi.controller.ControllerService;
|
||||
|
||||
/**
|
||||
* DropboxCredentialService interface to support getting Dropbox credentials (app key, app secret, access token, refresh token)
|
||||
*
|
||||
*
|
||||
* @see <a href="https://www.dropbox.com/developers/reference/getting-started">Dropbox Developers Getting Started</a>
|
||||
* @see <a href="https://dropbox.github.io/dropbox-sdk-java/api-docs/v4.0.0/com/dropbox/core/oauth/DbxCredential.html">DbxCredential</a>
|
||||
*/
|
||||
@Tags({"dropbox", "credentials", "auth", "session"})
|
||||
@CapabilityDescription("Provides DropboxCredentialDetails.")
|
||||
public interface DropboxCredentialService extends ControllerService {
|
||||
/**
|
||||
* Get Dropbox credentials
|
||||
* @return DropboxCredentialDetails object which contains app key, app secret, access and refresh tokens for authorizing
|
||||
* requests on the Dropbox platform.
|
||||
*/
|
||||
DropboxCredentialDetails getDropboxCredential();
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-bundle</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>nifi-dropbox-services-nar</artifactId>
|
||||
<packaging>nar</packaging>
|
||||
<properties>
|
||||
<maven.javadoc.skip>true</maven.javadoc.skip>
|
||||
<source.skip>true</source.skip>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-services-api-nar</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
<type>nar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-services</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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,5 @@
|
||||
nifi-dropbox-services-nar
|
||||
Copyright 2015-2022 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
@ -0,0 +1,45 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-bundle</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>nifi-dropbox-services</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-utils</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-dropbox-services-api</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -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.services.dropbox;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||
import org.apache.nifi.annotation.documentation.Tags;
|
||||
import org.apache.nifi.annotation.lifecycle.OnEnabled;
|
||||
import org.apache.nifi.components.PropertyDescriptor;
|
||||
import org.apache.nifi.controller.AbstractControllerService;
|
||||
import org.apache.nifi.controller.ConfigurationContext;
|
||||
import org.apache.nifi.dropbox.credentials.service.DropboxCredentialDetails;
|
||||
import org.apache.nifi.dropbox.credentials.service.DropboxCredentialService;
|
||||
import org.apache.nifi.expression.ExpressionLanguageScope;
|
||||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
|
||||
@CapabilityDescription("Defines credentials for Dropbox processors.")
|
||||
@Tags({"dropbox", "credentials", "provider"})
|
||||
public class StandardDropboxCredentialService extends AbstractControllerService implements DropboxCredentialService {
|
||||
|
||||
public static final PropertyDescriptor APP_KEY = new PropertyDescriptor.Builder()
|
||||
.name("app-key")
|
||||
.displayName("App Key")
|
||||
.description("App Key of the user's Dropbox app." +
|
||||
" See Additional Details for more information.")
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.required(true)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor APP_SECRET = new PropertyDescriptor.Builder()
|
||||
.name("app-secret")
|
||||
.displayName("App Secret")
|
||||
.description("App Secret of the user's Dropbox app." +
|
||||
" See Additional Details for more information.")
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
|
||||
.sensitive(true)
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.required(true)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor ACCESS_TOKEN = new PropertyDescriptor.Builder()
|
||||
.name("access-token")
|
||||
.displayName("Access Token")
|
||||
.description("Access Token of the user's Dropbox app." +
|
||||
" See Additional Details for more information about Access Token generation.")
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
|
||||
.sensitive(true)
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.required(true)
|
||||
.build();
|
||||
|
||||
public static final PropertyDescriptor REFRESH_TOKEN = new PropertyDescriptor.Builder()
|
||||
.name("refresh-token")
|
||||
.displayName("Refresh Token")
|
||||
.description("Refresh Token of the user's Dropbox app." +
|
||||
" See Additional Details for more information about Refresh Token generation.")
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
|
||||
.sensitive(true)
|
||||
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
|
||||
.required(true)
|
||||
.build();
|
||||
|
||||
private static final List<PropertyDescriptor> PROPERTIES;
|
||||
|
||||
static {
|
||||
final List<PropertyDescriptor> props = new ArrayList<>();
|
||||
props.add(APP_KEY);
|
||||
props.add(APP_SECRET);
|
||||
props.add(ACCESS_TOKEN);
|
||||
props.add(REFRESH_TOKEN);
|
||||
PROPERTIES = Collections.unmodifiableList(props);
|
||||
}
|
||||
|
||||
private DropboxCredentialDetails credential;
|
||||
|
||||
@Override
|
||||
public final List<PropertyDescriptor> getSupportedPropertyDescriptors() {
|
||||
return PROPERTIES;
|
||||
}
|
||||
|
||||
@OnEnabled
|
||||
public void onEnabled(final ConfigurationContext context) {
|
||||
final String appKey = context.getProperty(APP_KEY).evaluateAttributeExpressions().getValue();
|
||||
final String appSecret = context.getProperty(APP_SECRET).evaluateAttributeExpressions().getValue();
|
||||
final String accessToken = context.getProperty(ACCESS_TOKEN).evaluateAttributeExpressions().getValue();
|
||||
final String refreshToken = context.getProperty(REFRESH_TOKEN).evaluateAttributeExpressions().getValue();
|
||||
|
||||
this.credential = new DropboxCredentialDetails(appKey, appSecret, accessToken, refreshToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DropboxCredentialDetails getDropboxCredential() {
|
||||
return credential;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
# 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.
|
||||
org.apache.nifi.services.dropbox.StandardDropboxCredentialService
|
@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/html">
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>StandardDropboxCredentialService</title>
|
||||
<link rel="stylesheet" href="/nifi-docs/css/component-usage.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Generating credentials for Dropbox authentication</h1>
|
||||
|
||||
<p>
|
||||
StandardDropboxCredentialService requires "App Key", "App Secret", "Access Token" and "Refresh Token". <br><br>
|
||||
This document describes how to generate these credentials using an existing Dropbox account.
|
||||
</p>
|
||||
|
||||
<h3>Generate App Key and App Secret</h3>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li> Login with your Dropbox account.</li>
|
||||
<li>If you already have an app created, go to <a href="https://www.dropbox.com/developers">Dropbox Developers</a> page,
|
||||
click on "App Console" button and select your app. On the app's info page you will find the "App key" and "App secret".<br>
|
||||
(See also <a href="https://www.dropbox.com/developers/reference/getting-started"> Dropbox Getting Started</a>, App Console tab, "Navigating the App Console" chapter)</li>
|
||||
|
||||
<li> If you don't have any apps, go to <a href="https://www.dropbox.com/developers">Dropbox Developers</a> page and
|
||||
click on "Create app" button. (See also <a href="https://www.dropbox.com/developers/reference/getting-started"> Dropbox Getting Started</a>, App Console tab,
|
||||
"Creating a Dropbox app" chapter.)
|
||||
<ul>
|
||||
<li> On the next page select "Scoped access" and "Full Dropbox" as access type.</li>
|
||||
<li> Provide a name for your app.</li>
|
||||
<li>On the app's info page you will find the "App key" and "App secret".
|
||||
(See also <a href="https://www.dropbox.com/developers/reference/getting-started">
|
||||
Dropbox Getting Started</a>, App Console tab, "Navigating the App Console" chapter.)
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h3>Set required permissions for your app</h3>
|
||||
<p>The "files.content.read" permission has to be enabled for the application to be able to read the files in Dropbox.<br><br>
|
||||
You can set permissions in <a href="https://www.dropbox.com/developers">Dropbox Developers</a> page.
|
||||
<li> Click on "App Console" button and select your app.</li>
|
||||
<li> Go to "Permissions" tab and enable the "files.content.read" permission.</li>
|
||||
<li> Click "Submit" button.</li>
|
||||
<li> NOTE: In case you already have an Access Token and Refresh Token, those tokens have to be regenerated after the permission change.
|
||||
See "Generate Access Token and Refresh Token" chapter about token generation.</li>
|
||||
</p>
|
||||
|
||||
<h3>Generate Access Token and Refresh Token</h3>
|
||||
<p>
|
||||
<ul>
|
||||
<li>Go to the following web page:
|
||||
|
||||
<pre>https://www.dropbox.com/oauth2/authorize?token_access_type=offline&response_type=code&client_id=<i>your_app_key</i></pre></li>
|
||||
|
||||
<li>Click "Next" and click on "Allow" button on the next page.</li>
|
||||
<li>An access code will be generated for you, it will be displayed on the next page:</li>
|
||||
<pre>
|
||||
"Access Code Generated
|
||||
Enter this code into your_app_name to finish the process
|
||||
<i>your_generated_access_code</i>"
|
||||
</pre>
|
||||
<li>Execute the following command from terminal to fetch the access and refresh tokens. <br><br>
|
||||
Make sure you execute the curl command right after the access code generation, since the code expires very quickly.<br>
|
||||
In case the curl command returns "invalid grant" error, please generate a new access code (see previous step)<br>
|
||||
|
||||
<pre>curl https://api.dropbox.com/oauth2/token -d code=<i>your_generated_access_code</i> -d grant_type=authorization_code -u <i>your_app_key</i>:<i>your_app_secret</i></pre>
|
||||
<br><br>
|
||||
</li>
|
||||
<li>The curl command results a json file which contains the "access_token" and "refresh_token":</li>
|
||||
<code>
|
||||
<pre>
|
||||
{
|
||||
"access_token": "sl.xxxxxxxxxxx"
|
||||
"expires_in": 14400,
|
||||
"refresh_token": "xxxxxx",
|
||||
"scope": "files.content.read files.metadata.read",
|
||||
"uid": "xxxxxx",
|
||||
"account_id": "dbid:xxxx"
|
||||
}
|
||||
</pre>
|
||||
</code>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
41
nifi-nar-bundles/nifi-dropbox-bundle/pom.xml
Normal file
41
nifi-nar-bundles/nifi-dropbox-bundle/pom.xml
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0"?>
|
||||
<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">
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>nifi-nar-bundles</artifactId>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>nifi-dropbox-bundle</artifactId>
|
||||
<version>1.18.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<dropbox.client.version>4.0.1</dropbox.client.version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>nifi-dropbox-services-api</module>
|
||||
<module>nifi-dropbox-services-api-nar</module>
|
||||
<module>nifi-dropbox-processors</module>
|
||||
<module>nifi-dropbox-processors-nar</module>
|
||||
<module>nifi-dropbox-services</module>
|
||||
<module>nifi-dropbox-services-nar</module>
|
||||
</modules>
|
||||
</project>
|
@ -111,6 +111,7 @@
|
||||
<module>nifi-salesforce-bundle</module>
|
||||
<module>nifi-rocksdb-bundle</module>
|
||||
<module>nifi-hubspot-bundle</module>
|
||||
<module>nifi-dropbox-bundle</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
|
Loading…
x
Reference in New Issue
Block a user