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

lahirujayathilake pushed a commit to branch cybershuttle-staging
in repository https://gitbox.apache.org/repos/asf/airavata.git


The following commit(s) were added to refs/heads/cybershuttle-staging by this 
push:
     new 6288ddf04a Backend integration with portal
6288ddf04a is described below

commit 6288ddf04ad5a41cf3f830336a6ebf9ff2eeb37b
Author: Ganning Xu <[email protected]>
AuthorDate: Mon Mar 31 23:41:18 2025 -0400

    Backend integration with portal
    
    * Prep for demo (Frontend + Backend)
    
    * Add unversioned files
---
 modules/research-framework/portal/src/App.tsx      | 13 +++-
 .../portal/src/components/NavBar.tsx               | 12 +++-
 .../portal/src/components/datasets/index.tsx       |  2 +-
 .../portal/src/components/home/ProjectCard.tsx     | 77 +++++++++++++++++++++
 .../portal/src/components/home/ProjectsSection.tsx | 35 ++++++++++
 .../portal/src/components/home/ResourceCard.tsx    | 80 +++++++++++++---------
 .../portal/src/components/home/SessionCard.tsx     | 68 +++++++++---------
 .../portal/src/components/home/SessionsSection.tsx | 36 ++++++++--
 .../portal/src/components/home/index.tsx           | 10 +--
 .../src/components/models/ModelSpecificBox.tsx     |  2 +-
 .../portal/src/components/models/index.tsx         |  2 +-
 .../portal/src/components/notebooks/index.tsx      | 52 +++++++++-----
 .../portal/src/components/repositories/index.tsx   | 58 ++++++++++------
 .../src/components/resources/ResourceDetails.tsx   | 18 +++--
 .../portal/src/interfaces/ProjectType.tsx          | 11 +--
 .../portal/src/interfaces/SessionStatusEnum.ts     |  7 ++
 .../portal/src/interfaces/SessionType.tsx          | 20 +++---
 modules/research-framework/portal/src/lib/util.ts  |  9 +++
 .../service/config/DevDataInitializer.java         | 66 +++++++++---------
 .../service/controller/ResearchHubController.java  | 48 +++++++++++--
 .../research/service/enums/SessionStatusEnum.java  | 17 +++++
 .../service/handlers/ResearchHubHandler.java       | 11 ++-
 .../research/service/handlers/SessionHandler.java  | 24 +++++++
 .../research/service/model/entity/Project.java     | 11 +++
 .../research/service/model/entity/Session.java     | 27 +++++---
 .../service/model/repo/SessionRepository.java      |  9 +++
 .../src/main/resources/application.yml             |  2 +-
 27 files changed, 533 insertions(+), 194 deletions(-)

diff --git a/modules/research-framework/portal/src/App.tsx 
b/modules/research-framework/portal/src/App.tsx
index 64a6ce7ef4..0cfb22af89 100644
--- a/modules/research-framework/portal/src/App.tsx
+++ b/modules/research-framework/portal/src/App.tsx
@@ -7,6 +7,8 @@ import { ModelDetails } from "./components/models/ModelDetails";
 import { Datasets } from "./components/datasets";
 import { DatasetDetails } from "./components/datasets/DatasetDetails";
 import ResourceDetails from "./components/resources/ResourceDetails";
