Merge "Enable retries for the /authn/validate endpoint if it fails to connect"
diff --git a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/JU_BatchDataViewTest.java b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/JU_BatchDataViewTest.java
index 2ddd984..8ff2ec5 100644
--- a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/JU_BatchDataViewTest.java
+++ b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/JU_BatchDataViewTest.java
@@ -4,6 +4,9 @@
  * ===========================================================================
  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
  * ===========================================================================
+ * Modification Copyright © 2020 IBM.
+ * ===========================================================================
+ *
  * 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
@@ -21,7 +24,7 @@
 
 package org.onap.aaf.auth.batch.helpers;
 
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
 import static org.mockito.MockitoAnnotations.initMocks;
 
 import java.io.IOException;
@@ -71,57 +74,57 @@
     @Test
     public void testNs() {
         Result<NsDAO.Data> retVal = batchDataViewObj.ns(trans, "test");
-        assertTrue(retVal.status == 9);
+		assertEquals(9,retVal.status);
 
         NS n = new NS("test1", "test2", "test3", 1, 2);
         NS.data.put("test", n);
         retVal = batchDataViewObj.ns(trans, "test");
-        assertTrue(retVal.status == 0);
+		assertEquals(0,retVal.status);
     }
 
     @Test
     public void testRoleByName() {
         Result<RoleDAO.Data> retVal = batchDataViewObj.roleByName(trans,
                 "test");
-        assertTrue(retVal.status == 9);
+        assertEquals(9,retVal.status);
 
         Role n = new Role("test1");
         n.rdd = new RoleDAO.Data();
         Role.byName.put("test", n);
         retVal = batchDataViewObj.roleByName(trans, "test");
-        assertTrue(retVal.status == 0);
+        assertEquals(0,retVal.status);
 
         n.rdd = null;
         Role.byName.put("test", n);
         retVal = batchDataViewObj.roleByName(trans, "test");
-        assertTrue(retVal.status == 9);
+        assertEquals(9,retVal.status);
     }
     @Test
     public void testUrsByRole() {
         Result<List<UserRoleDAO.Data>> retVal = batchDataViewObj
                 .ursByRole(trans, "test");
-        assertTrue(retVal.status == 9);
+        assertEquals(9,retVal.status);
 
         Role n = new Role("test1");
         n.rdd = new RoleDAO.Data();
         UserRole ur = new UserRole("user", "role", "ns", "rname", new Date());
         (new UserRole.DataLoadVisitor()).visit(ur);
         retVal = batchDataViewObj.ursByRole(trans, "role");
-        assertTrue(retVal.status == 0);
+        assertEquals(retVal.status,0);
 
     }
     @Test
     public void testUrsByUser() {
         Result<List<UserRoleDAO.Data>> retVal = batchDataViewObj
                 .ursByUser(trans, "test");
-        assertTrue(retVal.status == 9);
+        assertEquals(retVal.status,9);
 
         Role n = new Role("test1");
         n.rdd = new RoleDAO.Data();
         UserRole ur = new UserRole("user", "role", "ns", "rname", new Date());
         (new UserRole.DataLoadVisitor()).visit(ur);
         retVal = batchDataViewObj.ursByUser(trans, "user");
-        assertTrue(retVal.status == 0);
+        assertEquals(retVal.status,0);
 
     }
     @Test
@@ -129,7 +132,7 @@
         FutureDAO.Data dataObj = new FutureDAO.Data();
         dataObj.id = new UUID(1000L, 1000L);
         Result<FutureDAO.Data> retVal = batchDataViewObj.delete(trans, dataObj);
-        assertTrue(retVal.status == 0);
+        assertEquals(retVal.status,0);
 
     }
     @Test
@@ -138,7 +141,7 @@
         dataObj.id = new UUID(1000L, 1000L);
         Result<ApprovalDAO.Data> retVal = batchDataViewObj.delete(trans,
                 dataObj);
-        assertTrue(retVal.status == 0);
+        assertEquals(retVal.status, 0);
 
     }
 
@@ -150,7 +153,7 @@
         dataObj.ticket = new UUID(1000L, 1000L);
         Result<ApprovalDAO.Data> retVal = batchDataViewObj.insert(trans,
                 dataObj);
-        assertTrue(retVal.status == 0);
+        assertEquals(retVal.status, 0);
 
     }
     @Test
