From 8f54f37825746cf82b33a21ff356950eb682d290 Mon Sep 17 00:00:00 2001 From: dglFromAtt Date: Tue, 19 Jun 2018 22:03:48 -0400 Subject: [PATCH] Actually remove pubs and subs on Feed delete Patch Set 2: include code to suspend/enable a subscriber Patch Set 3: validate FQDN of external MR Change-Id: I5c05791b020d389a0cfd672d81481d5295205c2f Signed-off-by: dglFromAtt Issue-ID: DMAAP-510 --- pom.xml | 2 +- .../onap/dmaap/dbcapi/client/DrProvConnection.java | 74 ++++++++++++++++++++++ .../java/org/onap/dmaap/dbcapi/model/DR_Sub.java | 3 +- .../onap/dmaap/dbcapi/resources/FeedResource.java | 3 +- .../onap/dmaap/dbcapi/service/DR_SubService.java | 11 +++- .../org/onap/dmaap/dbcapi/service/FeedService.java | 21 ++++-- .../onap/dmaap/dbcapi/service/TopicService.java | 21 ++++-- src/main/java/org/onap/dmaap/dbcapi/util/Fqdn.java | 42 ++++++++++++ version.properties | 2 +- 9 files changed, 162 insertions(+), 17 deletions(-) create mode 100644 src/main/java/org/onap/dmaap/dbcapi/util/Fqdn.java diff --git a/pom.xml b/pom.xml index a22096d..bf3b65a 100644 --- a/pom.xml +++ b/pom.xml @@ -344,7 +344,7 @@ UTF-8 9.3.9.v20160517 0.0.1 - 1.0.8-SNAPSHOT + 1.0.9-SNAPSHOT 0.7.7.201606060606 3.2 diff --git a/src/main/java/org/onap/dmaap/dbcapi/client/DrProvConnection.java b/src/main/java/org/onap/dmaap/dbcapi/client/DrProvConnection.java index 9807fba..751c5b8 100644 --- a/src/main/java/org/onap/dmaap/dbcapi/client/DrProvConnection.java +++ b/src/main/java/org/onap/dmaap/dbcapi/client/DrProvConnection.java @@ -778,6 +778,80 @@ public class DrProvConnection extends BaseLoggingClass { return responseBody; } + public String doDeleteDr_Sub(DR_Sub delSub, ApiError err) { + logger.info( "entry: doDeleteDr_Sub() " ); + byte[] postData = delSub.getBytes(); + logger.info( "post fields=" + postData ); + String responsemessage = null; + String responseBody = null; + + try { + + uc.setRequestMethod("DELETE"); + + uc.setRequestProperty("Content-Type", "application/vnd.att-dr.subscription"); + uc.setRequestProperty( "charset", "utf-8"); + uc.setRequestProperty( "X-ATT-DR-ON-BEHALF-OF", "DGL" ); + //uc.setRequestProperty( "Content-Length", Integer.toString( postData.length )); + uc.setUseCaches(false); + uc.setDoOutput(true); + OutputStream os = null; + int rc = -1; + + try { + uc.connect(); + os = uc.getOutputStream(); + //os.write( postData ); + + } catch (ProtocolException pe) { + // Rcvd error instead of 100-Continue + try { + // work around glitch in Java 1.7.0.21 and likely others + // without this, Java will connect multiple times to the server to run the same request + uc.setDoOutput(false); + } catch (Exception e) { + } + } + rc = uc.getResponseCode(); + logger.info( "http response code:" + rc ); + responsemessage = uc.getResponseMessage(); + logger.info( "responsemessage=" + responsemessage ); + + + if (responsemessage == null) { + // work around for glitch in Java 1.7.0.21 and likely others + // When Expect: 100 is set and a non-100 response is received, the response message is not set but the response code is + String h0 = uc.getHeaderField(0); + if (h0 != null) { + int i = h0.indexOf(' '); + int j = h0.indexOf(' ', i + 1); + if (i != -1 && j != -1) { + responsemessage = h0.substring(j + 1); + } + } + } + if (rc == 204 ) { + responseBody = bodyToString( uc.getInputStream() ); + logger.info( "responseBody=" + responseBody ); + + } else { + err.setCode(rc); + err.setMessage(responsemessage); + } + + } catch (ConnectException ce) { + errorLogger.error( DmaapbcLogMessageEnum.HTTP_CONNECTION_EXCEPTION, provURL, ce.getMessage() ); + err.setCode( 500 ); + err.setMessage("Backend connection refused"); + } catch (Exception e) { + System.err.println("Unable to read response " ); + e.printStackTrace(); + } finally { + uc.disconnect(); + } + return responseBody; + + } /* public static void main( String[] args ) throws Exception { PropertyConfigurator.configure("log4j.properties"); diff --git a/src/main/java/org/onap/dmaap/dbcapi/model/DR_Sub.java b/src/main/java/org/onap/dmaap/dbcapi/model/DR_Sub.java index 6d36a89..5a768c5 100644 --- a/src/main/java/org/onap/dmaap/dbcapi/model/DR_Sub.java +++ b/src/main/java/org/onap/dmaap/dbcapi/model/DR_Sub.java @@ -200,7 +200,8 @@ public class DR_Sub extends DmaapObject { // TODO: // - introduce Bus Controller API support for these attributes // - store the default values in the DB - String postJSON = String.format("{\"delivery\": {\"url\": \"%s\", \"user\": \"%s\", \"password\": \"%s\", \"use100\": \"%s\"}, \"metadataOnly\": %s, \"groupid\": \"%s\", \"follow_redirect\": %s }", + String postJSON = String.format("{\"suspend\": \"%s\", \"delivery\": {\"url\": \"%s\", \"user\": \"%s\", \"password\": \"%s\", \"use100\": \"%s\"}, \"metadataOnly\": %s, \"groupid\": \"%s\", \"follow_redirect\": %s }", + this.suspended, this.getDeliveryURL(), this.getUsername(), this.getUserpwd(), diff --git a/src/main/java/org/onap/dmaap/dbcapi/resources/FeedResource.java b/src/main/java/org/onap/dmaap/dbcapi/resources/FeedResource.java index eead1de..c0fdd0d 100644 --- a/src/main/java/org/onap/dmaap/dbcapi/resources/FeedResource.java +++ b/src/main/java/org/onap/dmaap/dbcapi/resources/FeedResource.java @@ -127,7 +127,8 @@ public class FeedResource extends BaseLoggingClass { return resp.error(); } } else if ( nfeed.getStatus() == DmaapObject_Status.DELETED ) { - nfeed = feedService.updateFeed(nfeed, resp.getErr()); + feed.setFeedId( nfeed.getFeedId()); + nfeed = feedService.updateFeed(feed, resp.getErr()); if ( nfeed != null ) { return resp.success(nfeed); } else { diff --git a/src/main/java/org/onap/dmaap/dbcapi/service/DR_SubService.java b/src/main/java/org/onap/dmaap/dbcapi/service/DR_SubService.java index 0fe1d9e..138ff57 100644 --- a/src/main/java/org/onap/dmaap/dbcapi/service/DR_SubService.java +++ b/src/main/java/org/onap/dmaap/dbcapi/service/DR_SubService.java @@ -167,14 +167,21 @@ public class DR_SubService extends BaseLoggingClass { public void removeDr_Sub( String key, ApiError apiError ) { logger.debug( "enter removeDR_Subs()"); + DR_Sub sub = dr_subs.get( key ); if ( sub == null ) { apiError.setCode(Status.NOT_FOUND.getStatusCode()); apiError.setFields( "subId"); apiError.setMessage("subId " + key + " not found"); } else { - dr_subs.remove(key); - apiError.setCode(200); + DrProvConnection prov = new DrProvConnection(); + prov.makeSubPutConnection( key ); + String resp = prov.doDeleteDr_Sub( sub, apiError ); + logger.debug( "resp=" + resp ); + + if ( apiError.is2xx() ) { + dr_subs.remove(key); + } } return; diff --git a/src/main/java/org/onap/dmaap/dbcapi/service/FeedService.java b/src/main/java/org/onap/dmaap/dbcapi/service/FeedService.java index 8332a35..18ca2c7 100644 --- a/src/main/java/org/onap/dmaap/dbcapi/service/FeedService.java +++ b/src/main/java/org/onap/dmaap/dbcapi/service/FeedService.java @@ -193,7 +193,7 @@ public class FeedService extends BaseLoggingClass { // need to save the Sub objects independently private boolean saveSubs( Feed fnew, Feed req ) { ArrayList subs = req.getSubs(); - if ( subs.size() == 0 ) { + if ( subs == null || subs.size() == 0 ) { logger.info( "No subs specified"); } else { DR_SubService subSvc = new DR_SubService( fnew.getSubscribeURL() ); @@ -393,12 +393,21 @@ public class FeedService extends BaseLoggingClass { } return feeds.remove(req.getFeedId()); } else { - req.setStatus(DmaapObject_Status.DELETED); - req.setPubs(null); + + logger.info( "Disable pubs for deleted feed - creating tmp pub"); + ArrayList tmppub = new ArrayList(); + tmppub.add( new DR_Pub( dcaeLocations.getCentralLocation()) + .setRandomUserName() + .setRandomPassword()); + req.setPubs(tmppub); req.setSubs(null); - req.setLastMod(); - feeds.put( req.getFeedId(), req ); - return null; + Feed fnew = updateFeed( req, err ); + if ( ! err.is2xx()) { + return req; + } + fnew.setStatus(DmaapObject_Status.DELETED); + feeds.put( fnew.getFeedId(), fnew ); + return null; } diff --git a/src/main/java/org/onap/dmaap/dbcapi/service/TopicService.java b/src/main/java/org/onap/dmaap/dbcapi/service/TopicService.java index d3c849c..eed5022 100644 --- a/src/main/java/org/onap/dmaap/dbcapi/service/TopicService.java +++ b/src/main/java/org/onap/dmaap/dbcapi/service/TopicService.java @@ -43,6 +43,7 @@ import org.onap.dmaap.dbcapi.model.ReplicationType; import org.onap.dmaap.dbcapi.model.Topic; import org.onap.dmaap.dbcapi.model.DmaapObject.DmaapObject_Status; import org.onap.dmaap.dbcapi.util.DmaapConfig; +import org.onap.dmaap.dbcapi.util.Fqdn; import org.onap.dmaap.dbcapi.util.Graph; public class TopicService extends BaseLoggingClass { @@ -124,6 +125,20 @@ public class TopicService extends BaseLoggingClass { return null; } } + if ( topic.getReplicationCase().involvesGlobal() ) { + if ( topic.getGlobalMrURL() == null ) { + topic.setGlobalMrURL(defaultGlobalMrHost); + } + if ( ! Fqdn.isValid( topic.getGlobalMrURL())) { + logger.error( "GlobalMR FQDN not valid: " + topic.getGlobalMrURL()); + topic.setStatus( DmaapObject_Status.INVALID); + err.setCode(500); + err.setMessage("Value is not a valid FQDN:" + topic.getGlobalMrURL() ); + err.setFields("globalMrURL"); + + return null; + } + } if ( topic.getNumClients() > 0 ) { @@ -146,11 +161,7 @@ public class TopicService extends BaseLoggingClass { topic.setClients(clients2); } - if ( topic.getReplicationCase().involvesGlobal() ) { - if ( topic.getGlobalMrURL() == null ) { - topic.setGlobalMrURL(defaultGlobalMrHost); - } - } + Topic ntopic = checkForBridge( topic, err ); if ( ntopic == null ) { topic.setStatus( DmaapObject_Status.INVALID); diff --git a/src/main/java/org/onap/dmaap/dbcapi/util/Fqdn.java b/src/main/java/org/onap/dmaap/dbcapi/util/Fqdn.java new file mode 100644 index 0000000..37715d3 --- /dev/null +++ b/src/main/java/org/onap/dmaap/dbcapi/util/Fqdn.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * org.onap.dmaap + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.dmaap.dbcapi.util; + +import java.util.regex.Pattern; + +import org.onap.dmaap.dbcapi.logging.BaseLoggingClass; + +public class Fqdn extends BaseLoggingClass { + // regexp value sourced from https://www.regextester.com/23 + static String regexp = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"; + + + public static boolean isValid( String s ) { + appLogger.info( "Fqdn testing: " + s ); + boolean b = false; + if ( s != null ) { + b = Pattern.matches( regexp, s); + } + appLogger.info( "Fqdn isValid=" + b ); + return b; + } + +} diff --git a/version.properties b/version.properties index f4cdd52..f1aed49 100644 --- a/version.properties +++ b/version.properties @@ -27,7 +27,7 @@ major=1 minor=0 -patch=8 +patch=9 base_version=${major}.${minor}.${patch} # Release must be completed with git revision # in Jenkins -- 2.16.6