This is an automated email from the ASF dual-hosted git repository.

madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new 7a22b82a5 RANGER-4138 Build ranger-react UI and backbone UI code base 
in webapp
7a22b82a5 is described below

commit 7a22b82a5c97406e80a9c9aeff5f2c1c289f470d
Author: Mugdha Varadkar <mug...@apache.org>
AuthorDate: Mon Mar 20 15:33:01 2023 +0530

    RANGER-4138 Build ranger-react UI and backbone UI code base in webapp
    
    Signed-off-by: Madhan Neethiraj <mad...@apache.org>
---
 security-admin/pom.xml                             | 1086 ++++++++------------
 .../webapp/{index.html => backbone-index.html}     |    0
 .../main/webapp/react-webapp/src/views/Header.jsx  |   11 +-
 .../react-webapp/src/views/SideBar/SideBarBody.jsx |   14 +-
 .../main/webapp/scripts/views/common/ProfileBar.js |    3 +-
 .../webapp/templates/common/ProfileBar_tmpl.html   |    5 +-
 6 files changed, 439 insertions(+), 680 deletions(-)

diff --git a/security-admin/pom.xml b/security-admin/pom.xml
index 08d289590..05fa7d836 100644
--- a/security-admin/pom.xml
+++ b/security-admin/pom.xml
@@ -801,344 +801,29 @@
                 <filtering>true</filtering>
             </resource>
         </resources>
-    </build>
 