+import Notebooks from "./components/notebooks";
+import Repositories from "./components/repositories";
 
 function App() {
   const colorMode = useColorMode();
@@ -19,9 +21,16 @@ function App() {
       <BrowserRouter>
         <Routes>
           <Route index element={<Home />} />
-          <Route path="/resources/">
-            <Route path=":id" element={<ResourceDetails />} />
+          <Route path="/resources">
+            <Route path="notebooks" element={<Notebooks />} />
+            <Route path="datasets" element={<Datasets />} />
+            <Route path="repositories" element={<Repositories />} />
+            <Route path="models" element={<Models />} />
+
+            {/* Dynamic Route for specific resource details */}
+            <Route path=":type/:id" element={<ResourceDetails />} />
           </Route>
+
           <Route path="/notebook">
             <Route path=":slug" element={<ProjectDetails />} />
           </Route>
diff --git a/modules/research-framework/portal/src/components/NavBar.tsx 
b/modules/research-framework/portal/src/components/NavBar.tsx
index 90ec9713ad..03ebf74e1b 100644
--- a/modules/research-framework/portal/src/components/NavBar.tsx
+++ b/modules/research-framework/portal/src/components/NavBar.tsx
@@ -9,11 +9,19 @@ const NAV_CONTENT = [
   },
   {
     title: "Datasets",
-    url: "/datasets",
+    url: "/resources/datasets",
+  },
+  {
+    title: "Repositories",
+    url: "/resources/repositories",
+  },
+  {
+    title: "Notebooks",
+    url: "/resources/notebooks",
   },
   {
     title: "Models",
-    url: "/models",
+    url: "/resources/models",
   },
 ];
 
diff --git 
a/modules/research-framework/portal/src/components/datasets/index.tsx 
b/modules/research-framework/portal/src/components/datasets/index.tsx
index 2abb968b6b..6d89984f6d 100644
--- a/modules/research-framework/portal/src/components/datasets/index.tsx
+++ b/modules/research-framework/portal/src/components/datasets/index.tsx
@@ -39,7 +39,7 @@ export const Datasets = () => {
     <>
       <NavBar />
 
-      <Container maxW="container.lg" p={4}>
+      <Container maxW="container.lg" mt={8}>
         <HStack alignItems="flex-end" justify="space-between">
           <PageHeader
             title="Datasets"
diff --git 
a/modules/research-framework/portal/src/components/home/ProjectCard.tsx 
b/modules/research-framework/portal/src/components/home/ProjectCard.tsx
new file mode 100644
index 0000000000..8096c93a4a
--- /dev/null
+++ b/modules/research-framework/portal/src/components/home/ProjectCard.tsx
@@ -0,0 +1,77 @@
+import { ProjectType } from "@/interfaces/ProjectType";
+import api from "@/lib/api";
+import { API_VERSION, BACKEND_URL } from "@/lib/constants";
+import { Button, Card, HStack, Text } from "@chakra-ui/react";
+import { useEffect, useState } from "react";
+
+async function checkIfSessionWithProjectExists(project: ProjectType) {
+  try {
+    await api.get(`/hub/project/${project.id}/exists`);
+
+    return true;
+  } catch (error: any) {
+    return false;
+  }
+}
+
+export const ProjectCard = ({ project }: { project: ProjectType }) => {
+  const [exists, setExists] = useState(false);
+  useEffect(() => {
+    let intervalId: NodeJS.Timeout;
+
+    async function fetchData() {
+      const exists = await checkIfSessionWithProjectExists(project);
+      setExists(exists);
+    }
+
+    fetchData(); // Initial fetch
+
+    intervalId = setInterval(fetchData, 2000); // Fetch every 5 seconds
+
+    return () => clearInterval(intervalId); // Cleanup on unmount
+  }, [project]); // Depend on project so it updates correctly
+
+  return (
+    <Card.Root overflow="hidden" size="md">
+      <Card.Body gap="2">
+        {/* Card Content */}
+        <HStack alignItems="center" justifyContent="space-between">
+          <Card.Title>{project.name}</Card.Title>
+          <Text color="gray.500">
+            {new Date(project.createdAt).toLocaleDateString()}
+          </Text>
+        </HStack>
+
+        <Text fontWeight="bold">
+          Repository:{" "}
+          <Text as="span" fontWeight="normal">
+            {project.repositoryResource.name}
+          </Text>
+        </Text>
+        <Text fontWeight="bold">
+          Datasets:{" "}
+          <Text as="span" fontWeight="normal">
+            {project.datasetResources.map((dataset) => dataset.name).join(", 
")}
+          </Text>
+        </Text>
+
+        {exists ? (
+          <Text color="green.600">Session already started</Text>
+        ) : (
+          <Button
+            colorPalette="black"
+            size="sm"
+            onClick={() => {
+              window.open(
+                
`${BACKEND_URL}/api/${API_VERSION}/rf/hub/project/${project.id}?sessionName=${project.name}`,
+                "_blank"
+              );
+            }}
+          >
+            Open Project
+          </Button>
+        )}
+      </Card.Body>
+    </Card.Root>
+  );
+};
diff --git 
a/modules/research-framework/portal/src/components/home/ProjectsSection.tsx 
b/modules/research-framework/portal/src/components/home/ProjectsSection.tsx
new file mode 100644
index 0000000000..ad8f930465
--- /dev/null
+++ b/modules/research-framework/portal/src/components/home/ProjectsSection.tsx
@@ -0,0 +1,35 @@
+import { ProjectType } from "@/interfaces/ProjectType";
+import api from "@/lib/api";
+import { SimpleGrid } from "@chakra-ui/react";
+import { useEffect, useState } from "react";
+import { ProjectCard } from "./ProjectCard";
+
+async function getAllProjects() {
+  try {
+    const response = await api.get("/hub/projects");
+    const data = response.data;
+    return data;
+  } catch (error) {
+    console.error("Error fetching:", error);
+  }
+}
+export const ProjectsSection = () => {
+  const [projects, setProjects] = useState<ProjectType[]>([]);
+
+  useEffect(() => {
+    async function init() {
+      const projects = await getAllProjects();
+      console.log(projects);
+      setProjects(projects);
+    }
+
+    init();
+  }, []);
+  return (
+    <SimpleGrid mt={2} columns={{ base: 1, md: 2, lg: 2 }}>
+      {projects.map((project: ProjectType) => {
+        return <ProjectCard project={project} key={project.id} />;
+      })}
+    </SimpleGrid>
+  );
+};
diff --git 
a/modules/research-framework/portal/src/components/home/ResourceCard.tsx 
b/modules/research-framework/portal/src/components/home/ResourceCard.tsx
index 49dc2e2b54..b5bc8c26e8 100644
--- a/modules/research-framework/portal/src/components/home/ResourceCard.tsx
+++ b/modules/research-framework/portal/src/components/home/ResourceCard.tsx
@@ -1,6 +1,6 @@
 import { ModelResource, Resource } from "@/interfaces/ResourceType";
 import { Tag } from "@/interfaces/TagType";
-import { resourceTypeToColor } from "@/lib/util";
+import { isValidImaage, resourceTypeToColor } from "@/lib/util";
 import {
   Text,
   Box,
@@ -18,31 +18,36 @@ import { ModelCardButton } from "../models/ModelCardButton";
 export const ResourceCard = ({ resource }: { resource: Resource }) => {
   console.log("Resource:", resource);
   const author = resource.authors[0];
+
+  const isValidImage = isValidImaage(resource.headerImage);
+
   return (
     <Box>
       <Card.Root overflow="hidden" size="md">
-        <Link to={`/resources/${resource.id}`}>
+        <Link to={`${resource.id}`}>
           {/* Image Container with Badge */}
-          <Box position="relative" width="full">
-            {/* Badge in the upper-left */}
-            <ResourceTypeBadge
-              type={resource.type}
-              position="absolute"
-              top="2"
-              left="2"
-              zIndex="1"
-              boxShadow="md" // Optional: Shadow for visibility
-            />
+          {isValidImage && (
+            <Box position="relative" width="full">
+              {/* Badge in the upper-left */}
+              <ResourceTypeBadge
+                type={resource.type}
+                position="absolute"
+                top="2"
+                left="2"
+                zIndex="1"
+                boxShadow="md" // Optional: Shadow for visibility
+              />
 
-            {/* Full-width Image */}
-            <Image
-              src={resource.headerImage}
-              alt={resource.name}
-              width="100%" // Ensure full width
-              height="200px"
-              objectFit="cover"
-            />
-          </Box>
+              {/* Full-width Image */}
+              <Image
+                src={resource.headerImage}
+                alt={resource.name}
+                width="100%" // Ensure full width
+                height="200px"
+                objectFit="cover"
+              />
+            </Box>
+          )}
 
           <Card.Body
             gap="2"
@@ -50,6 +55,11 @@ export const ResourceCard = ({ resource }: { resource: 
Resource }) => {
           >
             {/* Card Content */}
             <Card.Title>{resource.name}</Card.Title>
+            {!isValidImage && (
+              <Box>
+                <ResourceTypeBadge type={resource.type} />
+              </Box>
+            )}
             <HStack flexWrap="wrap">
               {resource.tags.map((tag: Tag) => (
                 <Badge
@@ -69,20 +79,22 @@ export const ResourceCard = ({ resource }: { resource: 
Resource }) => {
         </Link>
 
         <Card.Footer justifyContent="space-between" pt={4}>
-          <HStack>
-            <Avatar.Root shape="full" size="sm">
-              <Avatar.Fallback
-                name={author.firstName + " " + author.lastName}
-              />
-              <Avatar.Image src={author.avatar} />
-            </Avatar.Root>
+          {author && (
+            <HStack>
+              <Avatar.Root shape="full" size="sm">
+                <Avatar.Fallback
+                  name={author.firstName + " " + author.lastName}
+                />
+                <Avatar.Image src={author.avatar} />
+              </Avatar.Root>
 
-            <Box>
-              <Text fontWeight="bold">
-                {author.firstName + " " + author.lastName}
-              </Text>
-            </Box>
-          </HStack>
+              <Box>
+                <Text fontWeight="bold">
+                  {author.firstName + " " + author.lastName}
+                </Text>
+              </Box>
+            </HStack>
+          )}
 
           {(resource.type as ResourceTypeEnum) === ResourceTypeEnum.MODEL && (
             <ModelCardButton model={resource as ModelResource} />
diff --git 
a/modules/research-framework/portal/src/components/home/SessionCard.tsx 
b/modules/research-framework/portal/src/components/home/SessionCard.tsx
index a6bf2ee4be..a529a0cde8 100644
--- a/modules/research-framework/portal/src/components/home/SessionCard.tsx
+++ b/modules/research-framework/portal/src/components/home/SessionCard.tsx
@@ -1,17 +1,18 @@
 import { SessionType } from "@/interfaces/SessionType";
+import { API_VERSION, BACKEND_URL } from "@/lib/constants";
 import {
   Box,
   Text,
   Card,
   Heading,
   HStack,
-  SimpleGrid,
   Badge,
+  Button,
 } from "@chakra-ui/react";
 
 const getColorPalette = (status: string) => {
   switch (status) {
-    case "running":
+    case "CREATED":
       return "green";
     case "stopped":
       return "red";
@@ -23,19 +24,11 @@ const getColorPalette = (status: string) => {
 };
 export const SessionCard = ({ session }: { session: SessionType }) => {
   return (
-    <Card.Root
-      size="sm"
-      bg={
-        session.title.toLocaleLowerCase() === "jupyter"
-          ? "green.50"
-          : "purple.50"
-      }
-    >
+    <Card.Root size="sm">
       <Card.Header>
         <HStack justify="space-between" alignItems="flex-start">
           <Box>
-            <Heading size="lg">{session.title}</Heading>
-            <Text color="fg.muted">{session.started}</Text>
+            <Heading size="lg">{session.sessionName}</Heading>
           </Box>
           <Badge size="md" colorPalette={getColorPalette(session.status)}>
             {session.status}
@@ -43,29 +36,36 @@ export const SessionCard = ({ session }: { session: 
SessionType }) => {
         </HStack>
       </Card.Header>
       <Card.Body>
-        <SimpleGrid columns={2}>
-          <KeyValue label="Models" value={session.models.join(", ")} />
-          <KeyValue label="Datasets" value={session.datasets.join(", ")} />
-          <KeyValue label="Nodes" value={session.nodes.toString()} />
-          <KeyValue label="RAM" value={session.ram.toString()} />
-          <KeyValue label="Storage" value={session.storage.toString()} />
-        </SimpleGrid>
+        <Text color="fg.muted">
+          <Text as="span" fontWeight="bold">
+            Created
+          </Text>
+          : {new Date(session.createdAt).toLocaleString()}
+        </Text>
+
+        <HStack alignItems="center" mt={2}>
+          <Button
+            size="sm"
+            colorPalette="red"
+            variant="subtle"
+            onClick={() => {}}
+          >
+            Terminate
+          </Button>
+          <Button
+            size="sm"
+            colorPalette="green"
+            onClick={() => {
+              window.open(
+                
`${BACKEND_URL}/api/${API_VERSION}/rf/hub/sessions/${session.id}/resolve`,
+                "_blank"
+              );
+            }}
+          >
+            Open Session
+          </Button>
+        </HStack>
       </Card.Body>
     </Card.Root>
   );
 };
-
-export const KeyValue = ({
-  label,
-  value,
-}: {
-  label: string;
-  value: string;
-}) => {
-  return (
-    <HStack>
-      <Text fontWeight="bold">{label}:</Text>
-      <Text>{value}</Text>
-    </HStack>
-  );
-};
diff --git 
a/modules/research-framework/portal/src/components/home/SessionsSection.tsx 
b/modules/research-framework/portal/src/components/home/SessionsSection.tsx
index d3dd2eeea4..20e8e63f44 100644
--- a/modules/research-framework/portal/src/components/home/SessionsSection.tsx
+++ b/modules/research-framework/portal/src/components/home/SessionsSection.tsx
@@ -1,15 +1,43 @@
-// @ts-expect-error This is fine
-import { MOCK_SESSIONS } from "../../data/MOCK_DATA";
 import { SessionType } from "@/interfaces/SessionType";
 import { SessionCard } from "./SessionCard";
 import { GridContainer } from "../GridContainer";
+import api from "@/lib/api";
+import { useEffect, useState } from "react";
+
+async function getSessions() {
+  try {
+    const response = await api.get("/hub/sessions");
+    const data = response.data;
+    return data;
+  } catch (error) {
+    console.error("Error fetching:", error);
+  }
+}
 
 export const SessionsSection = () => {
+  const [sessions, setSessions] = useState<SessionType[]>([]);
+
+  useEffect(() => {
+    let intervalId: NodeJS.Timeout;
+
+    async function fetchData() {
+      const sessions = await getSessions();
+      setSessions(sessions);
+    }
+
+    fetchData(); // Initial fetch
+
+    // eslint-disable-next-line prefer-const
+    intervalId = setInterval(fetchData, 2000); // Fetch every 2 seconds
+
+    return () => clearInterval(intervalId); // Cleanup on unmount
+  }, []);
+
   return (
     <>
       <GridContainer>
-        {MOCK_SESSIONS.map((session: SessionType) => {
-          return <SessionCard key={session.sessionId} session={session} />;
+        {sessions.map((session: SessionType) => {
+          return <SessionCard key={session.id} session={session} />;
         })}
       </GridContainer>
     </>
diff --git a/modules/research-framework/portal/src/components/home/index.tsx 
b/modules/research-framework/portal/src/components/home/index.tsx
index 75e679536e..1007007e67 100644
--- a/modules/research-framework/portal/src/components/home/index.tsx
+++ b/modules/research-framework/portal/src/components/home/index.tsx
@@ -4,21 +4,21 @@ import NavBar from "../NavBar";
 import { PageHeader } from "../PageHeader";
 import { AddRepositoryButton } from "./AddRepositoryButton";
 import { AddZipButton } from "./AddZipButton";
-import { NotebooksAndRepositoriesSection } from 
"./NotebooksAndRepositoriesSection";
 import { ButtonWithIcon } from "./ButtonWithIcon";
 import { FaPlus } from "react-icons/fa";
 import { SessionsSection } from "./SessionsSection";
+import { ProjectsSection } from "./ProjectsSection";
 
 const Home = () => {
   return (
     <Box>
       <NavBar />
 
-      <Container maxW="container.xl" p={4}>
+      <Container maxW="container.xl" mt={8}>
         <HStack alignItems="flex-end" justify="space-between">
           <PageHeader
-            title="Notebook & Repositories"
-            description="Community-Published Scientific Notebooks and 
Repositories."
+            title="Projects"
+            description="Projects are a combination of repositories, 
notebooks, models, and datasets."
           />
 
           <HStack gap={4}>
@@ -27,7 +27,7 @@ const Home = () => {
           </HStack>
         </HStack>
 
-        <NotebooksAndRepositoriesSection />
+        <ProjectsSection />
 
         <HStack alignItems="flex-end" justify="space-between" mt={4}>
           <PageHeader
diff --git 
a/modules/research-framework/portal/src/components/models/ModelSpecificBox.tsx 
b/modules/research-framework/portal/src/components/models/ModelSpecificBox.tsx
index ca65114c85..b5e9f1d58e 100644
--- 
a/modules/research-framework/portal/src/components/models/ModelSpecificBox.tsx
+++ 
b/modules/research-framework/portal/src/components/models/ModelSpecificBox.tsx
@@ -9,7 +9,7 @@ export const ModelSpecificBox = ({ model }: { model: 
ModelResource }) => {
       as="a"
       w="100%"
       // @ts-expect-error This is fine
-      _target="_blank"
+      target="_blank"
       
href={`https://cybershuttle.org/workspace/applications/${model.applicationInterfaceId}/create_experiment`}
     >
       Create{" "}
diff --git a/modules/research-framework/portal/src/components/models/index.tsx 
b/modules/research-framework/portal/src/components/models/index.tsx
index 63c4863be6..0fa41c76b5 100644
--- a/modules/research-framework/portal/src/components/models/index.tsx
+++ b/modules/research-framework/portal/src/components/models/index.tsx
@@ -36,7 +36,7 @@ export const Models = () => {
     <>
       <NavBar />
 
-      <Container maxW="container.lg" p={4}>
+      <Container maxW="container.lg" mt={8}>
         <HStack alignItems="flex-end" justify="space-between">
           <PageHeader
             title="Models"
diff --git 
a/modules/research-framework/portal/src/components/notebooks/index.tsx 
b/modules/research-framework/portal/src/components/notebooks/index.tsx
index 7fa14096d3..5730581c7f 100644
--- a/modules/research-framework/portal/src/components/notebooks/index.tsx
+++ b/modules/research-framework/portal/src/components/notebooks/index.tsx
@@ -1,22 +1,37 @@
-import { Box, Container, HStack, Input, SimpleGrid } from "@chakra-ui/react";
+import { Container, Input, SimpleGrid } from "@chakra-ui/react";
 import NavBar from "../NavBar";
 import { PageHeader } from "../PageHeader";
-import { FaCode } from "react-icons/fa";
-import { MOCK_NOTEBOOKS } from "../../data/MOCK_DATA";
-import { NotebookCard } from "./NotebookCard";
 import { InputGroup } from "../ui/input-group";
 import { LuSearch } from "react-icons/lu";
-import { TagsInput } from "react-tag-input-component";
-import { useState } from "react";
+import { useEffect, useState } from "react";
+import api from "@/lib/api";
+import { NotebookResource } from "@/interfaces/ResourceType";
+import { ResourceCard } from "../home/ResourceCard";
 
-const Notebooks = () => {
-  const [tags, setTags] = useState<string[]>([]);
-  let filteredNotebooks = MOCK_NOTEBOOKS;
-  if (tags) {
-    filteredNotebooks = MOCK_NOTEBOOKS.filter((notebook) => {
-      return tags.every((tag) => notebook.tags.includes(tag));
-    });
+const getNotebooks = async () => {
+  try {
+    const response = await api.get(
+      "/project-management/resources?type=NOTEBOOK"
+    );
+    const data = response.data;
+    return data;
+  } catch (error) {
+    console.error("Error fetching:", error);
   }
+};
+
+const Notebooks = () => {
+  const [notebooks, setNotebooks] = useState<NotebookResource[]>([]);
+
+  useEffect(() => {
+    async function init() {
+      const notebooks = await getNotebooks();
+      setNotebooks(notebooks.content);
+    }
+
+    init();
+  }, []);
+
   return (
     <>
       <NavBar />
@@ -24,27 +39,26 @@ const Notebooks = () => {
       <Container maxW="container.lg" mt={8}>
         <PageHeader
           title="Notebooks"
-          icon={<FaCode />}
           description="Create and manage your notebooks. From here, you can 
create new notebooks, view existing ones, and manage them."
         />
-        <InputGroup endElement={<LuSearch />} w="100%" mt={16}>
+        <InputGroup endElement={<LuSearch />} w="100%" mt={4}>
           <Input placeholder="Search" rounded="md" />
         </InputGroup>
-        <Box mt={4}>
+        {/* <Box mt={4}>
           <TagsInput
             value={tags}
             onChange={setTags}
             placeHolder="Filter by tags"
           />
-        </Box>
+        </Box> */}
         <SimpleGrid
           columns={{ base: 1, md: 2, lg: 3 }}
           mt={4}
           gap={12}
           justifyContent="space-around"
         >
-          {filteredNotebooks.map((notebook: any) => {
-            return <NotebookCard key={notebook.slug} notebook={notebook} />;
+          {notebooks.map((notebook: NotebookResource) => {
+            return <ResourceCard resource={notebook} key={notebook.id} />;
           })}
         </SimpleGrid>
       </Container>
diff --git 
a/modules/research-framework/portal/src/components/repositories/index.tsx 
b/modules/research-framework/portal/src/components/repositories/index.tsx
index 4b1e1ebf2d..1100620a9b 100644
--- a/modules/research-framework/portal/src/components/repositories/index.tsx
+++ b/modules/research-framework/portal/src/components/repositories/index.tsx
@@ -1,11 +1,37 @@
-import { Container, VStack } from "@chakra-ui/react";
+import { Container, Input, SimpleGrid } from "@chakra-ui/react";
 import NavBar from "../NavBar";
-import { BsGithub } from "react-icons/bs";
 import { PageHeader } from "../PageHeader";
-import { MOCK_REPOSITORIES } from "../../data/MOCK_DATA";
-import { RepositoryCard } from "./RepositoryCard";
+import api from "@/lib/api";
+import { useEffect, useState } from "react";
+import { RepositoryResource } from "@/interfaces/ResourceType";
+import { ResourceCard } from "../home/ResourceCard";
+import { LuSearch } from "react-icons/lu";
+import { InputGroup } from "../ui/input-group";
+
+const getRepositories = async () => {
+  try {
+    const response = await api.get(
+      "/project-management/resources?type=REPOSITORY"
+    );
+    const data = response.data;
+    return data;
+  } catch (error) {
+    console.error("Error fetching:", error);
+  }
+};
 
 const Repositories = () => {
+  const [repositories, setRepositories] = useState<RepositoryResource[]>([]);
+
+  useEffect(() => {
+    async function init() {
+      const repositories = await getRepositories();
+      setRepositories(repositories.content);
+    }
+
+    init();
+  }, []);
+
   return (
     <>
       <NavBar />
@@ -13,24 +39,16 @@ const Repositories = () => {
       <Container maxW="container.lg" mt={8}>
         <PageHeader
           title="Repositories"
-          icon={<BsGithub />}
           description="View the most viewed repositories on GitHub, all 
central to this page."
         />
-
-        <VStack gap={4} mt={8}>
-          {
-            // This is the code that will be replaced by the code snippet
-            // from the instructions
-            MOCK_REPOSITORIES.map((repository) => {
-              return (
-                <RepositoryCard
-                  repository={repository}
-                  key={repository.githubUrl}
-                />
-              );
-            })
-          }
-        </VStack>
+        <InputGroup mt={4} endElement={<LuSearch />} w="100%">
+          <Input placeholder="Search" rounded="md" />
+        </InputGroup>
+        <SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} gap={4} mt={4}>
+          {repositories.map((repo: RepositoryResource) => {
+            return <ResourceCard resource={repo} key={repo.id} />;
+          })}
+        </SimpleGrid>
       </Container>
     </>
   );
diff --git 
a/modules/research-framework/portal/src/components/resources/ResourceDetails.tsx
 
b/modules/research-framework/portal/src/components/resources/ResourceDetails.tsx
index 230e600c23..9703047ba3 100644
--- 
a/modules/research-framework/portal/src/components/resources/ResourceDetails.tsx
+++ 
b/modules/research-framework/portal/src/components/resources/ResourceDetails.tsx
@@ -23,7 +23,7 @@ import {
 } from "@/interfaces/ResourceType";
 import { Tag } from "@/interfaces/TagType";
 import { User } from "@/interfaces/UserType";
-import { resourceTypeToColor } from "@/lib/util";
+import { isValidImaage, resourceTypeToColor } from "@/lib/util";
 import { ResourceTypeBadge } from "./ResourceTypeBadge";
 import { ResourceTypeEnum } from "@/interfaces/ResourceTypeEnum";
 import { ModelSpecificBox } from "../models/ModelSpecificBox";
@@ -52,6 +52,8 @@ const ResourceDetails = () => {
 
   if (!resource) return <Spinner />;
 
+  const validImage = isValidImaage(resource.headerImage);
+
   return (
     <>
       <NavBar />
@@ -123,12 +125,14 @@ const ResourceDetails = () => {
             </HStack>
           </Box>
 
-          <Image
-            src={resource.headerImage}
-            alt="Notebook Header"
-            rounded="md"
-            maxW="300px"
-          />
+          {validImage && (
+            <Image
+              src={resource.headerImage}
+              alt="Notebook Header"
+              rounded="md"
+              maxW="300px"
+            />
+          )}
         </HStack>
 
         <Separator my={6} />
diff --git a/modules/research-framework/portal/src/interfaces/ProjectType.tsx 
b/modules/research-framework/portal/src/interfaces/ProjectType.tsx
index b09bb66ced..40ecada683 100644
--- a/modules/research-framework/portal/src/interfaces/ProjectType.tsx
+++ b/modules/research-framework/portal/src/interfaces/ProjectType.tsx
@@ -1,7 +1,10 @@
-import { MetadataType } from "./MetadataType";
+import { DatasetResource, RepositoryResource } from "./ResourceType";
 
 export interface ProjectType {
-  metadata: MetadataType;
-  notebookViewer?: string;
-  repositoryUrl?: string;
+  id: string;
+  name: string;
+  repositoryResource: RepositoryResource;
+  datasetResources: DatasetResource[];
+  createdAt: string;
+  updatedAt: string;
 }
diff --git 
a/modules/research-framework/portal/src/interfaces/SessionStatusEnum.ts 
b/modules/research-framework/portal/src/interfaces/SessionStatusEnum.ts
new file mode 100644
index 0000000000..48a88ea8fe
--- /dev/null
+++ b/modules/research-framework/portal/src/interfaces/SessionStatusEnum.ts
@@ -0,0 +1,7 @@
+export enum SessionStatusEnum {
+  CREATED = "CREATED",
+  RUNNING = "RUNNING",
+  FINISHED = "FINISHED",
+  TERMINATED = "TERMINATED",
+  ERROR = "ERROR"
+};
\ No newline at end of file
diff --git a/modules/research-framework/portal/src/interfaces/SessionType.tsx 
b/modules/research-framework/portal/src/interfaces/SessionType.tsx
index fb483cc421..7948a6d73f 100644
--- a/modules/research-framework/portal/src/interfaces/SessionType.tsx
+++ b/modules/research-framework/portal/src/interfaces/SessionType.tsx
@@ -1,11 +1,13 @@
+import { ProjectType } from "./ProjectType";
+import { SessionStatusEnum } from "./SessionStatusEnum";
+import { User } from "./UserType";
+
 export interface SessionType {
-  sessionId: string;
-  title: string;
-  started: string;
-  models: string[];
-  datasets: string[];
-  nodes: number;
-  ram: number;
-  storage: number;
-  status: "running" | "stopped";
+  id: string;
+  sessionName: string;
+  user: User;
+  project: ProjectType;
+  createdAt: string;
+  updatedAt: string;
+  status: SessionStatusEnum;
 }
diff --git a/modules/research-framework/portal/src/lib/util.ts 
b/modules/research-framework/portal/src/lib/util.ts
index 2ccc730f1f..86fdb5c4ce 100644
--- a/modules/research-framework/portal/src/lib/util.ts
+++ b/modules/research-framework/portal/src/lib/util.ts
@@ -10,4 +10,13 @@ export const resourceTypeToColor = (type: string) => {
   } else {
     return "gray";
   }
+}
+
+export const isValidImaage = (url: string) => {
+  // should start with http or https 
+
+  if (url.startsWith("http")) {
+    return true;
+  }
+  return false
 }
\ No newline at end of file
diff --git 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/DevDataInitializer.java
 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/DevDataInitializer.java
index 63113523a2..10931bc7de 100644
--- 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/DevDataInitializer.java
+++ 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/config/DevDataInitializer.java
@@ -32,6 +32,9 @@ import org.springframework.boot.CommandLineRunner;
 import org.springframework.context.annotation.Profile;
 import org.springframework.stereotype.Component;
 
+import java.util.HashSet;
+import java.util.Set;
+
 @Component
 @Profile("dev")
 public class DevDataInitializer implements CommandLineRunner {
@@ -51,41 +54,40 @@ public class DevDataInitializer implements 
CommandLineRunner {
 
     @Override
     public void run(String... args) {
-        cleanup();
-
-        User user = new User(devUserEmail, "airavata", "admin", devUserEmail);
-        userRepository.save(user);
+        if (userRepository.count() == 0) {
+            User user = new User(devUserEmail, "airavata", "admin", 
devUserEmail);
+            user.setAvatar("");
+            userRepository.save(user);
 
-        RepositoryResource repositoryResource = new RepositoryResource();
-        repositoryResource.setName("BMTK Repository");
-        repositoryResource.setDescription("Repository for the BMTK workshop 
project");
-        repositoryResource.setHeaderImage("header_image.png");
-        
repositoryResource.setRepositoryUrl("https://github.com/AllenInstitute/bmtk-workshop.git";);
-        repositoryResource.setStatus(StatusEnum.VERIFIED);
-        repositoryResource.setPrivacy(PrivacyEnum.PUBLIC);
-        repositoryResource = resourceRepository.save(repositoryResource);
+            RepositoryResource repositoryResource = new RepositoryResource();
+            repositoryResource.setName("BMTK Repository");
+            repositoryResource.setDescription("Repository for the BMTK 
workshop project");
+            repositoryResource.setHeaderImage("header_image.png");
+            
repositoryResource.setRepositoryUrl("https://github.com/AllenInstitute/bmtk-workshop.git";);
+            repositoryResource.setStatus(StatusEnum.VERIFIED);
+            repositoryResource.setPrivacy(PrivacyEnum.PUBLIC);
+            repositoryResource = resourceRepository.save(repositoryResource);
 
-        DatasetResource datasetResource = new DatasetResource();
-        datasetResource.setName("BMTK Dataset");
-        datasetResource.setDescription("Dataset for the BMTK workshop 
project");
-        datasetResource.setHeaderImage("header_image.png");
-        datasetResource.setDatasetUrl("bmtk");
-        datasetResource.setStatus(StatusEnum.VERIFIED);
-        datasetResource.setPrivacy(PrivacyEnum.PUBLIC);
-        datasetResource = resourceRepository.save(datasetResource);
+            DatasetResource datasetResource = new DatasetResource();
+            datasetResource.setName("BMTK Dataset");
+            datasetResource.setDescription("Dataset for the BMTK workshop 
project");
+            datasetResource.setHeaderImage("header_image.png");
+            datasetResource.setDatasetUrl("bmtk");
+            datasetResource.setStatus(StatusEnum.VERIFIED);
+            datasetResource.setPrivacy(PrivacyEnum.PUBLIC);
+            Set<User> set = new HashSet<>();
+            set.add(user);
+            datasetResource.setAuthors(set);
+            datasetResource = resourceRepository.save(datasetResource);
 
-        Project project = new Project();
-        project.setRepositoryResource(repositoryResource);
-        project.getDatasetResources().add(datasetResource);
+            Project project = new Project();
+            project.setRepositoryResource(repositoryResource);
+            project.getDatasetResources().add(datasetResource);
+            project.setName("BMTK Workshop Project");
 
-        projectRepository.save(project);
-
-        System.out.println("Initialized Project with id: " + project.getId());
-    }
+            projectRepository.save(project);
 
-    public void cleanup() {
-        userRepository.deleteAll();
-        projectRepository.deleteAll();
-        resourceRepository.deleteAll();
+            System.out.println("Initialized Project with id: " + 
project.getId());
+        }
     }
-}
\ No newline at end of file
+}
diff --git 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/controller/ResearchHubController.java
 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/controller/ResearchHubController.java
index 38eab2f9ee..8f72290598 100644
--- 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/controller/ResearchHubController.java
+++ 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/controller/ResearchHubController.java
@@ -18,19 +18,24 @@
  */
 package org.apache.airavata.research.service.controller;
 
+import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import org.apache.airavata.research.service.enums.SessionStatusEnum;
 import org.apache.airavata.research.service.handlers.ResearchHubHandler;
+import org.apache.airavata.research.service.handlers.SessionHandler;
+import org.apache.airavata.research.service.model.UserContext;
+import org.apache.airavata.research.service.model.entity.Project;
+import org.apache.airavata.research.service.model.entity.Session;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.repository.query.Param;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.net.URI;
+import java.util.List;
 
 @RestController
 @RequestMapping("/api/v1/rf/hub")
@@ -41,11 +46,21 @@ public class ResearchHubController {
 
     private final ResearchHubHandler rHubHandler;
 
+    @Autowired
+    private SessionHandler sessionHandler;
+
     public ResearchHubController(ResearchHubHandler rHubHandler) {
         this.rHubHandler = rHubHandler;
     }
 
+    @GetMapping("/projects")
+    @Operation(summary = "Get all projects")
+    public ResponseEntity<List<Project>> getAllProjects() {
+        return ResponseEntity.ok(rHubHandler.getAllProjects());
+    }
+
     @GetMapping("/project/{projectId}")
+    @Operation(summary = "Spawn new project session")
     public ResponseEntity<?> resolveRHubUrl(@PathVariable("projectId") String 
projectId, @RequestParam("sessionName") String sessionName) {
         String spawnUrl = rHubHandler.spinRHubSession(projectId, sessionName);
 
@@ -53,7 +68,28 @@ public class ResearchHubController {
         return 
ResponseEntity.status(HttpStatus.FOUND).location(URI.create(spawnUrl)).build();
     }
 
-    @GetMapping("/session/{sessionId}")
+    @GetMapping("/project/{projectId}/exists")
+    @Operation(summary = "Check if session with project already exists")
+    public ResponseEntity<Boolean> 
getProjectSessionExists(@PathVariable("projectId") String projectId) {
+
+        return 
ResponseEntity.ok(sessionHandler.checkIfSessionExists(projectId, 
UserContext.user().getId()));
+    }
+
+    @GetMapping("/sessions")
+    @Operation(summary = "Get all sessions for a given user")
+    public ResponseEntity<List<Session>> getSessions() {
+        String userId = UserContext.user().getId();
+        List<Session> sessions = sessionHandler.findAllByUserId(userId);
+        return ResponseEntity.ok(sessions);
+    }
+
+    @PatchMapping("/sessions/{sessionId}")
+    @Operation(summary = "Update a session's status")
+    public ResponseEntity<Session> 
updateSessionStatus(@PathVariable(value="sessionId") String sessionId, 
@Param(value="status") SessionStatusEnum status) {
+        return ResponseEntity.ok(sessionHandler.updateSessionStatus(sessionId, 
status));
+    }
+
+    @GetMapping("/sessions/{sessionId}/resolve")
     public ResponseEntity<?> 
resolveRHubExistingSession(@PathVariable("sessionId") String sessionId) {
         String spawnUrl = rHubHandler.resolveRHubExistingSession(sessionId);
 
diff --git 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/enums/SessionStatusEnum.java
 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/enums/SessionStatusEnum.java
new file mode 100644
index 0000000000..031e539902
--- /dev/null
+++ 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/enums/SessionStatusEnum.java
@@ -0,0 +1,17 @@
+package org.apache.airavata.research.service.enums;
+
+public enum SessionStatusEnum {
+    CREATED("CREATED"),
+    RUNNING("RUNNING"),
+    FINISHED("FINISHED"),
+    TERMINATED("TERMINATED"),
+    ERROR("ERROR");
+
+    private String str;
+    SessionStatusEnum(String str) {
+        this.str = str;
+    }
+    public String toString() {
+        return str;
+    }
+}
diff --git 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ResearchHubHandler.java
 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ResearchHubHandler.java
index 308edd7dbe..2aa69ef473 100644
--- 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ResearchHubHandler.java
+++ 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/ResearchHubHandler.java
@@ -22,11 +22,14 @@ import 
org.apache.airavata.research.service.model.UserContext;
 import org.apache.airavata.research.service.model.entity.DatasetResource;
 import org.apache.airavata.research.service.model.entity.Project;
 import org.apache.airavata.research.service.model.entity.Session;
+import org.apache.airavata.research.service.model.repo.ProjectRepository;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 @Service
 public class ResearchHubHandler {
 
@@ -36,13 +39,15 @@ public class ResearchHubHandler {
 
     private final ProjectHandler projectHandler;
     private final SessionHandler sessionHandler;
+    private final ProjectRepository projectRepository;
 
     @Value("${cybershuttle.hub.url}")
     private String csHubUrl;
 
-    public ResearchHubHandler(ProjectHandler projectHandler, SessionHandler 
sessionHandler) {
+    public ResearchHubHandler(ProjectHandler projectHandler, SessionHandler 
sessionHandler, ProjectRepository projectRepository) {
         this.projectHandler = projectHandler;
         this.sessionHandler = sessionHandler;
+        this.projectRepository = projectRepository;
     }
 
     public String spinRHubSession(String projectId, String sessionName) {
@@ -65,4 +70,8 @@ public class ResearchHubHandler {
         LOGGER.debug("Generated the session url: {} for the user: {}", 
sessionUrl, UserContext.username());
         return sessionUrl;
     }
+
+    public List<Project> getAllProjects() {
+        return projectRepository.findAll();
+    }
 }
diff --git 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/SessionHandler.java
 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/SessionHandler.java
index d9c56d6127..45360420c0 100644
--- 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/SessionHandler.java
+++ 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/handlers/SessionHandler.java
@@ -19,6 +19,7 @@
 package org.apache.airavata.research.service.handlers;
 
 import jakarta.persistence.EntityNotFoundException;
+import org.apache.airavata.research.service.enums.SessionStatusEnum;
 import org.apache.airavata.research.service.model.UserContext;
 import org.apache.airavata.research.service.model.entity.Project;
 import org.apache.airavata.research.service.model.entity.Session;
@@ -28,6 +29,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
 import java.util.UUID;
 
 @Service
@@ -51,8 +53,30 @@ public class SessionHandler {
     public Session createSession(String sessionName, Project project) {
         sessionName = StringUtils.isNotBlank(sessionName) ? sessionName : 
UUID.randomUUID().toString().substring(0, 6);
         Session session = new Session(sessionName, UserContext.user(), 
project);
+        session.setStatus(SessionStatusEnum.CREATED);
         session = sessionRepository.save(session);
         LOGGER.debug("Created session with Id: {}, Name: {}", session.getId(), 
sessionName);
         return session;
     }
+
+    public List<Session> findAllByUserId(String userId) {
+        List<Session> sessions = sessionRepository.findByUserId(userId);
+        return sessions;
+    }
+
+    public Session updateSessionStatus(String sessionId, SessionStatusEnum 
status) {
+        Session session = findSession(sessionId);
+        session.setStatus(status);
+        session = sessionRepository.save(session);
+        LOGGER.debug("Updated session with Id: {}, Status: {}", 
session.getId(), status);
+        return session;
+    }
+
+    public boolean checkIfSessionExists(String projectId, String userId) {
+        if (sessionRepository.findSessionByProjectIdAndUserId(projectId, 
userId).isEmpty()) {
+            throw new RuntimeException("Session does not exist");
+        }
+        return true;
+    }
+
 }
diff --git 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/entity/Project.java
 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/entity/Project.java
index 7431ee79fb..1c0f3deebb 100644
--- 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/entity/Project.java
+++ 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/entity/Project.java
@@ -48,6 +48,9 @@ public class Project {
     @Column(nullable = false, updatable = false, length = 48)
     private String id;
 
+    @Column(nullable = false)
+    private String name;
+
     @ManyToOne(fetch = FetchType.EAGER, optional = false)
     @JoinColumn(name = "repository_resource_id")
     private RepositoryResource repositoryResource;
@@ -68,6 +71,14 @@ public class Project {
     @LastModifiedDate
     private Instant updatedAt;
 
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
     public String getId() {
         return id;
     }
diff --git 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/entity/Session.java
 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/entity/Session.java
index 826391ae11..6327a1fdb6 100644
--- 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/entity/Session.java
+++ 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/entity/Session.java
@@ -18,15 +18,8 @@
  */
 package org.apache.airavata.research.service.model.entity;
 
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.EntityListeners;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
+import jakarta.persistence.*;
+import org.apache.airavata.research.service.enums.SessionStatusEnum;
 import org.hibernate.annotations.UuidGenerator;
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.annotation.LastModifiedDate;
@@ -48,11 +41,11 @@ public class Session {
     @Column(nullable = false)
     private String sessionName;
 
-    @ManyToOne(fetch = FetchType.LAZY, optional = false)
+    @ManyToOne(fetch = FetchType.EAGER, optional = false)
     @JoinColumn(name = "user_id")
     private User user;
 
-    @ManyToOne(fetch = FetchType.LAZY, optional = false)
+    @ManyToOne(fetch = FetchType.EAGER, optional = false)
     @JoinColumn(name = "project_id")
     private Project project;
 
@@ -64,6 +57,10 @@ public class Session {
     @LastModifiedDate
     private Instant updatedAt;
 
+    @Column(nullable = false)
+    @Enumerated(EnumType.STRING)
+    private SessionStatusEnum status;
+
     public Session() {
     }
 
@@ -73,6 +70,14 @@ public class Session {
         this.project = project;
     }
 
+    public SessionStatusEnum getStatus() {
+        return status;
+    }
+
+    public void setStatus(SessionStatusEnum status) {
+        this.status = status;
+    }
+
     public String getId() {
         return id;
     }
diff --git 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/repo/SessionRepository.java
 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/repo/SessionRepository.java
index 1292613150..42e9ad95e5 100644
--- 
a/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/repo/SessionRepository.java
+++ 
b/modules/research-framework/research-service/src/main/java/org/apache/airavata/research/service/model/repo/SessionRepository.java
@@ -20,6 +20,15 @@ package org.apache.airavata.research.service.model.repo;
 
 import org.apache.airavata.research.service.model.entity.Session;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+import java.util.Optional;
 
 public interface SessionRepository extends JpaRepository<Session, String> {
+    List<Session> findByUserId(String userId);
+
+    @Query(value = "SELECT * FROM session WHERE project_id = :projectId AND 
user_id = :userId", nativeQuery = true)
+    Optional<Session> findSessionByProjectIdAndUserId(@Param("projectId") 
String projectId, @Param("userId") String userId);
 }
diff --git 
a/modules/research-framework/research-service/src/main/resources/application.yml
 
b/modules/research-framework/research-service/src/main/resources/application.yml
index 7e7f285635..9df2778bc3 100644
--- 
a/modules/research-framework/research-service/src/main/resources/application.yml
+++ 
b/modules/research-framework/research-service/src/main/resources/application.yml
@@ -9,7 +9,7 @@ server:
 cybershuttle:
   hub:
     url: https://hub.dev.cybershuttle.org
-    dev-user: "CHANGE_ME"
+    dev-user: "[email protected]"
 
 spring:
   servlet:

Reply via email to