Actually remove pubs and subs on Feed delete 57/55157/3
authordglFromAtt <dgl@research.att.com>
Wed, 20 Jun 2018 02:03:48 +0000 (22:03 -0400)
committerdglFromAtt <dgl@research.att.com>
Fri, 22 Jun 2018 18:07:11 +0000 (14:07 -0400)
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 <dgl@research.att.com>
Issue-ID: DMAAP-510

pom.xml
src/main/java/org/onap/dmaap/dbcapi/client/DrProvConnection.java
src/main/java/org/onap/dmaap/dbcapi/model/DR_Sub.java
src/main/java/org/onap/dmaap/dbcapi/resources/FeedResource.java
src/main/java/org/onap/dmaap/dbcapi/service/DR_SubService.java
src/main/java/org/onap/dmaap/dbcapi/service/FeedService.java
src/main/java/org/onap/dmaap/dbcapi/service/TopicService.java
src/main/java/org/onap/dmaap/dbcapi/util/Fqdn.java [new file with mode: 0644]
version.properties

diff --git a/pom.xml b/pom.xml
index a22096d..bf3b65a 100644 (file)
--- a/pom.xml
+++ b/pom.xml
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <jettyVersion>9.3.9.v20160517</jettyVersion> 
                <eelf.version>0.0.1</eelf.version>
-               <artifact.version>1.0.8-SNAPSHOT</artifact.version>
+               <artifact.version>1.0.9-SNAPSHOT</artifact.version>
                <!-- SONAR -->
                <jacoco.version>0.7.7.201606060606</jacoco.version>
                <sonar-jacoco-listeners.version>3.2</sonar-jacoco-listeners.version>
index 9807fba..751c5b8 100644 (file)
@@ -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");
index 6d36a89..5a768c5 100644 (file)
@@ -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(),
index eead1de..c0fdd0d 100644 (file)
@@ -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 {
index 0fe1d9e..138ff57 100644 (file)
@@ -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;
index 8332a35..18ca2c7 100644 (file)
@@ -193,7 +193,7 @@ public class FeedService  extends BaseLoggingClass {
        // need to save the Sub objects independently
        private boolean saveSubs( Feed fnew, Feed req ) {       
                ArrayList<DR_Sub> 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<DR_Pub> tmppub = new ArrayList<DR_Pub>();
+                       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;    
                }
 
                
index d3c849c..eed5022 100644 (file)
@@ -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 (file)
index 0000000..37715d3
--- /dev/null
@@ -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;
+       }
+
+}
index f4cdd52..f1aed49 100644 (file)
@@ -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