-    <profiles>
-        <profile>
-            <id>security-admin-backbone</id>
-            <activation>
-                <activeByDefault>true</activeByDefault>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-war-plugin</artifactId>
-                        <version>2.6</version>
-                        <executions>
-                            <execution>
-                                <id>prepare</id>
-                                <phase>prepare-package</phase>
-                                <goals>
-                                    <goal>exploded</goal>
-                                </goals>
-                                <configuration>
-                                    
<warSourceExcludes>react-webapp/**</warSourceExcludes>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>default-war</id>
-                                <phase>package</phase>
-                                <goals>
-                                    <goal>war</goal>
-                                </goals>
-                                <configuration>
-                                    <packagingExcludes>
-                                        WEB-INF/lib/spring-*.SEC03.jar,
-                                        WEB-INF/lib/spring-*.RC3.jar,
-                                        WEB-INF/lib/spring-2.*.jar,
-                                        WEB-INF/lib/jetty-*.jar
-                                    </packagingExcludes>
-                                    
<warSourceDirectory>${project.build.directory}/${project.build.finalName}</warSourceDirectory>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        
<groupId>com.google.code.maven-replacer-plugin</groupId>
-                        <artifactId>replacer</artifactId>
-                        <version>1.5.3</version>
-                        <executions>
-                            <execution>
-                                <phase>prepare-package</phase>
-                                <goals>
-                                    <goal>replace</goal>
-                                </goals>
-                                <configuration>
-                                    
<basedir>${project.build.directory}/${project.build.finalName}</basedir>
-                                    <includes>
-                                        <include>index.html</include>
-                                        <include>scripts/Init.js</include>
-                                    </includes>
-                                    <replacements>
-                                        <replacement>
-                                            <token>build.version</token>
-                                            <value>${project.version}</value>
-                                        </replacement>
-                                        <replacement>
-                                            <token>(?m)\&lt;\!-- *dev 
*--\>(.*)$</token>
-                                            <value>\&lt;\!-- dev $1 
--\></value>
-                                        </replacement>
-                                        <replacement>
-                                            <token>\&lt;\!-- *prod *(.*) 
*--\></token>
-                                            <value>\&lt;\!-- prod 
--\>$1</value>
-                                        </replacement>
-                                    </replacements>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>com.webcohesion.enunciate</groupId>
-                        <artifactId>enunciate-maven-plugin</artifactId>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <version>2.6</version>
+                <executions>
+                    <execution>
+                        <id>prepare</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>exploded</goal>
+                        </goals>
                         <configuration>
-                            
<configFile>${basedir}/../enunciate.xml</configFile>
-                            <docsDir>${basedir}/../docs/target/</docsDir>
+                            
<warSourceExcludes>react-webapp/**</warSourceExcludes>
                         </configuration>
-                        <dependencies>
-                            <!-- dependency management version doesn't apply 
here, need to repeat the version numbers -->
-                            <dependency>
-                                <groupId>javax.xml.bind</groupId>
-                                <artifactId>jaxb-api</artifactId>
-                                <version>${jaxb.api.version}</version>
-                            </dependency>
-                            <dependency>
-                                <groupId>javax.jws</groupId>
-                                <artifactId>javax.jws-api</artifactId>
-                                <version>1.1</version>
-                            </dependency>
-                        </dependencies>
-                    </plugin>
-                    <plugin>
-                        <artifactId>maven-resources-plugin</artifactId>
-                        <version>2.7</version>
-                        <executions>
-                            <execution>
-                                <id>copy-resources</id>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <phase>validate</phase>
-                                <configuration>
-                                    
<outputDirectory>${project.build.directory}/jsmain</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            
<directory>${basedir}/src/main/webapp</directory>
-                                            <includes>
-                                                <include>package.json</include>
-                                                
<include>package-lock.json</include>
-                                            </includes>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>copy-js-test-resources</id>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <phase>validate</phase>
-                                <configuration>
-                                    
<outputDirectory>${project.build.directory}/jstest</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            
<directory>${basedir}/src/test/javascript</directory>
-                                            <includes>
-                                                <include>package.json</include>
-                                                
<include>package-lock.json</include>
-                                            </includes>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>com.github.eirslett</groupId>
-                        <artifactId>frontend-maven-plugin</artifactId>
-                        <version>1.12.1</version>
-                        <configuration>
-                            
<workingDirectory>${project.build.directory}</workingDirectory>
-                            
<installDirectory>${project.build.directory}</installDirectory>
-                        </configuration>
-                        <executions>
-                            <execution>
-                                <phase>process-resources</phase>
-                                <id>install node and npm</id>
-                                <goals>
-                                    <goal>install-node-and-npm</goal>
-                                </goals>
-                                <configuration>
-                                    <nodeVersion>v8.12.0</nodeVersion>
-                                    <npmVersion>6.4.1</npmVersion>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <phase>prepare-package</phase>
-                                <id>npm install for packaging</id>
-                                <goals>
-                                    <goal>npm</goal>
-                                </goals>
-                                <configuration>
-                                    
<workingDirectory>${project.build.directory}/jsmain</workingDirectory>
-                                    <arguments>install</arguments>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <phase>prepare-package</phase>
-                                <id>npm run r.js</id>
-                                <goals>
-                                    <goal>npm</goal>
-                                </goals>
-                                <configuration>
-                                    
<workingDirectory>${project.build.directory}/jsmain</workingDirectory>
-                                    <arguments>run r.js -- -o 
../${project.build.finalName}/minify.build.js</arguments>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <phase>test</phase>
-                                <id>npm install for tests</id>
-                                <goals>
-                                    <goal>npm</goal>
-                                </goals>
-                                <configuration>
-                                    <skip>${skipJSTests}</skip>
-                                    
<workingDirectory>${project.build.directory}/jstest</workingDirectory>
-                                    <arguments>install</arguments>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <phase>test</phase>
-                                <id>karma dev</id>
-                                <goals>
-                                    <goal>karma</goal>
-                                </goals>
-                                <configuration>
-                                    <skip>${skipJSTests}</skip>
-                                    
<workingDirectory>${project.build.directory}/jstest</workingDirectory>
-                                    
<karmaConfPath>../../src/test/javascript/karma-dev.conf.js</karmaConfPath>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <phase>integration-test</phase>
-                                <id>karma prd</id>
-                                <goals>
-                                    <goal>karma</goal>
-                                </goals>
-                                <configuration>
-                                    <environmentVariables>
-                                        
<buildDir>${project.build.finalName}</buildDir>
-                                    </environmentVariables>
-                                    <skip>${skipJSTests}</skip>
-                                    
<workingDirectory>${project.build.directory}/jstest</workingDirectory>
-                                    
<karmaConfPath>../../src/test/javascript/karma-prd.conf.js</karmaConfPath>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-
-                    <!-- duplicate SQL patch file version validator plugin -->
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-enforcer-plugin</artifactId>
-                        <version>1.4.1</version>
-                        <executions>
-                            <execution>
-                                
<id>duplicate-sql-patch-file-version-validator</id>
-                                <goals>
-                                    <goal>enforce</goal>
-                                </goals>
-                                <phase>validate</phase>
-                                <configuration>
-                                    <rules>
-                                        <evaluateBeanshell>
-                                            <message>Looks like there are 
multiple SQL files with same version number prefix. Update prefix and build 
again.</message>
-                                            <condition>
-                                                List sqlFilePaths = 
org.codehaus.plexus.util.FileUtils.getFileNames(new File("security-admin/db"), 
"**/*.sql", null, false);
-                                                Map sqlFileMap    = new 
HashMap();
-                                                Boolean noDupPrfx = true;
-
-                                                for (Iterator it = 
sqlFilePaths.iterator(); it.hasNext();) {
-                                                    String currentSqlFilePath 
= it.next();
-
-                                                    if 
(currentSqlFilePath.contains("patches")) {
-                                                        String [] array      = 
currentSqlFilePath.split("/");
-                                                        String db            = 
array[0];
-                                                        String patch         = 
array[(array.length - 1)];
-                                                        Boolean prfxWithNums = 
java.util.regex.Pattern.matches("^[0-9]{3}-([a-zA-Z]+[-_]*)+.sql$", patch);
-
-                                                        if (prfxWithNums) {
-                                                            String sqlFile = 
sqlFileMap.get(db + "-" + patch.split("-")[0]);
-
-                                                            if (sqlFile == 
null) {
-                                                                
sqlFileMap.put(db + "-" + patch.split("-")[0], currentSqlFilePath);
-                                                            } else {
-                                                                
print("Multiple SQL files with combination: [DB=" + db + "] [VersionPrefix=" + 
patch.split("-")[0] + "] found, hence triggering build failure.");
-                                                                print("Review 
prefixs for following files.");
-                                                                print("1. " + 
sqlFile);
-                                                                print("2. " + 
currentSqlFilePath);
-                                                                noDupPrfx = 
false;
-                                                            };
-                                                        };
-                                                    };
-                                                };
-
-                                                noDupPrfx
-                                            </condition>
-                                        </evaluateBeanshell>
-                                    </rules>
-                                    <fail>true</fail>
-                                </configuration>
-                            </execution>
-
-                            <!-- duplicate JAVA patch file version validator 
plugin -->
-                            <execution>
-                                
<id>duplicate-java-patch-file-version-validator</id>
-                                <goals>
-                                    <goal>enforce</goal>
-                                </goals>
-                                <phase>validate</phase>
-                                <configuration>
-                                    <rules>
-                                        <evaluateBeanshell>
-                                            <message>Looks like there are 
multiple JAVA files with same version number suffix. Update suffix and build 
again.</message>
-                                            <condition>
-                                                List javaFilePaths  = 
org.codehaus.plexus.util.FileUtils.getFileNames(new 
File("security-admin/src/main/java/org/apache/ranger/patch"), "**/*.java", 
null, false);
-                                                Map javaFileMap     = new 
HashMap();
-                                                Boolean noDupSuffix = true;
-
-                                                for (Iterator it = 
javaFilePaths.iterator(); it.hasNext();) {
-                                                    String currentJavaFilePath 
= it.next();
-
-                                                    if 
(currentJavaFilePath.startsWith("Patch")) {
-                                                        String versionSuffix = 
currentJavaFilePath.split("_J")[1];
-                                                        String javaFile      = 
javaFileMap.get(versionSuffix);
-
-                                                        if (javaFile == null) {
-                                                            
javaFileMap.put(versionSuffix, currentJavaFilePath);
-                                                        } else {
-                                                            print("Multiple 
JAVA files with suffix: " + versionSuffix + " found, hence triggering build 
failure.");
-                                                            print("Review 
suffixes for following files.");
-                                                            print("1. " + 
javaFile);
-                                                            print("2. " + 
currentJavaFilePath);
-                                                            noDupSuffix = 
false;
-                                                        };
-                                                    };
-                                                };
-
-                                                noDupSuffix
-                                            </condition>
-                                        </evaluateBeanshell>
-                                    </rules>
-                                    <fail>true</fail>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>security-admin-react</id>
-            <activation>
-                <activeByDefault>false</activeByDefault>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-war-plugin</artifactId>
-                        <version>2.6</version>
+                    </execution>
+                    <execution>
+                        <id>default-war</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>war</goal>
+                        </goals>
                         <configuration>
                             <packagingExcludes>
                                 WEB-INF/lib/spring-*.SEC03.jar,
@@ -1148,359 +833,420 @@
                             </packagingExcludes>
                             
<warSourceDirectory>${project.build.directory}/${project.build.finalName}</warSourceDirectory>
                         </configuration>
-                    </plugin>
-                    <plugin>
-                        <groupId>com.webcohesion.enunciate</groupId>
-                        <artifactId>enunciate-maven-plugin</artifactId>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>com.google.code.maven-replacer-plugin</groupId>
+                <artifactId>replacer</artifactId>
+                <version>1.5.3</version>
+                <executions>
+                    <execution>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>replace</goal>
+                        </goals>
+                        <configuration>
+                            
<basedir>${project.build.directory}/${project.build.finalName}</basedir>
+                            <includes>
+                                <include>backbone-index.html</include>
+                                <include>scripts/Init.js</include>
+                            </includes>
+                            <replacements>
+                                <replacement>
+                                    <token>build.version</token>
+                                    <value>${project.version}</value>
+                                </replacement>
+                                <replacement>
+                                    <token>(?m)\&lt;\!-- *dev 
*--\>(.*)$</token>
+                                    <value>\&lt;\!-- dev $1 --\></value>
+                                </replacement>
+                                <replacement>
+                                    <token>\&lt;\!-- *prod *(.*) *--\></token>
+                                    <value>\&lt;\!-- prod --\>$1</value>
+                                </replacement>
+                            </replacements>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>com.webcohesion.enunciate</groupId>
+                <artifactId>enunciate-maven-plugin</artifactId>
+                <configuration>
+                    <configFile>${basedir}/../enunciate.xml</configFile>
+                    <docsDir>${basedir}/../docs/target/</docsDir>
+                </configuration>
+                <dependencies>
+                    <!-- dependency management version doesn't apply here, 
need to repeat the version numbers -->
+                    <dependency>
+                        <groupId>javax.xml.bind</groupId>
+                        <artifactId>jaxb-api</artifactId>
+                        <version>${jaxb.api.version}</version>
+                    </dependency>
+                    <dependency>
+                        <groupId>javax.jws</groupId>
+                        <artifactId>javax.jws-api</artifactId>
+                        <version>1.1</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <version>2.7</version>
+                <executions>
+                    <execution>
+                        <id>copy-resources</id>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <phase>validate</phase>
+                        <configuration>
+                            
<outputDirectory>${project.build.directory}/jsmain</outputDirectory>
+                            <resources>
+                                <resource>
+                                    
<directory>${basedir}/src/main/webapp</directory>
+                                    <includes>
+                                        <include>package.json</include>
+                                        <include>package-lock.json</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>copy-js-test-resources</id>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <phase>validate</phase>
+                        <configuration>
+                            
<outputDirectory>${project.build.directory}/jstest</outputDirectory>
+                            <resources>
+                                <resource>
+                                    
<directory>${basedir}/src/test/javascript</directory>
+                                    <includes>
+                                        <include>package.json</include>
+                                        <include>package-lock.json</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                    <!-- react-webapp copy-resources execution start -->
+                    <execution>
+                        <id>copy-resources-react-webapp</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            
<outputDirectory>${project.build.directory}/react-webapp</outputDirectory>
+                            <resources>
+                                <resource>
+                                    
<directory>${project.basedir}/src/main/webapp/react-webapp/</directory>
+                                    <filtering>false</filtering>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>copy-resources-react-webapp-dist</id>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            
<outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory>
+                            <resources>
+                                <resource>
+                                    
<directory>${project.build.directory}/react-webapp/dist/</directory>
+                                    <filtering>false</filtering>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>copy-resources-react-webapp-index-html</id>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            
<outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory>
+                            <resources>
+                                <resource>
+                                    
<directory>${project.basedir}/src/main/webapp/react-webapp/src/</directory>
+                                    <includes>
+                                        <include>index.html</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>copy-resources-react-webapp-login-jsp-styles</id>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            
<outputDirectory>${project.build.directory}/${project.build.finalName}/styles</outputDirectory>
+                            <resources>
+                                <resource>
+                                    
<directory>${project.basedir}/src/main/webapp/styles</directory>
+                                    <includes>
+                                        <include>bootstrap.min.css</include>
+                                        <include>font-awesome.min.css</include>
+                                        <include>xa.css</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>copy-resources-react-webapp-login-jsp-images</id>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            
<outputDirectory>${project.build.directory}/${project.build.finalName}/images</outputDirectory>
+                            <resources>
+                                <resource>
+                                    
<directory>${project.basedir}/src/main/webapp/images</directory>
+                                    <includes>
+                                        <include>ranger_logo.png</include>
+                                        <include>favicon.ico</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                    <!-- react-webapp copy-resources execution end -->
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>com.github.eirslett</groupId>
+                <artifactId>frontend-maven-plugin</artifactId>
+                <version>1.12.1</version>
+                <configuration>
+                    
<workingDirectory>${project.build.directory}</workingDirectory>
+                    
<installDirectory>${project.build.directory}</installDirectory>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>process-resources</phase>
+                        <id>install node and npm</id>
+                        <goals>
+                            <goal>install-node-and-npm</goal>
+                        </goals>
+                        <configuration>
+                            <nodeVersion>v8.12.0</nodeVersion>
+                            <npmVersion>6.4.1</npmVersion>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <phase>prepare-package</phase>
+                        <id>npm install for packaging</id>
+                        <goals>
+                            <goal>npm</goal>
+                        </goals>
+                        <configuration>
+                            
<workingDirectory>${project.build.directory}/jsmain</workingDirectory>
+                            <arguments>install</arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <phase>prepare-package</phase>
+                        <id>npm run r.js</id>
+                        <goals>
+                            <goal>npm</goal>
+                        </goals>
+                        <configuration>
+                            
<workingDirectory>${project.build.directory}/jsmain</workingDirectory>
+                            <arguments>run r.js -- -o 
../${project.build.finalName}/minify.build.js</arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <phase>test</phase>
+                        <id>npm install for tests</id>
+                        <goals>
+                            <goal>npm</goal>
+                        </goals>
                         <configuration>
-                            
<configFile>${basedir}/../enunciate.xml</configFile>
-                            <docsDir>${basedir}/../docs/target/</docsDir>
+                            <skip>${skipJSTests}</skip>
+                            
<workingDirectory>${project.build.directory}/jstest</workingDirectory>
+                            <arguments>install</arguments>
                         </configuration>
-                        <dependencies>
-                            <!-- dependency management version doesn't apply 
here, need to repeat the version numbers -->
-                            <dependency>
-                                <groupId>javax.xml.bind</groupId>
-                                <artifactId>jaxb-api</artifactId>
-                                <version>${jaxb.api.version}</version>
-                            </dependency>
-                            <dependency>
-                                <groupId>javax.jws</groupId>
-                                <artifactId>javax.jws-api</artifactId>
-                                <version>1.1</version>
-                            </dependency>
-                        </dependencies>
-                    </plugin>
-                    <plugin>
-                        <artifactId>maven-resources-plugin</artifactId>
-                        <version>2.7</version>
-                        <executions>
-                            <!-- react-webapp copy-resources execution start 
-->
-                            <execution>
-                                <id>copy-resources-react-webapp</id>
-                                <phase>generate-sources</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    
<outputDirectory>${project.build.directory}/react-webapp</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            
<directory>${project.basedir}/src/main/webapp/react-webapp/</directory>
-                                            <filtering>false</filtering>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>copy-resources-react-webapp-dist</id>
-                                <phase>process-resources</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    
<outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            
<directory>${project.build.directory}/react-webapp/dist/</directory>
-                                            <filtering>false</filtering>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>copy-resources-react-webapp-WEB-INF</id>
-                                <phase>process-resources</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            
<directory>${project.basedir}/src/main/webapp/WEB-INF/</directory>
-                                            <filtering>false</filtering>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>copy-resources-react-webapp-META-INF</id>
-                                <phase>process-resources</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    
<outputDirectory>${project.build.directory}/${project.build.finalName}/META-INF</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            
<directory>${project.basedir}/src/main/webapp/META-INF/</directory>
-                                            <filtering>false</filtering>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>copy-resources-react-webapp-login-jsp</id>
-                                <phase>process-resources</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    
<outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            
<directory>${project.basedir}/src/main/webapp</directory>
-                                            <includes>
-                                                <include>login.jsp</include>
-                                            </includes>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                
<id>copy-resources-react-webapp-login-jsp-styles</id>
-                                <phase>process-resources</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    
<outputDirectory>${project.build.directory}/${project.build.finalName}/styles</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            
<directory>${project.basedir}/src/main/webapp/styles</directory>
-                                            <includes>
-                                                
<include>bootstrap.min.css</include>
-                                                
<include>font-awesome.min.css</include>
-                                                <include>xa.css</include>
-                                            </includes>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                
<id>copy-resources-react-webapp-login-jsp-images</id>
-                                <phase>process-resources</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    
<outputDirectory>${project.build.directory}/${project.build.finalName}/images</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            
<directory>${project.basedir}/src/main/webapp/images</directory>
-                                            <includes>
-                                                
<include>ranger_logo.png</include>
-                                                <include>favicon.ico</include>
-                                            </includes>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                
<id>copy-resources-react-webapp-login-jsp-jquery-js</id>
-                                <phase>process-resources</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    
<outputDirectory>${project.build.directory}/${project.build.finalName}/libs/bower/jquery/js</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            
<directory>${project.basedir}/src/main/webapp/libs/bower/jquery/js</directory>
-                                            <includes>
-                                                
<include>jquery-3.5.1.js</include>
-                                            </includes>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                
<id>copy-resources-react-webapp-login-jsp-prelogin-js</id>
-                                <phase>process-resources</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    
<outputDirectory>${project.build.directory}/${project.build.finalName}/scripts/prelogin</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            
<directory>${project.basedir}/src/main/webapp/scripts/prelogin</directory>
-                                            <includes>
-                                                
<include>XAPrelogin.js</include>
-                                            </includes>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                
<id>copy-resources-react-webapp-login-jsp-fonts</id>
-                                <phase>process-resources</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    
<outputDirectory>${project.build.directory}/${project.build.finalName}/fonts</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            
<directory>${project.basedir}/src/main/webapp/fonts</directory>
-                                            <includes>
-                                                
<include>fontawesome-webfont.eot</include>
-                                                
<include>fontawesome-webfont.ttf</include>
-                                                
<include>fontawesome-webfont.woff</include>
-                                                
<include>fontawesome-webfont.woff2</include>
-                                            </includes>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <!-- react-webapp copy-resources execution end -->
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>com.github.eirslett</groupId>
-                        <artifactId>frontend-maven-plugin</artifactId>
-                        <version>1.12.1</version>
+                    </execution>
+                    <execution>
+                        <phase>test</phase>
+                        <id>karma dev</id>
+                        <goals>
+                            <goal>karma</goal>
+                        </goals>
+                        <configuration>
+                            <skip>${skipJSTests}</skip>
+                            
<workingDirectory>${project.build.directory}/jstest</workingDirectory>
+                            
<karmaConfPath>../../src/test/javascript/karma-dev.conf.js</karmaConfPath>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <phase>integration-test</phase>
+                        <id>karma prd</id>
+                        <goals>
+                            <goal>karma</goal>
+                        </goals>
+                        <configuration>
+                            <environmentVariables>
+                                <buildDir>${project.build.finalName}</buildDir>
+                            </environmentVariables>
+                            <skip>${skipJSTests}</skip>
+                            
<workingDirectory>${project.build.directory}/jstest</workingDirectory>
+                            
<karmaConfPath>../../src/test/javascript/karma-prd.conf.js</karmaConfPath>
+                        </configuration>
+                    </execution>
+                    <!-- react-webapp frontend-maven-plugin start -->
+                    <execution>
+                        <id>install node and npm for react-webapp</id>
+                        <goals>
+                            <goal>install-node-and-npm</goal>
+                        </goals>
+                        <phase>generate-resources</phase>
+                        <configuration>
+                            
<workingDirectory>${project.build.directory}/react-webapp</workingDirectory>
+                            
<installDirectory>${project.build.directory}/react-build</installDirectory>
+                            <nodeVersion>v16.0.0</nodeVersion>
+                            <npmVersion>7.10.0</npmVersion>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>run npm ci for react-webapp</id>
+                        <goals>
+                            <goal>npm</goal>
+                        </goals>
+                        <phase>generate-resources</phase>
+                        <configuration>
+                            
<workingDirectory>${project.build.directory}/react-webapp</workingDirectory>
+                            
<installDirectory>${project.build.directory}/react-build</installDirectory>
+                            <arguments>ci</arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>webpack build for react-webapp</id>
+                        <goals>
+                            <goal>npm</goal>
+                        </goals>
+                        <phase>generate-resources</phase>
                         <configuration>
                             
<workingDirectory>${project.build.directory}/react-webapp</workingDirectory>
                             
<installDirectory>${project.build.directory}/react-build</installDirectory>
+                            <arguments>run build</arguments>
                         </configuration>
-                        <executions>
-                            <!-- react-webapp frontend-maven-plugin start -->
-                            <execution>
-                                <id>install node and npm for react-webapp</id>
-                                <goals>
-                                    <goal>install-node-and-npm</goal>
-                                </goals>
-                                <phase>generate-resources</phase>
-                                <configuration>
-                                    <nodeVersion>v16.0.0</nodeVersion>
-                                    <npmVersion>7.10.0</npmVersion>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>run npm ci for react-webapp</id>
-                                <goals>
-                                    <goal>npm</goal>
-                                </goals>
-                                <phase>generate-resources</phase>
-                                <configuration>
-                                    <arguments>ci</arguments>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>webpack build for react-webapp</id>
-                                <goals>
-                                    <goal>npm</goal>
-                                </goals>
-                                <phase>generate-resources</phase>
-                                <configuration>
-                                    <arguments>run build</arguments>
-                                </configuration>
-                            </execution>
-                            <!-- react-webapp frontend-maven-plugin end -->
-                        </executions>
-                    </plugin>
+                    </execution>
+                    <!-- react-webapp frontend-maven-plugin end -->
+                </executions>
+            </plugin>
 
-                    <!-- duplicate SQL patch file version validator plugin -->
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-enforcer-plugin</artifactId>
-                        <version>1.4.1</version>
-                        <executions>
-                            <execution>
-                                
<id>duplicate-sql-patch-file-version-validator</id>
-                                <goals>
-                                    <goal>enforce</goal>
-                                </goals>
-                                <phase>validate</phase>
-                                <configuration>
-                                    <rules>
-                                        <evaluateBeanshell>
-                                            <message>Looks like there are 
multiple SQL files with same version number prefix. Update prefix and build 
again.</message>
-                                            <condition>
-                                                List sqlFilePaths = 
org.codehaus.plexus.util.FileUtils.getFileNames(new File("security-admin/db"), 
"**/*.sql", null, false);
-                                                Map sqlFileMap    = new 
HashMap();
-                                                Boolean noDupPrfx = true;
+            <!-- duplicate SQL patch file version validator plugin -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-enforcer-plugin</artifactId>
+                <version>1.4.1</version>
+                <executions>
+                    <execution>
+                        <id>duplicate-sql-patch-file-version-validator</id>
+                        <goals>
+                            <goal>enforce</goal>
+                        </goals>
+                        <phase>validate</phase>
+                        <configuration>
+                            <rules>
+                                <evaluateBeanshell>
+                                    <message>Looks like there are multiple SQL 
files with same version number prefix. Update prefix and build again.</message>
+                                    <condition>
+                                        List sqlFilePaths = 
org.codehaus.plexus.util.FileUtils.getFileNames(new File("security-admin/db"), 
"**/*.sql", null, false);
+                                        Map sqlFileMap    = new HashMap();
+                                        Boolean noDupPrfx = true;
 
-                                                for (Iterator it = 
sqlFilePaths.iterator(); it.hasNext();) {
-                                                    String currentSqlFilePath 
= it.next();
+                                        for (Iterator it = 
sqlFilePaths.iterator(); it.hasNext();) {
+                                            String currentSqlFilePath = 
it.next();
 
-                                                    if 
(currentSqlFilePath.contains("patches")) {
-                                                        String [] array      = 
currentSqlFilePath.split("/");
-                                                        String db            = 
array[0];
-                                                        String patch         = 
array[(array.length - 1)];
-                                                        Boolean prfxWithNums = 
java.util.regex.Pattern.matches("^[0-9]{3}-([a-zA-Z]+[-_]*)+.sql$", patch);
+                                            if 
(currentSqlFilePath.contains("patches")) {
+                                                String [] array      = 
currentSqlFilePath.split("/");
+                                                String db            = 
array[0];
+                                                String patch         = 
array[(array.length - 1)];
+                                                Boolean prfxWithNums = 
java.util.regex.Pattern.matches("^[0-9]{3}-([a-zA-Z]+[-_]*)+.sql$", patch);
 
-                                                        if (prfxWithNums) {
-                                                            String sqlFile = 
sqlFileMap.get(db + "-" + patch.split("-")[0]);
+                                                if (prfxWithNums) {
+                                                    String sqlFile = 
sqlFileMap.get(db + "-" + patch.split("-")[0]);
 
-                                                            if (sqlFile == 
null) {
-                                                                
sqlFileMap.put(db + "-" + patch.split("-")[0], currentSqlFilePath);
-                                                            } else {
-                                                                
print("Multiple SQL files with combination: [DB=" + db + "] [VersionPrefix=" + 
patch.split("-")[0] + "] found, hence triggering build failure.");
-                                                                print("Review 
prefixs for following files.");
-                                                                print("1. " + 
sqlFile);
-                                                                print("2. " + 
currentSqlFilePath);
-                                                                noDupPrfx = 
false;
-                                                            };
-                                                        };
+                                                    if (sqlFile == null) {
+                                                        sqlFileMap.put(db + 
"-" + patch.split("-")[0], currentSqlFilePath);
+                                                    } else {
+                                                        print("Multiple SQL 
files with combination: [DB=" + db + "] [VersionPrefix=" + patch.split("-")[0] 
+ "] found, hence triggering build failure.");
+                                                        print("Review prefixs 
for following files.");
+                                                        print("1. " + sqlFile);
+                                                        print("2. " + 
currentSqlFilePath);
+                                                        noDupPrfx = false;
                                                     };
                                                 };
+                                            };
+                                        };
 
-                                                noDupPrfx
-                                            </condition>
-                                        </evaluateBeanshell>
-                                    </rules>
-                                    <fail>true</fail>
-                                </configuration>
-                            </execution>
+                                        noDupPrfx
+                                    </condition>
+                                </evaluateBeanshell>
+                            </rules>
+                            <fail>true</fail>
+                        </configuration>
+                    </execution>
 
-                            <!-- duplicate JAVA patch file version validator 
plugin -->
-                            <execution>
-                                
<id>duplicate-java-patch-file-version-validator</id>
-                                <goals>
-                                    <goal>enforce</goal>
-                                </goals>
-                                <phase>validate</phase>
-                                <configuration>
-                                    <rules>
-                                        <evaluateBeanshell>
-                                            <message>Looks like there are 
multiple JAVA files with same version number suffix. Update suffix and build 
again.</message>
-                                            <condition>
-                                                List javaFilePaths  = 
org.codehaus.plexus.util.FileUtils.getFileNames(new 
File("security-admin/src/main/java/org/apache/ranger/patch"), "**/*.java", 
null, false);
-                                                Map javaFileMap     = new 
HashMap();
-                                                Boolean noDupSuffix = true;
+                    <!-- duplicate JAVA patch file version validator plugin -->
+                    <execution>
+                        <id>duplicate-java-patch-file-version-validator</id>
+                        <goals>
+                            <goal>enforce</goal>
+                        </goals>
+                        <phase>validate</phase>
+                        <configuration>
+                            <rules>
+                                <evaluateBeanshell>
+                                    <message>Looks like there are multiple 
JAVA files with same version number suffix. Update suffix and build 
again.</message>
+                                    <condition>
+                                        List javaFilePaths  = 
org.codehaus.plexus.util.FileUtils.getFileNames(new 
File("security-admin/src/main/java/org/apache/ranger/patch"), "**/*.java", 
null, false);
+                                        Map javaFileMap     = new HashMap();
+                                        Boolean noDupSuffix = true;
 
-                                                for (Iterator it = 
javaFilePaths.iterator(); it.hasNext();) {
-                                                    String currentJavaFilePath 
= it.next();
+                                        for (Iterator it = 
javaFilePaths.iterator(); it.hasNext();) {
+                                            String currentJavaFilePath = 
it.next();
 
-                                                    if 
(currentJavaFilePath.startsWith("Patch")) {
-                                                        String versionSuffix = 
currentJavaFilePath.split("_J")[1];
-                                                        String javaFile      = 
javaFileMap.get(versionSuffix);
+                                            if 
(currentJavaFilePath.startsWith("Patch")) {
+                                                String versionSuffix = 
currentJavaFilePath.split("_J")[1];
+                                                String javaFile      = 
javaFileMap.get(versionSuffix);
 
-                                                        if (javaFile == null) {
-                                                            
javaFileMap.put(versionSuffix, currentJavaFilePath);
-                                                        } else {
-                                                            print("Multiple 
JAVA files with suffix: " + versionSuffix + " found, hence triggering build 
failure.");
-                                                            print("Review 
suffixes for following files.");
-                                                            print("1. " + 
javaFile);
-                                                            print("2. " + 
currentJavaFilePath);
-                                                            noDupSuffix = 
false;
-                                                        };
-                                                    };
+                                                if (javaFile == null) {
+                                                    
javaFileMap.put(versionSuffix, currentJavaFilePath);
+                                                } else {
+                                                    print("Multiple JAVA files 
with suffix: " + versionSuffix + " found, hence triggering build failure.");
+                                                    print("Review suffixes for 
following files.");
+                                                    print("1. " + javaFile);
+                                                    print("2. " + 
currentJavaFilePath);
+                                                    noDupSuffix = false;
                                                 };
+                                            };
+                                        };
 
-                                                noDupSuffix
-                                            </condition>
-                                        </evaluateBeanshell>
-                                    </rules>
-                                    <fail>true</fail>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
+                                        noDupSuffix
+                                    </condition>
+                                </evaluateBeanshell>
+                            </rules>
+                            <fail>true</fail>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/security-admin/src/main/webapp/index.html 
b/security-admin/src/main/webapp/backbone-index.html
similarity index 100%
rename from security-admin/src/main/webapp/index.html
rename to security-admin/src/main/webapp/backbone-index.html
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/Header.jsx 
b/security-admin/src/main/webapp/react-webapp/src/views/Header.jsx
index 65a0414bc..a51e1a644 100644
--- a/security-admin/src/main/webapp/react-webapp/src/views/Header.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/Header.jsx
@@ -41,7 +41,8 @@ class Header extends Component {
 
   render() {
     const userProps = getUserProfile();
-    const apiUrl = getBaseUrl() + "apidocs/index.html";
+    const apiUrl = getBaseUrl() + "apidocs/swagger.html";
+    const backboneUrl = getBaseUrl() + "backbone-index.html";
     const loginId = (
       <span className="login-id">
         <i className="fa fa-user-circle fa-lg"></i>
@@ -118,7 +119,6 @@ class Header extends Component {
                   Audit
                 </Nav.Link>
               )}
-
               {hasAccessToTab("Security Zone") && (
                 <React.Fragment>
                   {!isKeyAdmin() && (
@@ -150,7 +150,7 @@ class Header extends Component {
                   )}
                 </React.Fragment>
               )}
-              <>
+              <React.Fragment>
                 {(hasAccessToTab("Users/Groups") ||
                   isAuditor() ||
                   isSystemAdmin()) && (
@@ -173,7 +173,7 @@ class Header extends Component {
                     )}
                   </NavDropdown>
                 )}
-              </>
+              </React.Fragment>
             </Nav>
             <Nav>
               <NavDropdown title={loginId} id="user-dropdown" alignRight>
@@ -184,6 +184,9 @@ class Header extends Component {
                 >
                   <i className="fa fa-user"></i> Profile
                 </NavDropdown.Item>
+                <a class="dropdown-item" href={backboneUrl}>
+                  <i className="fa fa fa-sign-out"></i> Backbone UI
+                </a>
                 <a className="dropdown-item" href={apiUrl} target="_blank">
                   <i className="fa fa-user"></i> API Documentation
                 </a>
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/views/SideBar/SideBarBody.jsx 
b/security-admin/src/main/webapp/react-webapp/src/views/SideBar/SideBarBody.jsx
index aa4a2d890..ce4300ac5 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/views/SideBar/SideBarBody.jsx
+++ 
b/security-admin/src/main/webapp/react-webapp/src/views/SideBar/SideBarBody.jsx
@@ -607,9 +607,17 @@ export const SideBarBody = (props) => {
                   Profile
                 </NavLink>
               </li>
-              {/* <li className="list-group-item">
-                <a href={backboneUrl}>Backbone Classic UI</a>
-              </li> */}
+              <li className="list-group-item">
+                <a
+                  href={backboneUrl}
+                  onClick={() => {
+                    props.closeCollapse();
+                    localStorage.clear();
+                  }}
+                >
+                  Backbone Classic UI
+                </a>
+              </li>
               <li className="list-group-item">
                 <a
                   href={apiUrl}
diff --git a/security-admin/src/main/webapp/scripts/views/common/ProfileBar.js 
b/security-admin/src/main/webapp/scripts/views/common/ProfileBar.js
index 87e4dca27..fee02c80f 100644
--- a/security-admin/src/main/webapp/scripts/views/common/ProfileBar.js
+++ b/security-admin/src/main/webapp/scripts/views/common/ProfileBar.js
@@ -44,7 +44,8 @@ define(function(require){
                return {
                        userProfile : this.userProfile,
                        oldUi : localStorage.getItem('setOldUI') == "true" ? 
false : true ,
-                               swaggerUI : urlString+"/apidocs/swagger.html"
+                               swaggerUI : urlString+"/apidocs/swagger.html",
+                               reactUI : urlString+"/index.html"
                };
        },
         
diff --git 
a/security-admin/src/main/webapp/templates/common/ProfileBar_tmpl.html 
b/security-admin/src/main/webapp/templates/common/ProfileBar_tmpl.html
index d8c2112f1..73baa158a 100644
--- a/security-admin/src/main/webapp/templates/common/ProfileBar_tmpl.html
+++ b/security-admin/src/main/webapp/templates/common/ProfileBar_tmpl.html
@@ -22,8 +22,8 @@
             </a>
             <div class="dropdown-menu dropdown-menu-right">
                 <a class="dropdown-item" href="#!/userprofile"><i class="fa 
fa-user m-r-xs"></i> Profile </a>
+                <a class="dropdown-item" href={{reactUI}}><i class="fa 
fa-sign-out m-r-xs"></i> React UI </a>
                 <a class="dropdown-item" href={{swaggerUI}} target='_blank'><i 
class="fa fa-user m-r-xs"></i> API Documentation </a>
-                <a class="dropdown-item" href="javascript:;" class="_allowNav" 
data-id="logout"><i class="fa fa-power-off m-r-xs"></i> Log Out </a>
                 {{#if oldUi}}
                     <a class="dropdown-item" href="javascript:;" 
data-id="oldNewSwitch" data-value="true">
                       <i class="fa fa-sign-out m-r-xs"></i> Switch to classic 
UI </a>
@@ -31,7 +31,8 @@
                     <a class="dropdown-item" href="javascript:;" 
data-id="oldNewSwitch" data-value="false">
                       <i class="fa fa-sign-out m-r-xs"></i> Switch to latest 
UI </a>
                 {{/if}}
+                <a class="dropdown-item" href="javascript:;" class="_allowNav" 
data-id="logout"><i class="fa fa-power-off m-r-xs"></i> Log Out </a>
             </div>
         </li>
     </ul>
-</div>
\ No newline at end of file
+</div>

Reply via email to