You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2023/10/13 05:06:34 UTC

[ranger] branch RANGER-3923 updated (d0f39291c -> 0a45ab730)

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

madhan pushed a change to branch RANGER-3923
in repository https://gitbox.apache.org/repos/asf/ranger.git


    from d0f39291c RANGER-4459: add filters for sharedResourceName and sharedResourceNamePartial in get sharedResource API #2
     new e5dd94c07 RANGER-4440: added column x_security_zone.gz_jsonData to store compressed bytes - #3
     new 0a45ab730 RANGER-4283: [WIP] UI for GDS: Added validity period changes. Multiple default tag datamask condition for datashare and CSS

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../ranger/authorization/utils/StringUtil.java     |  24 +-
 .../optimized/current/ranger_core_db_mysql.sql     |   1 +
 .../optimized/current/ranger_core_db_postgres.sql  |   1 +
 .../apache/ranger/entity/XXSecurityZoneBase.java   |  12 +-
 .../service/RangerSecurityZoneServiceService.java  |  30 +-
 .../main/webapp/react-webapp/src/styles/style.css  |   7 +-
 .../GovernedData/Dataset/DatasetDetailLayout.jsx   |  56 ++-
 .../GovernedData/Dataset/MyDatasetListing.jsx      |  30 +-
 .../GovernedData/Datashare/AddDatashareView.jsx    | 408 +++++++++-------
 .../Datashare/AddSharedResourceComp.jsx            | 519 ++++++++++-----------
 .../Datashare/DatashareDetailLayout.jsx            | 147 ++++--
 .../GovernedData/Datashare/MyDatashareListing.jsx  |  88 +++-
 .../GovernedData/Request/RequestDetailView.jsx     | 161 ++++---
 .../views/GovernedData/Request/RequestListing.jsx  |   6 +-
 .../PolicyListing/PolicyValidityPeriodComp.jsx     |   3 +-
 .../react-webapp/src/views/SideBar/TopNavBar.jsx   |  15 +-
 16 files changed, 898 insertions(+), 610 deletions(-)
 mode change 100755 => 100644 security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql
 mode change 100755 => 100644 security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql


[ranger] 02/02: RANGER-4283: [WIP] UI for GDS: Added validity period changes. Multiple default tag datamask condition for datashare and CSS

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 0a45ab730e7c22e9a002fc3228ca508829b6e7f8
Author: Anand Nadar <na...@gmail.com>
AuthorDate: Thu Oct 12 20:32:05 2023 -0700

    RANGER-4283: [WIP] UI for GDS: Added validity period changes. Multiple default tag datamask condition for datashare and CSS
    
    Signed-off-by: Madhan Neethiraj <ma...@apache.org>
---
 .../main/webapp/react-webapp/src/styles/style.css  |   7 +-
 .../GovernedData/Dataset/DatasetDetailLayout.jsx   |  56 ++-
 .../GovernedData/Dataset/MyDatasetListing.jsx      |  30 +-
 .../GovernedData/Datashare/AddDatashareView.jsx    | 408 +++++++++-------
 .../Datashare/AddSharedResourceComp.jsx            | 519 ++++++++++-----------
 .../Datashare/DatashareDetailLayout.jsx            | 147 ++++--
 .../GovernedData/Datashare/MyDatashareListing.jsx  |  88 +++-
 .../GovernedData/Request/RequestDetailView.jsx     | 161 ++++---
 .../views/GovernedData/Request/RequestListing.jsx  |   6 +-
 .../PolicyListing/PolicyValidityPeriodComp.jsx     |   3 +-
 .../react-webapp/src/views/SideBar/TopNavBar.jsx   |  15 +-
 11 files changed, 860 insertions(+), 580 deletions(-)

diff --git a/security-admin/src/main/webapp/react-webapp/src/styles/style.css b/security-admin/src/main/webapp/react-webapp/src/styles/style.css
index 0ad5f27d0..be11597c3 100755
--- a/security-admin/src/main/webapp/react-webapp/src/styles/style.css
+++ b/security-admin/src/main/webapp/react-webapp/src/styles/style.css
@@ -2374,6 +2374,7 @@ div#ranger-content {
   padding-left: 0;
   padding-right: 0;
   color: rgb(33, 37, 41) !important;
