Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,6 @@ jobs:
uses: softprops/action-gh-release@v1
with:
generate_release_notes: true
files: |
dist/*.whl
build/sphinx/html
# files: |
# dist/*.whl
# build/sphinx/html
2 changes: 1 addition & 1 deletion ansys/rep/client/__version__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "0.1.dev0"
__version__ = "0.2.dev0"
__external_version__ = "2023 R2"
__version_no_dots__ = "232"
__company__ = "ANSYS, Inc."
Expand Down
50 changes: 50 additions & 0 deletions ansys/rep/client/jms/api/jms_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from typing import List, Union
import uuid

import requests

from ansys.rep.client.client import Client
from ansys.rep.client.exceptions import REPError
from ansys.rep.client.jms.resource import (
Expand Down Expand Up @@ -46,12 +48,20 @@ class JmsApi(object):

def __init__(self, client: Client):
self.client = client
self._fs_url = None

@property
def url(self) -> str:
"""Returns the API url"""
return f"{self.client.rep_url}/jms/api/v1"

@property
def fs_url(self) -> str:
"""URL of the file storage gateway"""
if self._fs_url is None:
self._fs_url = get_fs_url(self.client, self.url)
return self._fs_url

def get_api_info(self):
"""Return info like version, build date etc of the JMS API the client is connected to"""
r = self.client.session.get(self.url)
Expand Down Expand Up @@ -234,6 +244,12 @@ def get_operation(self, id, as_object=True) -> Operation:
def _monitor_operation(self, operation_id: str, interval: float = 1.0):
return _monitor_operation(self, operation_id, interval)

################################################################
# Storages
def get_storage(self):
"""Return a list of storages"""
return get_storages(self.client, self.url)


def get_projects(client, api_url, as_objects=True, **query_params) -> List[Project]:
"""
Expand Down Expand Up @@ -382,3 +398,37 @@ def restore_project(jms_api, archive_path):
r = jms_api.client.session.put(f"{jms_api.client.rep_url}/fs/api/v1/remove/{bucket}")

return get_project(jms_api.client, jms_api.url, project_id)


def get_storages(client, api_url):
"""
Returns list of storages
"""
url = f"{api_url}/storage"
r = client.session.get(url)
return r.json()["backends"]


def get_fs_url(client, api_url):

file_storages = get_storages(client, api_url)

if not file_storages:
raise REPError(f"No file storage information.")

rest_gateways = [fs for fs in file_storages if fs["obj_type"] == "RestGateway"]
rest_gateways.sort(key=lambda fs: fs["priority"])

if not rest_gateways:
raise REPError(f"No Rest Gateway defined.")

for d in rest_gateways:
url = d["url"]
try:
r = requests.get(url, verify=False, timeout=2)
except Exception as ex:
log.debug(ex)
continue
if r.status_code == 200:
return url
return None
33 changes: 3 additions & 30 deletions ansys/rep/client/jms/api/project_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
from typing import Callable, List, Type, Union
from warnings import warn

from cachetools import TTLCache, cached
from marshmallow.utils import missing
import requests

from ansys.rep.client.client import Client
Expand All @@ -22,14 +20,13 @@
ParameterDefinition,
ParameterMapping,
Permission,
Project,
Task,
TaskDefinition,
)
from ansys.rep.client.jms.schema.job import JobSchema

from .base import create_objects, delete_objects, get_objects, update_objects
from .jms_api import JmsApi, _monitor_operation, get_project
from .jms_api import JmsApi, _monitor_operation

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -93,10 +90,8 @@ def url(self) -> str:
@property
def fs_url(self) -> str:
"""URL of the file storage gateway"""
if self._fs_url is None or self._fs_project_id != self.project_id:
self._fs_project_id = self.project_id
project = get_project(self.client, self.jms_api_url, id=self.project_id)
self._fs_url = get_fs_url(project)
if self._fs_url is None:
self._fs_url = JmsApi(self.client).fs_url
return self._fs_url

@property
Expand Down Expand Up @@ -615,28 +610,6 @@ def sync_jobs(project_api: ProjectApi, jobs: List[Job]):
r = project_api.client.session.put(f"{url}", data=json_data)


@cached(cache=TTLCache(1024, 60), key=lambda project: project.id)
def get_fs_url(project: Project):
if project.file_storages == missing:
raise REPError(f"The project object has no file storages information.")
rest_gateways = [fs for fs in project.file_storages if fs["obj_type"] == "RestGateway"]
rest_gateways.sort(key=lambda fs: fs["priority"])

if not rest_gateways:
raise REPError(f"Project {project.name} (id={project.id}) has no Rest Gateway defined.")

for d in rest_gateways:
url = d["url"]
try:
r = requests.get(url, verify=False, timeout=2)
except Exception as ex:
log.debug(ex)
continue
if r.status_code == 200:
return url
return None


def _fs_copy_file(
session: requests.Session,
fs_url: str,
Expand Down
4 changes: 0 additions & 4 deletions ansys/rep/client/jms/resource/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ class Project(Object):
The date and time the project was created.
modification_time : datetime, optional
The date and time the project was last modified.
file_storages : list
List of file storages defined for the project.
statistics : dict
Optional dictionary containing various project statistics.

Expand All @@ -38,7 +36,6 @@ def __init__(self,
priority=missing,
creation_time=missing,
modification_time=missing,
file_storages=missing,
statistics=missing
):
self.id = id
Expand All @@ -47,7 +44,6 @@ def __init__(self,
self.priority = priority
self.creation_time = creation_time
self.modification_time = modification_time
self.file_storages = file_storages
self.statistics = statistics

self.obj_type = self.__class__.__name__
Expand Down
3 changes: 0 additions & 3 deletions ansys/rep/client/jms/schema/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ class Meta(BaseSchema.Meta):
description="The date and time the project was last modified.",
)

file_storages = fields.List(
fields.Dict(), description="List of file storages defined for the project."
)
statistics = fields.Dict(
load_only=True, description="Optional dictionary containing various project statistics."
)
10 changes: 10 additions & 0 deletions tests/jms/test_jms_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,16 @@ def test_fields_query_parameter(self):
# Delete project
JmsApi(client1).delete_project(project)

def test_storage_configuration(self):

client = self.client()
jms_api = JmsApi(client)
storages = jms_api.get_storage()
for storage in storages:
self.assertTrue("name" in storage)
self.assertTrue("priority" in storage)
self.assertTrue("obj_type" in storage)


if __name__ == "__main__":
unittest.main()
34 changes: 0 additions & 34 deletions tests/jms/test_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,34 +44,6 @@ def test_project_deserialization(self):
},
"num_jobs": 56,
},
"file_storages": [
{
"obj_type": "RestGateway",
"name": "dc_fs_gateway",
"url": "https://212.126.163.153:443/dcs/fs/api",
"use_default_url": False,
"priority": 20,
"reference": "file_system_storage",
},
{
"obj_type": "FileSystemStorage",
"name": "file_system_storage",
"cache": False,
"persistent": True,
"priority": 10,
"storage_directory": "/media/dcp_data/ansft_gateway/default_fs_storage/",
"owner_uuid": "0ea21dc4-37da-46e2-85e2-4f4a78dcdf0a",
},
{
"obj_type": "FileSystemStorage",
"name": "shared_file_system_storage",
"cache": False,
"persistent": True,
"priority": 5,
"storage_directory": "/media/ansys/tmp_storage/",
"owner_uuid": "0ea21dc4-37da-46e2-85e2-4f4a78dcdf0a",
},
],
}

project = ProjectSchema().load(project_dict)
Expand All @@ -89,11 +61,6 @@ def test_project_deserialization(self):
project_dict["statistics"]["eval_status"]["failed"],
)

self.assertEqual(len(project.file_storages), 3)
self.assertEqual(project.file_storages[0]["name"], "dc_fs_gateway")
self.assertEqual(project.file_storages[0]["reference"], "file_system_storage")
self.assertEqual(project.file_storages[2]["storage_directory"], "/media/ansys/tmp_storage/")

def test_project_serialization(self):

project = Project(name="new_project")
Expand All @@ -104,7 +71,6 @@ def test_project_serialization(self):
serialized_project = ProjectSchema().dump(project)

self.assertTrue("name" in serialized_project.keys())
self.assertFalse("file_storages" in serialized_project.keys())
self.assertEqual(serialized_project["name"], "new_project")

def test_project_integration(self):
Expand Down