Skip to content

Commit fbced45

Browse files
committed
Upgrade: Added the possibility to add tags to the datasets uploaded to CKAN. Both for new datasets and backups.
Signed-off-by: Ricardo Ruiz Saiz <dorm.std@gmail.com>
1 parent 8724644 commit fbced45

3 files changed

Lines changed: 137 additions & 40 deletions

File tree

CKAN_API_Handler/src/main/java/net/atos/qrowd/handlers/CKAN_API_Handler.java

Lines changed: 83 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.http.client.methods.CloseableHttpResponse;
2424
import org.apache.http.client.methods.HttpPost;
2525
import org.apache.http.entity.ContentType;
26+
import org.apache.http.entity.StringEntity;
2627
import org.apache.http.entity.mime.MultipartEntityBuilder;
2728
import org.apache.http.entity.mime.content.ContentBody;
2829
import org.apache.http.entity.mime.content.FileBody;
@@ -37,7 +38,25 @@
3738
import java.io.InputStreamReader;
3839
import java.net.URL;
3940
import java.text.SimpleDateFormat;
41+
import java.util.ArrayList;
4042
import java.util.Date;
43+
import java.util.List;
44+
45+
/**
46+
* Copyright 2018 Atos
47+
*
48+
* Licensed under the Apache License, Version 2.0 (the "License");
49+
* you may not use this file except in compliance with the License.
50+
* You may obtain a copy of the License at
51+
*
52+
* http://www.apache.org/licenses/LICENSE-2.0
53+
*
54+
* Unless required by applicable law or agreed to in writing, software
55+
* distributed under the License is distributed on an "AS IS" BASIS,
56+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
57+
* See the License for the specific language governing permissions and
58+
* limitations under the License.
59+
*/
4160