+  text-align: right;
 }
 .header-wraper .last-response-time {
   padding-left: 1rem;
@@ -2577,7 +2578,7 @@ li.list-group-item:hover {
   display: flex;
   justify-content: space-between;
   align-items: center;
-  padding: 1rem;
+  padding: 0 1rem;
   border-bottom: 1px solid #d6d6d6;
   position: sticky;
   top: 0;
@@ -2899,3 +2900,7 @@ textarea.gds-placeholder::placeholder,
 .w-50 {
   width: 50% !important;
 }
+
+.gds-label-color {
+  color: #777777;
+}
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/DatasetDetailLayout.jsx b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/DatasetDetailLayout.jsx
index 63ef239df..3dfc08624 100755
--- a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/DatasetDetailLayout.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/DatasetDetailLayout.jsx
@@ -53,6 +53,7 @@ import arrayMutators from "final-form-arrays";
 import { groupBy, isEmpty, isArray } from "lodash";
 import PrinciplePermissionComp from "./PrinciplePermissionComp";
 import ReactPaginate from "react-paginate";
+import CustomBreadcrumb from "../../CustomBreadcrumb";
 
 const initialState = {
   loader: false,
@@ -967,6 +968,8 @@ const DatasetDetailLayout = () => {
             <i className="fa fa-angle-left fa-lg font-weight-bold" />
           </Button>
           <h3 className="gds-header bold"> Dataset : {datasetInfo.name}</h3>
+          <CustomBreadcrumb />
+          <span className="pipe"></span>
           {saveCancelButtons ? (
             <div className="gds-header-btn-grp">
               <Button
@@ -1087,7 +1090,9 @@ const DatasetDetailLayout = () => {
                                     className="gds-left-inline-field"
                                     height="30px"
                                   >
-                                    Date Updated
+                                    <span className="gds-label-color">
+                                      Date Updated
+                                    </span>
                                   </div>
                                   <div line-height="30px">
                                     {dateFormat(
@@ -1102,7 +1107,9 @@ const DatasetDetailLayout = () => {
                                     className="gds-left-inline-field"
                                     line-height="30px"
                                   >
-                                    Date Created
+                                    <span className="gds-label-color">
+                                      Date Created
+                                    </span>
                                   </div>
                                   <div line-height="30px">
                                     {dateFormat(
@@ -1114,7 +1121,11 @@ const DatasetDetailLayout = () => {
                               </div>
 
                               <div>
-                                <div>Description</div>
+                                <div>
+                                  <span className="gds-label-color">
+                                    Description
+                                  </span>
+                                </div>
                               </div>
                               <div>
                                 <div>
@@ -1207,9 +1218,9 @@ const DatasetDetailLayout = () => {
                                                     {requestAccordionState[
                                                       obj.id
                                                     ] ? (
-                                                      <i className="fa fa-angle-down fa-lg font-weight-bold"></i>
-                                                    ) : (
                                                       <i className="fa fa-angle-up fa-lg font-weight-bold"></i>
+                                                    ) : (
+                                                      <i className="fa fa-angle-down fa-lg font-weight-bold"></i>
                                                     )}
                                                     <h5 className="gds-heading-5 m-0">
                                                       {/* {obj.name} */}{" "}
@@ -1328,7 +1339,11 @@ const DatasetDetailLayout = () => {
                                                         </div>
                                                       </div>
                                                       <div className="w-100 text-right">
-                                                        <div>View Request</div>
+                                                        <Link
+                                                          to={`/gds/request/detail/${obj.id}`}
+                                                        >
+                                                          View Request
+                                                        </Link>
                                                       </div>
                                                     </div>
                                                   </div>
@@ -1715,21 +1730,22 @@ const DatasetDetailLayout = () => {
                           value={obj.id}
                           onChange={checkBocChange}
                         />
-                        <span title={obj.name} className="fnt-14">
-                          {obj.name}{" "}
-                          <CustomTooltip
-                            placement="right"
-                            content={
-                              <p
-                                className="pd-10"
-                                style={{ fontSize: "small" }}
-                              >
-                                {obj.description}
-                              </p>
-                            }
-                            icon="fa-fw fa fa-info-circle gds-opacity-lowest"
-                          />
+                        <span
+                          title={obj.name}
+                          className="fnt-14 text-truncate"
+                          style={{ maxWidth: "300px", display: "inline-block" }}
+                        >
+                          {obj.name}
                         </span>
+                        <CustomTooltip
+                          placement="right"
+                          content={
+                            <p className="pd-10" style={{ fontSize: "small" }}>
+                              {obj.description}
+                            </p>
+                          }
+                          icon="fa-fw fa fa-info-circle gds-opacity-lowest"
+                        />
                       </div>
                     );
                   })
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/MyDatasetListing.jsx b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/MyDatasetListing.jsx
index a81aa2869..f6a7fd991 100755
--- a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/MyDatasetListing.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/MyDatasetListing.jsx
@@ -32,6 +32,7 @@ import {
   serverError,
   parseSearchFilter
 } from "../../../utils/XAUtils";
+import CustomBreadcrumb from "../../CustomBreadcrumb";
 
 const MyDatasetListing = () => {
   const navigate = useNavigate();
@@ -202,9 +203,17 @@ const MyDatasetListing = () => {
         Header: "Name",
         accessor: "name",
         width: 470,
-        disableResizing: true,
-        disableSortBy: true,
-        getResizerProps: () => {}
+        Cell: (val) => {
+          return (
+            <span
+              className="text-truncate"
+              title={val.value}
+              style={{ maxWidth: "240px", display: "inline-block" }}
+            >
+              {val.value}
+            </span>
+          );
+        }
       },
       {
         Header: "Created",
@@ -346,9 +355,17 @@ const MyDatasetListing = () => {
         Header: "Name",
         accessor: "name",
         width: 600,
-        disableResizing: true,
-        disableSortBy: true,
-        getResizerProps: () => {}
+        Cell: (val) => {
+          return (
+            <span
+              className="text-truncate"
+              title={val.value}
+              style={{ maxWidth: "240px", display: "inline-block" }}
+            >
+              {val.value}
+            </span>
+          );
+        }
       },
       {
         Header: "Permission",
@@ -433,6 +450,7 @@ const MyDatasetListing = () => {
             <h3 className="gds-header bold">
               {isMyDatasetPage ? "My" : ""} Datasets
             </h3>
+            <CustomBreadcrumb />
           </div>
           <div className="wrap">
             <React.Fragment>
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddDatashareView.jsx b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddDatashareView.jsx
index b18f5e432..0c75642e1 100755
--- a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddDatashareView.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddDatashareView.jsx
@@ -31,9 +31,10 @@ import AsyncSelect from "react-select/async";
 import { Form, Field } from "react-final-form";
 import { fetchApi } from "Utils/fetchAPI";
 import PrinciplePermissionComp from "../Dataset/PrinciplePermissionComp";
-
+import { FieldArray } from "react-final-form-arrays";
 import AddSharedResourceComp from "./AddSharedResourceComp";
 import { toast } from "react-toastify";
+import arrayMutators from "final-form-arrays";
 
 const initialState = {
   loader: false,
@@ -154,7 +155,6 @@ const AddDatashareView = () => {
           groups: {},
           roles: {}
         },
-        zone: selectedZone != undefined ? selectedZone.label : "",
         service: selectedService.label,
         description: datashareDescription,
         termsOfUse: datashareTermsAndConditions,
@@ -164,25 +164,24 @@ const AddDatashareView = () => {
             ? Object.entries(values.permission).map(([key, obj]) => {
                 return obj.value;
               })
-            : [],
-        defaultMasks: {}
+            : []
       };
 
-      if (values.shareDataMaskInfo != undefined) {
-        let data = {};
-        if (values.shareDataMaskInfo.valueExpr != undefined) {
-          data = {
-            [tagName]: {
-              dataMaskType: values.shareDataMaskInfo.value,
-              valueExpr: values.shareDataMaskInfo.valueExpr
-            }
-          };
-        } else {
-          data = {
-            [tagName]: { dataMaskType: values.shareDataMaskInfo.value }
-          };
+      if (selectedZone != undefined) {
+        dataShareInfo.zone = selectedZone.label;
+      }
+
+      dataShareInfo.defaultTagMasks = [];
+      if (values.tagMaskInfo != undefined) {
+        for (let i = 0; i < values.tagMaskInfo.length; i++) {
+          let data = {};
+          data.tagName = values.tagMaskInfo[i].tagName;
+          data.maskInfo = {};
+          data.maskInfo.dataMaskType = values.tagMaskInfo[i].masking.value;
+          data.maskInfo.conditionExpr =
+            values.tagMaskInfo[i].shareDataMaskInfo?.valueExpr;
+          dataShareInfo.defaultTagMasks.push(data);
         }
-        dataShareInfo.defaultMasks = data;
       }
 
       userList.forEach((user) => {
@@ -383,81 +382,6 @@ const AddDatashareView = () => {
     }
   };
 
-  const showMoreOptionsComp = () => {
-    setShowMoreOptions(true);
-  };
-
-  const handleSubmit = async (values) => {
-    let data = {};
-    let serviceCompRes = serviceDef.resources;
-    const grpResources = groupBy(serviceCompRes || [], "level");
-    let grpResourcesKeys = [];
-    data.dataShareId = dataShareId;
-    //data.name =
-    for (const resourceKey in grpResources) {
-      grpResourcesKeys.push(+resourceKey);
-    }
-    grpResourcesKeys = grpResourcesKeys.sort();
-    data.resources = {};
-    for (const level of grpResourcesKeys) {
-      if (
-        values[`resourceName-${level}`] &&
-        values[`resourceName-${level}`].value !== noneOptions.value
-      ) {
-        let defObj = serviceCompRes.find(function (m) {
-          if (m.name == values[`resourceName-${level}`].name) {
-            return m;
-          }
-        });
-        data.resources[values[`resourceName-${level}`].name] = {
-          values: isArray(values[`value-${level}`])
-            ? values[`value-${level}`]?.map(({ value }) => value)
-            : [values[`value-${level}`].value]
-        };
-      }
-    }
-    try {
-      setBlockUI(true);
-      const resp = await fetchApi({
-        url: "plugins/policies",
-        method: "POST",
-        data
-      });
-      let tblpageData = {};
-      if (state && state != null) {
-        tblpageData = state.tblpageData;
-        if (state.tblpageData.pageRecords % state.tblpageData.pageSize == 0) {
-          tblpageData["totalPage"] = state.tblpageData.totalPage + 1;
-        } else {
-          if (tblpageData !== undefined) {
-            tblpageData["totalPage"] = state.tblpageData.totalPage;
-          }
-        }
-      }
-      setBlockUI(false);
-      toast.dismiss(toastId.current);
-      toastId.current = toast.success("Policy save successfully!!");
-      navigate(`/service/${serviceId}/policies/${policyType}`, {
-        state: {
-          showLastPage: true,
-          addPageData: tblpageData
-        }
-      });
-    } catch (error) {
-      setBlockUI(false);
-      let errorMsg = `Failed to save policy form`;
-      if (error?.response?.data?.msgDesc) {
-        errorMsg = `Error! ${error.response.data.msgDesc}`;
-      }
-      toast.error(errorMsg);
-      console.error(`Error while saving policy form! ${error}`);
-    }
-  };
-
-  const addResources = (resourceList) => {
-    setSharedResourceList(resourceList);
-  };
-
   const onAccessTypeChange = (event, input) => {
     setAccessType(event);
     input.onChange(event);
@@ -493,11 +417,119 @@ const AddDatashareView = () => {
     setDatashareConditionExpr(event.target.value);
   };
 
-  const fetchMaskOptions = () => {
-    return serviceDef.dataMaskDef.maskTypes.map(({ label, name: value }) => ({
-      label,
-      value
-    }));
+  const MaskingConfig = (props) => {
+    const { addTagMaskingConfig } = props;
+    return (
+      <div>
+        <FieldArray name="tagMaskInfo">
+          {({ fields }) =>
+            fields.map((name, index) => (
+              <div>
+                <span>Tag Name : </span>
+                <div className="gds-form-input">
+                  <Field
+                    name={`${name}.tagName`}
+                    render={({ input, meta }) => (
+                      <input
+                        {...input}
+                        type="text"
+                        //name={`${name}.tagName`}
+                        className="form-control"
+                        data-cy="tagName"
+                        //onChange={tagNameChange}
+                        //value={tagName}
+                      />
+                    )}
+                  />
+                </div>
+                <span>Masking Type : </span>
+                <Field
+                  className="form-control"
+                  name={`${name}.shareDataMaskInfo`}
+                  render={({ input, meta }) => (
+                    <div>
+                      <Field
+                        name={`maskType`}
+                        render={({ input, meta }) => (
+                          <Field
+                            name={`${name}.masking`}
+                            render={({ input, meta }) => (
+                              <div className="d-flex ">
+                                <div className="w-50">
+                                  <Select
+                                    {...input}
+                                    defaultOptions
+                                    //value={selectedShareMask}
+                                    options={maskTypeOptions}
+                                    onChange={(e) =>
+                                      onShareMaskChange(e, input)
+                                    }
+                                    isClearable={false}
+                                    width="500px"
+                                  />
+                                </div>
+                                {fields?.value[index]?.masking?.label ==
+                                  "Custom" && (
+                                  <div className="pl-2 w-50">
+                                    <Field
+                                      className="form-control"
+                                      name={`${name}.shareDataMaskInfo.valueExpr`}
+                                      //validate={required}
+                                      render={({ input, meta }) => (
+                                        <>
+                                          <FormB.Control
+                                            type="text"
+                                            className="gds-input"
+                                            {...input}
+                                            placeholder="Enter masked value or expression..."
+                                          />
+                                          {meta.error && (
+                                            <span className="invalid-field">
+                                              {meta.error}
+                                            </span>
+                                          )}
+                                        </>
+                                      )}
+                                    />
+                                  </div>
+                                )}
+                              </div>
+                            )}
+                          />
+                        )}
+                      />
+                    </div>
+                  )}
+                />
+                <Button
+                  variant="danger"
+                  size="sm"
+                  title="Remove"
+                  onClick={() => {
+                    fields.remove(index);
+                  }}
+                  data-action="delete"
+                  data-cy="delete"
+                >
+                  <i className="fa-fw fa fa-remove"></i>
+                </Button>
+              </div>
+            ))
+          }
+        </FieldArray>
+
+        <Button
+          className="btn btn-mini mt-2"
+          type="button"
+          onClick={() => addTagMaskingConfig("tagMaskInfo", undefined)}
+          data-action="addTagMaskInfo"
+          data-cy="addTagMaskInfo"
+          title="Add"
+        >
+          Add More
+        </Button>
+      </div>
+    );
   };
 
   return (
@@ -506,7 +538,18 @@ const AddDatashareView = () => {
         id="myform2"
         name="myform2"
         onSubmit={onSubmit}
-        render={({ handleSubmit, submitting, required, values }) => (
+        mutators={{
+          ...arrayMutators
+        }}
+        render={({
+          handleSubmit,
+          submitting,
+          required,
+          values,
+          form: {
+            mutators: { push: addTagMaskingConfig, pop }
+          }
+        }) => (
           <div>
             <div className="gds-form-header-wrapper">
               <h3 className="gds-header bold">Create Datashare</h3>
@@ -673,64 +716,117 @@ const AddDatashareView = () => {
                 </div>
                 {maskDef ? (
                   <div className="gds-section-title">
-                    <p className="gds-card-heading">Masking Configuration</p>
-                    <div>
-                      <span>Tag Name : </span>
-                      <div className="gds-form-input">
-                        <input
-                          type="text"
-                          name="tagName"
-                          className="form-control"
-                          data-cy="tagName"
-                          onChange={tagNameChange}
-                          value={tagName}
-                        />
-                      </div>
-                    </div>
-                    <div>
-                      <span>Masking Type : </span>
-                      <Field
-                        className="form-control"
-                        name={`shareDataMaskInfo`}
-                        render={({ input, meta }) => (
-                          <div>
-                            <Select
-                              {...input}
-                              defaultOptions
-                              value={selectedShareMask}
-                              options={maskTypeOptions}
-                              onChange={(e) => onShareMaskChange(e, input)}
-                              isClearable={false}
-                              width="500px"
-                            />
-                            {selectedShareMask != undefined &&
-                              selectedShareMask.label == "Custom" && (
-                                <>
-                                  <Field
-                                    className="form-control"
-                                    name={`shareDataMaskInfo.valueExpr`}
-                                    validate={required}
-                                    render={({ input, meta }) => (
-                                      <>
-                                        <FormB.Control
-                                          type="text"
-                                          {...input}
-                                          placeholder="Enter masked value or expression..."
+                    <p className="gds-card-heading">
+                      Tag Masking Configuration
+                    </p>
+
+                    <MaskingConfig addTagMaskingConfig={addTagMaskingConfig} />
+                    {/* <div>
+                      <FieldArray name="tagMaskInfo">
+                        {({ fields }) =>
+                          fields.map((name, index) => (
+                            <div>
+                              <span>Tag Name : </span>
+                              <div className="gds-form-input">
+                                <input
+                                  type="text"
+                                  name="tagName"
+                                  className="form-control"
+                                  data-cy="tagName"
+                                  onChange={tagNameChange}
+                                  value={tagName}
+                                />
+                              </div>
+                              <span>Masking Type : </span>
+                              <Field
+                                className="form-control"
+                                name={`shareDataMaskInfo`}
+                                render={({ input, meta }) => (
+                                  <div>
+                                    <Field
+                                      name={`maskType`}
+                                      render={({ input, meta }) => (
+                                        <Field
+                                          name="masking"
+                                          render={({ input, meta }) => (
+                                            <div className="d-flex ">
+                                              <div className="w-50">
+                                                <Select
+                                                  {...input}
+                                                  defaultOptions
+                                                  value={selectedShareMask}
+                                                  options={maskTypeOptions}
+                                                  onChange={(e) =>
+                                                    onShareMaskChange(e, input)
+                                                  }
+                                                  isClearable={false}
+                                                  width="500px"
+                                                />
+                                              </div>
+                                              {selectedShareMask?.label ==
+                                                "Custom" && (
+                                                <div className="pl-2 w-50">
+                                                  <Field
+                                                    className="form-control"
+                                                    name={`shareDataMaskInfo.valueExpr`}
+                                                    validate={required}
+                                                    render={({
+                                                      input,
+                                                      meta
+                                                    }) => (
+                                                      <>
+                                                        <FormB.Control
+                                                          type="text"
+                                                          className="gds-input"
+                                                          {...input}
+                                                          placeholder="Enter masked value or expression..."
+                                                        />
+                                                        {meta.error && (
+                                                          <span className="invalid-field">
+                                                            {meta.error}
+                                                          </span>
+                                                        )}
+                                                      </>
+                                                    )}
+                                                  />
+                                                </div>
+                                              )}
+                                            </div>
+                                          )}
                                         />
-                                        {meta.error && (
-                                          <span className="invalid-field">
-                                            {meta.error}
-                                          </span>
-                                        )}
-                                      </>
-                                    )}
-                                  />
-                                </>
-                              )}
-                          </div>
-                        )}
-                      />
-                    </div>
+                                      )}
+                                    />
+                                  </div>
+                                )}
+                              />
+                              <Button
+                                variant="danger"
+                                size="sm"
+                                title="Remove"
+                                onClick={() => {
+                                  fields.remove(index);
+                                }}
+                                data-action="delete"
+                                data-cy="delete"
+                              >
+                                <i className="fa-fw fa fa-remove"></i>
+                              </Button>
+                            </div>
+                          ))
+                        }
+                      </FieldArray>
+
+                      <Button
+                        className="btn btn-mini mt-2"
+                        type="button"
+                        onClick={() => push("tagMaskInfo", undefined)}
+                        data-action="addTagMaskInfo"
+                        data-cy="addTagMaskInfo"
+                        title="Add"
+                      >
+                        Add More
+                      </Button>
+                    </div> */}
                   </div>
                 ) : (
                   <div></div>
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddSharedResourceComp.jsx b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddSharedResourceComp.jsx
index e5e16a8fe..a583e7d62 100755
--- a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddSharedResourceComp.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddSharedResourceComp.jsx
@@ -40,28 +40,24 @@ const AddSharedResourceComp = ({
   datashareId,
   onSharedResourceDataChange,
   onToggleAddResourceClose,
-  loadSharedResource
+  isEdit,
+  sharedResourceId
 }) => {
   const [accessType, setAccessType] = useState();
-  const [sharedResources, setSharedResources] = useState();
-  const [conditionModalData, setConditionModalData] = useState();
-  const [showConditionModal, setShowConditionModal] = useState(false);
   const [datashareInfo, setDatashareInfo] = useState({});
   const [showMaskInput, setShowMaskInput] = useState(false);
   const [showRowFilterInput, setShowRowFilterInput] = useState(false);
   const [serviceDef, setServiceDef] = useState({});
   const [serviceDetails, setService] = useState({});
-  const [blockUI, setBlockUI] = useState(false);
   const [loader, setLoader] = useState(false);
-  const navigate = useNavigate();
+  const [showAddResourceModal, setShowAddResourceModal] = useState(false);
   const [openConfigAccordion, setOpenConfigAccordion] = useState(false);
   const [formData, setFormData] = useState();
-  //const [accessTypeOptions, setAccessTypeOptions] = useState([]);
   const [selectedResShareMask, setSelectedResShareMask] = useState({});
+  const [loadSharedResource, setLoadSharedResource] = useState();
 
   useEffect(() => {
     fetchDatashareInfo(datashareId);
-    fetchSharedResources(datashareId);
   }, []);
 
   const generateFormData = (obj, serviceDef) => {
@@ -162,23 +158,20 @@ const AddSharedResourceComp = ({
       setShowRowFilterInput(true);
     }
 
-    // setShowMaskInput(true);
-    // setShowRowFilterInput(true);
     setServiceDef(modifiedServiceDef);
     if (loadSharedResource != undefined) {
       setFormData(generateFormData(loadSharedResource, modifiedServiceDef));
     }
   };
 
-  const fetchSharedResources = async () => {
+  const fetchSharedResource = async (sharedResourceId) => {
     try {
       let params = {};
-      params["dataShareId"] = datashareId;
       const resp = await fetchApi({
-        url: `gds/resource`,
-        params: params
+        url: `gds/resource/${sharedResourceId}`
       });
-      setSharedResources(resp.data.list);
+      setLoadSharedResource(resp.data);
+      setFormData(generateFormData(resp.data, serviceDef));
     } catch (error) {
       console.error(
         `Error occurred while fetching shared resource details ! ${error}`
@@ -270,9 +263,8 @@ const AddSharedResourceComp = ({
     data.resourceMask = values.resourceMask;
 
     try {
-      setBlockUI(true);
       setLoader(true);
-      if (loadSharedResource != undefined) {
+      if (isEdit) {
         data.guid = loadSharedResource.guid;
         await fetchApi({
           url: `gds/resource/${loadSharedResource.id}`,
@@ -288,9 +280,7 @@ const AddSharedResourceComp = ({
         });
         toast.success("Shared resource created successfully!!");
       }
-      setBlockUI(false);
     } catch (error) {
-      setBlockUI(false);
       setLoader(false);
       serverError(error);
       if (loadSharedResource != undefined) {
@@ -305,26 +295,13 @@ const AddSharedResourceComp = ({
     onSharedResourceDataChange();
     setLoader(false);
     if (closeModal) {
-      onToggleAddResourceClose();
+      setShowAddResourceModal(false);
     }
     console.log(data);
   };
 
-  const showConfitionModal = (data) => {
-    setConditionModalData(data);
-    setShowConditionModal(true);
-  };
-
-  const toggleConditionModalClose = () => {
-    setShowConditionModal(false);
-  };
-
-  const back = () => {
-    navigate(`/gds/datashare/${datashareId}/detail`);
-  };
-
   const toggleAddResourceClose = () => {
-    onToggleAddResourceClose();
+    setShowAddResourceModal(false);
   };
 
   const onResShareMaskChange = (event, input) => {
@@ -332,6 +309,15 @@ const AddSharedResourceComp = ({
     input.onChange(event);
   };
 
+  const addResource = () => {
+    //setLoadSharedResource();
+    setShowAddResourceModal(true);
+  };
+
+  const toggleAddResourceModalClose = () => {
+    setShowAddResourceModal(false);
+  };
+
   return (
     <>
       {/* <div className="gds-form-header-wrapper gap-half">
@@ -350,18 +336,69 @@ const AddSharedResourceComp = ({
       {loader ? (
         <Loader />
       ) : (
-        <div className="gds-form-wrap">
-          <div className="gds-form-content pt-5">
+        <>
+          <div className="gds-header-btn-grp">
+            {!isEdit ? (
+              <Button
+                variant="primary"
+                onClick={addResource}
+                size="sm"
+                data-id="save"
+                data-cy="save"
+              >
+                Add Resources
+              </Button>
+            ) : (
+              <Button
+                variant="outline-dark"
+                size="sm"
+                title="Edit"
+                onClick={(e) => {
+                  // e.stopPropagation();
+                  // setLoadSharedResource(obj);
+                  fetchSharedResource(sharedResourceId);
+                  setShowAddResourceModal(true);
+                }}
+                data-name="editSharedResource"
+                data-id="editSharedResource"
+              >
+                <i className="fa-fw fa fa-edit"></i>
+              </Button>
+            )}
+          </div>
+          <Modal
+            show={showAddResourceModal}
+            onHide={toggleAddResourceModalClose}
+            //className="mb-7"
+            size="xl"
+          >
+            <Modal.Header closeButton>
+              <h5 className="mb-0">Add Resources</h5>
+            </Modal.Header>
+            {/* <div className="gds-form-wrap"> */}
+            {/* <div className="gds-form-content"> */}
             <div>
-              <div className="mb-2 gds-chips">
-                <span className="badge badge-light">
+              <div className="mb-2 gds-chips flex-wrap">
+                <span
+                  title={datashareInfo.name}
+                  className="badge badge-light text-truncate"
+                  style={{ maxWidth: "250px", display: "inline-block" }}
+                >
                   Datashare: {datashareInfo.name}
                 </span>
-                <span className="badge badge-light">
+                <span
+                  title={datashareInfo.service}
+                  className="badge badge-light text-truncate"
+                  style={{ maxWidth: "250px", display: "inline-block" }}
+                >
                   Service: {datashareInfo.service}
                 </span>
                 {datashareInfo.zone != undefined ? (
-                  <span className="badge badge-light">
+                  <span
+                    title={datashareInfo.zone}
+                    className="badge badge-light text-truncate"
+                    style={{ maxWidth: "250px", display: "inline-block" }}
+                  >
                     Security Zone: {datashareInfo.zone}
                   </span>
                 ) : (
@@ -404,163 +441,162 @@ const AddSharedResourceComp = ({
                             }
                           });
                         }
-                        handleSubmit();
                       }}
                     >
-                      <div className="mb-4 mt-4">
-                        <h6>Resource Details</h6>
-                        <hr className="mt-1 mb-1 gds-hr" />
-                      </div>
-                      <div className="mb-3 form-group row">
-                        <Col sm={3}>
-                          <label className="form-label pull-right fnt-14">
-                            Shared Resource Name
-                          </label>
-                          <span className="compulsory-resource top-0">*</span>
-                        </Col>
-                        <Col sm={9}>
-                          <Field
-                            name="shareName"
-                            render={({ input, meta }) => (
-                              <div className="flex-1">
-                                <input
-                                  {...input}
-                                  type="text"
-                                  name="shareName"
-                                  className="form-control"
-                                  data-cy="shareName"
-                                />
-                              </div>
-                            )}
+                      <Modal.Body>
+                        <div className="mb-4 mt-4">
+                          <h6>Resource Details</h6>
+                          <hr className="mt-1 mb-1 gds-hr" />
+                        </div>
+                        <div className="mb-3 form-group row">
+                          <Col sm={3}>
+                            <label className="form-label pull-right fnt-14">
+                              Shared Resource Name
+                            </label>
+                            <span className="compulsory-resource top-0">*</span>
+                          </Col>
+                          <Col sm={9}>
+                            <Field
+                              name="shareName"
+                              render={({ input, meta }) => (
+                                <div className="flex-1">
+                                  <input
+                                    {...input}
+                                    type="text"
+                                    name="shareName"
+                                    className="form-control"
+                                    data-cy="shareName"
+                                  />
+                                </div>
+                              )}
+                            />
+                          </Col>
+                        </div>
+                        <div className="gds-resource-hierarchy">
+                          <ResourceComp
+                            serviceDetails={serviceDetails}
+                            serviceCompDetails={serviceDef}
+                            formValues={values}
+                            policyType={0}
+                            policyItem={false}
+                            policyId={0}
+                            isGds={true}
                           />
-                        </Col>
-                      </div>
-                      <div className="gds-resource-hierarchy">
-                        <ResourceComp
-                          serviceDetails={serviceDetails}
-                          serviceCompDetails={serviceDef}
-                          formValues={values}
-                          policyType={0}
-                          policyItem={false}
-                          policyId={0}
-                          isGds={true}
-                        />
-                      </div>
+                        </div>
 
-                      <Accordion className="mb-3" defaultActiveKey="0">
-                        <Card className="border-0 gds-resource-options">
-                          <div>
-                            <Accordion.Toggle
-                              as={Card.Header}
-                              eventKey="1"
-                              onClick={onAccessConfigAccordianChange}
-                              className="d-flex align-items-center gds-res-acc-header gap-half"
-                              data-id="panel"
-                              data-cy="panel"
-                            >
-                              {openConfigAccordion ? (
-                                <i className="fa fa-angle-up pull-up fa-lg font-weight-bold"></i>
-                              ) : (
-                                <i className="fa fa-angle-down pull-down fa-lg font-weight-bold"></i>
-                              )}
-                              <Link to="">
-                                Add Default access type, row level filters and
-                                conditions (Optional)
-                              </Link>
-                            </Accordion.Toggle>
-                          </div>
-                          <Accordion.Collapse eventKey="1">
-                            <Card.Body className="gds-res-card-body">
-                              <div className="mb-3 form-group row">
-                                <Col sm={3}>
-                                  <label className="form-label pull-right fnt-14">
-                                    Add Permissions
-                                  </label>
-                                </Col>
-                                <Field
-                                  name="permission"
-                                  render={({ input, meta }) => (
-                                    <Col sm={9}>
-                                      <Select
-                                        {...input}
-                                        options={getAccessTypeOptions(values)}
-                                        onChange={(e) =>
-                                          onAccessTypeChange(e, input)
-                                        }
-                                        //menuPortalTarget={document.body}
-                                        //value={accessType}
-                                        menuPlacement="auto"
-                                        isClearable
-                                        isMulti
-                                      />
-                                    </Col>
-                                  )}
-                                />
-                              </div>
-                              {showRowFilterInput ? (
+                        <Accordion className="mb-3" defaultActiveKey="0">
+                          <Card className="border-0 gds-resource-options">
+                            <div>
+                              <Accordion.Toggle
+                                as={Card.Header}
+                                eventKey="1"
+                                onClick={onAccessConfigAccordianChange}
+                                className="d-flex align-items-center gds-res-acc-header gap-half"
+                                data-id="panel"
+                                data-cy="panel"
+                              >
+                                {openConfigAccordion ? (
+                                  <i className="fa fa-angle-up pull-up fa-lg font-weight-bold"></i>
+                                ) : (
+                                  <i className="fa fa-angle-down pull-down fa-lg font-weight-bold"></i>
+                                )}
+                                <Link to="">
+                                  Add Default access type, row level filters and
+                                  conditions (Optional)
+                                </Link>
+                              </Accordion.Toggle>
+                            </div>
+                            <Accordion.Collapse eventKey="1">
+                              <Card.Body className="gds-res-card-body">
                                 <div className="mb-3 form-group row">
                                   <Col sm={3}>
                                     <label className="form-label pull-right fnt-14">
-                                      Row Filter
+                                      Add Permissions
                                     </label>
                                   </Col>
-
                                   <Field
-                                    name={`rowFilter`}
+                                    name="permission"
                                     render={({ input, meta }) => (
                                       <Col sm={9}>
-                                        <input
+                                        <Select
                                           {...input}
-                                          type="text"
-                                          name="rowFilter"
-                                          className="form-control gds-placeholder"
-                                          data-cy="rowFilter"
+                                          options={getAccessTypeOptions(values)}
+                                          onChange={(e) =>
+                                            onAccessTypeChange(e, input)
+                                          }
+                                          //menuPortalTarget={document.body}
+                                          //value={accessType}
+                                          menuPlacement="auto"
+                                          isClearable
+                                          isMulti
                                         />
                                       </Col>
                                     )}
                                   />
                                 </div>
-                              ) : (
-                                <div></div>
-                              )}
+                                {showRowFilterInput ? (
+                                  <div className="mb-3 form-group row">
+                                    <Col sm={3}>
+                                      <label className="form-label pull-right fnt-14">
+                                        Row Filter
+                                      </label>
+                                    </Col>
 
-                              {showMaskInput ? (
-                                <div className="mb-3 form-group row">
-                                  <Col sm={3}>
-                                    <label className="form-label pull-right fnt-14">
-                                      Mask
-                                    </label>
-                                  </Col>
+                                    <Field
+                                      name={`rowFilter`}
+                                      render={({ input, meta }) => (
+                                        <Col sm={9}>
+                                          <input
+                                            {...input}
+                                            type="text"
+                                            name="rowFilter"
+                                            className="form-control gds-placeholder"
+                                            data-cy="rowFilter"
+                                          />
+                                        </Col>
+                                      )}
+                                    />
+                                  </div>
+                                ) : (
+                                  <div></div>
+                                )}
 
-                                  <Field
-                                    name={`maskType`}
-                                    render={({ input, meta }) => (
-                                      <Col sm={9}>
-                                        <Field
-                                          name="masking"
-                                          render={({ input, meta }) => (
-                                            <div>
-                                              <Col sm={9}>
-                                                <Select
-                                                  {...input}
-                                                  options={
-                                                    serviceDef.dataMaskDef
-                                                      .maskTypes
-                                                  }
-                                                  onChange={(e) =>
-                                                    onResShareMaskChange(
-                                                      e,
-                                                      input
-                                                    )
-                                                  }
-                                                  menuPlacement="auto"
-                                                  isClearable
-                                                />
-                                              </Col>
-                                              <div>
+                                {showMaskInput ? (
+                                  <div className="mb-3 form-group row">
+                                    <Col sm={3}>
+                                      <label className="form-label pull-right fnt-14">
+                                        Mask
+                                      </label>
+                                    </Col>
+
+                                    <Field
+                                      name={`maskType`}
+                                      render={({ input, meta }) => (
+                                        <Col sm={9}>
+                                          <Field
+                                            name="masking"
+                                            render={({ input, meta }) => (
+                                              <div className="d-flex ">
+                                                <div className="w-50">
+                                                  <Select
+                                                    {...input}
+                                                    options={
+                                                      serviceDef.dataMaskDef
+                                                        .maskTypes
+                                                    }
+                                                    onChange={(e) =>
+                                                      onResShareMaskChange(
+                                                        e,
+                                                        input
+                                                      )
+                                                    }
+                                                    menuPlacement="auto"
+                                                    isClearable
+                                                  />
+                                                </div>
                                                 {selectedResShareMask?.label ==
                                                   "Custom" && (
-                                                  <>
+                                                  <div className="pl-2 w-50">
                                                     <Field
                                                       className="form-control"
                                                       name={`resShareDataMaskInfo.valueExpr`}
@@ -572,6 +608,7 @@ const AddSharedResourceComp = ({
                                                         <>
                                                           <FormB.Control
                                                             type="text"
+                                                            className="gds-input"
                                                             {...input}
                                                             placeholder="Enter masked value or expression..."
                                                           />
@@ -583,50 +620,48 @@ const AddSharedResourceComp = ({
                                                         </>
                                                       )}
                                                     />
-                                                  </>
+                                                  </div>
                                                 )}
                                               </div>
-                                            </div>
-                                          )}
+                                            )}
+                                          />
+                                        </Col>
+                                      )}
+                                    />
+                                  </div>
+                                ) : (
+                                  <div></div>
+                                )}
+
+                                <div className="mb-0 form-group row">
+                                  <Col sm={3}>
+                                    <label className="form-label pull-right fnt-14">
+                                      Add Condition
+                                    </label>
+                                  </Col>
+                                  <Field
+                                    name={`booleanExpression`}
+                                    render={({ input, meta }) => (
+                                      <Col sm={9}>
+                                        <textarea
+                                          {...input}
+                                          placeholder="Enter Boolean Expression"
+                                          className="form-control gds-placeholder"
+                                          id="booleanExpression"
+                                          data-cy="booleanExpression"
+                                          rows={4}
                                         />
                                       </Col>
                                     )}
                                   />
                                 </div>
-                              ) : (
-                                <div></div>
-                              )}
-
-                              <div className="mb-0 form-group row">
-                                <Col sm={3}>
-                                  <label className="form-label pull-right fnt-14">
-                                    Add Condition
-                                  </label>
-                                </Col>
-                                <Field
-                                  name={`booleanExpression`}
-                                  render={({ input, meta }) => (
-                                    <Col sm={9}>
-                                      <textarea
-                                        {...input}
-                                        placeholder="Enter Boolean Expression"
-                                        className="form-control gds-placeholder"
-                                        id="booleanExpression"
-                                        data-cy="booleanExpression"
-                                        rows={4}
-                                      />
-                                    </Col>
-                                  )}
-                                />
-                              </div>
-                            </Card.Body>
-                          </Accordion.Collapse>
-                        </Card>
-                      </Accordion>
-
-                      <div className="mb-3 form-group row">
-                        <Col sm={3} />
-                        <Col sm={9}>
+                              </Card.Body>
+                            </Accordion.Collapse>
+                          </Card>
+                        </Accordion>
+                      </Modal.Body>
+                      <Modal.Footer>
+                        <div className="d-flex gap-half justify-content-end w-100">
                           <Button
                             variant="secondary"
                             size="sm"
@@ -635,21 +670,15 @@ const AddSharedResourceComp = ({
                             Cancel
                           </Button>
                           <Button
-                            variant={
-                              loadSharedResource == undefined
-                                ? "secondary"
-                                : "primary"
-                            }
+                            variant="primary"
                             size="sm"
                             onClick={(event) => {
                               handleSubmit(event, true);
                             }}
                           >
-                            {loadSharedResource != undefined
-                              ? "Update"
-                              : "Save & Close"}
+                            {isEdit ? "Update" : "Save & Close"}
                           </Button>
-                          {loadSharedResource == undefined ? (
+                          {!isEdit ? (
                             <Button
                               onClick={(event) => {
                                 handleSubmit(event, false);
@@ -664,53 +693,17 @@ const AddSharedResourceComp = ({
                           ) : (
                             <div></div>
                           )}
-                        </Col>
-                      </div>
-
-                      <Modal
-                        show={showConditionModal}
-                        onHide={toggleConditionModalClose}
-                      >
-                        <Modal.Header closeButton>
-                          <h3 className="gds-header bold">Conditions</h3>
-                        </Modal.Header>
-                        <Modal.Body>
-                          <div className="p-1">
-                            <div className="gds-inline-field-grp">
-                              <div className="wrapper">
-                                <div
-                                  className="gds-left-inline-field"
-                                  height="30px"
-                                >
-                                  Boolean Expression :
-                                </div>
-                                <div line-height="30px">
-                                  {conditionModalData != undefined &&
-                                  conditionModalData.conditionExpr != undefined
-                                    ? conditionModalData.conditionExpr
-                                    : ""}
-                                </div>
-                              </div>
-                            </div>
-                          </div>
-                        </Modal.Body>
-                        <Modal.Footer>
-                          <Button
-                            variant="secondary"
-                            size="sm"
-                            onClick={toggleConditionModalClose}
-                          >
-                            Close
-                          </Button>
-                        </Modal.Footer>
-                      </Modal>
+                        </div>
+                      </Modal.Footer>
                     </form>
                   </div>
                 )}
               />
             </div>
-          </div>
-        </div>
+            {/* </div> */}
+            {/* </div> */}
+          </Modal>
+        </>
       )}
     </>
   );
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/DatashareDetailLayout.jsx b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/DatashareDetailLayout.jsx
index f0a0beaa4..8a798d923 100755
--- a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/DatashareDetailLayout.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/DatashareDetailLayout.jsx
@@ -41,6 +41,7 @@ import { Form } from "react-final-form";
 import arrayMutators from "final-form-arrays";
 import ReactPaginate from "react-paginate";
 import AddSharedResourceComp from "./AddSharedResourceComp";
+import CustomBreadcrumb from "../../CustomBreadcrumb";
 
 const DatashareDetailLayout = () => {
   let { datashareId } = useParams();
@@ -322,12 +323,6 @@ const DatashareDetailLayout = () => {
 
   const handleSubmit = () => {};
 
-  const addResource = () => {
-    //navigate(`/gds/datashare/resource/${datashareId}`);
-    setLoadSharedResource();
-    setShowAddResourceModal(true);
-  };
-
   const back = () => {
     navigate("/gds/mydatasharelisting");
   };
@@ -493,8 +488,15 @@ const DatashareDetailLayout = () => {
                 <i className="fa fa-angle-left fa-lg font-weight-bold" />
               </Button>
               <h3 className="gds-header bold">
-                Datashare : {datashareInfo.name}
+                <span
+                  className="text-truncate"
+                  style={{ maxWidth: "900px", display: "inline-block" }}
+                >
+                  Datashare : {datashareInfo.name}
+                </span>
               </h3>
+              <CustomBreadcrumb />
+              <span className="pipe"></span>
               {saveCancelButtons ? (
                 <div className="gds-header-btn-grp">
                   <Button
@@ -517,17 +519,13 @@ const DatashareDetailLayout = () => {
                   </Button>
                 </div>
               ) : (
-                <div className="gds-header-btn-grp">
-                  <Button
-                    variant="primary"
-                    onClick={addResource}
-                    size="sm"
-                    data-id="save"
-                    data-cy="save"
-                  >
-                    Add a Resource
-                  </Button>
-                </div>
+                <AddSharedResourceComp
+                  datashareId={datashareId}
+                  onSharedResourceDataChange={handleSharedResourceChange}
+                  onToggleAddResourceClose={toggleAddResourceModalClose}
+                  isEdit={false}
+                  loadSharedResource={loadSharedResource}
+                />
               )}
               <div>
                 <DropdownButton
@@ -604,7 +602,9 @@ const DatashareDetailLayout = () => {
                                   className="gds-left-inline-field pl-1 fnt-14"
                                   height="30px"
                                 >
-                                  Date Updated
+                                  <span className="gds-label-color">
+                                    Date Updated
+                                  </span>
                                 </div>
                                 <div className="fnt-14" line-height="30px">
                                   {dateFormat(
@@ -619,7 +619,9 @@ const DatashareDetailLayout = () => {
                                   className="gds-left-inline-field pl-1 fnt-14"
                                   line-height="30px"
                                 >
-                                  Date Created
+                                  <span className="gds-label-color">
+                                    Date Created
+                                  </span>
                                 </div>
                                 <div className="fnt-14" line-height="30px">
                                   {dateFormat(
@@ -630,7 +632,11 @@ const DatashareDetailLayout = () => {
                               </div>
                             </div>
                             <div>
-                              <div className="fnt-14 pl-1">Description</div>
+                              <div className="fnt-14 pl-1">
+                                <span className="gds-label-color">
+                                  Description
+                                </span>
+                              </div>
                             </div>
                             <div>
                               <div>
@@ -702,9 +708,9 @@ const DatashareDetailLayout = () => {
                                                       {resourceAccordionState[
                                                         obj.id
                                                       ] ? (
-                                                        <i className="fa fa-angle-down fa-lg font-weight-bold"></i>
-                                                      ) : (
                                                         <i className="fa fa-angle-up fa-lg font-weight-bold"></i>
+                                                      ) : (
+                                                        <i className="fa fa-angle-down fa-lg font-weight-bold"></i>
                                                       )}
                                                       <div className="d-flex justify-content-between">
                                                         <h6 className="m-0">
@@ -713,7 +719,25 @@ const DatashareDetailLayout = () => {
                                                       </div>
                                                     </div>
                                                     <div className="d-flex gap-half align-items-start">
-                                                      <Button
+                                                      <AddSharedResourceComp
+                                                        datashareId={
+                                                          datashareId
+                                                        }
+                                                        onSharedResourceDataChange={
+                                                          handleSharedResourceChange
+                                                        }
+                                                        onToggleAddResourceClose={
+                                                          toggleAddResourceModalClose
+                                                        }
+                                                        isEdit={true}
+                                                        sharedResourceId={
+                                                          obj.id
+                                                        }
+                                                        loadSharedResource={
+                                                          loadSharedResource
+                                                        }
+                                                      />
+                                                      {/* <Button
                                                         variant="outline-dark"
                                                         size="sm"
                                                         title="Edit"
@@ -730,7 +754,7 @@ const DatashareDetailLayout = () => {
                                                         data-id={obj.id}
                                                       >
                                                         <i className="fa-fw fa fa-edit"></i>
-                                                      </Button>
+                                                      </Button> */}
                                                       <Button
                                                         variant="danger"
                                                         size="sm"
@@ -880,9 +904,9 @@ const DatashareDetailLayout = () => {
                                                           {requestAccordionState[
                                                             obj.id
                                                           ] ? (
-                                                            <i className="fa fa-angle-down fa-lg font-weight-bold"></i>
-                                                          ) : (
                                                             <i className="fa fa-angle-up fa-lg font-weight-bold"></i>
+                                                          ) : (
+                                                            <i className="fa fa-angle-down fa-lg font-weight-bold"></i>
                                                           )}
                                                           <h6 className="m-0">
                                                             {obj.name} Dataset{" "}
@@ -953,13 +977,58 @@ const DatashareDetailLayout = () => {
                                                                 className="gds-left-inline-field"
                                                                 height="30px"
                                                               >
-                                                                Expiry
+                                                                Validity Period
                                                               </div>
                                                               <div line-height="30px">
                                                                 {obj["service"]}
                                                               </div>
                                                             </div>
-                                                            {obj.validitySchedule !==
+                                                            {obj.validitySchedule !=
+                                                            undefined ? (
+                                                              <div className="gds-inline-field-grp">
+                                                                <div className="wrapper">
+                                                                  <div className="gds-left-inline-field">
+                                                                    <span className="gds-label-color">
+                                                                      Start Date{" "}
+                                                                    </span>
+                                                                  </div>
+                                                                  <span>
+                                                                    {dateFormat(
+                                                                      obj
+                                                                        .validitySchedule
+                                                                        .startTime,
+                                                                      "mm/dd/yyyy hh:MM:ss TT"
+                                                                    )}
+                                                                  </span>
+                                                                  <span className="gds-label-color pl-5">
+                                                                    {
+                                                                      obj
+                                                                        .validitySchedule
+                                                                        .timeZone
+                                                                    }
+                                                                  </span>
+                                                                </div>
+                                                                <div className="wrapper">
+                                                                  <div className="gds-left-inline-field">
+                                                                    <span className="gds-label-color">
+                                                                      {" "}
+                                                                      End Date{" "}
+                                                                    </span>
+                                                                  </div>
+                                                                  <span>
+                                                                    {dateFormat(
+                                                                      obj
+                                                                        .validitySchedule
+                                                                        .endTime,
+                                                                      "mm/dd/yyyy hh:MM:ss TT"
+                                                                    )}
+                                                                  </span>
+                                                                </div>
+                                                              </div>
+                                                            ) : (
+                                                              <p>--</p>
+                                                            )}
+                                                            {/* {obj.validitySchedule !==
                                                             undefined ? (
                                                               <div className="gds-flex">
                                                                 <div className="gds-right-inline-field">
@@ -996,7 +1065,7 @@ const DatashareDetailLayout = () => {
                                                               </div>
                                                             ) : (
                                                               <div>--</div>
-                                                            )}
+                                                            )} */}
                                                           </div>
                                                           <div className="gds-right-inline-field-grp">
                                                             <div className="wrapper">
@@ -1023,7 +1092,11 @@ const DatashareDetailLayout = () => {
                                                             </div>
                                                             <div className="w-100 text-right">
                                                               <div>
-                                                                View Request
+                                                                <Link
+                                                                  to={`/gds/request/detail/${obj.id}`}
+                                                                >
+                                                                  View Request
+                                                                </Link>
                                                               </div>
                                                             </div>
                                                           </div>
@@ -1098,12 +1171,14 @@ const DatashareDetailLayout = () => {
                   </Tabs>
                 </div>
 
-                <Modal
+                {/* <Modal
                   show={showAddResourceModal}
                   onHide={toggleAddResourceModalClose}
+                  //className="mb-7"
+                  size="xl"
                 >
                   <Modal.Header closeButton>
-                    <span className="text-word-break">Add Resources</span>
+                    <h5 className="mb-0">Add Resources</h5>
                   </Modal.Header>
                   <Modal.Body>
                     <AddSharedResourceComp
@@ -1113,7 +1188,7 @@ const DatashareDetailLayout = () => {
                       loadSharedResource={loadSharedResource}
                     />
                   </Modal.Body>
-                  {/* <Modal.Footer>
+                   <Modal.Footer>
                     <Button variant="secondary" size="sm" onClick={toggleClose}>
                       Cancel
                     </Button>
@@ -1128,8 +1203,8 @@ const DatashareDetailLayout = () => {
                     >
                       Yes
                     </Button>
-                  </Modal.Footer> */}
-                </Modal>
+                  </Modal.Footer>
+                </Modal> */}
 
                 <Modal show={confirmDeleteModal.showPopup} onHide={toggleClose}>
                   <Modal.Header closeButton>
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/MyDatashareListing.jsx b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/MyDatashareListing.jsx
index 64a84e631..1d47384b2 100755
--- a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/MyDatashareListing.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/MyDatashareListing.jsx
@@ -39,6 +39,7 @@ import {
 } from "../../../utils/XAUtils";
 import moment from "moment-timezone";
 import { sortBy } from "lodash";
+import CustomBreadcrumb from "../../CustomBreadcrumb";
 
 const MyDatashareListing = () => {
   const navigate = useNavigate();
@@ -166,25 +167,49 @@ const MyDatashareListing = () => {
         Header: "Name",
         accessor: "name",
         width: 250,
-        disableResizing: true,
-        disableSortBy: true,
-        getResizerProps: () => {}
+        Cell: (val) => {
+          return (
+            <span
+              className="text-truncate"
+              title={val.value}
+              style={{ maxWidth: "240px", display: "inline-block" }}
+            >
+              {val.value}
+            </span>
+          );
+        }
       },
       {
         Header: "Service",
         accessor: "serviceName",
         width: 250,
-        disableResizing: true,
-        disableSortBy: true,
-        getResizerProps: () => {}
+        Cell: (val) => {
+          return (
+            <span
+              className="text-truncate"
+              title={val.value}
+              style={{ maxWidth: "240px", display: "inline-block" }}
+            >
+              {val.value}
+            </span>
+          );
+        }
       },
       {
         Header: "Zone",
         accessor: "zoneName",
         width: 250,
-        disableResizing: true,
-        disableSortBy: true,
-        getResizerProps: () => {}
+        Cell: (val) => {
+          return (
+            <span
+              className="text-truncate"
+              title={val.value}
+              style={{ maxWidth: "240px", display: "inline-block" }}
+            >
+              {val.value}
+            </span>
+          );
+        }
       },
       {
         Header: "Created",
@@ -260,7 +285,7 @@ const MyDatashareListing = () => {
               <div className="position-relative text-center">
                 <Link
                   title="Edit"
-                  to={`/gds/dataset/${row.original.id}/detail`}
+                  to={`/gds/datashare/${row.original.id}/detail`}
                 >
                   {row.original.id}
                 </Link>
@@ -279,25 +304,49 @@ const MyDatashareListing = () => {
         Header: "Name",
         accessor: "name",
         width: 250,
-        disableResizing: true,
-        disableSortBy: true,
-        getResizerProps: () => {}
+        Cell: (val) => {
+          return (
+            <span
+              className="text-truncate"
+              title={val.value}
+              style={{ maxWidth: "240px", display: "inline-block" }}
+            >
+              {val.value}
+            </span>
+          );
+        }
       },
       {
         Header: "Service",
         accessor: "serviceName",
         width: 250,
-        disableResizing: true,
-        disableSortBy: true,
-        getResizerProps: () => {}
+        Cell: (val) => {
+          return (
+            <span
+              className="text-truncate"
+              title={val.value}
+              style={{ maxWidth: "240px", display: "inline-block" }}
+            >
+              {val.value}
+            </span>
+          );
+        }
       },
       {
         Header: "Zone",
         accessor: "zoneName",
         width: 250,
-        disableResizing: true,
-        disableSortBy: true,
-        getResizerProps: () => {}
+        Cell: (val) => {
+          return (
+            <span
+              className="text-truncate"
+              title={val.value}
+              style={{ maxWidth: "240px", display: "inline-block" }}
+            >
+              {val.value}
+            </span>
+          );
+        }
       },
       {
         Header: "Permission",
@@ -416,6 +465,7 @@ const MyDatashareListing = () => {
         <h3 className="gds-header bold">
           {isMyDatasharePage ? "My" : ""} Datashares
         </h3>
+        <CustomBreadcrumb />
       </div>
       <div className="wrap">
         <React.Fragment>
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Request/RequestDetailView.jsx b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Request/RequestDetailView.jsx
index c43cffd45..dcf118e6a 100755
--- a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Request/RequestDetailView.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Request/RequestDetailView.jsx
@@ -30,6 +30,7 @@ import arrayMutators from "final-form-arrays";
 import moment from "moment-timezone";
 import { isEmpty } from "lodash";
 import { toast } from "react-toastify";
+import { getAllTimeZoneList } from "../../../utils/XAUtils";
 
 const RequestDetailView = () => {
   let { requestId } = useParams();
@@ -39,6 +40,8 @@ const RequestDetailView = () => {
   const [datasetInfo, setDatasetInfo] = useState({});
   const [datashareInfo, setDatashareInfo] = useState({});
   const [acceptTerms, setAcceptTerms] = useState(false);
+  const [formData, setFormData] = useState();
+  const [editValidityPeriod, setEditValidityPeriod] = useState(false);
 
   useEffect(() => {
     fetchRequestDetail(requestId);
@@ -50,6 +53,26 @@ const RequestDetailView = () => {
       const resp = await fetchApi({
         url: `gds/datashare/dataset/${requestId}`
       });
+      if (resp.data.validitySchedule !== undefined) {
+        let val = resp.data.validitySchedule;
+        let data = {};
+        data["validitySchedules"] = [];
+        let obj = {};
+        if (val.endTime) {
+          obj["endTime"] = moment(val.endTime, "YYYY/MM/DD HH:mm:ss");
+        }
+        if (val.startTime) {
+          obj["startTime"] = moment(val.startTime, "YYYY/MM/DD HH:mm:ss");
+        }
+        if (val.timeZone) {
+          obj["timeZone"] = getAllTimeZoneList().find((tZoneVal) => {
+            return tZoneVal.id == val.timeZone;
+          });
+        }
+        data["validitySchedules"].push(obj);
+        setFormData(data);
+        setEditValidityPeriod(true);
+      }
       setRequestInfo(resp.data);
       fetchdatasetInfo(resp.data.datasetId);
       fetchDatashaerInfo(resp.data.dataShareId);
@@ -85,7 +108,7 @@ const RequestDetailView = () => {
     navigate(`/gds/request/list`);
   };
 
-  const handleSubmit = async (values) => {
+  const handleSubmit = async (values, type) => {
     if (
       datasetInfo.termsOfUse != undefined &&
       requestInfo.status === "GRANTED" &&
@@ -119,7 +142,8 @@ const RequestDetailView = () => {
     }
 
     if (requestInfo.status === "REQUESTED") {
-      requestInfo["status"] = "GRANTED";
+      if (type == "grant") requestInfo["status"] = "GRANTED";
+      else requestInfo["status"] = "DENIED";
     } else if (requestInfo.status === "GRANTED") {
       requestInfo["status"] = "ACTIVE";
     }
@@ -155,6 +179,7 @@ const RequestDetailView = () => {
         mutators={{
           ...arrayMutators
         }}
+        initialValues={formData}
         render={({
           form: {
             mutators: { push: addPolicyItem, pop }
@@ -162,7 +187,7 @@ const RequestDetailView = () => {
           values
         }) => (
           <div>
-            <div className="gds-header-wrapper gap-half">
+            <div className="gds-header-wrapper gap-half py-3">
               <Button
                 variant="light"
                 className="border-0 bg-transparent"
@@ -178,7 +203,7 @@ const RequestDetailView = () => {
                 <div className="gds-header-btn-grp">
                   <Button
                     variant="secondary"
-                    //onClick={() => removeChanges()}
+                    onClick={() => handleSubmit(values, "deny")}
                     size="sm"
                     data-id="deny"
                     data-cy="deny"
@@ -187,7 +212,7 @@ const RequestDetailView = () => {
                   </Button>
                   <Button
                     variant="primary"
-                    onClick={() => handleSubmit(values)}
+                    onClick={() => handleSubmit(values, "grant")}
                     size="sm"
                     data-id="grant"
                     data-cy="grant"
@@ -200,7 +225,7 @@ const RequestDetailView = () => {
                   {requestInfo.status === "GRANTED" ? (
                     <Button
                       variant="primary"
-                      onClick={() => handleSubmit(values)}
+                      onClick={() => handleSubmit(values, "active")}
                       size="sm"
                       data-id="activate"
                       data-cy="activate"
@@ -221,10 +246,9 @@ const RequestDetailView = () => {
                   <div className="gds-inline-field-grp">
                     <div className="wrapper">
                       <div className="gds-left-inline-field" height="30px">
-                        <span>Status</span>
+                        <span className="gds-label-color">Status</span>
                       </div>
                       <span
-                        //className="badge badge-light gds-requested-status"
                         className={
                           requestInfo.status === "REQUESTED"
                             ? "badge badge-light gds-requested-status"
@@ -240,20 +264,20 @@ const RequestDetailView = () => {
                     </div>
                     <div className="wrapper">
                       <div className="gds-left-inline-field" height="30px">
-                        <span>Created by</span>
+                        <span className="gds-label-color">Created by</span>
                       </div>
                       <div line-height="30px">{requestInfo.createdBy}</div>
                     </div>
                     <div className="wrapper">
                       <div className="gds-left-inline-field" height="30px">
-                        <span>Approver</span>
+                        <span className="gds-label-color">Approver</span>
                       </div>
                       <div line-height="30px">{requestInfo.approvedBy}</div>
                     </div>
                   </div>
                   <div className="gds-right-inline-field-grp">
                     <div className="wrapper">
-                      <div>Created</div>
+                      <div className="gds-label-color">Created</div>
                       <div className="gds-right-inline-field">
                         <span>
                           {dateFormat(
@@ -264,7 +288,7 @@ const RequestDetailView = () => {
                       </div>
                     </div>
                     <div className="wrapper">
-                      <div>Last Updated</div>
+                      <div className="gds-label-color">Last Updated</div>
                       <div className="gds-right-inline-field">
                         <span>
                           {dateFormat(
@@ -274,57 +298,52 @@ const RequestDetailView = () => {
                         </span>
                       </div>
                     </div>
-                    {requestInfo.status == "REQUESTED" ? (
-                      <Field name="validityPeriod">
-                        {({ input, meta }) => (
-                          <PolicyValidityPeriodComp
-                            addPolicyItem={addPolicyItem}
-                            isGdsRequest={
-                              requestInfo.validitySchedule == undefined
-                                ? true
-                                : false
-                            }
-                          />
-                        )}
-                      </Field>
-                    ) : (
-                      <div>
-                        {requestInfo.validitySchedule != undefined ? (
-                          <div className="wrapper">
-                            <div>
-                              <span>Validity Period</span>
-                            </div>
-                            <div className="gds-right-inline-field">
-                              <span>
-                                Start Time:{" "}
-                                {dateFormat(
-                                  requestInfo.validitySchedule.startTime,
-                                  "mm/dd/yyyy hh:MM:ss TT"
-                                )}
-                              </span>
-                            </div>
-                            <div className="gds-right-inline-field">
-                              <span>
-                                End Time:{" "}
-                                {dateFormat(
-                                  requestInfo.validitySchedule.endTime,
-                                  "mm/dd/yyyy hh:MM:ss TT"
-                                )}
-                              </span>
-                            </div>
-                            <div className="gds-right-inline-field">
-                              <span>
-                                {requestInfo.validitySchedule.timeZone}
-                              </span>
-                            </div>
-                          </div>
-                        ) : (
-                          <div></div>
-                        )}
-                      </div>
-                    )}
                   </div>
                 </div>
+                <div className="mb-5">
+                  <hr className="m-0" />
+                  <div className="d-flex align-items-center justify-content-between mb-4 pt-4">
+                    <span className="gds-card-heading border-0 p-0">
+                      Validity Period
+                    </span>
+                    <PolicyValidityPeriodComp
+                      addPolicyItem={addPolicyItem}
+                      isGdsRequest={
+                        requestInfo.validitySchedule == undefined ? true : false
+                      }
+                      editValidityPeriod={editValidityPeriod}
+                    />
+                  </div>
+                  {requestInfo.validitySchedule != undefined && (
+                    <div className="gds-inline-field-grp">
+                      <div className="wrapper">
+                        <div className="gds-left-inline-field">
+                          <span className="gds-label-color">Start Date </span>
+                        </div>
+                        <span>
+                          {dateFormat(
+                            requestInfo.validitySchedule.startTime,
+                            "mm/dd/yyyy hh:MM:ss TT"
+                          )}
+                        </span>
+                        <span className="gds-label-color pl-5">
+                          {requestInfo.validitySchedule.timeZone}
+                        </span>
+                      </div>
+                      <div className="wrapper">
+                        <div className="gds-left-inline-field">
+                          <span className="gds-label-color"> End Date </span>
+                        </div>
+                        <span>
+                          {dateFormat(
+                            requestInfo.validitySchedule.endTime,
+                            "mm/dd/yyyy hh:MM:ss TT"
+                          )}
+                        </span>
+                      </div>
+                    </div>
+                  )}
+                </div>
                 <div className="mb-5">
                   <Card className="gds-section-card gds-bg-white">
                     <div className="gds-section-title">
@@ -354,7 +373,7 @@ const RequestDetailView = () => {
                       <div className="w-100 mb-3">
                         <div className="wrapper">
                           <div className="gds-left-inline-field" height="30px">
-                            <span>Name </span>
+                            <span className="gds-label-color">Name </span>
                           </div>
                           <div line-height="30px">{datashareInfo.name}</div>
                         </div>
@@ -362,12 +381,12 @@ const RequestDetailView = () => {
                       <div className="w-100 mb-3 d-flex justify-content-between">
                         <div className="wrapper w-50">
                           <div className="gds-left-inline-field" height="30px">
-                            <span>Service </span>
+                            <span className="gds-label-color">Service </span>
                           </div>
                           <div line-height="30px">{datashareInfo.service}</div>
                         </div>
                         <div className="wrapper w-50">
-                          <div>Security Zone</div>
+                          <div className="gds-label-color">Security Zone</div>
                           <div className="gds-right-inline-field">
                             <span>{datashareInfo.zone}</span>
                           </div>
@@ -376,7 +395,7 @@ const RequestDetailView = () => {
                       <div className="w-100 mb-3">
                         <div className="wrapper">
                           <div className="gds-left-inline-field" height="30px">
-                            <span>Conditions</span>
+                            <span className="gds-label-color">Conditions</span>
                           </div>
                           <div line-height="30px">
                             {datashareInfo.conditionExpr}
@@ -385,7 +404,11 @@ const RequestDetailView = () => {
                       </div>
                       <div className="w-100 mb-3">
                         <div className="wrapper">
-                          <div>Default Access Type</div>
+                          <div className="gds-left-inline-field" height="30px">
+                            <span className="gds-label-color">
+                              Default Access Type
+                            </span>
+                          </div>
                           <div className="gds-left-inline-field">
                             <span>
                               {datashareInfo.defaultAccessTypes != undefined ? (
@@ -416,7 +439,7 @@ const RequestDetailView = () => {
                             className="gds-left-inline-field flex-shrink-0"
                             height="30px"
                           >
-                            <span>Name </span>
+                            <span className="gds-label-color">Name </span>
                           </div>
                           <div line-height="30px">{datasetInfo.name}</div>
                         </div>
@@ -425,7 +448,9 @@ const RequestDetailView = () => {
                             className="gds-left-inline-field flex-shrink-0"
                             height="30px"
                           >
-                            <span>Description </span>
+                            <span className="gds-label-color">
+                              Description{" "}
+                            </span>
                           </div>
                           <div line-height="30px">
                             <span>{datasetInfo.description}</span>
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Request/RequestListing.jsx b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Request/RequestListing.jsx
index f0cae8c8c..60b96699f 100755
--- a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Request/RequestListing.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Request/RequestListing.jsx
@@ -35,6 +35,7 @@ import {
   BlockUi
 } from "../../../components/CommonComponents";
 import moment from "moment-timezone";
+import CustomBreadcrumb from "../../CustomBreadcrumb";
 import {
   isKeyAdmin,
   isKMSAuditor,
@@ -196,8 +197,9 @@ const RequestListing = () => {
     <Loader />
   ) : (
     <>
-      <div className="gds-header-wrapper">
-        <h3 className="gds-header bold">My Requests</h3>
+      <div className="header-wraper">
+        <h3 className="wrap-header bold">My Requests</h3>
+        <CustomBreadcrumb />
       </div>
       <div className="wrap">
         <React.Fragment>
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyValidityPeriodComp.jsx b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyValidityPeriodComp.jsx
index 02419e61e..e2ef63188 100644
--- a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyValidityPeriodComp.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyValidityPeriodComp.jsx
@@ -93,7 +93,8 @@ export default function PolicyValidityPeriodComp(props) {
         data-js="policyTimeBtn"
         data-cy="policyTimeBtn"
       >
-        <i className="fa fa-clock-o"></i> Add Validity Period
+        <i className="fa fa-clock-o"></i>{" "}
+        {props.editValidityPeriod ? "Edit" : "Add"} Validity Period
       </Button>
       <Modal show={showModal} size="lg" onHide={toggleModal} backdrop="static">
         <Modal.Header closeButton>
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/SideBar/TopNavBar.jsx b/security-admin/src/main/webapp/react-webapp/src/views/SideBar/TopNavBar.jsx
index d4dbc57d1..e77cdd5e6 100644
--- a/security-admin/src/main/webapp/react-webapp/src/views/SideBar/TopNavBar.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/SideBar/TopNavBar.jsx
@@ -240,9 +240,15 @@ export const TopNavBar = (props) => {
         )}
       </div>
       <div
-        className="collapse navbar-collapse justify-content-end"
+        className="collapse navbar-collapse justify-content-end gap-half"
         id="navbarText"
       >
+        <span className="navbar-text last-response-time">
+          <strong>Last Response Time</strong>
+          <br />
+          {moment(moment()).format("MM/DD/YYYY hh:mm:ss A")}
+        </span>
+        {(!isUserRole || isAdminRole) && <span className="pipe"></span>}
         {(!isUserRole || isAdminRole) && (
           <DropdownButton
             id="dropdown-item-button"
@@ -302,13 +308,6 @@ export const TopNavBar = (props) => {
             )}
           </DropdownButton>
         )}
-
-        {(!isUserRole || isAdminRole) && <span className="pipe"></span>}
-        <span className="navbar-text last-response-time">
-          <strong>Last Response Time</strong>
-          <br />
-          {moment(moment()).format("MM/DD/YYYY hh:mm:ss A")}
-        </span>
       </div>
       <Modal
         show={showView === serviceData?.id}


[ranger] 01/02: RANGER-4440: added column x_security_zone.gz_jsonData to store compressed bytes - #3

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit e5dd94c07b8d9724de5167b3e295338bcb5fd883
Author: Madhan Neethiraj <ma...@apache.org>
AuthorDate: Wed Oct 11 22:17:22 2023 -0700

    RANGER-4440: added column x_security_zone.gz_jsonData to store compressed bytes - #3
---
 .../ranger/authorization/utils/StringUtil.java     | 24 +++++------------
 .../optimized/current/ranger_core_db_mysql.sql     |  1 +
 .../optimized/current/ranger_core_db_postgres.sql  |  1 +
 .../apache/ranger/entity/XXSecurityZoneBase.java   | 12 ++++++---
 .../service/RangerSecurityZoneServiceService.java  | 30 +++++++++++++++-------
 5 files changed, 38 insertions(+), 30 deletions(-)

diff --git a/agents-common/src/main/java/org/apache/ranger/authorization/utils/StringUtil.java b/agents-common/src/main/java/org/apache/ranger/authorization/utils/StringUtil.java
index 12a89889a..db04e5539 100644
--- a/agents-common/src/main/java/org/apache/ranger/authorization/utils/StringUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/authorization/utils/StringUtil.java
@@ -46,8 +46,6 @@ import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 public class StringUtil {
     private static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT+0");
 
-    private static final String COMPRESS_GZIP_MAGIC = "GZip:";
-
 
     public static boolean equals(String str1, String str2) {
 		boolean ret = false;
@@ -526,11 +524,7 @@ public class StringUtil {
 		if (StringUtils.isEmpty(input)) {
 			ret = input;
 		} else {
-			byte[] bytes = input.getBytes(StandardCharsets.ISO_8859_1);
-
-			bytes = gzipCompress(bytes);
-
-			ret = COMPRESS_GZIP_MAGIC + new String(bytes, StandardCharsets.ISO_8859_1);
+			ret = new String(gzipCompress(input), StandardCharsets.ISO_8859_1);
 		}
 
 		return ret;
@@ -541,30 +535,24 @@ public class StringUtil {
 
 		if (StringUtils.isEmpty(input)) {
 			ret = input;
-		} else if (input.startsWith(COMPRESS_GZIP_MAGIC)) {
-			byte[] bytes = input.substring(COMPRESS_GZIP_MAGIC.length()).getBytes(StandardCharsets.ISO_8859_1);
-
-			bytes = gzipDecompress(bytes);
-
-			ret = new String(bytes, StandardCharsets.ISO_8859_1);
 		} else {
-			ret = input;
+			ret = gzipDecompress(input.getBytes(StandardCharsets.ISO_8859_1));
 		}
 
 		return ret;
 	}
 
-	public static byte[] gzipCompress(byte[] input) throws IOException {
+	public static byte[] gzipCompress(String input) throws IOException {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
 		GZIPOutputStream      gos = new GZIPOutputStream(out);
 
-		gos.write(input);
+		gos.write(input.getBytes(StandardCharsets.ISO_8859_1));
 		gos.close();
 
 		return out.toByteArray();
 	}
 
-	public static byte[] gzipDecompress(byte[] input) throws IOException {
+	public static String gzipDecompress(byte[] input) throws IOException {
 		ByteArrayInputStream  in  = new ByteArrayInputStream(input);
 		GZIPInputStream       gis = new GZIPInputStream(in);
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -582,6 +570,6 @@ public class StringUtil {
 
 		gis.close();
 
-		return out.toByteArray();
+		return new String(out.toByteArray(), StandardCharsets.ISO_8859_1);
 	}
 }
diff --git a/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql b/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql
old mode 100755
new mode 100644
index dbeeaf423..3cbca48ef
--- a/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql
+++ b/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql
@@ -588,6 +588,7 @@ CREATE TABLE IF NOT EXISTS `x_security_zone`(
 `version` bigint(20) NULL DEFAULT NULL,
 `name` varchar(255) NOT NULL,
 `jsonData` MEDIUMTEXT NULL DEFAULT NULL,
+`gz_jsonData` LONGBLOB NULL DEFAULT NULL,
 `description` varchar(1024) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `x_security_zone_UK_name`(`name`(190)),
diff --git a/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql b/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql
old mode 100755
new mode 100644
index 065bae0df..4cdf7e27d
--- a/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql
+++ b/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql
@@ -595,6 +595,7 @@ upd_by_id BIGINT DEFAULT NULL NULL,
 version BIGINT DEFAULT NULL NULL,
 name varchar(255) NOT NULL,
 jsonData text DEFAULT NULL NULL,
+gz_jsonData BYTEA NULL DEFAULT NULL,
 description VARCHAR(1024) DEFAULT NULL NULL,
 primary key (id),
 CONSTRAINT x_security_zone_UK_name UNIQUE (name),
diff --git a/security-admin/src/main/java/org/apache/ranger/entity/XXSecurityZoneBase.java b/security-admin/src/main/java/org/apache/ranger/entity/XXSecurityZoneBase.java
index ecdaf2485..e46b2c8a8 100644
--- a/security-admin/src/main/java/org/apache/ranger/entity/XXSecurityZoneBase.java
+++ b/security-admin/src/main/java/org/apache/ranger/entity/XXSecurityZoneBase.java
@@ -36,12 +36,16 @@ public abstract class XXSecurityZoneBase extends XXDBBase {
     @Column(name = "jsonData")
     protected String jsonData;
 
+    @Column(name = "gz_jsonData")
+    protected byte[] gzJsonData;
+
     @Column(name = "description")
     protected String description;
 
     public Long getVersion() { return version; }
     public String getName() { return name; }
     public String getJsonData() { return jsonData; }
+    public byte[] getGzJsonData() { return gzJsonData; }
     public String getDescription() { return description; }
 
     public void setName(String name) {
@@ -50,6 +54,7 @@ public abstract class XXSecurityZoneBase extends XXDBBase {
     public void setJsonData(String jsonData) {
         this.jsonData = jsonData;
     }
+    public void setGzJsonData(byte[] gzJsonData) { this.gzJsonData = gzJsonData; }
     public void setDescription(String description) {
         this.description = description;
     }
@@ -70,19 +75,20 @@ public abstract class XXSecurityZoneBase extends XXDBBase {
 
         return Objects.equals(version, other.version) &&
                 Objects.equals(name, other.name) &&
-                Objects.equals(jsonData, other.jsonData);
+                Objects.equals(jsonData, other.jsonData) &&
+                Objects.equals(gzJsonData, other.gzJsonData);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(super.hashCode(), version, name, jsonData);
+        return Objects.hash(super.hashCode(), version, name, jsonData, gzJsonData);
     }
 
     @Override
     public String toString() {
         String str = "XXSecurityZoneBase={";
         str += super.toString();
-        str += " [version=" + version + ", name=" + name + ", jsonData=" + jsonData + "]";
+        str += " [version=" + version + ", name=" + name + ", jsonData=" + jsonData + ", gzJsonData=" + gzJsonData + "]";
         str += "}";
         return str;
     }
diff --git a/security-admin/src/main/java/org/apache/ranger/service/RangerSecurityZoneServiceService.java b/security-admin/src/main/java/org/apache/ranger/service/RangerSecurityZoneServiceService.java
index 8acdd9813..d500acb8e 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/RangerSecurityZoneServiceService.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/RangerSecurityZoneServiceService.java
@@ -98,7 +98,7 @@ public class RangerSecurityZoneServiceService extends RangerSecurityZoneServiceB
 
         RangerAdminConfig config = RangerAdminConfig.getInstance();
 
-        compressJsonData = config.getBoolean("ranger.admin.store.security.zone.compress.json_data", false);
+        compressJsonData = config.getBoolean("ranger.admin.store.security.zone.compress.json_data", compressJsonData);
 
         logger.info("ranger.admin.store.security.zone.compress.json_data={}", compressJsonData);
 
@@ -128,28 +128,40 @@ public class RangerSecurityZoneServiceService extends RangerSecurityZoneServiceB
 
         if (StringUtils.isNotEmpty(json) && compressJsonData) {
             try {
-                json = StringUtil.compressString(json);
+                ret.setJsonData(null);
+                ret.setGzJsonData(StringUtil.gzipCompress(json));
             } catch (IOException excp) {
                 logger.error("mapViewToEntityBean(): json compression failed (length={}). Will save uncompressed json", json.length(), excp);
+
+                ret.setJsonData(json);
+                ret.setGzJsonData(null);
             }
+        } else {
+            ret.setJsonData(json);
+            ret.setGzJsonData(null);
         }
 
-        ret.setJsonData(json);
-
         return ret;
     }
     @Override
     protected RangerSecurityZone mapEntityToViewBean(RangerSecurityZone securityZone, XXSecurityZone xxSecurityZone) {
-        RangerSecurityZone ret  = super.mapEntityToViewBean(securityZone, xxSecurityZone);
-        String             json = xxSecurityZone.getJsonData();
+        RangerSecurityZone ret    = super.mapEntityToViewBean(securityZone, xxSecurityZone);
+        byte[]             gzJson = xxSecurityZone.getGzJsonData();
+        String             json;
 
-        if (StringUtils.isNotEmpty(json)) {
+        if (gzJson != null) {
             try {
-                json = StringUtil.decompressString(json);
+                json = StringUtil.gzipDecompress(gzJson);
             } catch (IOException excp) {
-                logger.error("mapEntityToViewBean(): json decompression failed (length={}). Will treat as uncompressed json", json.length(), excp);
+                json = xxSecurityZone.getJsonData();
+
+                logger.error("mapEntityToViewBean(): decompression of x_security_zone.gz_jsonData failed (length={}). Will use contents of x_security_zone.jsonData (length={})", gzJson.length, (json != null ? json.length() : 0), excp);
             }
+        } else {
+            json = xxSecurityZone.getJsonData();
+        }
 
+        if (StringUtils.isNotEmpty(json)) {
             RangerSecurityZone zoneFromJsonData = gsonBuilder.fromJson(json, RangerSecurityZone.class);
 
             if (zoneFromJsonData == null) {