@@ -160,11 +163,11 @@
         dataObj.memo = "memo";
         dataObj.construct = ByteBuffer.allocate(1000);
         Result<FutureDAO.Data> retVal = batchDataViewObj.insert(trans, dataObj);
-        assertTrue(retVal.status == 0);
+        assertEquals(retVal.status, 0);
 
         dataObj.target_key = "memo";
         retVal = batchDataViewObj.insert(trans, dataObj);
-        assertTrue(retVal.status == 0);
+        assertEquals(retVal.status, 0);
     }
     @Test
     public void testFlush() {
diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java
index e5cde35..761ebec 100644
--- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java
+++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java
@@ -759,7 +759,7 @@
             }
 
             for (CredDAO.Data cd : cdr.value) {
-                if (cd.expires.after(now)) {
+                if (cd.expires.after(now) || trans.org().isUserExpireExempt(cd.id, cd.expires)) {
                     return Result.ok();
                 }
             }
@@ -1440,7 +1440,7 @@
         List<UserRoleDAO.Data> list = rurdd.value;
         List<String> rv = new ArrayList<>(list.size()); // presize
         for (UserRoleDAO.Data urdd : rurdd.value) {
-            if (includeExpired || urdd.expires.after(now)) {
+            if (includeExpired || urdd.expires.after(now) || trans.org().isUserExpireExempt(urdd.user, urdd.expires)) {
                 rv.add(urdd.user);
             }
         }
diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java
index 39578f8..2e8e55f 100644
--- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java
+++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java
@@ -938,7 +938,7 @@
                     if (!cdd.id.equals(user)) {
                         trans.error().log("doesUserCredMatch DB call does not match for user: " + user);
                     }
-                    if (cdd.expires.after(now)) {
+                    if (cdd.expires.after(now) || trans.org().isUserExpireExempt(cdd.id, cdd.expires)) {
                         byte[] dbcred = cdd.cred.array();
 
                         try {
@@ -1273,7 +1273,7 @@
         if (rur.isOKhasData()) {
             Date now = new Date();
             for (UserRoleDAO.Data urdd : rur.value){
-                if (urdd.expires.after(now)) {
+                if (urdd.expires.after(now) || trans.org().isUserExpireExempt(urdd.user, urdd.expires)) {
                     return true;
                 }
             }
@@ -1285,7 +1285,7 @@
         Result<List<UserRoleDAO.Data>> rur = userRoleDAO().read(trans, user,ns+DOT_OWNER);
         if (rur.isOKhasData()) {for (UserRoleDAO.Data urdd : rur.value){
             Date now = new Date();
-            if (urdd.expires.after(now)) {
+            if (urdd.expires.after(now) || trans.org().isUserExpireExempt(urdd.user, urdd.expires)) {
                 return true;
             }
         }};
@@ -1297,7 +1297,7 @@
         Date now = new Date();
         int count = 0;
         if (rur.isOKhasData()) {for (UserRoleDAO.Data urdd : rur.value){
-            if (urdd.expires.after(now)) {
+            if (urdd.expires.after(now) || trans.org().isUserExpireExempt(urdd.user, urdd.expires)) {
                 ++count;
             }
         }};
diff --git a/auth/auth-cmd/pom.xml b/auth/auth-cmd/pom.xml
index 7133a5b..01ec4ec 100644
--- a/auth/auth-cmd/pom.xml
+++ b/auth/auth-cmd/pom.xml
@@ -178,7 +178,11 @@
             <artifactId>jline</artifactId>
             <version>2.14.2</version>
         </dependency>
-
+        <dependency>		
+			<groupId>org.owasp.encoder</groupId>		
+			<artifactId>encoder</artifactId>		
+			<version>1.2.1</version>		
+		</dependency>
     </dependencies>
 
     <distributionManagement>
diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/Cmd.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/Cmd.java
index 0ae4ce9..40616ab 100644
--- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/Cmd.java
+++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/Cmd.java
@@ -54,6 +54,7 @@
 import aaf.v2_0.History.Item;
 import aaf.v2_0.Request;
 
+import org.owasp.encoder.Encode;
 
 public abstract class Cmd {
     // Sonar claims DateFormat is not thread safe.  Leave as Instance Variable.
@@ -272,7 +273,7 @@
             sb.append(", ");
             sb.append(desc);
         }
-        pw().println(sb);
+        pw().println(Encode.forJava(sb.toString()));
     }
 
 
diff --git a/auth/auth-core/pom.xml b/auth/auth-core/pom.xml
index 884ecbe..972b12c 100644
--- a/auth/auth-core/pom.xml
+++ b/auth/auth-core/pom.xml
@@ -107,6 +107,11 @@
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-log4j12</artifactId>
         </dependency>
+        <dependency>		
+			<groupId>org.owasp.encoder</groupId>		
+			<artifactId>encoder</artifactId>		
+			<version>1.2.1</version>		
+		</dependency>
     </dependencies>
     
     <build>
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Organization.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Organization.java
index 795231e..778eb29 100644
--- a/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Organization.java
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Organization.java
@@ -349,8 +349,8 @@
     public void setTestMode(boolean dryRun);
 
     /**
-     * Evaluates a user to determine if they are exempt from role expiration.
-     * Returns true if true, false is false. Default implementation is always false.
+     * Evaluates a user to determine if they are exempt from role and cred expiration.
+     * Returns true if true, false if false. Default implementation is always false.
      *
      * @param user
      * @param expires
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CachingFileAccess.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CachingFileAccess.java
index cdda50d..b342c42 100644
--- a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CachingFileAccess.java
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CachingFileAccess.java
@@ -53,6 +53,7 @@
 import org.onap.aaf.misc.env.LogTarget;
 import org.onap.aaf.misc.env.Store;
 import org.onap.aaf.misc.env.Trans;
+import org.owasp.encoder.Encode;
 /*
  * CachingFileAccess
  *
@@ -429,9 +430,9 @@
                     w.append(name);
                     w.append('/');
                 }
-                w.append(f.getName());
+                w.append(Encode.forJava(f.getName()));
                 w.append("\">");
-                w.append(f.getName());
+                w.append(Encode.forJava(f.getName()));
                 w.append("</a></li>\n");
             }
             w.append(F);
diff --git a/auth/auth-fs/pom.xml b/auth/auth-fs/pom.xml
index 39cb03b..943c108 100644
--- a/auth/auth-fs/pom.xml
+++ b/auth/auth-fs/pom.xml
@@ -76,6 +76,16 @@
             <groupId>org.onap.aaf.authz</groupId>
             <artifactId>aaf-cadi-core</artifactId>
         </dependency>
+         <dependency>	
+			<groupId>org.owasp.encoder</groupId>		
+			<artifactId>encoder</artifactId>		
+			<version>1.2.1</version>		
+		</dependency>	
+		<dependency>	
+            <groupId>org.owasp.esapi</groupId>	
+			<artifactId>esapi</artifactId>	
+			<version>2.0.1</version>	
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/auth/auth-fs/src/main/java/org/onap/aaf/auth/fs/AAF_FS.java b/auth/auth-fs/src/main/java/org/onap/aaf/auth/fs/AAF_FS.java
index 64d9353..fdedd6b 100644
--- a/auth/auth-fs/src/main/java/org/onap/aaf/auth/fs/AAF_FS.java
+++ b/auth/auth-fs/src/main/java/org/onap/aaf/auth/fs/AAF_FS.java
@@ -45,7 +45,7 @@
 import org.onap.aaf.cadi.register.Registrant;
 import org.onap.aaf.cadi.register.RemoteRegistrant;
 
-
+import org.owasp.esapi.reference.DefaultHTTPUtilities;
 
 public class AAF_FS extends AbsService<AuthzEnv, AuthzTrans>  {
 
@@ -82,7 +82,8 @@
         @Override
         public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
             trans.info().printf("Redirecting %s to HTTP/S %s", req.getRemoteAddr(), req.getLocalAddr());
-            resp.sendRedirect(url);
+            DefaultHTTPUtilities util = new DefaultHTTPUtilities();        	
+            util.sendRedirect(url);
         }
     };
 
diff --git a/auth/auth-hello/pom.xml b/auth/auth-hello/pom.xml
index 11971e0..f9a420f 100644
--- a/auth/auth-hello/pom.xml
+++ b/auth/auth-hello/pom.xml
@@ -55,7 +55,12 @@
             <groupId>org.onap.aaf.authz</groupId>
             <artifactId>aaf-cadi-aaf</artifactId>
         </dependency>
-
+		<dependency>		
+			<groupId>org.owasp.encoder</groupId>		
+			<artifactId>encoder</artifactId>		
+			<version>1.2.1</version>		
+		</dependency>
+		
     </dependencies>
 
     <build>
diff --git a/auth/auth-hello/src/main/java/org/onap/aaf/auth/hello/API_Hello.java b/auth/auth-hello/src/main/java/org/onap/aaf/auth/hello/API_Hello.java
index 4ffb178..cdaa6a7 100644
--- a/auth/auth-hello/src/main/java/org/onap/aaf/auth/hello/API_Hello.java
+++ b/auth/auth-hello/src/main/java/org/onap/aaf/auth/hello/API_Hello.java
@@ -35,6 +35,8 @@
 import org.onap.aaf.misc.env.Env;
 import org.onap.aaf.misc.env.TimeTaken;
 
+import org.owasp.encoder.Encode;
+
 /**
  * API Apis
  * @author Jonathan
@@ -70,7 +72,7 @@
                 String perm = pathParam(req, "perm");
                 if (perm!=null && perm.length()>0) {
                     os.print('(');
-                    os.print(req.getUserPrincipal().getName());
+                    os.print(Encode.forJava(req.getUserPrincipal().getName()));
                     TimeTaken tt = trans.start("Authorize perm", Env.REMOTE);
                     try {
                         if (req.isUserInRole(perm)) {
@@ -82,7 +84,7 @@
                         tt.done();
                     }
                     os.print("Permission: ");
-                    os.print(perm);
+                    os.print(Encode.forJava(perm));
                     os.print(')');
                 }
                 os.println();
@@ -144,7 +146,7 @@
                 }
                 sb.append("}");
                 ServletOutputStream os = resp.getOutputStream();
-                os.println(sb.toString());
+                os.println(Encode.forJava(sb.toString()));
                 trans.info().printf("Said 'RESTful Hello' to %s, Authentication type: %s",trans.getUserPrincipal().getName(),trans.getUserPrincipal().getClass().getSimpleName());
             }
         },APPLICATION_JSON);
@@ -164,7 +166,7 @@
                 trans.info().printf("Content from %s: %s\n", pathParam(req, ":id"),content);
                 if (content.startsWith("{") && content.endsWith("}")) {
                     resp.setStatus(200 /* OK */);
-                    resp.getOutputStream().print(content);
+                    resp.getOutputStream().print(Encode.forJava(content));
                 } else {
                     resp.getOutputStream().write(NOT_JSON);
                     resp.setStatus(406);
diff --git a/auth/auth-locate/pom.xml b/auth/auth-locate/pom.xml
index 2b6568b..3658598 100644
--- a/auth/auth-locate/pom.xml
+++ b/auth/auth-locate/pom.xml
@@ -78,6 +78,17 @@
             <groupId>org.onap.aaf.authz</groupId>
             <artifactId>aaf-misc-rosetta</artifactId>
         </dependency>
+        <dependency>		
+			<groupId>org.owasp.encoder</groupId>		
+			<artifactId>encoder</artifactId>		
+			<version>1.2.1</version>		
+		</dependency>
+		<dependency>	
+            <groupId>org.owasp.esapi</groupId>	
+			<artifactId>esapi</artifactId>	
+			<version>2.0.1</version>	
+        </dependency>
+        
     </dependencies>
 
     <build>
diff --git a/auth/auth-locate/src/main/java/org/onap/aaf/auth/locate/api/API_AAFAccess.java b/auth/auth-locate/src/main/java/org/onap/aaf/auth/locate/api/API_AAFAccess.java
index 36a987e..7b23c89 100644
--- a/auth/auth-locate/src/main/java/org/onap/aaf/auth/locate/api/API_AAFAccess.java
+++ b/auth/auth-locate/src/main/java/org/onap/aaf/auth/locate/api/API_AAFAccess.java
@@ -53,6 +53,9 @@
 import org.onap.aaf.misc.env.APIException;
 import org.onap.aaf.misc.env.Env;
 import org.onap.aaf.misc.env.TimeTaken;
+import org.owasp.esapi.errors.AccessControlException;
+import org.owasp.esapi.reference.DefaultHTTPUtilities;
+import org.owasp.encoder.Encode;
 
 public class API_AAFAccess {
 //    private static String service, version, envContext;
@@ -104,7 +107,7 @@
                                         ServletOutputStream sos;
                                         try {
                                             sos = resp.getOutputStream();
-                                            sos.print(fp.value);
+                                            sos.print(Encode.forJava(fp.value));
                                         } catch (IOException e) {
                                             throw new CadiException(e);
                                         }
@@ -122,7 +125,7 @@
                         User u = (User)d.data.get(0);
                         resp.setStatus(u.code);
                         ServletOutputStream sos = resp.getOutputStream();
-                        sos.print(u.resp);
+                        sos.print(Encode.forJava(u.resp));
                     }
                 } finally {
                     tt.done();
@@ -256,7 +259,7 @@
         });
     }
 
-    private static void redirect(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, LocateFacade context, Locator<URI> loc, String path) throws IOException {
+    private static void redirect(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, LocateFacade context, Locator<URI> loc, String path) throws IOException, AccessControlException {
         try {
             if (loc.hasItems()) {
                 Item item = loc.best();
@@ -270,7 +273,9 @@
                     redirectURL.append(str);
                 }
                 trans.info().log("Redirect to",redirectURL);
-                resp.sendRedirect(redirectURL.toString());
+                DefaultHTTPUtilities util = new DefaultHTTPUtilities();            	
+                util.sendRedirect(redirectURL.toString());                
+                //resp.sendRedirect(redirectURL.toString());
             } else {
                 context.error(trans, resp, Result.err(Result.ERR_NotFound,"No Locations found for redirection"));
             }
diff --git a/auth/auth-locate/src/main/java/org/onap/aaf/auth/locate/facade/LocateFacadeImpl.java b/auth/auth-locate/src/main/java/org/onap/aaf/auth/locate/facade/LocateFacadeImpl.java
index 6710708..047663c 100644
--- a/auth/auth-locate/src/main/java/org/onap/aaf/auth/locate/facade/LocateFacadeImpl.java
+++ b/auth/auth-locate/src/main/java/org/onap/aaf/auth/locate/facade/LocateFacadeImpl.java
@@ -59,6 +59,7 @@
 import org.onap.aaf.misc.env.TimeTaken;
 import org.onap.aaf.misc.rosetta.env.RosettaDF;
 import org.onap.aaf.misc.rosetta.env.RosettaData;
+import org.owasp.encoder.Encode;
 
 import locate_local.v1_0.Api;
 
@@ -266,7 +267,7 @@
         TimeTaken tt = trans.start(API_EXAMPLE, Env.SUB);
         try {
             String content =Examples.print(apiDF.getEnv(), nameOrContentType, optional);
-            resp.getOutputStream().print(content);
+            resp.getOutputStream().print(Encode.forJava(content));
             setContentType(resp,content.contains("<?xml")?TYPE.XML:TYPE.JSON);
             return Result.ok();
         } catch (Exception e) {
@@ -311,7 +312,7 @@
                     }
                 }
             }
-            resp.getOutputStream().println(output);
+            resp.getOutputStream().println(Encode.forJava(output));
             setContentType(resp,epDF.getOutType());
             return Result.ok();
         } catch (Exception e) {
diff --git a/cadi/client/src/main/java/org/onap/aaf/cadi/http/HClient.java b/cadi/client/src/main/java/org/onap/aaf/cadi/http/HClient.java
index c7b2605..898b99c 100644
--- a/cadi/client/src/main/java/org/onap/aaf/cadi/http/HClient.java
+++ b/cadi/client/src/main/java/org/onap/aaf/cadi/http/HClient.java
@@ -47,7 +47,7 @@
 import org.onap.aaf.misc.env.Data.TYPE;
 import org.onap.aaf.misc.env.util.Pool.Pooled;
 import org.onap.aaf.misc.rosetta.env.RosettaDF;
-
+import org.owasp.encoder.Encode;
 /**
  * Low Level Http Client Mechanism. Chances are, you want the high level "HRcli"
  * for Rosetta Object Translation
@@ -396,8 +396,10 @@
                     // reuse Buffers
                     Pooled<byte[]> pbuff = Rcli.buffPool.get();
                     try {
+                    	String strTemp;
                         while ((read=is.read(pbuff.content))>=0) {
-                            os.write(pbuff.content,0,read);
+                        	strTemp = new String(pbuff.content,0,read);                        	
+                        	os.write(Encode.forJava(strTemp).getBytes());
                         }
                     } finally {
                         pbuff.done();
@@ -412,8 +414,10 @@
                         errContent = new StringBuilder();
                         Pooled<byte[]> pbuff = Rcli.buffPool.get();
                         try {
+                        	String strTemp; 
                             while ((read=is.read(pbuff.content))>=0) {
-                                os.write(pbuff.content,0,read);
+                            	strTemp = new String(pbuff.content,0,read);                            	
+                            	os.write(Encode.forJava(strTemp).getBytes());
                             }
                         } finally {
                             pbuff.done();
diff --git a/docs/conf.py b/docs/conf.py
index 8f40e8b..5371015 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -12,4 +12,4 @@
 html_last_updated_fmt = '%d-%b-%y %H:%M'
 
 def setup(app):
-    app.add_stylesheet("css/ribbon_onap.css")
+    app.add_stylesheet("css/ribbon.css")
diff --git a/docs/sections/release-notes.rst b/docs/sections/release-notes.rst
index b7beed3..7981ed4 100644
--- a/docs/sections/release-notes.rst
+++ b/docs/sections/release-notes.rst
@@ -6,6 +6,25 @@
 Release Notes
 =============
 
+Version: 2.1.23 (Frankfurt, 6.0.0)
+---------------------------------------------
+
+:Release Date: 2020-06-05
+
+**New Features**
+Certificate Management Protocol Version 2 (CMPv2) support was added to retrieve X.509 certificates from servers which supports CMPv2 over HTTP. SDNC as first ONAP component was integrated to enroll certificate from CMPv2 server to protect traffic between SDNC and Network Functions (xNFs).
+More details about CMPv2 support in ONAP can be found on a dedicated page.
+
+
+**Bug Fixes**
+	- `AAF-383 <https://jira.onap.org/browse/AAF-383>`_ AAF aaf-sms chart should use nodePortPrefix variable
+	- `AAF-783 <https://jira.onap.org/browse/AAF-783>`_ Consul container is outdated
+    - `AAF-784 <https://jira.onap.org/browse/AAF-784>`_ Vault container is outdated
+    - `AAF-1102 <https://jira.onap.org/browse/AAF-1102>`_ Pods still run as root
+
+**Known Issues - solve in Guilin**
+    - `AAF-1087 <https://jira.onap.org/browse/AAF-1087>`_ AAF init containers init with exit 0 even if failing
+
 Version: 2.1.15 (El Alto, 5.0.1)
 ---------------------------------------------
 
diff --git a/misc/pom.xml b/misc/pom.xml
index 66851bc..61d4f5d 100644
--- a/misc/pom.xml
+++ b/misc/pom.xml
@@ -73,6 +73,12 @@
             <artifactId>junit</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>		
+			<groupId>org.owasp.encoder</groupId>		
+			<artifactId>encoder</artifactId>		
+			<version>1.2.1</version>		
+		</dependency>
+        
     </dependencies>
 
     <modules>
diff --git a/misc/xgen/pom.xml b/misc/xgen/pom.xml
index d24e851..d4183fb 100644
--- a/misc/xgen/pom.xml
+++ b/misc/xgen/pom.xml
@@ -78,6 +78,11 @@
             <artifactId>aaf-misc-env</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>		
+			<groupId>org.owasp.encoder</groupId>		
+			<artifactId>encoder</artifactId>		
+			<version>1.2.1</version>		
+		</dependency>        
     </dependencies>
     
     <!-- ============================================================== -->
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Section.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Section.java
index 9f1f2a3..0d41bd9 100644
--- a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Section.java
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Section.java
@@ -28,6 +28,7 @@
 import org.onap.aaf.misc.env.Env;

 import org.onap.aaf.misc.env.Trans;

 import org.onap.aaf.misc.xgen.html.State;

+import org.owasp.encoder.Encode;

 

 public class Section<G extends XGen<G>> {

     protected int indent;

@@ -48,11 +49,11 @@
     }

 

     public void forward(Writer w) throws IOException {

-        w.write(forward);

+    	w.write(Encode.forJava(forward));

     }

     

     public void back(Writer w) throws IOException {

-        w.write(backward);

+    	w.write(Encode.forJava(backward));

     }

     

     public String toString() {