4261
public class CKAN_API_Handler {
4362
private final Logger log = Logger.getLogger(CKAN_API_Handler.class);
@@ -147,18 +166,41 @@ public Package_ getPackageByName(String name) throws IOException {
147166

148167
}
149168

150-
public void createPackage(String package_id) throws IOException{
169+
public void createPackage(String package_id, String tags) throws IOException{
151170

152171
HttpPost postRequest;
153172
StringBuilder sb = new StringBuilder();
154173
String line;
155174

156-
HttpEntity reqEntity = MultipartEntityBuilder.create()
157-
.addPart("name",new StringBody(package_id,ContentType.TEXT_PLAIN))
158-
.addPart("owner_org",new StringBody(organization_id,ContentType.TEXT_PLAIN))
159-
.addPart("notes",new StringBody(package_description,ContentType.TEXT_PLAIN))
160-
.addPart("private",new StringBody(package_private.toString(),ContentType.TEXT_PLAIN))
161-
.build();
175+
//Split <tags> by "," and for each element in the list generate a tag
176+
177+
String[] tagList = tags.split(",");
178+
List<Tag> list = new ArrayList<>();
179+
for(String tag: tagList)
180+
{
181+
Tag t = new Tag();
182+
//Since CKAN only allows alphanumeric and _ we need to deal with illegal characters/spaces...
183+
t.setName(tag.replaceAll("[\\W]+","_"));
184+
list.add(t);
185+
}
186+
187+
Package_ pack = new Package_();
188+
pack.setName(package_id);
189+
pack.setOwnerOrg(organization_id);
190+
pack.setNotes(package_description);
191+
pack.setPrivate(package_private);
192+
//Set the new list of tags for the dataset
193+
194+
if(list.size()==0 || tags.trim().isEmpty()) {
195+
pack.setTags(null);
196+
pack.setNumTags(0);
197+
}else {
198+
pack.setTags(list);
199+
pack.setNumTags(list.size());
200+
}
201+
Gson gson = new Gson();
202+
203+
StringEntity reqEntity = new StringEntity(gson.toJson(pack));
162204

163205
postRequest = new HttpPost(HOST+"/api/3/action/package_create?use_default_schema=true");
164206
postRequest.setEntity(reqEntity);
@@ -189,44 +231,46 @@ public void createPackage(String package_id) throws IOException{
189231
log.info(sb);
190232
}
191233
}
192-
public void createPackagePojo(Package_ dataset, String name) throws IOException{
234+
public void createPackagePojoNoResources(Package_ dataset, String name, String tags) throws IOException{
235+
236+
//Split <tags> by "," and for each element in the list generate a tag
237+
238+
String[] tagList = tags.split(",");
239+
List<Tag> list = new ArrayList<>();
240+
for(String tag: tagList)
241+
{
242+
Tag t = new Tag();
243+
//Since CKAN only allows alphanumeric and _ we need to deal with illegal characters/spaces...
244+
t.setName(tag.replaceAll("[\\W]+","_"));
245+
list.add(t);
246+
}
193247

194248
HttpPost postRequest;
195249
StringBuilder sb = new StringBuilder();
196250
String line;
251+
//Set the new dataset name and title
252+
dataset.setName(name);
253+
dataset.setTitle(name);
197254

198-
MultipartEntityBuilder multipart = MultipartEntityBuilder.create()
199-
.addPart("name",new StringBody(name,ContentType.TEXT_PLAIN));
200-
// ToDo: Improve this way of handling null values in the returned dataset
201-
if(dataset.getAuthor()!=null) {
202-
multipart.addPart("author", new StringBody(dataset.getAuthor(), ContentType.TEXT_PLAIN));
203-
}
204-
if(dataset.getAuthorEmail()!=null) {
205-
multipart.addPart("author_email", new StringBody(dataset.getAuthorEmail(), ContentType.TEXT_PLAIN));
206-
}
207-
if(dataset.getOwnerOrg()!=null) {
208-
multipart.addPart("owner_org", new StringBody(dataset.getOwnerOrg(), ContentType.TEXT_PLAIN));
209-
}
210-
if(dataset.getNotes()!=null) {
211-
multipart.addPart("notes", new StringBody(dataset.getNotes(), ContentType.TEXT_PLAIN));
212-
}
213-
if(dataset.getPrivate()!=null) {
214-
multipart.addPart("private", new StringBody(dataset.getPrivate().toString(), ContentType.TEXT_PLAIN));
215-
}
216-
if(dataset.getLicenseTitle()!=null) {
217-
multipart.addPart("license_title", new StringBody(dataset.getLicenseTitle(), ContentType.TEXT_PLAIN));
218-
}
219-
if(dataset.getLicenseId()!=null) {
220-
multipart.addPart("license_id", new StringBody(dataset.getLicenseId(), ContentType.TEXT_PLAIN));
221-
}
222-
if(dataset.getLicenseTitle() != null){
223-
multipart.addPart("license_title", new StringBody(dataset.getLicenseTitle(), ContentType.TEXT_PLAIN));
224-
}
225-
if(dataset.getMaintainerEmail() != null){
226-
multipart.addPart("maintainer_email", new StringBody(dataset.getMaintainerEmail(), ContentType.TEXT_PLAIN));
255+
//Remove identifiers of the old dataset and its resources
256+
dataset.setId(null);
257+
dataset.setRevisionId(null);
258+
dataset.setResources(null);
259+
dataset.setNumResources(null);
260+
261+
//Set the new list of tags for the dataset
262+
263+
if(list.size()==0 || tags.trim().isEmpty()) {
264+
dataset.setTags(null);
265+
dataset.setNumTags(0);
266+
}else {
267+
dataset.setTags(list);
268+
dataset.setNumTags(list.size());
227269
}
270+
Gson gson = new Gson();
228271

229-
HttpEntity reqEntity = multipart.build();
272+
System.out.println(gson.toJson(dataset));
273+
StringEntity reqEntity = new StringEntity(gson.toJson(dataset));
230274

231275
postRequest = new HttpPost(HOST+"/api/action/package_create");
232276
postRequest.setEntity(reqEntity);
@@ -249,6 +293,7 @@ public void createPackagePojo(Package_ dataset, String name) throws IOException{
249293

250294
if(statusCode!=200){
251295
log.error("statusCode =!=" +statusCode);
296+
252297
log.error(sb);
253298
}
254299
else {

nifi-nifiCKANDatasetBackup-processors/src/main/java/net/atos/qrowd/processors/nifiCKANDatasetBackup/CKAN_Package_Backup.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@
3838
import java.time.format.DateTimeFormatter;
3939
import java.util.*;
4040

41+
/**
42+
* Copyright 2018 Atos
43+
*
44+
* Licensed under the Apache License, Version 2.0 (the "License");
45+
* you may not use this file except in compliance with the License.
46+
* You may obtain a copy of the License at
47+
*
48+
* http://www.apache.org/licenses/LICENSE-2.0
49+
*
50+
* Unless required by applicable law or agreed to in writing, software
51+
* distributed under the License is distributed on an "AS IS" BASIS,
52+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
53+
* See the License for the specific language governing permissions and
54+
* limitations under the License.
55+
*/
56+
4157
@EventDriven
4258
@SupportsBatching
4359
@Tags({"ckan","backup","web service","request","local"})
@@ -67,6 +83,13 @@ public class CKAN_Package_Backup extends AbstractProcessor {
6783
.addValidator(Validator.VALID)
6884
.required(true)
6985
.build();
86+
private static final PropertyDescriptor tag_list = new PropertyDescriptor
87+
.Builder().name("tag_list")
88+
.displayName("Comma-separated Tag List")
89+
.description("Comma-separated tag list to be set for the dataset. Only alphanumeric characters and '_' accepted")
90+
.addValidator(Validator.VALID)
91+
.required(false)
92+
.build();
7093

7194
private static final Relationship REL_BACKUP_CREATED = new Relationship.Builder()
7295
.name("BACKUP_SUCCESS")
@@ -92,6 +115,7 @@ protected void init(final ProcessorInitializationContext context) {
92115
descriptors.add(CKAN_url);
93116
descriptors.add(api_key);
94117
descriptors.add(package_name);
118+
descriptors.add(tag_list);
95119

96120
this.descriptors = Collections.unmodifiableList(descriptors);
97121

@@ -125,6 +149,8 @@ public void onTrigger(final ProcessContext context, final ProcessSession session
125149
String url = context.getProperty(CKAN_url).getValue();
126150
final String apiKey = context.getProperty(api_key).getValue();
127151

152+
String tagList = context.getProperty(tag_list).getValue();
153+
128154
/* *****************
129155
* Main logic of the CKAN package backup:
130156
* - Look in CKAN for a package with the same name as the file
@@ -154,7 +180,7 @@ public void onTrigger(final ProcessContext context, final ProcessSession session
154180

155181
getLogger().info("Creating the package: {}", new Object[]{datasetName});
156182
//Create the new timestamped package
157-
ckan_api_handler.createPackagePojo(dataset,datasetName);
183+
ckan_api_handler.createPackagePojoNoResources(dataset,datasetName,tagList);
158184

159185
//Check when the list of resources of the package is empty
160186
if(resourceList.size()>0) {

nifi-nifiCKANFlowfileUploader-processors/src/main/java/net/atos/qrowd/processors/nifiCKANprocessor/CKAN_Flowfile_Uploader.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,22 @@
3737
import java.nio.file.Paths;
3838
import java.util.*;
3939

40+
/**
41+
* Copyright 2018 Atos
42+
*
43+
* Licensed under the Apache License, Version 2.0 (the "License");
44+
* you may not use this file except in compliance with the License.
45+
* You may obtain a copy of the License at
46+
*
47+
* http://www.apache.org/licenses/LICENSE-2.0
48+
*
49+
* Unless required by applicable law or agreed to in writing, software
50+
* distributed under the License is distributed on an "AS IS" BASIS,
51+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
52+
* See the License for the specific language governing permissions and
53+
* limitations under the License.
54+
*/
55+
4056
@Tags({"ckan","web service","request","local"})
4157
@CapabilityDescription("Nifi Processor that will upload the specified flowfile to CKAN through its API, it will create the organization and package if needed.")
4258
@ReadsAttributes
@@ -94,6 +110,13 @@ public class CKAN_Flowfile_Uploader extends AbstractProcessor {
94110
.defaultValue(PRIVATE_TRUE.getValue())
95111
.required(true)
96112
.build();
113+
private static final PropertyDescriptor tag_list = new PropertyDescriptor
114+
.Builder().name("tag_list")
115+
.displayName("Comma-separated Tag List")
116+
.description("Comma-separated tag list to be set for the dataset. Only alphanumeric characters and '_' accepted")
117+
.addValidator(Validator.VALID)
118+
.required(false)
119+
.build();
97120

98121
private static final Relationship REL_SUCCESS = new Relationship.Builder()
99122
.name("SUCCESS")
@@ -118,6 +141,7 @@ protected void init(final ProcessorInitializationContext context) {
118141
descriptors.add(package_name);
119142
descriptors.add(package_description);
120143
descriptors.add(package_private);
144+
descriptors.add(tag_list);
121145

122146
this.descriptors = Collections.unmodifiableList(descriptors);
123147

@@ -148,6 +172,8 @@ public void onTrigger(final ProcessContext context, final ProcessSession session
148172
//This is the way to get the value of a property
149173
String url = context.getProperty(CKAN_url).getValue();
150174

175+
String tagList = context.getProperty(tag_list).getValue();
176+
151177
String filename = flowFile.getAttribute(CoreAttributes.FILENAME.key());
152178

153179
String tDir = System.getProperty("java.io.tmpdir");
@@ -203,7 +229,7 @@ public void onTrigger(final ProcessContext context, final ProcessSession session
203229
ckan_api_handler.createOrganization();
204230
}
205231
if (!ckan_api_handler.packageExists(filenameNoExtension)) {
206-
ckan_api_handler.createPackage(filenameNoExtension);
232+
ckan_api_handler.createPackage(filenameNoExtension,tagList);
207233
}
208234
if(ckan_api_handler.createOrUpdateResource(file.toFile().toString())) {
209235
getLogger().info("File tried to be uploaded to CKAN: {}", new Object[]{file.toFile().toString()});

0 commit comments

Comments
 (0)